Mercurial > sqlpython
comparison sqlpyPlus.py @ 3:cd23cd62de3c
history working pretty well
author | devlinjs@FA7CZA6N1254998.wrightpatterson.afmc.ds.af.mil |
---|---|
date | Mon, 03 Dec 2007 16:43:43 -0500 |
parents | 59903dcaf327 |
children | 23c3a58d7804 |
comparison
equal
deleted
inserted
replaced
2:59903dcaf327 | 3:cd23cd62de3c |
---|---|
259 except KeyError: | 259 except KeyError: |
260 if not givenBindVars.has_key(varname): | 260 if not givenBindVars.has_key(varname): |
261 print 'Bind variable %s not defined.' % (varname) | 261 print 'Bind variable %s not defined.' % (varname) |
262 return result | 262 return result |
263 | 263 |
264 class HistoryItem(str): | |
265 def __init__(self, instr): | |
266 str.__init__(self, instr) | |
267 self.lowercase = self.lower() | |
268 self.idx = None | |
269 def pr(self): | |
270 print '-------------------------[%d]' % (self.idx) | |
271 print self | |
272 | |
273 class History(list): | |
274 def append(self, new): | |
275 new = HistoryItem(new) | |
276 list.append(self, new) | |
277 new.idx = len(self) | |
278 def extend(self, new): | |
279 for n in new: | |
280 self.append(n) | |
281 def get(self, getme): | |
282 try: | |
283 idx = int(getme) | |
284 try: | |
285 return [self[idx-1]] | |
286 except IndexError: | |
287 return [] | |
288 except ValueError: # search for a string | |
289 try: | |
290 getme = getme.strip() | |
291 except: | |
292 print "Don't know how to handle %s." % (str(getme)) | |
293 return | |
294 if getme.startswith(r'/') and getme.endswith(r'/'): | |
295 finder = re.compile(getme[1:-1], re.DOTALL | re.MULTILINE | re.IGNORECASE) | |
296 def isin(hi): | |
297 return finder.search(hi) | |
298 else: | |
299 def isin(hi): | |
300 return (getme.lower() in hi.lowercase) | |
301 return [itm for itm in self[:-1] if isin(itm)] | |
302 | |
264 class sqlpyPlus(sqlpython.sqlpython): | 303 class sqlpyPlus(sqlpython.sqlpython): |
265 def __init__(self): | 304 def __init__(self): |
266 sqlpython.sqlpython.__init__(self) | 305 sqlpython.sqlpython.__init__(self) |
267 self.binds = CaselessDict() | 306 self.binds = CaselessDict() |
268 self.sqlBuffer = [] | 307 self.sqlBuffer = [] |
269 self.history = [] | 308 self.history = History() |
270 self.settable = ['maxtselctrows', 'maxfetch', 'autobind', 'failover', 'timeout'] # settables must be lowercase | 309 self.settable = ['maxtselctrows', 'maxfetch', 'autobind', 'failover', 'timeout'] # settables must be lowercase |
271 self.stdoutBeforeSpool = sys.stdout | 310 self.stdoutBeforeSpool = sys.stdout |
272 self.spoolFile = None | 311 self.spoolFile = None |
273 self.autobind = False | 312 self.autobind = False |
274 self.failover = False | 313 self.failover = False |
326 args = line.split(None,1) | 365 args = line.split(None,1) |
327 args[0] = args[0].lower() | 366 args[0] = args[0].lower() |
328 statement = ' '.join(args) | 367 statement = ' '.join(args) |
329 if args[0] in self.singleline: | 368 if args[0] in self.singleline: |
330 statement = sqlpython.finishStatement(statement) | 369 statement = sqlpython.finishStatement(statement) |
370 self.history.append(statement) | |
331 return statement | 371 return statement |
332 except Exception: | 372 except Exception: |
333 return line | 373 return line |
334 | 374 |
335 def do_shortcuts(self,arg): | 375 def do_shortcuts(self,arg): |
609 self.write(query, fnames[n]) | 649 self.write(query, fnames[n]) |
610 diffMergeSearcher.invoke(fnames[0], fnames[1]) | 650 diffMergeSearcher.invoke(fnames[0], fnames[1]) |
611 | 651 |
612 bufferPosPattern = re.compile('\d+') | 652 bufferPosPattern = re.compile('\d+') |
613 rangeIndicators = ('-',':') | 653 rangeIndicators = ('-',':') |
614 def bufferPositions(self, arg): | 654 |
615 if not self.sqlBuffer: | 655 def last_matching_command(self, arg): |
616 return [] | |
617 arg = arg.strip(self.terminator) | |
618 arg = arg.strip() | |
619 if not arg: | 656 if not arg: |
620 return [0] | 657 return self.history[-2] |
621 arg = arg.strip().lower() | 658 else: |
622 if arg in ('*', 'all', '-', ':'): | 659 history = self.history.get(arg) |
623 return range(len(self.sqlBuffer)) | 660 if history: |
624 | 661 return history[-1] |
625 edges = [e for e in self.bufferPosPattern.findall(arg)] | 662 return None |
626 edges = [int(e) for e in edges] | 663 |
627 if len(edges) > 1: | |
628 edges = edges[:2] | |
629 else: | |
630 if arg[0] in self.rangeIndicators or arg[-1] in self.rangeIndicators: | |
631 edges.append(0) | |
632 edges.sort() | |
633 start = max(edges[0], 0) | |
634 end = min(edges[-1], len(self.sqlBuffer)-1) | |
635 return range(start, end+1) | |
636 def do_run(self, arg): | 664 def do_run(self, arg): |
637 'run [N]: runs the SQL that was run N commands ago' | 665 """run [arg]: re-runs an earlier command |
638 for pos in self.bufferPositions(arg): | 666 |
639 self.onecmd(self.sqlBuffer[-1-pos]) | 667 no arg -> run most recent command |
668 arg is integer -> run one history item, by index | |
669 arg is string -> run most recent command by string search | |
670 arg is /enclosed in forward-slashes/ -> run most recent by regex | |
671 """ | |
672 'run [N]: runs the SQL that was run N commands ago' | |
673 runme = self.last_matching_command(arg) | |
674 print runme | |
675 self.onecmd(runme) | |
676 do_r = do_run | |
640 def do_history(self, arg): | 677 def do_history(self, arg): |
641 for (i, itm) in enumerate(self.history): | 678 """history [arg]: lists past commands issued |
642 print '-------------------------[%d]' % (i+1) | 679 |
643 print itm | 680 no arg -> list all |
681 arg is integer -> list one history item, by index | |
682 arg is string -> string search | |
683 arg is /enclosed in forward-slashes/ -> regular expression search | |
684 """ | |
685 if arg: | |
686 history = self.history.get(arg) | |
687 else: | |
688 history = self.history | |
689 for hi in history: | |
690 hi.pr() | |
644 def do_list(self, arg): | 691 def do_list(self, arg): |
645 'list [N]: lists the SQL that was run N commands ago' | 692 """list: lists single most recent command issued""" |
646 for pos in self.bufferPositions(arg): | 693 self.last_matching_command(None).pr() |
647 print '*** %i statements ago ***' % pos | 694 do_hi = do_history |
648 print self.sqlBuffer[-1-pos] | 695 do_l = do_list |
649 def load(self, fname): | 696 def load(self, fname): |
650 """Pulls command(s) into sql buffer. Returns number of commands loaded.""" | 697 """Pulls command(s) into sql buffer. Returns number of commands loaded.""" |
651 initialLength = len(self.sqlBuffer) | |
652 try: | 698 try: |
653 f = open(fname, 'r') | 699 f = open(fname, 'r') |
654 except IOError, e: | 700 except IOError, e: |
655 try: | 701 try: |
656 f = open('%s.sql' % fname, 'r') | 702 f = open('%s.sql' % fname, 'r') |
657 except: | 703 except: |
658 print 'Problem opening file %s: \n%s' % (fname, e) | 704 print 'Problem opening file %s: \n%s' % (fname, e) |
659 return 0 | 705 return 0 |
660 txt = f.read() | 706 txt = f.read() |
661 f.close() | 707 f.close() |
662 self.sqlBuffer.extend(commandSeparator.separate(txt)) | 708 result = commandSeparator.separate(txt) |
663 return len(self.sqlBuffer) - initialLength | 709 self.history.extend(result) |
710 return len(result) | |
664 def do_ed(self, arg): | 711 def do_ed(self, arg): |
665 'ed [N]: brings up SQL from N commands ago in text editor, and puts result in SQL buffer.' | 712 'ed [N]: brings up SQL from N commands ago in text editor, and puts result in SQL buffer.' |
666 fname = 'mysqlpy_temp.sql' | 713 fname = 'sqlpython_temp.sql' |
667 try: | 714 buffer = self.last_matching_command(arg) |
668 buffer = self.sqlBuffer[-1 - (int(arg or 0))] | |
669 except IndexError: | |
670 buffer = '' | |
671 f = open(fname, 'w') | 715 f = open(fname, 'w') |
672 f.write(buffer) | 716 f.write(buffer) |
673 f.close() | 717 f.close() |
674 editSearcher.invoke(fname) | 718 editSearcher.invoke(fname) |
675 self.load(fname) | 719 self.load(fname) |
679 commandsLoaded = self.load(fname) | 723 commandsLoaded = self.load(fname) |
680 if commandsLoaded: | 724 if commandsLoaded: |
681 self.do_list('1-%d' % (commandsLoaded-1)) | 725 self.do_list('1-%d' % (commandsLoaded-1)) |
682 def do_getrun(self, fname): | 726 def do_getrun(self, fname): |
683 'Brings SQL commands from a file to the in-memory SQL buffer, and executes them.' | 727 'Brings SQL commands from a file to the in-memory SQL buffer, and executes them.' |
684 commandNums = range(self.load(fname)) | 728 newCommands = self.load(fname) * -1 |
685 commandNums.reverse() | 729 if newCommands: |
686 for commandNum in commandNums: | 730 for command in self.history[newCommands:]: |
687 self.do_run(str(commandNum)) | 731 self.onecmd(command) |
688 self.sqlBuffer.pop() | |
689 def do_psql(self, arg): | 732 def do_psql(self, arg): |
690 '''Shortcut commands emulating psql's backslash commands. | 733 '''Shortcut commands emulating psql's backslash commands. |
691 | 734 |
692 \c connect | 735 \c connect |
693 \d desc | 736 \d desc |
714 self.onecmd('q') | 757 self.onecmd('q') |
715 except KeyError: | 758 except KeyError: |
716 print 'psql command \%s not yet supported.' % abbrev | 759 print 'psql command \%s not yet supported.' % abbrev |
717 def do_save(self, fname): | 760 def do_save(self, fname): |
718 'save FILENAME: Saves most recent SQL command to disk.' | 761 'save FILENAME: Saves most recent SQL command to disk.' |
719 f = open(fname, 'w') | 762 try: |
720 f.write(self.sqlBuffer[-1]) | 763 f = open(fname, 'w') |
721 f.close() | 764 f.write(self.sqlBuffer[-1]) |
765 f.close() | |
766 except Exception, e: | |
767 print 'Error saving %s: %s' % (fname, str(e)) | |
722 | 768 |
723 def do_print(self, arg): | 769 def do_print(self, arg): |
724 'print VARNAME: Show current value of bind variable VARNAME.' | 770 'print VARNAME: Show current value of bind variable VARNAME.' |
725 if arg: | 771 if arg: |
726 if arg[0] == ':': | 772 if arg[0] == ':': |