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