-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Prototype command line interface entry point. * Use SQLParse package for parsing SQL.
- Loading branch information
0 parents
commit ebd5a9c
Showing
5 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
iPSQL design | ||
============ | ||
|
||
This document specifies concept of intelligent PostgreSQL shell. | ||
|
||
Planned features | ||
---------------- | ||
|
||
List of planned features: | ||
|
||
* Vi-mode and Emacs-mode line editing facilities. | ||
|
||
* Syntax highlighting. | ||
|
||
* Contextual completion. | ||
|
||
* Own parser for SQL with fallback to PostgreSQL parser (allow better | ||
experiments with language). | ||
|
||
* Better interface with pagers (search by columns, maybe). | ||
|
||
* Better interface with editors (streamline completion). | ||
|
||
* Alternative query syntax (HTSQL maybe?). | ||
|
||
* Async operations. | ||
|
||
* Configurable prompt. | ||
|
||
* Possible macro support (loops, conditionals). |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
""" Command line interface entry point.""" | ||
|
||
import getpass | ||
import optparse | ||
|
||
import psycopg2 | ||
|
||
from ipsql.shell import Shell | ||
|
||
def get_parser(): | ||
parser = optparse.OptionParser(add_help_option=False) | ||
parser.add_option( | ||
"-c", "--command", | ||
help="run only single command (SQL or internal) and exit") | ||
parser.add_option( | ||
"-h", "--host", | ||
help="database server host or socket directory") | ||
parser.add_option( | ||
"-p", "--port", | ||
help="database server port") | ||
parser.add_option( | ||
"-d", "--dbname", | ||
help="database name to connect to") | ||
parser.add_option( | ||
"-U", "--username", | ||
help="database user name") | ||
return parser | ||
|
||
def main(): | ||
parser = get_parser() | ||
options, args = parser.parse_args() | ||
|
||
# TODO: Better handling data type conversion errors. | ||
host = options.host if options.host else "localhost" | ||
port = int(options.port) if options.port else 5432 | ||
username = options.username if options.username else getpass.getuser() | ||
dbname = options.dbname if options.dbname else username | ||
|
||
connection = psycopg2.connect( | ||
database=dbname, | ||
user=username, | ||
host=host, | ||
port=port) | ||
|
||
shell = Shell(connection) | ||
shell.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
""" Shell.""" | ||
|
||
import sys | ||
import copy | ||
|
||
import sqlparse | ||
from rl import completer as rlcompleter | ||
from rl import completion as rlcompletion | ||
|
||
__all__ = ["Shell"] | ||
|
||
class Shell(object): | ||
|
||
def __init__(self, connection, prompt="#"): | ||
self.connection = connection | ||
self.prompt = prompt | ||
self._buffer = _Buffer() | ||
|
||
def run(self): | ||
|
||
rlcompleter.parse_and_bind("TAB: complete") | ||
rlcompleter.completer = self.complete | ||
|
||
while True: | ||
try: | ||
self._buffer.add_line(raw_input(self.prompt + " ")) | ||
except (EOFError, KeyboardInterrupt), e: | ||
break | ||
|
||
self.exit() | ||
|
||
def exit(self): | ||
# TODO: Better move that to parametrized callback. | ||
sys.exit(0) | ||
|
||
def complete(self, _text, _state): | ||
buffer = self._buffer.copy() | ||
buffer.add_line(rlcompletion.line_buffer) | ||
|
||
class _Buffer(object): | ||
|
||
def __init__(self, statements=None, lines=None, current_statement=None): | ||
self.statements = statements or [] | ||
self.lines = lines or [] | ||
self.current_statement = current_statement or None | ||
|
||
def add_statement(self, line): | ||
self.statements.append(sqlparse.parse(line)) | ||
|
||
def add_line(self, line): | ||
splitted = sqlparse.split(line) | ||
for line in splitted: | ||
lines = self.lines + [line] | ||
if line.strip().endswith(";"): | ||
self.statements.append(sqlparse.parse("\n".join(lines))[0]) | ||
self.lines = [] | ||
self.current_statement = None | ||
else: | ||
self.lines = lines | ||
self.current_statement = sqlparse.parse("\n".join(lines))[0] | ||
|
||
@property | ||
def is_ready_for_exec(self): | ||
return bool(self.statements) | ||
|
||
def copy(self): | ||
statements = copy.deepcopy(self.statements) | ||
lines = copy.deepcopy(self.lines) | ||
current_statement = copy.deepcopy(self.current_statement) | ||
return _Buffer(statements, lines, current_statement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from setuptools import setup, find_packages | ||
import sys, os | ||
|
||
version = "0.1" | ||
|
||
setup( | ||
name="ipsql", | ||
version=version, | ||
description="Intelligent PostgreSQL shell.", | ||
author="Andrey Popp", | ||
author_email="8mayday@gmail.com", | ||
license="3BSD", | ||
packages=find_packages(exclude=["ez_setup", "examples", "tests"]), | ||
include_package_data=True, | ||
zip_safe=False, | ||
install_requires=[ | ||
"psycopg2", | ||
"rl", | ||
"sqlparse" | ||
], | ||
entry_points=""" | ||
[console_scripts] | ||
ipsql = ipsql.cli:main | ||
""", | ||
) |