Mercurial > sqlpython
comparison sqlpyPlus.py @ 7:d44784122203
more history tweaks
author | devlinjs@FA7CZA6N1254998.wrightpatterson.afmc.ds.af.mil |
---|---|
date | Wed, 05 Dec 2007 16:27:43 -0500 |
parents | f9ec5c20beb4 |
children | 8e909570e7de |
comparison
equal
deleted
inserted
replaced
6:f9ec5c20beb4 | 7:d44784122203 |
---|---|
353 def pr(self): | 353 def pr(self): |
354 print '-------------------------[%d]' % (self.idx) | 354 print '-------------------------[%d]' % (self.idx) |
355 print self | 355 print self |
356 | 356 |
357 class History(list): | 357 class History(list): |
358 digitsOnly = re.compile('^[\d]+$') | |
359 rangeTo = re.compile(r'^\-\s*([-d])+$') | |
358 def append(self, new): | 360 def append(self, new): |
359 new = HistoryItem(new) | 361 new = HistoryItem(new) |
360 list.append(self, new) | 362 list.append(self, new) |
361 new.idx = len(self) | 363 new.idx = len(self) |
362 def extend(self, new): | 364 def extend(self, new): |
363 for n in new: | 365 for n in new: |
364 self.append(n) | 366 self.append(n) |
365 def get(self, getme): | 367 def get(self, getme): |
366 try: | 368 getme = getme.strip() |
367 idx = int(getme) | 369 if not getme: |
370 return [] | |
371 if self.digitsOnly.search(getme): | |
368 try: | 372 try: |
369 return [self[idx-1]] | 373 idx = int(getme) |
370 except IndexError: | 374 try: |
371 return [] | 375 return [self[idx-1]] |
376 except IndexError: | |
377 return [] | |
378 m = self.rangeTo.search(getme) | |
379 if m: | |
380 return self[int(:m.group(1))] | |
381 | |
382 excep | |
372 except ValueError: # search for a string | 383 except ValueError: # search for a string |
373 try: | 384 try: |
374 getme = getme.strip() | 385 getme = getme.strip() |
375 except: | 386 except: |
376 print "Don't know how to handle %s." % (str(getme)) | 387 print "Don't know how to handle %s." % (str(getme)) |
380 def isin(hi): | 391 def isin(hi): |
381 return finder.search(hi) | 392 return finder.search(hi) |
382 else: | 393 else: |
383 def isin(hi): | 394 def isin(hi): |
384 return (getme.lower() in hi.lowercase) | 395 return (getme.lower() in hi.lowercase) |
385 return [itm for itm in self[:-1] if isin(itm)] | 396 return [itm for itm in self if isin(itm)] |
386 | 397 |
387 class sqlpyPlus(sqlpython.sqlpython): | 398 class sqlpyPlus(sqlpython.sqlpython): |
388 def __init__(self): | 399 def __init__(self): |
389 sqlpython.sqlpython.__init__(self) | 400 sqlpython.sqlpython.__init__(self) |
390 self.binds = CaselessDict() | 401 self.binds = CaselessDict() |
454 args = line.split(None,1) | 465 args = line.split(None,1) |
455 args[0] = args[0].lower() | 466 args[0] = args[0].lower() |
456 statement = ' '.join(args) | 467 statement = ' '.join(args) |
457 if args[0] in self.multiline: | 468 if args[0] in self.multiline: |
458 statement = sqlpython.finishStatement(statement) | 469 statement = sqlpython.finishStatement(statement) |
459 if args[0] not in self.excludeFromHistory: | |
460 self.history.append(statement) | |
461 return statement | 470 return statement |
462 except Exception: | 471 except Exception: |
463 return line | 472 return line |
464 | 473 |
474 def postcmd(self, stop, line): | |
475 """Hook method executed just after a command dispatch is finished.""" | |
476 command = line.split(None,1)[0].lower() | |
477 if command not in self.excludeFromHistory: | |
478 self.history.append(line) | |
479 return stop | |
480 | |
481 def onecmd_plus_hooks(self, line): | |
482 line = self.precmd(line) | |
483 stop = self.onecmd(line) | |
484 stop = self.postcmd(stop, line) | |
485 | |
465 def do_shortcuts(self,arg): | 486 def do_shortcuts(self,arg): |
466 """Lists available first-character shortcuts | 487 """Lists available first-character shortcuts |
467 (i.e. '!dir' is equivalent to 'shell dir')""" | 488 (i.e. '!dir' is equivalent to 'shell dir')""" |
468 for (scchar, scto) in self.shortcuts.items(): | 489 for (scchar, scto) in self.shortcuts.items(): |
469 print '%s: %s' % (scchar, scto) | 490 print '%s: %s' % (scchar, scto) |
733 | 754 |
734 def write(self, arg, fname): | 755 def write(self, arg, fname): |
735 originalOut = sys.stdout | 756 originalOut = sys.stdout |
736 f = open(fname, 'w') | 757 f = open(fname, 'w') |
737 sys.stdout = f | 758 sys.stdout = f |
738 self.onecmd(arg) | 759 self.onecmd_plus_hooks(arg) |
739 f.close() | 760 f.close() |
740 sys.stdout = originalOut | 761 sys.stdout = originalOut |
741 | 762 |
742 def do_write(self, args): | 763 def do_write(self, args): |
743 'write [filename.extension] query - writes result to a file' | 764 'write [filename.extension] query - writes result to a file' |
763 self.write(query, fnames[n]) | 784 self.write(query, fnames[n]) |
764 diffMergeSearcher.invoke(fnames[0], fnames[1]) | 785 diffMergeSearcher.invoke(fnames[0], fnames[1]) |
765 | 786 |
766 bufferPosPattern = re.compile('\d+') | 787 bufferPosPattern = re.compile('\d+') |
767 rangeIndicators = ('-',':') | 788 rangeIndicators = ('-',':') |
768 | |
769 def last_matching_command(self, arg): | |
770 if not arg: | |
771 return self.history[-2] | |
772 else: | |
773 history = self.history.get(arg) | |
774 if history: | |
775 return history[-1] | |
776 return None | |
777 | 789 |
778 def do_run(self, arg): | 790 def do_run(self, arg): |
779 """run [arg]: re-runs an earlier command | 791 """run [arg]: re-runs an earlier command |
780 | 792 |
781 no arg -> run most recent command | 793 no arg -> run most recent command |
782 arg is integer -> run one history item, by index | 794 arg is integer -> run one history item, by index |
783 arg is string -> run most recent command by string search | 795 arg is string -> run most recent command by string search |
784 arg is /enclosed in forward-slashes/ -> run most recent by regex | 796 arg is /enclosed in forward-slashes/ -> run most recent by regex |
785 """ | 797 """ |
786 'run [N]: runs the SQL that was run N commands ago' | 798 'run [N]: runs the SQL that was run N commands ago' |
787 runme = self.last_matching_command(arg) | 799 runme = self.last_matching(arg) |
788 print runme | 800 print runme |
789 self.onecmd(runme) | 801 self.onecmd_plus_hooks(runme) |
790 do_r = do_run | 802 do_r = do_run |
791 def do_history(self, arg): | 803 def do_history(self, arg): |
792 """history [arg]: lists past commands issued | 804 """history [arg]: lists past commands issued |
793 | 805 |
794 no arg -> list all | 806 no arg -> list all |
800 history = self.history.get(arg) | 812 history = self.history.get(arg) |
801 else: | 813 else: |
802 history = self.history | 814 history = self.history |
803 for hi in history: | 815 for hi in history: |
804 hi.pr() | 816 hi.pr() |
817 def last_matching(self, arg): | |
818 try: | |
819 if arg: | |
820 return self.history.get(arg)[-1] | |
821 else: | |
822 return self.history[-1] | |
823 except: | |
824 return None | |
805 def do_list(self, arg): | 825 def do_list(self, arg): |
806 """list: lists single most recent command issued""" | 826 """list [arg]: lists last command issued |
807 self.last_matching_command(None).pr() | 827 |
828 no arg -> list absolute last | |
829 arg is integer -> list one history item, by index | |
830 - arg, arg - (integer) -> list up to or after #arg | |
831 arg is string -> list last command matching string search | |
832 arg is /enclosed in forward-slashes/ -> regular expression search | |
833 """ | |
834 try: | |
835 self.last_matching(arg).pr() | |
836 except: | |
837 pass | |
808 do_hi = do_history | 838 do_hi = do_history |
809 do_l = do_list | 839 do_l = do_list |
840 do_li = do_list | |
810 def load(self, fname): | 841 def load(self, fname): |
811 """Pulls command(s) into sql buffer. Returns number of commands loaded.""" | 842 """Pulls command(s) into sql buffer. Returns number of commands loaded.""" |
812 try: | 843 try: |
813 f = open(fname, 'r') | 844 f = open(fname, 'r') |
814 except IOError, e: | 845 except IOError, e: |
823 self.history.extend(result) | 854 self.history.extend(result) |
824 return len(result) | 855 return len(result) |
825 def do_ed(self, arg): | 856 def do_ed(self, arg): |
826 'ed [N]: brings up SQL from N commands ago in text editor, and puts result in SQL buffer.' | 857 'ed [N]: brings up SQL from N commands ago in text editor, and puts result in SQL buffer.' |
827 fname = 'sqlpython_temp.sql' | 858 fname = 'sqlpython_temp.sql' |
828 buffer = self.last_matching_command(arg) | 859 buffer = self.last_matching(arg) |
860 if not buffer: | |
861 print 'Nothing appropriate in buffer to edit.' | |
862 return | |
829 f = open(fname, 'w') | 863 f = open(fname, 'w') |
830 f.write(buffer) | 864 f.write(buffer) |
831 f.close() | 865 f.close() |
832 editSearcher.invoke(fname) | 866 editSearcher.invoke(fname) |
833 self.load(fname) | 867 self.load(fname) |
834 do_edit = do_ed | 868 do_edit = do_ed |
835 def do_get(self, fname): | 869 def do_get(self, fname): |
836 'Brings SQL commands from a file to the in-memory SQL buffer.' | 870 'Brings SQL commands from a file to the in-memory SQL buffer.' |
837 commandsLoaded = self.load(fname) | 871 numCommandsLoaded = self.load(fname) |
838 if commandsLoaded: | 872 if numCommandsLoaded: |
839 self.do_list('1-%d' % (commandsLoaded-1)) | 873 self.do_list('%d -' % (len(self.history) - numCommandsLoaded)) |
840 def do_getrun(self, fname): | 874 def do_getrun(self, fname): |
841 'Brings SQL commands from a file to the in-memory SQL buffer, and executes them.' | 875 'Brings SQL commands from a file to the in-memory SQL buffer, and executes them.' |
842 newCommands = self.load(fname) * -1 | 876 numCommandsLoaded = self.load(fname) * -1 |
843 if newCommands: | 877 if numCommandsLoaded: |
844 for command in self.history[newCommands:]: | 878 for command in self.history[numCommandsLoaded:]: |
845 self.onecmd(command) | 879 self.onecmd_plus_hooks(command) |
846 def do_psql(self, arg): | 880 def do_psql(self, arg): |
847 '''Shortcut commands emulating psql's backslash commands. | 881 '''Shortcut commands emulating psql's backslash commands. |
848 | 882 |
849 \c connect | 883 \c connect |
850 \d desc | 884 \d desc |
923 """grep PATTERN TABLE - search for term in any of TABLE's fields""" | 957 """grep PATTERN TABLE - search for term in any of TABLE's fields""" |
924 targets = arg.split() | 958 targets = arg.split() |
925 pattern = targets.pop(0) | 959 pattern = targets.pop(0) |
926 for target in targets: | 960 for target in targets: |
927 sql = [] | 961 sql = [] |
928 self.curs.execute('select * from %s where 1=0' % target) | 962 print 'select * from %s where 1=0' % target |
929 sql = ' or '.join("%s LIKE '%%%s%%'" % (d[0], pattern) for d in self.curs.description) | 963 try: |
930 sql = '* FROM %s WHERE %s' % (target, sql) | 964 self.curs.execute('select * from %s where 1=0' % target) |
931 self.do_select(sql) | 965 sql = ' or '.join("%s LIKE '%%%s%%'" % (d[0], pattern) for d in self.curs.description) |
966 sql = '* FROM %s WHERE %s' % (target, sql) | |
967 self.do_select(sql) | |
968 except Exception, e: | |
969 print e | |
970 import traceback | |
971 traceback.print_exc(file=sys.stdout) | |
932 | 972 |
933 def _test(): | 973 def _test(): |
934 import doctest | 974 import doctest |
935 doctest.testmod() | 975 doctest.testmod() |
936 | 976 |