changeset 415:3a2db0db302f

must synch
author catherine@bothari
date Fri, 30 Oct 2009 19:45:23 -0400
parents c42d9619e715
children e7769bc81960
files setup.py sqlpython/mysqlpy.py sqlpython/plothandler.py sqlpython/sqlpyPlus.py sqlpython/sqlpython.py
diffstat 5 files changed, 70 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/setup.py	Fri Oct 16 18:11:08 2009 -0400
+++ b/setup.py	Fri Oct 30 19:45:23 2009 -0400
@@ -17,8 +17,12 @@
       url="http://packages.python.org/sqlpython",
       packages=find_packages(),
       include_package_data=True,    
-      install_requires=['pyparsing','cmd2>=0.5.6','cx_Oracle>=5.0.2',
+      install_requires=['pyparsing','cmd2>=0.5.6',
                         'genshi>=0.5','sqlalchemy'],
+      extras_require = {
+        'oracle':  ['cx_Oracle>=5.0.2'],
+        'postgres': ['psycopg2'],
+        },
       keywords = 'client oracle database',
       license = 'MIT',
       platforms = ['any'],
--- a/sqlpython/mysqlpy.py	Fri Oct 16 18:11:08 2009 -0400
+++ b/sqlpython/mysqlpy.py	Fri Oct 30 19:45:23 2009 -0400
@@ -163,18 +163,19 @@
         except Exception, e:
             self.perror(e)
 
-    def do_sessinfo(self,args):
-        '''Reports session info for the given sid, extended to RAC with gv$'''
-        try:
-            if not args:
-                self.curs.execute('SELECT sid FROM v$mystat')
-                args = self.curs.fetchone()[0]
-            self.onecmd('SELECT * from gv$session where sid=%s\\t' % args)
-        except cx_Oracle.DatabaseError, e:
-            if 'table or view does not exist' in str(e):
-                self.perror('This account has not been granted SELECT privileges to v$mystat or gv$session.')
-            else:
-                raise 
+    if cx_Oracle:
+        def do_sessinfo(self,args):
+            '''Reports session info for the given sid, extended to RAC with gv$'''
+            try:
+                if not args:
+                    self.curs.execute('SELECT sid FROM v$mystat')
+                    args = self.curs.fetchone()[0]
+                self.onecmd('SELECT * from gv$session where sid=%s\\t' % args)
+            except cx_Oracle.DatabaseError, e:
+                if 'table or view does not exist' in str(e):
+                    self.perror('This account has not been granted SELECT privileges to v$mystat or gv$session.')
+                else:
+                    raise 
 
     def do_sleect(self,args):    
         '''implements sleect = select, a common typo'''
--- a/sqlpython/plothandler.py	Fri Oct 16 18:11:08 2009 -0400
+++ b/sqlpython/plothandler.py	Fri Oct 30 19:45:23 2009 -0400
@@ -1,10 +1,12 @@
-import shelve, pickle, cx_Oracle, datetime, sys, itertools
+import shelve, pickle, datetime, sys, itertools
+from sqlpython import cx_Oracle
 shelvename = 'plot.shelve'
 
 try:
     import pylab
     class Plot(object):
-        plottable_types = (cx_Oracle.NUMBER, datetime.datetime)    
+        plottable_types = (cx_Oracle and cx_Oracle.NUMBER, datetime.datetime)
+        #TODO: add non-Oracle types
         def __init__(self):
             self.legends = []
             self.yserieslists = []
--- a/sqlpython/sqlpyPlus.py	Fri Oct 16 18:11:08 2009 -0400
+++ b/sqlpython/sqlpyPlus.py	Fri Oct 30 19:45:23 2009 -0400
@@ -23,7 +23,7 @@
 
 - catherinedevlin.blogspot.com  May 31, 2006
 """
-import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion
+import sys, os, re, sqlpython, pyparsing, re, completion
 import datetime, pickle, binascii, subprocess, time, itertools, hashlib
 import traceback, operator
 from cmd2 import Cmd, make_option, options, Statekeeper, Cmd2TestCase
@@ -31,7 +31,7 @@
 from schemagroup import MetaData
 from metadata import metaqueries
 from plothandler import Plot
-from sqlpython import Parser
+from sqlpython import Parser, cx_Oracle, psycopg2
 import imagedetect
 import warnings
 warnings.filterwarnings('ignore', 'BaseException.message', DeprecationWarning)
@@ -412,7 +412,7 @@
     def dbms_output(self):
         "Dumps contents of Oracle's DBMS_OUTPUT buffer (where PUT_LINE goes)"
         try:
-            line = self.curs.var(cx_Oracle.STRING)
+            line = self.curs.var(cx_Oracle.STRING) # TODO: would regular string and number work?
             status = self.curs.var(cx_Oracle.NUMBER)
             self.curs.callproc('dbms_output.get_line', [line, status])
             while not status.getvalue():
@@ -752,7 +752,8 @@
         self.rows = self.curs.fetchmany(min(self.maxfetch, (rowlimit or self.maxfetch)))
         self.colnames = [d[0] for d in self.curs.description]
         self.coltypes = [d[1] for d in self.curs.description]
-        if cx_Oracle.BLOB in self.coltypes:
+        #TODO: Other databases can have BLOBs, too
+        if cx_Oracle and (cx_Oracle.BLOB in self.coltypes):
             self.rows = [
                  [(    (coltype == cx_Oracle.BLOB) 
                    and BlobDisplayer(datum, (rownum < self.bloblimit)))
@@ -833,7 +834,7 @@
 
                 self.poutput(txt)
                 if opts.full:
-                    # Hmm... dependent objects...
+                    # TODO: 'full' option for gerald metadata
             
                     if opts.full:
                         for dependent_type in ('OBJECT_GRANT', 'CONSTRAINT', 'TRIGGER'):        
@@ -986,10 +987,13 @@
                             self.poutput('%d: %s' % (line_num, line))
             
     def _col_type_descriptor(self, col):
-        if 'precision' in col:
-            return '%s(%d,%d)' % (col['type'], col['length'], col['precision'])
-        elif 'length' in col:
-            return '%s(%d)' % (col['type'], col['length'])
+        #if col['type'] in ('integer',):
+        #    return col['type']
+        if ('length' in col) and (col['length'] is not None):
+            if ('precision' in col) and (col['precision'] is not None):
+                return '%s(%d,%d)' % (col['type'], col['length'], col['precision'])
+            else:
+                return '%s(%d)' % (col['type'], col['length'])
         else:
             return col['type']
         
@@ -997,6 +1001,7 @@
         columns = [c['columns'] for c in tbl.constraints.values() if c['type'] == type]
         if columns:
             return reduce(list.extend, columns)
+                    #TODO: in postgres, _key_columns returns 'fishies_pkey' instead of 'n'        
         else:
             return []
         
@@ -1050,23 +1055,23 @@
     def do_deps(self, arg):
         '''Lists all objects that are dependent upon the object.'''
         #TODO: Can this be Geraldized?
-        target = arg.upper()
-        object_type, owner, object_name = self.resolve(target)
-        if object_type == 'PACKAGE BODY':
-            q = "and (type != 'PACKAGE BODY' or name != :object_name)'"
-            object_type = 'PACKAGE'
-        else:
-            q = ""
-        q = """SELECT name,
-          type
-          from user_dependencies
-          where
-          referenced_name like :object_name
-          and	referenced_type like :object_type
-          and	referenced_owner like :owner
-          %s;""" % (q)
-        self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix), 
-                       bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner})
+        for obj in self._matching_database_objects(arg, opts):
+
+            if object_type == 'PACKAGE BODY':
+                q = "and (type != 'PACKAGE BODY' or name != :object_name)'"
+                object_type = 'PACKAGE'
+            else:
+                q = ""
+            q = """SELECT name,
+              type
+              from user_dependencies
+              where
+              referenced_name like :object_name
+              and	referenced_type like :object_type
+              and	referenced_owner like :owner
+              %s;""" % (q)
+            self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix), 
+                           bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner})
 
     @options([all_users_option])        
     def do_comments(self, arg, opts):
@@ -1274,8 +1279,7 @@
     @options(standard_options)
     def do__dir_constraints(self, arg, opts):
         '''
-        Called with an exact table name, lists the indexes of that table.
-        Otherwise, acts as shortcut for `ls index/*(arg)*`
+        Lists constaints of a table.
         '''
         self.do__dir_(arg, opts, 'constraints', self._str_constraint)
 
@@ -1369,7 +1373,7 @@
                         sql = 'SELECT %s'
                     self.curs.execute(sql % val)
                     return True, var, self.curs.fetchone()[0]
-                except:   # should not be bare - should catch cx_Oracle.DatabaseError, etc.
+                except:   # TODO: should not be bare - should catch cx_Oracle.DatabaseError, etc.
                     return True, var, val  # we give up and assume it's a string
             
     def do_setbind(self, arg):
@@ -1492,7 +1496,11 @@
         
     def metadata(self):
         schemas = self.connections[self.connection_number]['schemas']
-        username = self.connections[self.connection_number]['user'].upper()
+        username = self.connections[self.connection_number]['user']
+        if self.rdbms == 'oracle':
+            username = username.upper()
+        elif self.rdbms == 'postgres':
+            username = username.lower()
         return (username, schemas)
         
     def _to_sql_wildcards(self, original):
@@ -1550,7 +1558,7 @@
             self.pfeedback('Results are incomplete - only %d schemas mapped so far' % schemas.complete)        
         
         seek = self._regex(arg, opts.get('exact'))
-        qualified = opts.get('all')
+        qualified = opts.get('all') or '.' in arg   # TODO: is this working?
         for (schema_name, schema) in schemas.items():
             if schema_name == username or opts.get('all'):
                 for (name, dbobj) in schema.schema.items():                
--- a/sqlpython/sqlpython.py	Fri Oct 16 18:11:08 2009 -0400
+++ b/sqlpython/sqlpython.py	Fri Oct 30 19:45:23 2009 -0400
@@ -8,9 +8,17 @@
 # Best used with the companion modules sqlpyPlus and mysqlpy 
 # See also http://twiki.cern.ch/twiki/bin/view/PSSGroup/SqlPython
 
-import cmd2,getpass,binascii,cx_Oracle,re,os,platform
+import cmd2,getpass,binascii,re,os,platform
 import sqlalchemy, pyparsing, schemagroup
 __version__ = '1.6.8'    
+try:
+    import cx_Oracle
+except ImportError:
+    cx_Oracle = None
+try:
+    import psycopg2
+except ImportError:
+    psycopg2 = None
 
 class Parser(object):
     comment_def = "--" + pyparsing.NotAny('-' + pyparsing.CaselessKeyword('begin')) + pyparsing.ZeroOrMore(pyparsing.CharsNotIn("\n"))