comparison sqlpyPlus.py @ 115:43f5dc75b791

migrating to onecmd from select
author catherine@Elli.myhome.westell.com
date Sat, 28 Jun 2008 11:10:09 -0400
parents c1c05670b4e5
children
comparison
equal deleted inserted replaced
114:c1c05670b4e5 115:43f5dc75b791
23 - catherinedevlin.blogspot.com May 31, 2006 23 - catherinedevlin.blogspot.com May 31, 2006
24 """ 24 """
25 # note in cmd.cmd about supporting emacs commands? 25 # note in cmd.cmd about supporting emacs commands?
26 26
27 descQueries = { 27 descQueries = {
28 'TABLE': (""" 28 'TABLE': ("""SELECT
29 atc.column_name, 29 atc.column_name,
30 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?", 30 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?",
31 atc.data_type || 31 atc.data_type ||
32 CASE atc.data_type WHEN 'DATE' THEN '' 32 CASE atc.data_type WHEN 'DATE' THEN ''
33 ELSE '(' || 33 ELSE '(' ||
40 data_type 40 data_type
41 FROM all_tab_columns atc 41 FROM all_tab_columns atc
42 WHERE atc.table_name = :object_name 42 WHERE atc.table_name = :object_name
43 AND atc.owner = :owner 43 AND atc.owner = :owner
44 ORDER BY atc.column_id;""",), 44 ORDER BY atc.column_id;""",),
45 'PROCEDURE': (""" 45 'PROCEDURE': ("""SELECT
46 argument_name, 46 argument_name,
47 data_type, 47 data_type,
48 in_out, 48 in_out,
49 default_value 49 default_value
50 FROM all_arguments 50 FROM all_arguments
515 result = '\n' + sqlpython.pmatrix(transpr,newdesc) 515 result = '\n' + sqlpython.pmatrix(transpr,newdesc)
516 else: 516 else:
517 result = sqlpython.pmatrix(self.rows, self.curs.description, self.maxfetch) 517 result = sqlpython.pmatrix(self.rows, self.curs.description, self.maxfetch)
518 return result 518 return result
519 519
520 statementEndPattern = re.compile(r'(.*)(;|\\[gGhtxicCsS])\s*(\d*)\s*$', re.DOTALL | re.MULTILINE)
521 # what about quote-enclosed?
522
523 legalOracle = re.compile('[a-zA-Z_$#]') 520 legalOracle = re.compile('[a-zA-Z_$#]')
524 521
525 def do_select(self, arg, bindVarsIn=None, override_terminator=None): 522 def do_select(self, arg, bindVarsIn=None, override_terminator=None):
526 """Fetch rows from a table. 523 """Fetch rows from a table.
527 524
531 528
532 Output may be formatted by choosing an alternative terminator 529 Output may be formatted by choosing an alternative terminator
533 ("help terminators" for details) 530 ("help terminators" for details)
534 """ 531 """
535 bindVarsIn = bindVarsIn or {} 532 bindVarsIn = bindVarsIn or {}
536 self.query = 'select ' + arg 533 self.query = arg.parent.executable
537 terminator = self.commmand_terminator_finder(self.query) 534 terminator = arg.parent.terminator or ';'
538 if terminator: 535 rowlimit = int(arg.parent.terminator_suffix or '0')
539 (self.query, terminator, dummy) = terminator
540 else:
541 terminator = [';']
542 try:
543 terminator, rowlimit = terminator[0], int(terminator[1])
544 except (IndexError, ValueError):
545 terminator, rowlimit = terminator[0], 0
546 if override_terminator: 536 if override_terminator:
547 terminator = override_terminator 537 terminator = override_terminator
548 try: 538 try:
549 self.varsUsed = findBinds(self.query, self.binds, bindVarsIn) 539 self.varsUsed = findBinds(self.query, self.binds, bindVarsIn)
550 self.curs.execute(self.query, self.varsUsed) 540 self.curs.execute(self.query, self.varsUsed)
573 563
574 @options([make_option('-f', '--full', action='store_true', help='get dependent objects as well')]) 564 @options([make_option('-f', '--full', action='store_true', help='get dependent objects as well')])
575 def do_pull(self, arg, opts): 565 def do_pull(self, arg, opts):
576 """Displays source code.""" 566 """Displays source code."""
577 567
578 object_type, owner, object_name = self.resolve(arg.strip(self.terminator).upper()) 568 object_type, owner, object_name = self.resolve(arg.upper())
579 if not object_type: 569 if not object_type:
580 return 570 return
581 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name)) 571 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name))
582 self.stdout.write(str(self.curs.callfunc('DBMS_METADATA.GET_DDL', cx_Oracle.CLOB, 572 self.stdout.write(str(self.curs.callfunc('DBMS_METADATA.GET_DDL', cx_Oracle.CLOB,
583 [object_type, object_name, owner]))) 573 [object_type, object_name, owner])))
596 if opts.insensitive: 586 if opts.insensitive:
597 searchfor = "LOWER(text)" 587 searchfor = "LOWER(text)"
598 arg = arg.lower() 588 arg = arg.lower()
599 else: 589 else:
600 searchfor = "text" 590 searchfor = "text"
601 self.do_select("* from all_source where %s like '%%%s%%'" % (searchfor, arg)) 591 self.onecmd("select * from all_source where %s like '%%%s%%';" % (searchfor, arg))
602 592
603 @options([make_option('-a','--all',action='store_true', 593 @options([make_option('-a','--all',action='store_true',
604 help='Describe all objects (not just my own)')]) 594 help='Describe all objects (not just my own)')])
605 def do_describe(self, arg, opts): 595 def do_describe(self, arg, opts):
606 "emulates SQL*Plus's DESCRIBE" 596 "emulates SQL*Plus's DESCRIBE"
609 which_view = (', owner', 'all') 599 which_view = (', owner', 'all')
610 else: 600 else:
611 which_view = ('', 'user') 601 which_view = ('', 'user')
612 602
613 if not arg: 603 if not arg:
614 self.do_select("""object_name, object_type%s FROM %s_objects WHERE object_type IN ('TABLE','VIEW','INDEX') ORDER BY object_name""" % which_view) 604 self.onecmd("""SELECT object_name, object_type%s FROM %s_objects WHERE object_type IN ('TABLE','VIEW','INDEX') ORDER BY object_name;""" % which_view)
615 return 605 return
616 object_type, owner, object_name = self.resolve(arg.strip(self.terminator).upper()) 606 object_type, owner, object_name = self.resolve(arg.upper())
617 if not object_type: 607 if not object_type:
618 self.do_select("""object_name, object_type%s FROM %s_objects 608 self.onecmd("""SELECT object_name, object_type%s FROM %s_objects
619 WHERE object_type IN ('TABLE','VIEW','INDEX') 609 WHERE object_type IN ('TABLE','VIEW','INDEX')
620 AND object_name LIKE '%%%s%%' 610 AND object_name LIKE '%%%s%%'
621 ORDER BY object_name""" % 611 ORDER BY object_name;""" %
622 (which_view[0], which_view[1], arg.upper()) ) 612 (which_view[0], which_view[1], arg.upper()) )
623 return 613 return
624 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name)) 614 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name))
625 descQ = descQueries.get(object_type) 615 descQ = descQueries.get(object_type)
626 if descQ: 616 if descQ:
627 for q in descQ: 617 for q in descQ:
628 self.do_select(q,bindVarsIn={'object_name':object_name, 'owner':owner}) 618 self.onecmd(q,bindVarsIn={'object_name':object_name, 'owner':owner})
629 elif object_type == 'PACKAGE': 619 elif object_type == 'PACKAGE':
630 self.curs.execute(descQueries['PackageObjects'][0], {'package_name':object_name, 'owner':owner}) 620 self.curs.execute(descQueries['PackageObjects'][0], {'package_name':object_name, 'owner':owner})
631 packageContents = self.curs.fetchall() 621 packageContents = self.curs.fetchall()
632 for (packageObj_name,) in packageContents: 622 for (packageObj_name,) in packageContents:
633 self.stdout.write(packageObj_name + '\n') 623 self.stdout.write(packageObj_name + '\n')
634 self.do_select(descQueries['PackageObjArgs'][0],bindVarsIn={'package_name':object_name, 'owner':owner, 'object_name':packageObj_name}) 624 self.onecmd(descQueries['PackageObjArgs'][0],bindVarsIn={'package_name':object_name, 'owner':owner, 'object_name':packageObj_name})
635 do_desc = do_describe 625 do_desc = do_describe
636 626
637 def do_deps(self, arg): 627 def do_deps(self, arg):
638 object_type, owner, object_name = self.resolve(arg.strip(self.terminator).upper()) 628 object_type, owner, object_name = self.resolve(arg.upper())
639 if object_type == 'PACKAGE BODY': 629 if object_type == 'PACKAGE BODY':
640 q = "and (type != 'PACKAGE BODY' or name != :object_name)'" 630 q = "and (type != 'PACKAGE BODY' or name != :object_name)'"
641 object_type = 'PACKAGE' 631 object_type = 'PACKAGE'
642 else: 632 else:
643 q = "" 633 q = ""
644 q = """ name, 634 q = """SELECT
635 name,
645 type 636 type
646 from user_dependencies 637 from user_dependencies
647 where 638 where
648 referenced_name like :object_name 639 referenced_name like :object_name
649 and referenced_type like :object_type 640 and referenced_type like :object_type
650 and referenced_owner like :owner 641 and referenced_owner like :owner
651 %s""" % (q) 642 %s;""" % (q)
652 self.do_select(q, {'object_name':object_name, 'object_type':object_type, 'owner':owner}) 643 self.onecmd(q, {'object_name':object_name, 'object_type':object_type, 'owner':owner})
653 644
654 def do_comments(self, arg): 645 def do_comments(self, arg):
655 'Prints comments on a table and its columns.' 646 'Prints comments on a table and its columns.'
656 object_type, owner, object_name = self.resolve(arg.strip(self.terminator).upper()) 647 object_type, owner, object_name = self.resolve(arg.upper())
657 if object_type: 648 if object_type:
658 self.curs.execute(queries['tabComments'],{'table_name':object_name, 'owner':owner}) 649 self.curs.execute(queries['tabComments'],{'table_name':object_name, 'owner':owner})
659 self.stdout.write("%s %s.%s: %s\n" % (object_type, owner, object_name, self.curs.fetchone()[0])) 650 self.stdout.write("%s %s.%s: %s\n" % (object_type, owner, object_name, self.curs.fetchone()[0]))
660 self.do_select(queries['colComments'],bindVarsIn={'owner':owner, 'object_name': object_name}) 651 self.onecmd(queries['colComments'],bindVarsIn={'owner':owner, 'object_name': object_name})
661 652
662 def resolve(self, identifier): 653 def resolve(self, identifier):
663 """Checks (my objects).name, (my synonyms).name, (public synonyms).name 654 """Checks (my objects).name, (my synonyms).name, (public synonyms).name
664 to resolve a database object's name. """ 655 to resolve a database object's name. """
665 parts = identifier.split('.') 656 parts = identifier.split('.')
717 print self.do_compare.__doc__ 708 print self.do_compare.__doc__
718 return 709 return
719 for n in range(len(args2)): 710 for n in range(len(args2)):
720 query = args2[n] 711 query = args2[n]
721 fnames.append('compare%s.txt' % n) 712 fnames.append('compare%s.txt' % n)
722 if query.rstrip()[-1] != self.terminator: 713 if query.rstrip()[-1] != self.terminator: #TODO: fix with new terminators
723 query = '%s%s' % (query, self.terminator) 714 query = '%s%s' % (query, self.terminator)
724 self.onecmd_plus_hooks('%s > %s' % (query, fnames[n])) 715 self.onecmd_plus_hooks('%s > %s' % (query, fnames[n]))
725 diffMergeSearcher.invoke(fnames[0], fnames[1]) 716 diffMergeSearcher.invoke(fnames[0], fnames[1])
726 717
727 bufferPosPattern = re.compile('\d+') 718 bufferPosPattern = re.compile('\d+')
770 def do__dir_tables(self, arg, opts): 761 def do__dir_tables(self, arg, opts):
771 if opts.all: 762 if opts.all:
772 which_view = (', owner', 'all') 763 which_view = (', owner', 'all')
773 else: 764 else:
774 which_view = ('', 'user') 765 which_view = ('', 'user')
775 self.do_select("""table_name, 'TABLE' as type%s FROM %s_tables WHERE table_name LIKE '%%%s%%'""" % 766 self.onecmd("""SELECT table_name, 'TABLE' as type%s FROM %s_tables WHERE table_name LIKE '%%%s%%';""" %
776 (which_view[0], which_view[1], arg.upper())) 767 (which_view[0], which_view[1], arg.upper()))
777 768
778 @options([make_option('-a','--all',action='store_true', 769 @options([make_option('-a','--all',action='store_true',
779 help='Describe all objects (not just my own)')]) 770 help='Describe all objects (not just my own)')])
780 def do__dir_views(self, arg, opts): 771 def do__dir_views(self, arg, opts):
781 if opts.all: 772 if opts.all:
782 which_view = (', owner', 'all') 773 which_view = (', owner', 'all')
783 else: 774 else:
784 which_view = ('', 'user') 775 which_view = ('', 'user')
785 self.do_select("""view_name, 'VIEW' as type%s FROM %s_views WHERE view_name LIKE '%%%s%%'""" % 776 self.onecmd("""SELECT view_name, 'VIEW' as type%s FROM %s_views WHERE view_name LIKE '%%%s%%';""" %
786 (which_view[0], which_view[1], arg.upper())) 777 (which_view[0], which_view[1], arg.upper()))
787 778
788 @options([make_option('-a','--all',action='store_true', 779 @options([make_option('-a','--all',action='store_true',
789 help='Describe all objects (not just my own)')]) 780 help='Describe all objects (not just my own)')])
790 def do__dir_indexes(self, arg, opts): 781 def do__dir_indexes(self, arg, opts):
791 if opts.all: 782 if opts.all:
792 which_view = (', owner', 'all') 783 which_view = (', owner', 'all')
793 else: 784 else:
794 which_view = ('', 'user') 785 which_view = ('', 'user')
795 self.do_select("""index_name, index_type%s FROM %s_indexes WHERE index_name LIKE '%%%s%%' OR table_name LIKE '%%%s%%'""" % 786 self.onecmd("""SELECT index_name, index_type%s FROM %s_indexes WHERE index_name LIKE '%%%s%%' OR table_name LIKE '%%%s%%';""" %
796 (which_view[0], which_view[1], arg.upper(), arg.upper())) 787 (which_view[0], which_view[1], arg.upper(), arg.upper()))
797 788
798 def do__dir_tablespaces(self, arg): 789 def do__dir_tablespaces(self, arg):
799 self.do_select("""tablespace_name, file_name from dba_data_files""") 790 self.onecmd("""SELECT tablespace_name, file_name from dba_data_files;""")
800 791
801 def do__dir_schemas(self, arg): 792 def do__dir_schemas(self, arg):
802 self.do_select("""owner, count(*) AS objects FROM all_objects GROUP BY owner ORDER BY owner""") 793 self.onecmd("""SELECT owner, count(*) AS objects FROM all_objects GROUP BY owner ORDER BY owner;""")
803 794
804 def do_head(self, arg): 795 def do_head(self, arg):
805 nrows = 10 796 nrows = 10
806 args = arg.split() 797 args = arg.split()
807 if len(args) > 1: 798 if len(args) > 1:
811 nrows = int(a[1:]) 802 nrows = int(a[1:])
812 args.remove(a) 803 args.remove(a)
813 except: 804 except:
814 pass 805 pass
815 arg = ' '.join(args) 806 arg = ' '.join(args)
816 self.do_select('* from %s;%d' % (arg, nrows)) 807 self.onecmd('SELECT * from %s;%d' % (arg, nrows))
817 808
818 def do_print(self, arg): 809 def do_print(self, arg):
819 'print VARNAME: Show current value of bind variable VARNAME.' 810 'print VARNAME: Show current value of bind variable VARNAME.'
820 if arg: 811 if arg:
821 if arg[0] == ':': 812 if arg[0] == ':':
923 self.stdout.write('\n'.join(result) + '\n') 914 self.stdout.write('\n'.join(result) + '\n')
924 915
925 def do_cat(self, arg): 916 def do_cat(self, arg):
926 targets = arg.split() 917 targets = arg.split()
927 for target in targets: 918 for target in targets:
928 self.do_select('* from %s' % target) 919 self.onecmd('select * from %s;' % target)
929 920
930 @options([make_option('-i', '--ignore-case', dest='ignorecase', action='store_true', help='Case-insensitive search')]) 921 @options([make_option('-i', '--ignore-case', dest='ignorecase', action='store_true', help='Case-insensitive search')])
931 def do_grep(self, arg, opts): 922 def do_grep(self, arg, opts):
932 """grep PATTERN TABLE - search for term in any of TABLE's fields""" 923 """grep PATTERN TABLE - search for term in any of TABLE's fields"""
933 924
949 self.curs.execute('select * from %s where 1=0' % target) 940 self.curs.execute('select * from %s where 1=0' % target)
950 if opts.ignorecase: 941 if opts.ignorecase:
951 sql = ' or '.join("LOWER(%s) LIKE '%%%s%%'" % (d[0], pattern.lower()) for d in self.curs.description) 942 sql = ' or '.join("LOWER(%s) LIKE '%%%s%%'" % (d[0], pattern.lower()) for d in self.curs.description)
952 else: 943 else:
953 sql = ' or '.join("%s LIKE '%%%s%%'" % (d[0], pattern) for d in self.curs.description) 944 sql = ' or '.join("%s LIKE '%%%s%%'" % (d[0], pattern) for d in self.curs.description)
954 sql = '* FROM %s WHERE %s' % (target, sql) 945 sql = 'SELECT * FROM %s WHERE %s;' % (target, sql)
955 self.do_select(sql) 946 self.onecmd(sql)
956 except Exception, e: 947 except Exception, e:
957 print e 948 print e
958 import traceback 949 import traceback
959 traceback.print_exc(file=sys.stdout) 950 traceback.print_exc(file=sys.stdout)
960 951
961 def do_refs(self, arg): 952 def do_refs(self, arg):
962 object_type, owner, object_name = self.resolve(arg.strip(self.terminator).upper()) 953 object_type, owner, object_name = self.resolve(arg.upper())
963 if object_type == 'TABLE': 954 if object_type == 'TABLE':
964 self.do_select(queries['refs'],bindVarsIn={'object_name':object_name, 'owner':owner}) 955 self.onecmd(queries['refs'],bindVarsIn={'object_name':object_name, 'owner':owner})
965 956
966 def _test(): 957 def _test():
967 import doctest 958 import doctest
968 doctest.testmod() 959 doctest.testmod()
969 960