[Python-modules-commits] [python-pgspecial] 01/07: Import python-pgspecial_1.8.0.orig.tar.gz

ChangZhuo Chen czchen at moszumanska.debian.org
Tue Jun 6 12:24:33 UTC 2017


This is an automated email from the git hooks/post-receive script.

czchen pushed a commit to branch debian/experimental
in repository python-pgspecial.

commit fdcdce524a54bf568ac753d60b62d560cbd1826f
Author: ChangZhuo Chen (陳昌倬) <czchen at debian.org>
Date:   Tue Jun 6 20:15:50 2017 +0800

    Import python-pgspecial_1.8.0.orig.tar.gz
---
 PKG-INFO                                           |   2 +-
 pgspecial.egg-info/PKG-INFO                        |   2 +-
 pgspecial/__init__.py                              |   2 +-
 pgspecial/dbcommands.py                            |  89 +++++----
 pgspecial/iocommands.py                            |  25 ++-
 pgspecial/main.py                                  |   1 -
 .../test_specials.cpython-27-PYTEST.pyc            | Bin 19482 -> 32806 bytes
 tests/dbutils.py                                   |  11 +-
 tests/dbutils.pyc                                  | Bin 2497 -> 2692 bytes
 tests/test_specials.py                             | 208 ++++++++++++++++++++-
 10 files changed, 284 insertions(+), 56 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index 7ecc020..d557cc3 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pgspecial
-Version: 1.7.0
+Version: 1.8.0
 Summary: Meta-commands handler for Postgres Database.
 Home-page: http://pgcli.com
 Author: Amjith Ramanujam
diff --git a/pgspecial.egg-info/PKG-INFO b/pgspecial.egg-info/PKG-INFO
index 7ecc020..d557cc3 100644
--- a/pgspecial.egg-info/PKG-INFO
+++ b/pgspecial.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pgspecial
-Version: 1.7.0
+Version: 1.8.0
 Summary: Meta-commands handler for Postgres Database.
 Home-page: http://pgcli.com
 Author: Amjith Ramanujam
diff --git a/pgspecial/__init__.py b/pgspecial/__init__.py
index 32d911c..8851104 100644
--- a/pgspecial/__init__.py
+++ b/pgspecial/__init__.py
@@ -1,5 +1,5 @@
 __all__ = []
-__version__ = '1.7.0'
+__version__ = '1.8.0'
 
 
 def export(defn):
diff --git a/pgspecial/dbcommands.py b/pgspecial/dbcommands.py
index 4091ac0..99b6208 100644
--- a/pgspecial/dbcommands.py
+++ b/pgspecial/dbcommands.py
@@ -1,5 +1,6 @@
 import logging
 from collections import namedtuple
