• R/O
  • SSH

execsql: Commit

Default repository for execsql.py


Commit MetaInfo

Révision993b1fdb5d5beac5862fdaebe0e4e391f8f416c4 (tree)
l'heure2020-02-07 10:10:26
AuteurDreas Nielsen <dreas.nielsen@gmai...>
CommiterDreas Nielsen

Message de Log

Modified so that PROMPT ASK accepts multi-line messages.

Change Summary

Modification

diff -r fade9e1287ba -r 993b1fdb5d5b execsql/execsql.py
--- a/execsql/execsql.py Thu Feb 06 07:08:42 2020 -0800
+++ b/execsql/execsql.py Thu Feb 06 17:10:26 2020 -0800
@@ -27,12 +27,12 @@
2727 #
2828 # ===============================================================================
2929
30-__version__ = "1.61.3"
30+__version__ = "1.61.5"
3131 __vdate = "2020-02-06"
3232
3333 primary_vno = 1
3434 secondary_vno = 61
35-tertiary_vno = 2
35+tertiary_vno = 5
3636
3737 import os
3838 import os.path
@@ -798,7 +798,6 @@
798798 time_left = self.maxtime - elapsed_time
799799 barlength = 30
800800 bar_left = int(round(barlength * time_left/self.maxtime, 0))
801- #sys.stdout.write("%s |%s%s|\r" % ("{:8.1f}".format(time_left), "+"*bar_left, "-"*(barlength-bar_left)))
802801 output.write("%s |%s%s|\r" % ("{:8.1f}".format(time_left), "+"*bar_left, "-"*(barlength-bar_left)))
803802
804803
@@ -1245,22 +1244,17 @@
12451244 elif isinstance(item, datetime.datetime):
12461245 self.define_iso_datetime_style()
12471246 tc = odf.table.TableCell(valuetype="date", datevalue=item.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3], stylename="iso_datetime")
1248- #tc.addElement(odf.text.P(text=item.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]))
12491247 elif isinstance(item, datetime.date):
12501248 self.define_iso_date_style()
12511249 tc = odf.table.TableCell(valuetype="date", datevalue=item.strftime("%Y-%m-%d"), stylename="iso_date")
1252- #tc.addElement(odf.text.P(text=item.strftime("%Y-%m-%d")))
12531250 elif isinstance(item, datetime.time):
12541251 self.define_iso_datetime_style()
12551252 timeval = datetime.datetime(1899, 12, 30, item.hour, item.minute, item.second, item.microsecond, item.tzinfo)
12561253 tc = odf.table.TableCell(timevalue=timeval.strftime("PT%HH%MM%S.%fS"), stylename="iso_datetime")
12571254 tc.addElement(odf.text.P(text=timeval.strftime("%H:%M:%S.%f")))
1258- #tc = odf.table.TableCell(valuetype="time", value=datetime.datetime(1899,12,30, item.hour, item.minute, item.second, item.microsecond, item.tzinfo))
12591255 elif isinstance(item, stringtypes):
1260- #tc = odf.table.TableCell(stringvalue=item)
12611256 item = item.replace(u'\n', u' ').replace(u'\r', u' ')
12621257 tc = odf.table.TableCell(valuetype="string", stringvalue=item)
1263- #tc.addElement(odf.text.P(text=unicode(item)))
12641258 else:
12651259 tc = odf.table.TableCell(value=item)
12661260 if item is not None:
@@ -1433,7 +1427,6 @@
14331427 return u''.join(chr(ord(t)^ord(k)) for t,k in zip(text, itertools.cycle(enckey)))
14341428 def encrypt(self, plaintext):
14351429 random.seed()
1436- #kykey = self.ky.keys()[random.randint(0, len(self.ky.keys())-1)]
14371430 kykey = list(self.ky)[random.randint(0, len(list(self.ky))-1)]
14381431 kyval = self.ky[kykey]
14391432 noiselen = random.randint(1, 15)
@@ -1703,12 +1696,10 @@
17031696 elif hasattr(exc_param, 'value') and isinstance(exc_param.value, stringtypes) and len(exc_param.value) > 0:
17041697 exc_message = exc_param.value
17051698 else:
1706- #exc_message = repr(exc_param)
17071699 exc_message = type(u"")(exc_param)
17081700 try:
17091701 exc_message = type(u"")(exc_message)
17101702 except:
1711- # UnicodeDecode error. 'repr()' will escape bad characters, but also newlines.
17121703 exc_message = repr(exc_message)
17131704 return sys.exc_info()[0].__name__, exc_message, strace[0][0], xline, strace[0][3]
17141705
@@ -2792,23 +2783,6 @@
27922783 return "Method %s is not implemented for database %s" % (self.method, self.db_name)
27932784
27942785
2795-#class DictRows(object):
2796-# def __init__(self, cursor, encoding):
2797-# self.headers = [d[0] for d in cursor.description]
2798-# self.curs = cursor
2799-# self.encoding = encoding
2800-# self.dict = None
2801-# def __iter__(self):
2802-# return self
2803-# def next(self):
2804-# row = self.curs.fetchone()
2805-# if row:
2806-# r = [c.decode(self.encoding) if isinstance(c, stringtypes) else c for c in row]
2807-# self.dict = dict(zip(self.headers, r))
2808-# return self.dict
2809-# else:
2810-# raise StopIteration
2811-
28122786 class Database(object):
28132787 if sys.version_info < (3,):
28142788 dt_cast = {int: int, long: long, float: float, str: str, unicode: unicode,
@@ -3044,7 +3018,6 @@
30443018 # Construct INSERT statement.
30453019 columns = [self.type.quoted(col) for col in sel_cols]
30463020 colspec = ",".join(columns)
3047- #paramspec = ",".join([self.paramstr for c in columns])
30483021 paramspec = self.paramsubs(len(columns))
30493022 sql = u"insert into %s (%s) values (%s);" % (sq_name, colspec, paramspec)
30503023 def load_line(line):
@@ -3388,7 +3361,6 @@
33883361 with io.open(file_name, "rb") as f:
33893362 filedata = f.read()
33903363 sq_name = self.schema_qualified_table_name(schema_name, table_name)
3391- #sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramstr)
33923364 sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramsubs(1))
33933365 self.cursor().execute(sql, (pyodbc.Binary(filedata),))
33943366
@@ -3460,7 +3432,6 @@
34603432 with io.open(file_name, "rb") as f:
34613433 filedata = f.read()
34623434 sq_name = self.schema_qualified_table_name(schema_name, table_name)
3463- #sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramstr)
34643435 sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramsubs(1))
34653436 self.cursor().execute(sql, (pyodbc.Binary(filedata),))
34663437
@@ -3606,12 +3577,10 @@
36063577 except:
36073578 self.rollback()
36083579 raise ErrInfo(type="db", command_text=sql, exception_msg=exception_desc(), other_msg=u"Can't load data into table %s from line {%s}" % (sq_name, line))
3609- #self.commit()
36103580 def import_entire_file(self, schema_name, table_name, column_name, file_name):
36113581 with io.open(file_name, "rb") as f:
36123582 filedata = f.read()
36133583 sq_name = self.schema_qualified_table_name(schema_name, table_name)
3614- #sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramstr)
36153584 sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramsubs(1))
36163585 self.cursor().execute(sql, (pyodbc.Binary(filedata),))
36173586
@@ -3770,7 +3739,6 @@
37703739 except:
37713740 self.rollback()
37723741 raise ErrInfo(type="db", command_text=sql_template, exception_msg=exception_desc(), other_msg=u"Import from file into table %s, line {%s}" % (sq_name, line))
3773- #data_indexes = [csv_file_cols.index(col) for col in import_cols]
37743742 data_indexes = [csv_file_cols_q.index(col) for col in import_cols]
37753743 paramspec = ",".join(['%s']*len(import_cols))
37763744 sql_template = u"insert into %s (%s) values (%s);" % (sq_name, input_col_list, paramspec)
@@ -3785,7 +3753,6 @@
37853753 with io.open(file_name, "rb") as f:
37863754 filedata = f.read()
37873755 sq_name = self.schema_qualified_table_name(schema_name, table_name)
3788- #sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramstr)
37893756 sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramsubs(1))
37903757 self.cursor().execute(sql, (psycopg2.Binary(filedata),))
37913758
@@ -3873,7 +3840,6 @@
38733840 def column_exists(self, table_name, column_name, schema_name=None):
38743841 curs = self.cursor()
38753842 sql = "select column_name from all_tab_columns where table_name='%s'%s and column_name='%s'" % (table_name, "" if not schema_name else " and owner ='%s'" % schema_name, column_name)
3876- #sql = "select column_name from all_tab_columns where table_name='%s' and column_name='%s'" % (table_name, column_name)
38773843 try:
38783844 curs.execute(sql)
38793845 except ErrInfo:
@@ -3902,7 +3868,6 @@
39023868 def view_exists(self, view_name, schema_name=None):
39033869 curs = self.cursor()
39043870 sql = "select view_name from sys.all_views where view_name = '%s'%s" % (view_name, "" if not schema_name else " and owner ='%s'" % schema_name)
3905- #sql = "select view_name from sys.all_views where view_name = '%s'" % view_name
39063871 try:
39073872 curs.execute(sql)
39083873 except ErrInfo:
@@ -4072,12 +4037,10 @@
40724037 except:
40734038 self.rollback()
40744039 raise ErrInfo(type="db", command_text=sql, exception_msg=exception_desc(), other_msg=u"Can't load data into table %s from line {%s}" % (sq_name, line))
4075- #self.commit()
40764040 def import_entire_file(self, schema_name, table_name, column_name, file_name):
40774041 with io.open(file_name, "rb") as f:
40784042 filedata = f.read()
40794043 sq_name = self.schema_qualified_table_name(schema_name, table_name)
4080- #sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramstr)
40814044 sql = u"insert into %s (%s) values (%s);" % (sq_name, column_name, self.paramsubs(1))
40824045 self.cursor().execute(sql, (sqlite3.Binary(filedata), ))
40834046
@@ -4330,7 +4293,6 @@
43304293 # Firebird will thrown an error if there are foreign keys into the table.
43314294 tablename = self.type.quoted(tablename)
43324295 self.execute(u"DROP TABLE %s;" % tablename)
4333- #self.execute(u"COMMIT;")
43344296 self.conn.commit()
43354297
43364298
@@ -4483,7 +4445,7 @@
44834445 self.item_errors.append(u"%s in position %d." % (errmsg, pos_no))
44844446 def items(self, delim, qchar):
44854447 # Parses the line into a list of items, breaking it at delimiters that are not
4486- # within quoted stretches. (This is a almost CSV parser, for valid delim and qchar,
4448+ # within quoted stretches. (This is almost a CSV parser, for valid delim and qchar,
44874449 # except that it does not eliminate quote characters or reduce escaped quotes.)
44884450 self.item_errors = []
44894451 if qchar is None:
@@ -5400,8 +5362,8 @@
54005362
54015363
54025364 class LocalSubVarSet(SubVarSet):
5403- # A pool of local substitution variables
5404- # Inherits everything from the base class except the allowed prefix list
5365+ # A pool of local substitution variables.
5366+ # Inherits everything from the base class except the allowed prefix list.
54055367 # For local variables, only '~' is allowed as a prefix and MUST be present
54065368 def __init__(self):
54075369 SubVarSet.__init__(self)
@@ -5413,8 +5375,8 @@
54135375
54145376
54155377 class ScriptArgSubVarSet(SubVarSet):
5416- # A pool of script argument names
5417- # Inherits everything from the base class except the allowed prefix list
5378+ # A pool of script argument names.
5379+ # Inherits everything from the base class except the allowed prefix list.
54185380 # For script arguments, only '#' is allowed as a prefix and MUST be present
54195381 def __init__(self):
54205382 SubVarSet.__init__(self)
@@ -5481,7 +5443,7 @@
54815443 # Returns the result of the metacommand that was run, or None.
54825444 # Arguments:
54835445 # localvars: a SubVarSet object.
5484- # "commit : not used; included to allow an isomorphic interface with SqlStmt.run().
5446+ # commit : not used; included to allow an isomorphic interface with SqlStmt.run().
54855447 errmsg = "Unknown metacommand"
54865448 cmd = substitute_vars(self.statement, localvars)
54875449 if if_stack.all_true() and varlike.search(cmd):
@@ -5583,7 +5545,7 @@
55835545 global loop_nest_level
55845546 cmditem = self.cmdlist[self.cmdptr]
55855547 if compiling_loop:
5586- # Don't run this, but save the command or complete the loop and add its commands to the stack.
5548+ # Don't run this command, but save it or complete the loop and add the loop's set of commands to the stack.
55875549 if cmditem.command_type == 'cmd' and loop_rx.match(cmditem.command.statement):
55885550 loop_nest_level += 1
55895551 loopcommandstack[-1].add(cmditem)
@@ -5625,7 +5587,7 @@
56255587
56265588
56275589 class CommandListWhileLoop(CommandList):
5628- # Subclass of CommandList() that will loop WHILE a condition is met
5590+ # Subclass of CommandList() that will loop WHILE a condition is met.
56295591 # Additional argument:
56305592 # loopcondition : A string containing the conditional for continuing the WHILE loop.
56315593 def __init__(self, cmdlist, listname, paramnames, loopcondition):
@@ -5645,7 +5607,7 @@
56455607
56465608
56475609 class CommandListUntilLoop(CommandList):
5648- # Subclass of CommandList() that will loop UNTIL a condition is met
5610+ # Subclass of CommandList() that will loop UNTIL a condition is met.
56495611 # Additional argument:
56505612 # loopcondition : A string containing the conditional for terminating the UNTIL loop.
56515613 def __init__(self, cmdlist, listname, paramnames, loopcondition):
@@ -5779,7 +5741,7 @@
57795741 cl.set_paramvals(scriptvarset)
57805742 # If argument expressions were NOT found, confirm that the command list is not expecting named params
57815743 else:
5782- # 'Cause if it IS, there's a problem
5744+ # because if it IS, there's a problem.
57835745 if cl.paramnames is not None:
57845746 raise ErrInfo("error", other_msg="Missing expected parameters (%s) in call to %s." % (", ".join(cl.paramnames), cl.listname))
57855747 commandliststack.append(cl)
@@ -5820,10 +5782,10 @@
58205782 # Sort columns in Tkinter Treeview. From https://stackoverflow.com/questions/1966929/tk-treeview-column-sort#1967793
58215783 colvals = [(tv.set(k, col), k) for k in tv.get_children()]
58225784 colvals.sort(reverse=reverse)
5823- # rearrange items in sorted positions
5785+ # Rearrange items in sorted positions
58245786 for index, (val, k) in enumerate(colvals):
58255787 tv.move(k, '', index)
5826- # reverse sort next time
5788+ # Reverse sort next time
58275789 tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))
58285790
58295791 def gui_manager():
@@ -7137,7 +7099,6 @@
71377099 self.resp_queue = queue.Queue()
71387100 self.kill_event = threading.Event()
71397101 self.stop_update_event = threading.Event()
7140- #self.console_killed_event = threading.Event()
71417102 gui_manager_queue.put(GuiSpec(gui_type=GUI_CONSOLE,
71427103 gui_args={"kill_event": self.kill_event,
71437104 "stop_update_event": self.stop_update_event,
@@ -7178,7 +7139,6 @@
71787139 def __init__(self, title, message, countdown=None):
71797140 # Countdown must be an integer indicating the maximum number of seconds
71807141 # that the UI will be displayed.
7181- #global tk, ttk
71827142 try:
71837143 import Tkinter as tk
71847144 except:
@@ -7814,7 +7774,7 @@
78147774
78157775
78167776 class CondParser(CondTokens, object):
7817- # Takes a numeric expression string
7777+ # Takes a conditional expression string.
78187778 def __init__(self, condexpr):
78197779 self.cond_expr = SourceString(condexpr)
78207780 def match_metacommand(self, metacmd):
@@ -7861,7 +7821,7 @@
78617821 if m1 is not None:
78627822 m1 = self.factor()
78637823 return CondAstNode(self.NOT, m1, None)
7864- # match_any_metacommand returns a tuple consisting of (metacommand, groupdict)
7824+ # Match_any_metacommand -- returns a tuple consisting of (metacommand, groupdict)
78657825 m1 = self.match_any_metacommand(conditionals)
78667826 if m1 is not None:
78677827 return CondAstNode(self.CONDITIONAL, m1, None)
@@ -8629,8 +8589,8 @@
86298589 return None
86308590
86318591 metacommands.append(MetaCommand(
8632- ins_table_rxs(r'^\s*PROMPT\s+ASK\s+"(?P<question>.+)"\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+', r')?\s*$') +
8633- ins_table_rxs(r"^\s*PROMPT\s+ASK\s+'(?P<question>.+)'\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+", r')?\s*$') +
8592+ ins_table_rxs(r'^\s*PROMPT\s+ASK\s+"(?P<question>[^"]+)"\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+', r')?\s*$') +
8593+ ins_table_rxs(r"^\s*PROMPT\s+ASK\s+'(?P<question>[^']+)'\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+", r')?\s*$') +
86348594 ins_table_rxs(r'^\s*PROMPT\s+ASK\s+\[(?P<question>[^\]]+)\]\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+', r')?\s*$'),
86358595 x_prompt_ask))
86368596
@@ -8807,7 +8767,6 @@
88078767 script, line_no = current_script_line()
88088768 cmd = u"select * from %s;" % sq_name
88098769 colnames, rows = db.select_data(cmd)
8810- #title, message, button_list, selected_button=0, no_cancel=False, column_headers=None, rowset=None, textentry=None
88118770 enable_gui()
88128771 return_queue = queue.Queue()
88138772 gui_args = {"title": table,
@@ -8892,7 +8851,6 @@
88928851 exec_log.log_exit_halt(script, line_no, msg)
88938852 exit_now(2, None)
88948853
8895-
88968854 metacommands.append(MetaCommand(
88978855 ins_table_rxs(r'^\s*PROMPT\s+ACTION\s+', ins_table_rxs(r'\s+MESSAGE\s+"(?P<message>(.|\n)*)"(?:\s+DISPLAY\s+', r')?(?:\s+COMPACT\s+(?P<compact>\d+))?(?:\s+(?P<continue>CONTINUE))?\s*$', suffix="disp")),
88988856 x_prompt_action))
@@ -9401,7 +9359,6 @@
94019359 subvarset.add_substitution(varname, dataval)
94029360 return None
94039361
9404-
94059362 metacommands.append(MetaCommand(r'^\s*SUBDATA\s+(?P<match>[+~]?\w+)\s+(?P<datasource>.+)\s*$', x_subdata))
94069363
94079364
diff -r fade9e1287ba -r 993b1fdb5d5b setup.py
--- a/setup.py Thu Feb 06 07:08:42 2020 -0800
+++ b/setup.py Thu Feb 06 17:10:26 2020 -0800
@@ -4,7 +4,7 @@
44 long_description = f.read()
55
66 setuptools.setup(name='execsql',
7- version='1.61.3',
7+ version='1.61.5',
88 description="Runs a SQL script against a PostgreSQL, MS-Access, SQLite, MS-SQL-Server, MySQL, MariaDB, Firebird, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables. Data can be exported in 13 different formats, including CSV, TSV, ODS, HTML, JSON, LaTeX, and Markdown tables, and using custom templates.",
99 author='Dreas Nielsen',
1010 author_email='dreas.nielsen@gmail.com',
Afficher sur ancien navigateur de dépôt.