diff options
author | Amjith Ramanujam <amjith@newrelic.com> | 2014-12-11 20:07:54 -0800 |
---|---|---|
committer | Amjith Ramanujam <amjith@newrelic.com> | 2014-12-11 20:07:54 -0800 |
commit | a865c5d40ae27599d5b04edb439e60f23663230f (patch) | |
tree | fe8076c37cdcefb75bce3998563684c057cbd617 | |
parent | 5618104a3beb03108151c83bd828fa31bdc5b643 (diff) |
Add DESCRIBE command to pgspecial.
-rw-r--r-- | TODO | 8 | ||||
-rw-r--r-- | pgcli/packages/pgspecial.py | 25 | ||||
-rw-r--r-- | pgcli/pgcompleter.py | 2 | ||||
-rw-r--r-- | pgcli/pgexecute.py | 14 |
4 files changed, 32 insertions, 17 deletions
@@ -1,21 +1,21 @@ +* [O] Add MySQL commands (use, describe etc) * [] Check why Indexes have a invalid at the end when \d is called on them. -* [] Fix smartcompletion for special commands. \d <tab> * [] Add some tests. Sanity, Unit, Completion, Config. * [ ] Add tests for smart completion. * [] Check how to add the name of the table before printing the table. * [] Show only table sensitive columns in autocompletion. -* [] Add a toolbar at the bottom with some helpful keyboard shortcuts. * [] Add logging. * [] Setup the pgcli.com website. * [ ] Add a new trigger for M-/ that does dumb completion. -* [] Add function keys that can enable/disable smart completion. * [] Improve the smart completion for Insert statement. * [] Improve the smart completion for Update statement. * [ ] Find a way to add documentation to sql commands. This could get tricky. * [ ] Detect a '.' and parse the word before it and get it's real name. * [] Refactor the execution and output into a separate class. * [] Create a class for the config and make it easy to access. -* [O] Add MySQL commands (use, describe etc) +* [X] Add function keys that can enable/disable smart completion. +* [X] Add a toolbar at the bottom with some helpful keyboard shortcuts. +* [X] Fix smartcompletion for special commands. \d <tab> * [X] Add more complex slash commands such as \d <table_name>. * This is going to take a separate lib. * [X] Create a better framework for adding special commands. diff --git a/pgcli/packages/pgspecial.py b/pgcli/packages/pgspecial.py index 39b28f55..4f647eff 100644 --- a/pgcli/packages/pgspecial.py +++ b/pgcli/packages/pgspecial.py @@ -19,6 +19,24 @@ class MockLogging(object): #log = MockLogging() +#def parse_special_command(sql): + + ## Sort the command by the length, so the longest command comes first. This + ## is to ensure we match the most specific command first. For example: \dt+ + ## will match \dt instead of \d. + #ordered_commands = sorted(COMMANDS, key=len, reverse=True) + #for command in ordered_commands: + #if sql.startswith(command): + #plus, _, arg = sql[len(command):].partition(' ') + #break + #verbose = '+' in plus + #return (command.strip(), verbose, arg.strip()) + +def parse_special_command(sql): + command, _, arg = sql.partition(' ') + verbose = '+' in command + return (command.strip(), verbose, arg.strip()) + def describe_table_details(cur, pattern, verbose): """ Returns (rows, headers, status) @@ -670,6 +688,7 @@ def sql_name_pattern(pattern): return schema, relname COMMANDS = { + 'describe': describe_table_details, '\d': describe_table_details, '\dt': '''SELECT n.nspname as "Schema", c.relname as "Name", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN @@ -683,12 +702,12 @@ COMMANDS = { 1,2;''' } -command_available = COMMANDS.__contains__ - -def execute(cur, command, verbose, arg): +def execute(cur, sql): """Execute a special command and return the results. If the special command is not supported a KeyError will be raised. """ + command, verbose, arg = parse_special_command(sql) + global COMMANDS command_executor = COMMANDS[command] diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py index 5d4f879e..9a2cb4db 100644 --- a/pgcli/pgcompleter.py +++ b/pgcli/pgcompleter.py @@ -94,7 +94,7 @@ class PGCompleter(Completer): return self.find_matches(word_before_cursor, self.column_names) elif last_token.lower() in ('from', 'update', 'into'): return self.find_matches(word_before_cursor, self.table_names) - elif last_token in ('d',): # This for the \d special command. + elif last_token in ('d', 'describe'): # This for the \d special command. return self.find_matches(word_before_cursor, self.table_names) elif last_token in ('c',): # This for the \c special command. return self.find_matches(word_before_cursor, self.database_names) diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py index e24741ba..a043e187 100644 --- a/pgcli/pgexecute.py +++ b/pgcli/pgexecute.py @@ -24,12 +24,6 @@ class PGExecute(object): self.port = port self.conn.autocommit = True - @staticmethod - def parse_pattern(sql): - command, _, arg = sql.partition(' ') - verbose = '+' in command - return (command.strip(), verbose, arg.strip()) - def run(self, sql): """Execute the sql in the database and return the results. The results are a list of tuples. Each tuple has 3 values (rows, headers, status). @@ -43,7 +37,10 @@ class PGExecute(object): # that cannot be offloaded to `pgspecial` lib. Because we have to # change the database connection that we're connected to. if sql.startswith('\c') or sql.lower().startswith('use'): - dbname = self.parse_pattern(sql)[2] + try: + dbname = sql.split()[1] + except: + raise RuntimeError('Database name missing.') self.conn = psycopg2.connect(database=dbname, user=self.user, password=self.password, host=self.host, port=self.port) @@ -53,8 +50,7 @@ class PGExecute(object): with self.conn.cursor() as cur: try: - results = pgspecial.execute(cur, *self.parse_pattern(sql)) - return results + return pgspecial.execute(cur, sql) except KeyError: cur.execute(sql) |