diff options
author | catherinedevlin <catherine.devlin@gmail.com> | 2018-05-15 10:52:51 -0400 |
---|---|---|
committer | Irina Truong <i.chernyavska@gmail.com> | 2018-06-16 21:46:31 -0700 |
commit | 675e1dbff26c42722493703c7a792bae97c7d538 (patch) | |
tree | fe66b2d651ce1c9374b5026c6aff5e9260944794 | |
parent | aee99b9a40e17b07a252e388aff7a016691a043c (diff) |
Moved code to pgexecute
-rw-r--r-- | pgcli/main.py | 30 | ||||
-rw-r--r-- | pgcli/packages/parseutils/tables.py | 10 | ||||
-rw-r--r-- | pgcli/pgexecute.py | 17 | ||||
-rw-r--r-- | tests/parseutils/test_parseutils.py | 11 |
4 files changed, 58 insertions, 10 deletions
diff --git a/pgcli/main.py b/pgcli/main.py index f577a1c8..e4f0e396 100644 --- a/pgcli/main.py +++ b/pgcli/main.py @@ -480,19 +480,29 @@ class PGCli(object): # We may find a better way to do it in the future. saved_callables = cli.application.pre_run_callables try: - while special.editor_command(document.text): - filename = special.get_filename(document.text) - query = (special.get_editor_query(document.text) or - self.get_last_query()) + editor_command = special.editor_command(document.text) + while editor_command: + if editor_command == '\\e': + filename = special.get_filename(document.text) + query = (special.get_editor_query(document.text) or + self.get_last_query()) + else: # \ev or \ef + filename = None + spec = document.text.split()[1] + query = self.pgexecute.view_definitions(spec) + if not query: + raise RuntimeError( + 'View {} does not exist.'.format(spec)) sql, message = special.open_external_editor( filename, sql=query) if message: # Something went wrong. Raise an exception and bail. raise RuntimeError(message) - cli.current_buffer.document = Document(sql, - cursor_position=len(sql)) + cli.current_buffer.document = Document( + sql, cursor_position=len(sql)) cli.application.pre_run_callables = [] document = cli.run() + editor_command = special.editor_command(document.text) finally: cli.application.pre_run_callables = saved_callables return document @@ -599,14 +609,16 @@ class PGCli(object): continue self.watch_command, timing = special.get_watch_command( - document.text) + document.text) if self.watch_command: while self.watch_command: try: + query = self.execute_command( + self.watch_command, query) query = self.execute_command(self.watch_command) click.echo( - 'Waiting for {0} seconds before repeating' - .format(timing)) + 'Waiting for {0} seconds before repeating' + .format(timing)) sleep(timing) except KeyboardInterrupt: self.watch_command = None diff --git a/pgcli/packages/parseutils/tables.py b/pgcli/packages/parseutils/tables.py index 12513591..a81ffbfa 100644 --- a/pgcli/packages/parseutils/tables.py +++ b/pgcli/packages/parseutils/tables.py @@ -145,3 +145,13 @@ def extract_tables(sql): allow_functions=not insert_stmt) # In the case 'sche.<cursor>', we get an empty TableReference; remove that return tuple(i for i in identifiers if i.name) + + +def schema_table_split(spec): + """ "myschema.mytable" -> ('myschema', 'mytable); "mytable" -> (None, 'mytable')""" + + pieces = spec.strip().split('.') + if len(pieces) == 1: + return ('%', pieces[0]) + else: + return (pieces[0], '.'.join(pieces[1:])) diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py index 149efc51..9ab3d413 100644 --- a/pgcli/pgexecute.py +++ b/pgcli/pgexecute.py @@ -9,6 +9,7 @@ import pgspecial as special import select from psycopg2.extensions import POLL_OK, POLL_READ, POLL_WRITE from .packages.parseutils.meta import FunctionMetadata, ForeignKey +from .packages.parseutils.tables import schema_table_split from .encodingutils import unicode2utf8, PY2, utf8tounicode _logger = logging.getLogger(__name__) @@ -161,6 +162,11 @@ class PGExecute(object): FROM pg_settings WHERE name = 'unix_socket_directories' ''' + view_definition_query = ''' + SELECT table_schema, table_name, view_definition + FROM information_schema.views + WHERE table_schema LIKE %s + AND table_name LIKE %s''' def __init__(self, database, user, password, host, port, dsn, **kwargs): self.dbname = database @@ -384,6 +390,17 @@ class PGExecute(object): cur.execute(fallback) return cur.fetchone()[0] + def view_definitions(self, spec): + """Returns the SQL defining views described by `spec` """ + + template = 'CREATE OR REPLACE VIEW {}.{} AS \n{}' + schema_pattern, view_pattern = schema_table_split(spec) + with self.conn.cursor() as cur: + sql = self.view_definition_query + _logger.debug('View Definition Query. sql: %r\nschema: %r\nview: %r', + sql, schema_pattern, view_pattern) + cur.execute(sql, (schema_pattern, view_pattern)) + return ';\n\n'.join(template.format(*row) for row in cur) def schemata(self): """Returns a list of schema names in the database""" diff --git a/tests/parseutils/test_parseutils.py b/tests/parseutils/test_parseutils.py index 4ffc7ee3..28918c07 100644 --- a/tests/parseutils/test_parseutils.py +++ b/tests/parseutils/test_parseutils.py @@ -1,5 +1,5 @@ import pytest -from pgcli.packages.parseutils.tables import extract_tables +from pgcli.packages.parseutils.tables import extract_tables, schema_table_split from pgcli.packages.parseutils.utils import find_prev_keyword, is_open_quote @@ -265,3 +265,12 @@ def test_is_open_quote__closed(sql): ]) def test_is_open_quote__open(sql): assert is_open_quote(sql) + + +def test_schema_table_split(): + assert schema_table_split('myschema.mytable') == ('myschema', 'mytable') + assert schema_table_split('mytable') == ('%', 'mytable') + assert schema_table_split('') == ('%', '') + assert schema_table_split('myschema.mytable.foo') == ( + 'myschema', 'mytable.foo') + assert schema_table_split('%') == ('%', '%') |