Mercurial > sqlpython
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 |