summaryrefslogtreecommitdiff
path: root/sqlplain
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-01-03 10:13:40 +0000
committermichele.simionato <devnull@localhost>2009-01-03 10:13:40 +0000
commita4820faa64e0660b97cd602bcdc639a3c56b88d1 (patch)
tree04b8476f48108d8b25f0147b5cbfb27b9c8f39e9 /sqlplain
parentd86c2bbe2174c13e7df9579796475b113c7684ec (diff)
downloadmicheles-a4820faa64e0660b97cd602bcdc639a3c56b88d1.tar.gz
Added sql_repl.py
Diffstat (limited to 'sqlplain')
-rw-r--r--sqlplain/configurator.py9
-rw-r--r--sqlplain/connection.py1
-rw-r--r--sqlplain/doc/sql_repl.py63
-rw-r--r--sqlplain/uri.py9
4 files changed, 74 insertions, 8 deletions
diff --git a/sqlplain/configurator.py b/sqlplain/configurator.py
index 16b4516..4d5b45f 100644
--- a/sqlplain/configurator.py
+++ b/sqlplain/configurator.py
@@ -30,13 +30,13 @@ class ReadOnlyObject(object):
useful for debugging (the default is 'anonymous').
"""
def __init__(self, items, name='anonymous'):
- keys = []
+ names = []
for name, value in items:
if name.startswith('_'):
raise TypeError('Inner attributes cannot begin with "_"')
object.__setattr__(self, name, value)
- keys.append(name)
- object.__setattr__(self, '_names', keys)
+ names.append(name)
+ object.__setattr__(self, '_names', names)
object.__setattr__(self, '_name', name)
def __iter__(self):
for name in self._names:
@@ -67,7 +67,8 @@ class _Configurator(object): # singleton
[(sect, ReadOnlyObject(cfp.items(sect), sect))
for sect in cfp.sections()], self._conf_file)
self._initialized = True
-
+ self._databases = self._conf_obj.uri._names
+
def __getattr__(self, name):
if not self._initialized:
self._initialize()
diff --git a/sqlplain/connection.py b/sqlplain/connection.py
index 5c64f4c..d6ec1b1 100644
--- a/sqlplain/connection.py
+++ b/sqlplain/connection.py
@@ -106,6 +106,7 @@ class LazyConnection(object):
def __init__(self, uri, isolation_level=None, threadlocal=False):
self.uri = URI(uri)
+ self.name = self.uri['database']
self.dbtype = self.uri['dbtype']
self.driver, connect, params = self.uri.get_driver_connect_params()
args = params, isolation_level
diff --git a/sqlplain/doc/sql_repl.py b/sqlplain/doc/sql_repl.py
new file mode 100644
index 0000000..ad7b92d
--- /dev/null
+++ b/sqlplain/doc/sql_repl.py
@@ -0,0 +1,63 @@
+"""
+usage: sql_repl <dbname>
+"""
+# alias sql_repl="rlwrap python ~/gcode/sqlplain/doc/sql_repl.py"
+
+import os, sys, subprocess
+from sqlplain import lazyconnect
+
+def less(text):
+ "Send a text to less via a pipe"
+ # -c clear the screen before starting less
+ po = subprocess.Popen(['less', '-c'], stdin=subprocess.PIPE)
+ try:
+ po.stdin.write(text)
+ po.stdin.flush()
+ except IOError:
+ pass
+ po.stdin.close()
+ po.wait()
+
+class Console(object):
+ "A textual console to interact with a database"
+
+ def __init__(self, dbname, input_src=sys.stdin):
+ self.db = lazyconnect(dbname)
+ self.input_src = input_src
+ self.prompt = '%s> ' % self.db.name
+
+ def sql_eval(self, code):
+ rows = self.db.execute(code)
+ out = ['Return %d rows' % len(rows), '\t'.join(rows.header)]
+ for row in rows:
+ out.append('\t'.join(map(str, row)))
+ return '\n'.join(out)
+
+ def readcode(self):
+ lines = []
+ while True:
+ sys.stdout.write(self.prompt)
+ sys.stdout.flush()
+ line = self.input_src.readline()
+ if not line:
+ raise EOFError
+ lines.append(line)
+ if line.endswith(';\n'):
+ return '\n'.join(lines)
+
+ def repl(self):
+ while True:
+ try:
+ code = self.readcode()
+ less(self.sql_eval(code))
+ except EOFError:
+ break
+ except Exception, e:
+ print e.__class__.__name__, str(e)
+
+if __name__ == '__main__':
+ try:
+ alias = sys.argv[1]
+ except IndexError:
+ sys.exit(__doc__)
+ Console(alias).repl()
diff --git a/sqlplain/uri.py b/sqlplain/uri.py
index f9cd31c..23712a8 100644
--- a/sqlplain/uri.py
+++ b/sqlplain/uri.py
@@ -37,15 +37,16 @@ class URI(object):
except AttributeError: # missing [scripdir] section in conf
pass
else:
- scriptdir = section.get(uri)
+ scriptdir = getattr(section, uri, None)
if scriptdir:
self.scriptdir = os.path.expanduser(scriptdir)
try:
uri = getattr(configurator.uri, uri)
except AttributeError:
- raise NameError(
- '%s is not a valid URI, not a recognized alias in %s' %
- (uri, configurator._conf_file))
+ msg = '%s is not a valid URI, not a recognized alias in %s' % (
+ uri, configurator._conf_file)
+ msg += '; available aliases are %s' % configurator._databases
+ raise NameError(msg)
if not uri.startswith(SUPPORTED_DBTYPES):
raise NameError('Invalid URI %s' % uri)
dbtype, partial_uri = uri.split('://')