+
 from .main import special_command, RAW_QUERY
 
 TableInfo = namedtuple("TableInfo", ['checks', 'relkind', 'hasindex',
@@ -75,7 +76,7 @@ def list_roles(cur, pattern, verbose):
 
 
 @special_command('\\db', '\\db[+] [pattern]', 'List tablespaces.')
-def list_tablestpaces(cur, pattern, **_):
+def list_tablespaces(cur, pattern, **_):
     """
     Returns (title, rows, headers, status)
     """
@@ -192,13 +193,13 @@ def _find_extensions(cur, pattern):
 
 def _describe_extension(cur, oid):
     sql = '''
-        SELECT 	pg_catalog.pg_describe_object(classid, objid, 0)
+        SELECT  pg_catalog.pg_describe_object(classid, objid, 0)
                   AS "Object Description"
-        FROM 	pg_catalog.pg_depend
+        FROM    pg_catalog.pg_depend
         WHERE   refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass
                 AND refobjid = %s
                 AND deptype = 'e'
-        ORDER BY 1 '''
+        ORDER BY 1'''
     sql = cur.mogrify(sql, [oid])
     log.debug(sql)
     cur.execute(sql)
@@ -211,7 +212,8 @@ def list_objects(cur, pattern, verbose, relkinds):
     """
         Returns (title, rows, header, status)
 
-        This method is used by list_tables, list_views, and list_indexes
+        This method is used by list_tables, list_views, list_materialized views
+        and list_indexes
 
         relkinds is a list of strings to filter pg_class.relkind
 
@@ -276,6 +278,11 @@ def list_views(cur, pattern, verbose):
     return list_objects(cur, pattern, verbose, ['v', 's', ''])
 
 
+ at special_command('\\dm', '\\dm[+] [pattern]', 'List materialized views.')
+def list_materialized_views(cur, pattern, verbose):
+    return list_objects(cur, pattern, verbose, ['m', 's', ''])
+
+
 @special_command('\\ds', '\\ds[+] [pattern]', 'List sequences.')
 def list_sequences(cur, pattern, verbose):
     return list_objects(cur, pattern, verbose, ['S', 's', ''])
@@ -448,38 +455,15 @@ def list_datatypes(cur, pattern, verbose):
 
 
 @special_command('describe', 'DESCRIBE [pattern]', '', hidden=True, case_sensitive=False)
- at special_command('\\d', '\\d [pattern]', 'List or describe tables, views and sequences.')
+ at special_command('\\d', '\\d[+] [pattern]', 'List or describe tables, views and sequences.')
 def describe_table_details(cur, pattern, verbose):
     """
     Returns (title, rows, headers, status)
     """
 
-    # This is a simple \d command. No table name to follow.
+    # This is a simple \d[+] command. No table name to follow.
     if not pattern:
-        sql = """SELECT n.nspname as "Schema", c.relname as "Name",
-                    CASE c.relkind WHEN 'r' THEN 'table'
-                        WHEN 'v' THEN 'view'
-                        WHEN 'm' THEN 'materialized view'
-                        WHEN 'i' THEN 'index'
-                        WHEN 'S' THEN 'sequence'
-                        WHEN 's' THEN 'special'
-                        WHEN 'f' THEN 'foreign table'
-                    END as "Type",
-                    pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
-                FROM pg_catalog.pg_class c
-                LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
-                WHERE c.relkind IN ('r','v','m','S','f','')
-                AND n.nspname <> 'pg_catalog'
-                AND n.nspname <> 'information_schema'
-                AND n.nspname !~ '^pg_toast'
-                AND pg_catalog.pg_table_is_visible(c.oid)
-                ORDER BY 1,2 """
-
-        log.debug(sql)
-        cur.execute(sql)
-        if cur.description:
-            headers = [x[0] for x in cur.description]
-            return [(None, cur, headers, cur.statusmessage)]
+        return list_objects(cur, pattern, verbose, ['r', 'v', 'm', 'S', 'f', ''])
 
     # This is a \d <tablename> command. A royal pain in the ass.
     schema, relname = sql_name_pattern(pattern)
@@ -656,8 +640,6 @@ def describe_one_table_details(cur, schema_name, relation_name, oid, verbose):
     cur.execute(sql)
     res = cur.fetchall()
 
-    title = (tableinfo.relkind, schema_name, relation_name)
-
     # Set the column names.
     headers = ['Column', 'Type']
 
@@ -996,7 +978,7 @@ def describe_one_table_details(cur, schema_name, relation_name, oid, verbose):
             for row in cur:
                 #/* untranslated contraint name and def */
                 status.append("    \"%s\" %s" % row)
-            status.append('\n')
+                status.append('\n')
 
         #/* print foreign-key constraints (there are none if no triggers) */
         if (tableinfo.hastriggers):
@@ -1310,3 +1292,42 @@ def sql_name_pattern(pattern):
         schema = '^(' + schema + ')$'
 
     return schema, relname
+
+
+class _FakeCursor(list):
+    "Minimalistic wrapper simulating a real cursor, as far as pgcli is concerned."
+
+    def rowcount(self):
+        return len(self)
+
+
+ at special_command('\\sf', '\\sf[+] FUNCNAME', 'Show a function\'s definition.')
+def show_function_definition(cur, pattern, verbose):
+    if '(' in pattern:
+        sql = cur.mogrify("SELECT %s::pg_catalog.regprocedure::pg_catalog.oid", [pattern])
+    else:
+        sql = cur.mogrify("SELECT %s::pg_catalog.regproc::pg_catalog.oid", [pattern])
+    log.debug(sql)
+    cur.execute(sql)
+    (foid,) = cur.fetchone()
+
+    sql = cur.mogrify("SELECT pg_catalog.pg_get_functiondef(%s) as source", [foid])
+    log.debug(sql)
+    cur.execute(sql)
+    if cur.description:
+        headers = [x[0] for x in cur.description]
+        if verbose:
+            (source,) = cur.fetchone()
+            rows = _FakeCursor()
+            rown = None
+            for row in source.splitlines():
+                if rown is None:
+                    if row.startswith('AS '):
+                        rown = 1
+                else:
+                    rown += 1
+                rows.append('%-7s %s' % ('' if rown is None else rown, row))
+            cur = [('\n'.join(rows) + '\n',)]
+    else:
+        headers = None
+    return [(None, cur, headers, None)]
diff --git a/pgspecial/iocommands.py b/pgspecial/iocommands.py
index 14a869c..5544a70 100644
--- a/pgspecial/iocommands.py
+++ b/pgspecial/iocommands.py
@@ -43,13 +43,8 @@ def get_watch_command(command):
 
 
 @export
-def open_external_editor(filename=None, sql=''):
-    """
-    Open external editor, wait for the user to type in his query,
-    return the query.
-    :return: list with one tuple, query as first element.
-    """
-
+def get_editor_query(sql):
+    """Get the query part of an editor command."""
     sql = sql.strip()
 
     # The reason we can't simply do .strip('\e') is that it strips characters,
@@ -59,15 +54,27 @@ def open_external_editor(filename=None, sql=''):
     while pattern.search(sql):
         sql = pattern.sub('', sql)
 
+    return sql
+
+
+ at export
+def open_external_editor(filename=None, sql=None):
+    """
+    Open external editor, wait for the user to type in his query,
+    return the query.
+    :return: list with one tuple, query as first element.
+    """
+
     message = None
     filename = filename.strip().split(' ', 1)[0] if filename else None
 
+    sql = sql or ''
     MARKER = '# Type your query above this line.\n'
 
     # Populate the editor buffer with the partial sql (if available) and a
     # placeholder comment.
-    query = click.edit(sql + '\n\n' + MARKER, filename=filename,
-            extension='.sql')
+    query = click.edit('{sql}\n\n{marker}'.format(sql=sql, marker=MARKER),
+                       filename=filename, extension='.sql')
 
     if filename:
         try:
diff --git a/pgspecial/main.py b/pgspecial/main.py
index 202f5d0..d9e0f02 100644
--- a/pgspecial/main.py
+++ b/pgspecial/main.py
@@ -240,7 +240,6 @@ def doc_only():
 
 
 @special_command('\\ef', '\\ef [funcname [line]]', 'Edit the contents of the query buffer.', arg_type=NO_QUERY, hidden=True)
- at special_command('\\sf', '\\sf[+] FUNCNAME', 'Show a function\'s definition.', arg_type=NO_QUERY, hidden=True)
 @special_command('\\do', '\\do[S] [pattern]', 'List operators.', arg_type=NO_QUERY, hidden=True)
 @special_command('\\dp', '\\dp [pattern]', 'List table, view, and sequence access privileges.', arg_type=NO_QUERY, hidden=True)
 @special_command('\\z', '\\z [pattern]', 'Same as \\dp.', arg_type=NO_QUERY, hidden=True)
diff --git a/tests/__pycache__/test_specials.cpython-27-PYTEST.pyc b/tests/__pycache__/test_specials.cpython-27-PYTEST.pyc
index 16f8c12..7f67762 100644
Binary files a/tests/__pycache__/test_specials.cpython-27-PYTEST.pyc and b/tests/__pycache__/test_specials.cpython-27-PYTEST.pyc differ
diff --git a/tests/dbutils.py b/tests/dbutils.py
index 4d13527..a454f65 100644
--- a/tests/dbutils.py
+++ b/tests/dbutils.py
@@ -45,13 +45,18 @@ def setup_db(conn):
 
         # tables
         cur.execute('create table tbl1(id1 integer, txt1 text, CONSTRAINT id_text PRIMARY KEY(id1, txt1))')
-        cur.execute('create table tbl2(id2 integer, txt2 text)')
+        cur.execute('create table tbl2(id2 serial, txt2 text)')
         cur.execute('create table schema1.s1_tbl1(id1 integer, txt1 text)')
 
         # views
         cur.execute('create view vw1 as select * from tbl1')
-        cur.execute('''create view schema1.s1_vw1 as select * from
-                schema1.s1_tbl1''')
+        cur.execute('''create view schema1.s1_vw1 as
+                       select * from schema1.s1_tbl1''')
+
+        # materialized views
+        cur.execute('create materialized view mvw1 as select * from tbl1')
+        cur.execute('''create materialized view schema1.s1_mvw1 as
+                       select * from schema1.s1_tbl1''')
 
         # datatype
         cur.execute('create type foo AS (a int, b text)')
diff --git a/tests/dbutils.pyc b/tests/dbutils.pyc
index a464794..9aaa852 100644
Binary files a/tests/dbutils.pyc and b/tests/dbutils.pyc differ
diff --git a/tests/test_specials.py b/tests/test_specials.py
index 5499e3f..4b4aa6f 100644
--- a/tests/test_specials.py
+++ b/tests/test_specials.py
@@ -3,18 +3,37 @@
 
 from dbutils import dbtest, POSTGRES_USER
 import itertools
-from codecs import open
+
+objects_listing_headers = ['Schema', 'Name', 'Type', 'Owner', 'Size', 'Description']
 
 
 @dbtest
 def test_slash_d(executor):
     results = executor('\d')
     title = None
-    rows = [('public', 'tbl1', 'table', POSTGRES_USER),
+    rows = [('public', 'mvw1', 'materialized view', POSTGRES_USER),
+            ('public', 'tbl1', 'table', POSTGRES_USER),
             ('public', 'tbl2', 'table', POSTGRES_USER),
+            ('public', 'tbl2_id2_seq', 'sequence', POSTGRES_USER),
             ('public', 'vw1', 'view', POSTGRES_USER)]
-    headers = ['Schema', 'Name', 'Type', 'Owner']
-    status = 'SELECT 3'
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 5'
+    expected = [title, rows, headers, status]
+
+    assert results == expected
+
+
+ at dbtest
+def test_slash_d_verbose(executor):
+    results = executor('\d+')
+    title = None
+    rows = [('public', 'mvw1', 'materialized view', POSTGRES_USER, '8192 bytes', None),
+            ('public', 'tbl1', 'table', POSTGRES_USER, '8192 bytes', None),
+            ('public', 'tbl2', 'table', POSTGRES_USER, '8192 bytes', None),
+            ('public', 'tbl2_id2_seq', 'sequence', POSTGRES_USER, '8192 bytes', None),
+            ('public', 'vw1', 'view', POSTGRES_USER, '0 bytes', None)]
+    headers = objects_listing_headers
+    status = 'SELECT 5'
     expected = [title, rows, headers, status]
 
     assert results == expected
@@ -34,6 +53,19 @@ def test_slash_d_table(executor):
 
 
 @dbtest
+def test_slash_d_table_verbose(executor):
+    results = executor('\d+ tbl1')
+    title = None
+    rows = [['id1', 'integer', ' not null', 'plain', None, None],
+            ['txt1', 'text', ' not null', 'extended', None, None],
+            ]
+    headers = ['Column', 'Type', 'Modifiers', 'Storage', 'Stats target', 'Description']
+    status = 'Indexes:\n    "id_text" PRIMARY KEY, btree (id1, txt1)\nHas OIDs: no\n'
+    expected = [title, rows, headers, status]
+    assert results == expected
+
+
+ at dbtest
 def test_slash_dn(executor):
     """List all schemas."""
     results = executor('\dn')
@@ -54,13 +86,122 @@ def test_slash_dt(executor):
     title = None
     rows = [('public', 'tbl1', 'table', POSTGRES_USER),
             ('public', 'tbl2', 'table', POSTGRES_USER)]
-    headers = ['Schema', 'Name', 'Type', 'Owner']
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 2'
+    expected = [title, rows, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_dt_verbose(executor):
+    """List all tables in public schema in verbose mode."""
+    results = executor('\dt+')
+    title = None
+    rows = [('public', 'tbl1', 'table', POSTGRES_USER, '8192 bytes', None),
+            ('public', 'tbl2', 'table', POSTGRES_USER, '8192 bytes', None)]
+    headers = objects_listing_headers
     status = 'SELECT 2'
     expected = [title, rows, headers, status]
     assert results == expected
 
 
 @dbtest
+def test_slash_dv(executor):
+    """List all views in public schema."""
+    results = executor('\dv')
+    title = None
+    row = [('public', 'vw1', 'view', POSTGRES_USER)]
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_dv_verbose(executor):
+    """List all views in s1 schema in verbose mode."""
+    results = executor('\dv+ schema1.*')
+    title = None
+    row = [('schema1', 's1_vw1', 'view', POSTGRES_USER, '0 bytes', None)]
+    headers = objects_listing_headers
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_dm(executor):
+    """List all materialized views in schema1."""
+    results = executor('\dm schema1.*')
+    title = None
+    row = [('schema1', 's1_mvw1', 'materialized view', POSTGRES_USER)]
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_dm_verbose(executor):
+    """List all materialized views in public schema in verbose mode."""
+    results = executor('\dm+')
+    title = None
+    row = [('public', 'mvw1', 'materialized view', POSTGRES_USER, '8192 bytes', None)]
+    headers = objects_listing_headers
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_ds(executor):
+    """List all sequences in public schema."""
+    results = executor('\ds')
+    title = None
+    row = [('public', 'tbl2_id2_seq', 'sequence', POSTGRES_USER)]
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_ds_verbose(executor):
+    """List all sequences in public schema in verbose mode."""
+    results = executor('\ds+')
+    title = None
+    row = [('public', 'tbl2_id2_seq', 'sequence', POSTGRES_USER, '8192 bytes', None)]
+    headers = objects_listing_headers
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_di(executor):
+    """List all indexes in public schema."""
+    results = executor('\di')
+    title = None
+    row = [('public', 'id_text', 'index', POSTGRES_USER)]
+    headers = objects_listing_headers[:-2]
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_di_verbose(executor):
+    """List all indexes in public schema in verbose mode."""
+    results = executor('\di+')
+    title = None
+    row = [('public', 'id_text', 'index', POSTGRES_USER, '8192 bytes', None)]
+    headers = objects_listing_headers
+    status = 'SELECT 1'
+    expected = [title, row, headers, status]
+    assert results == expected
+
+
+ at dbtest
 def test_slash_dT(executor):
     """List all datatypes."""
     results = executor('\dT')
@@ -150,7 +291,7 @@ def test_slash_copy_to_csv(executor, tmpdir):
     filepath = tmpdir.join('pycons.tsv')
     executor(u"\copy (SELECT 'Montréal', 'Portland', 'Cleveland') TO '{0}' WITH csv"
              .format(filepath))
-    infile =filepath.open(encoding='utf-8')
+    infile = filepath.open(encoding='utf-8')
     contents = infile.read()
     assert len(contents.splitlines()) == 1
     assert u'Montréal' in contents
@@ -167,3 +308,58 @@ def test_slash_copy_from_csv(executor, connection, tmpdir):
     cur.execute("SELECT * FROM tbl1 WHERE id1 = 22")
     row = cur.fetchone()
     assert row[1] == 'elephant'
+
+
+ at dbtest
+def test_slash_sf(executor):
+    results = executor('\sf func1')
+    title = None
+    rows = [('CREATE OR REPLACE FUNCTION public.func1()\n'
+             ' RETURNS integer\n'
+             ' LANGUAGE sql\n'
+             'AS $function$select 1$function$\n',),
+            ]
+    headers = ['source']
+    status = None
+    expected = [title, rows, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_sf_unknown(executor):
+    try:
+        executor('\sf non_existing')
+    except Exception as e:
+        assert 'non_existing' in str(e)
+    else:
+        assert False, "Expected an exception"
+
+
+ at dbtest
+def test_slash_sf_parens(executor):
+    results = executor('\sf func1()')
+    title = None
+    rows = [('CREATE OR REPLACE FUNCTION public.func1()\n'
+             ' RETURNS integer\n'
+             ' LANGUAGE sql\n'
+             'AS $function$select 1$function$\n',),
+            ]
+    headers = ['source']
+    status = None
+    expected = [title, rows, headers, status]
+    assert results == expected
+
+
+ at dbtest
+def test_slash_sf_verbose(executor):
+    results = executor('\sf+ schema1.s1_func1')
+    title = None
+    rows = [('        CREATE OR REPLACE FUNCTION schema1.s1_func1()\n'
+             '         RETURNS integer\n'
+             '         LANGUAGE sql\n'
+             '1       AS $function$select 2$function$\n',),
+            ]
+    headers = ['source']
+    status = None
+    expected = [title, rows, headers, status]
+    assert results == expected

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-pgspecial.git



More information about the Python-modules-commits mailing list