--- 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('''