diff -r ba323bbed6a4 -r 0bcc13460dae pgtoolkit/pgbrowser.py --- a/pgtoolkit/pgbrowser.py Mon Dec 17 21:12:04 2012 +0100 +++ b/pgtoolkit/pgbrowser.py Thu Jan 24 17:11:17 2013 +0100 @@ -112,9 +112,30 @@ return self._indexes indexes = property(getindexes) + +class Function: + def __init__(self, browser, schema, oid, name, type, arguments, result, source): + self.browser = browser + self.oid = oid + self.name = name + self.type = type + self.arguments = arguments + self.result = result + self.source = source + self._definition = None + + @property + def definition(self): + """Get full function definition including CREATE command.""" + if not self._definition: + self._definition = self.browser.get_function_definition(self.oid) + return self._definition + + class Schema: def __init__(self, browser, name, owner, acl, description, system): self._tables = None + self._functions = None self.browser = browser self.name = name self.owner = owner @@ -123,14 +144,28 @@ self.system = system def refresh(self): + self.refresh_tables() + self.refresh_functions() + + def refresh_tables(self): rows = self.browser.list_tables(self.name) self._tables = OrderedDict([(x['name'], Table(self.browser, self, **x)) for x in rows]) - def gettables(self): + def refresh_functions(self): + rows = self.browser.list_functions(self.name) + self._functions = OrderedDict([(x['name'], Function(self.browser, self, **x)) for x in rows]) + + @property + def tables(self): if self._tables is None: - self.refresh() + self.refresh_tables() return self._tables - tables = property(gettables) + + @property + def functions(self): + if self._functions is None: + self.refresh_functions() + return self._functions class PgBrowser: @@ -142,14 +177,17 @@ self.conn = conn def refresh(self): + self.refresh_schemas() + + def refresh_schemas(self): rows = self.list_schemas() self._schemas = OrderedDict([(x['name'], Schema(self, **x)) for x in rows]) - def getschemas(self): + @property + def schemas(self): if self._schemas is None: - self.refresh() + self.refresh_schemas() return self._schemas - schemas = property(getschemas) def _query(self, query, args): try: @@ -263,6 +301,37 @@ ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname ''', {'schema': schema, 'table': table}) + def list_functions(self, schema='public'): + '''List functions in schema.''' + return self._query(''' + SELECT + p.oid as "oid", + p.proname as "name", + pg_catalog.pg_get_function_result(p.oid) as "result", + pg_catalog.pg_get_function_arguments(p.oid) as "arguments", + p.prosrc as "source", + CASE + WHEN p.proisagg THEN 'agg' + WHEN p.proiswindow THEN 'window' + WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger' + ELSE 'normal' + END as "type" + FROM pg_catalog.pg_proc p + LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace + WHERE pg_catalog.pg_function_is_visible(p.oid) + AND n.nspname = %s + ORDER BY 1, 2, 4; + ''', [schema]) + + def get_function_definition(self, oid): + """Get full function definition, including CREATE command etc. + + Args: + oid: function oid from pg_catalog.pg_proc (returned by list_functions) + + """ + return self._query('''select pg_get_functiondef(%s);''', [oid]) + def list_sequences(self, schema=None): '''List sequences in schema.''' return self._query('''