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