Mercurial > sqlpython
changeset 329:3efffbf7481f
fixed bug in assigning 0, null to bind vars
author | Catherine Devlin <catherine.devlin@gmail.com> |
---|---|
date | Mon, 06 Apr 2009 14:45:05 -0400 |
parents | 8721372d81be |
children | 8dd71d47f3cb |
files | docs/source/capabilities.rst docs/source/intro.rst sqlpython/pexpecter.py sqlpython/sqlpyPlus.py sqlpython_epm.list |
diffstat | 5 files changed, 143 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/docs/source/capabilities.rst Fri Apr 03 13:09:59 2009 -0400 +++ b/docs/source/capabilities.rst Mon Apr 06 14:45:05 2009 -0400 @@ -104,9 +104,10 @@ \\h HTML table web reports \\i INSERT statements copying to other instances \\j JSON +\\r ReStructured Text inclusion in documentation \\s CSV (with headings) \\S CSV (no headings) -\\t transposed "narrow" tables like v$database +\\t transposed "wide" tables like v$database \\x XML \\l line plot, with markers \\L scatter plot (no lines) @@ -115,7 +116,7 @@ ========== ======================== ================================ Most of these output formats are even more useful when combined with special output -destinations. For example, `SELECT * FROM party\h > /var/www/party_report.html` +destinations. For example, `SELECT * FROM party\\h > /var/www/party_report.html` could create an HTML report in the webserver's documents directory, ready to serve. UNIX-like commands
--- a/docs/source/intro.rst Fri Apr 03 13:09:59 2009 -0400 +++ b/docs/source/intro.rst Mon Apr 06 14:45:05 2009 -0400 @@ -5,29 +5,90 @@ * PyPI: http://pypi.python.org/pypi/sqlpython * News: http://catherinedevlin.blogspot.com/search/label/sqlpython * Current docs: http://packages.python.org/sqlpython/ +* Mailing list: http://groups.google.com/group/sqlpython SQLPython is a command-line interface to Oracle databases. It is intended as an alternative to Oracle's SQL\*Plus. For the most part, it can be used the same way SQL\*Plus would be used; this documentation focuses on the places where SQLPython differs. -SQLPython was created by `Luca Canali <http://canali.web.cern.ch/canali/>`_ at CERN. Most new development -has been done by `Catherine Devlin <http://catherinedevlin.blogspot.com/>`_. The development trunk (very unstable) is at `assembla <https://www.assembla.com/wiki/show/sqlpython>`_; you can install the trunk on your machine with:: +License +------- + +sqlpython is free and open-source software. Its use is governed by the +`MIT License <http://www.opensource.org/licenses/mit-license.php>`_. + +Authorship +---------- + +SQLPython was created by `Luca Canali <http://canali.web.cern.ch/canali/>`_ at CERN. Most recent +development has been done by `Catherine Devlin <http://catherinedevlin.blogspot.com/>`_. A group +of additional sqlpython contributors has formed at +`Google Groups <http://groups.google.com/group/sqlpython>`_. + +Installation +------------ + +If `python-setuptools <http://pypi.python.org/pypi/setuptools>`_ is present on your machine, you +can easily install the latest release of sqlpython by issuing from a command prompt:: + + easy_install sqlpython + +The development trunk +(very unstable) is at `assembla <https://www.assembla.com/wiki/show/sqlpython>`_; +you can install the trunk on your machine with:: hg clone http://hg.assembla.com/python-cmd2 cmd2 cd cmd2 python setup.py develop + cd .. hg clone http://hg.assembla.com/sqlpython sqlpython cd sqlpython python setup.py develop Using `hg pull`, `hg update` subsequently will update from the current trunk. +You may also install from the trunk with easy_install:: + + easy_install + +Running +------- + +sqlpython [username[/password][@SID]] ["SQL command 1", "@script.sql", "SQL command 2..."] + +Database connections can also be specified with URL syntax or with Oracle Easy Connect:: + + oracle://username:password@SID + + oracle://username:password@hostname:port/dbname + + oracle://username:password@hostname:port/dbname + +SID represents an entry from the `tnsnames.ora` file. + +Once connected, most familiar SQL\*Plus commands can be used. Type `help` for additional +information. + +Bugs +---- + +Please report bugs at http://trac-hg.assembla.com/sqlpython or to catherine.devlin@gmail.com. + +Origins +------- + SQLPython is based on the Python standard library's `cmd <http://docs.python.org/library/cmd.html#module-cmd>`_ module, and on an extension to it called `cmd2 <http://pypi.python.org/pypi/cmd2>`_. SQLPython also draws considerable inspiration from two Perl-based open-source SQL clients, `Senora <http://senora.sourceforge.net/>`_ and `YASQL <http://sourceforge.net/projects/yasql>`_. -SQLPython is currently only compatible with Oracle databases. Expanding it to other RDBMS is a dream -for "one fine day". Call it "SQLPython 3000". +Non-Oracle RDBMS +---------------- + +As of sqlpython 1.6.4, preliminary work has begun to adapt sqlpython to non-Oracle databases. +You may use it to run queries against postgreSQL, MySQL, etc., but data-dictionary access +commands (`ls`, `grep`, `refs`, etc.) will generate errors. Connection to non-Oracle databases +is currently only possible via URL connection strings. +
--- a/sqlpython/pexpecter.py Fri Apr 03 13:09:59 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -""" -pexpecter - -Uses pexpect to handle interactive sessions -Create subclass of Session for each type of program to be used -""" -import re, os - -try: - import pexpect - - class Session(object): - available = True - call = 'theprogram %s' - errPattern = re.compile('.') - validPattern = re.compile('Connected to:') - promptstub = '>' - def __init__(self, argstring): - self.argstring = argstring - self.sess = pexpect.spawn("%s %s" % (self.call, self.argstring)) - try: - self.sess.expect(self.promptstub) - self.valid = self.validPattern.search(self.sess.before) - self.prompt = '[\r\n]%s%s' % (self.sess.before.splitlines()[-1], self.promptstub) - except: - self.valid = False - def success(self, result): - return not self.errPattern.search(result) - def attempt(self, command, timeout=30): - self.sess.sendline(self._pre_attempt(command)) - try: - self.sess.expect(self.prompt, timeout=timeout) - except pexpect.TIMEOUT: - return (False, """Errror: Waited %d seconds with no response from %s. - To wait longer, set timeout.""" % (timeout, str(self.__class__))) - result = self.sess.before - success = self.success(result) - if success: - print 'Executed through %s' % (str(self.__class__)) - return (success, result) - def _pre_attempt(self, command): - return command - - class YASQLSession(Session): - errPattern = re.compile('\n[A-Z2]{3,4}-\d{4}:\s') - terminatorPattern = re.compile('(;|\\g|\\i|\/|\\G|\\s|\\S)\s*\d*\s*$') - call = os.popen('locate -r /yasql$').readline().strip() - if not call: - print 'yasql not found; commands cannot failover to YASQL' - available = False - def _pre_attempt(self, command): - if not self.terminatorPattern.search(command): - return '%s;' % (command) - return command - - class SQLSession(Session): - def _pre_attempt(self, command): - if command.strip()[-1] != ';': - return '%s;' % (command) - return command - - class SqlPlusSession(SQLSession): - call = r'sqlplus' - errPattern = re.compile('\n[A-Z2]{3,4}-\d{4}:\s') - """ def _pre_attempt(self, command): - if command.strip()[-1] != ';': - return '%s;' % (command) - return command""" - # can still trip on: apparent error messages listed as data - - class SenoraSession(SQLSession): - errPattern = re.compile('(\n[A-Z2]{3,4}-\d{4}:\s)|(\nwhat ? )') - call = os.popen('locate -r Senora\.pm$').readline().strip() - if call: - call = 'perl %s' % (call) - else: - print 'Senora.pm not found; commands cannot failover to Senora' - available = False - -except ImportError: - print '''Python's pexpect module is not installed; cannot pass - commands through to sqlplus, etc.''' - class Session(object): - valid = False - available = False - class YASQLSession(Session): - pass - class SqlPlusSession(Session): - pass - class SenoraSession(Session): - pass - -available = [s for s in [SenoraSession, YASQLSession, SqlPlusSession] if s.available]
--- a/sqlpython/sqlpyPlus.py Fri Apr 03 13:09:59 2009 -0400 +++ b/sqlpython/sqlpyPlus.py Mon Apr 06 14:45:05 2009 -0400 @@ -1188,42 +1188,47 @@ Accepts strings like `foo = 'bar'` or `baz := 22`, returning Python variables as appropriate ''' - var, val = self.split_on_parser(self.assignmentScanner, arg) - if not var: - return None, None + try: + assigner, startat, endat = self.assignmentScanner.scanner.scanString(arg).next() + (var, val) = (arg[:startat].strip(), arg[endat:].strip()) + except StopIteration: + if arg.split()[:1]: + return False, arg.split()[0], None + else: + return False, None, None if (len(val) > 1) and ((val[0] == val[-1] == "'") or (val[0] == val[-1] == '"')): - return var, val[1:-1] + return True, var, val[1:-1] try: - return var, int(val) + return True, var, int(val) except ValueError: try: - return var, float(val) + return True, var, float(val) except ValueError: # use the conversions implicit in cx_Oracle's select to # cast the value into an appropriate type (dates, for instance) try: self.curs.execute('SELECT %s FROM dual' % val) - return var, self.curs.fetchone()[0] + return True, var, self.curs.fetchone()[0] except cx_Oracle.DatabaseError: - return var, val # we give up and assume it's a string + return True, var, val # we give up and assume it's a string def do_setbind(self, arg): '''Sets or shows values of bind (`:`) variables.''' if not arg: return self.do_print(arg) - var, val = self.interpret_variable_assignment(arg) - if val: + assigned, var, val = self.interpret_variable_assignment(arg) + if not assigned: + return self.do_print(var) + else: self.binds[var] = val - else: - return self.do_print(var) def do_define(self, arg): '''Sets or shows values of substitution (`&`) variables.''' if not arg: for (substvar, val) in sorted(self.substvars.items()): print 'DEFINE %s = "%s" (%s)' % (substvar, val, type(val)) - var, val = self.interpret_variable_assignment(arg) - if val: + assigned, var, val = self.interpret_variable_assignment(arg) + if assigned: self.substvars[var] = val else: if var in self.substvars:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sqlpython_epm.list Mon Apr 06 14:45:05 2009 -0400 @@ -0,0 +1,56 @@ +#EPM List File Can Be Used To Create Package For Any Of These Vendor Platforms +#epm -f format foo bar.list ENTER +#The format option can be one of the following keywords: + +#aix - AIX software packages. +#bsd - FreeBSD, NetBSD, or OpenBSD software packages. +#depot or swinstall - HP-UX software packages. +#dpkg - Debian software packages. +#inst or tardist - IRIX software packages. +#native - "Native" software packages (RPM, INST, DEPOT, PKG, etc.) for the platform. +#osx - MacOS X software packages. +#pkg - Solaris software packages. +#portable - Portable software packages (default). +#rpm - Red Hat software packages. +#setld - Tru64 (setld) software packages. +#slackware - Slackware software packages. + + +# Product Information Section + +%product sqlpython +%copyright 2009 Catherine Devlin +%vendor None +%license COPYING +%readme doc/source/intro.rst +%description Command-line ad-hoc SQL tool, akin to Oracle's SQL*Plus +%version 1.6.4 + +# Autoconfiguration Variables + +$prefix=/usr +$exec_prefix=/usr +$bindir=${exec_prefix}/bin +$datadir=/usr/share +$docdir=${datadir}/doc/sqlpython +$libdir=/usr/lib +$mandir=/usr/share/man +$srcdir=. + +# Executables + +%system all +f 0555 root sys ${bindir}/sqlpython sqlpython/mysqlpy.py + +# Documentation + +%subpackage documentation +f 0444 root sys ${docdir}/README $srcdir/docs/source/intro.rst +f 0444 root sys ${docdir}/COPYING $srcdir/COPYING +f 0444 root sys ${docdir}/index.html $srcdir/docs/build/index.html + +# Man pages + +%subpackage man +%description Man pages for sqlpython +f 0444 root sys ${mandir}/man1/sqlpython.1 $srcdir/docs/source/sqlpython.man