execsql2 2.12.2__py3-none-any.whl → 2.12.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- execsql/db/base.py +7 -0
- execsql/exporters/delimited.py +44 -2
- execsql/metacommands/io_fileops.py +4 -0
- execsql/script/__init__.py +4 -0
- execsql/script/engine.py +55 -23
- execsql/script/variables.py +35 -2
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/METADATA +1 -1
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/RECORD +27 -27
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/README.md +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/execsql.conf +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/WHEEL +0 -0
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/entry_points.txt +0 -0
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.12.2.dist-info → execsql2-2.12.3.dist-info}/licenses/NOTICE +0 -0
execsql/db/base.py
CHANGED
|
@@ -686,6 +686,13 @@ class DatabasePool:
|
|
|
686
686
|
)
|
|
687
687
|
self.pool[db_alias].close()
|
|
688
688
|
self.pool[db_alias] = db_obj
|
|
689
|
+
# Refresh static system vars so $DB_NAME, $DB_USER, etc. reflect the new connection.
|
|
690
|
+
try:
|
|
691
|
+
from execsql.script.engine import set_static_system_vars
|
|
692
|
+
|
|
693
|
+
set_static_system_vars()
|
|
694
|
+
except Exception:
|
|
695
|
+
pass # Engine not yet initialized (early startup).
|
|
689
696
|
|
|
690
697
|
def aliases(self) -> list[str]:
|
|
691
698
|
"""Return a list of all currently registered database aliases."""
|
execsql/exporters/delimited.py
CHANGED
|
@@ -40,6 +40,7 @@ class LineDelimiter:
|
|
|
40
40
|
self.delimiter = delim
|
|
41
41
|
self.joinchar = delim if delim else ""
|
|
42
42
|
self.quotechar = quote
|
|
43
|
+
self.quote_all_text = _state.conf.quote_all_text if _state.conf else False
|
|
43
44
|
if quote:
|
|
44
45
|
if escchar:
|
|
45
46
|
self.quotedquote = escchar + quote
|
|
@@ -50,13 +51,12 @@ class LineDelimiter:
|
|
|
50
51
|
|
|
51
52
|
def delimited(self, datarow: Any, add_newline: bool = True) -> str:
|
|
52
53
|
"""Format a sequence of values as a single delimited text line."""
|
|
53
|
-
conf = _state.conf
|
|
54
54
|
if self.quotechar:
|
|
55
55
|
d_row = []
|
|
56
56
|
for e in datarow:
|
|
57
57
|
if isinstance(e, str):
|
|
58
58
|
if (
|
|
59
|
-
|
|
59
|
+
self.quote_all_text
|
|
60
60
|
or (self.quotechar in e)
|
|
61
61
|
or (self.delimiter is not None and self.delimiter in e)
|
|
62
62
|
or ("\n" in e)
|
|
@@ -609,10 +609,52 @@ class CsvFile(EncodedFile):
|
|
|
609
609
|
raise ErrInfo("error", other_msg=", ".join(self.parse_errors))
|
|
610
610
|
return elements
|
|
611
611
|
|
|
612
|
+
def _can_use_fast_csv_reader(self) -> bool:
|
|
613
|
+
"""Return True if the detected format is compatible with Python's csv module."""
|
|
614
|
+
# The csv module handles comma/tab delimiters with doubled-quote escaping.
|
|
615
|
+
# It cannot handle: space-delimiter collapsing, escape chars, or no delimiter.
|
|
616
|
+
if self.delimiter is None or self.delimiter == " ":
|
|
617
|
+
return False
|
|
618
|
+
return self.escapechar is None
|
|
619
|
+
|
|
612
620
|
def reader(self) -> Any:
|
|
613
621
|
"""Yield parsed rows from the file as lists of field values."""
|
|
614
622
|
conf = _state.conf
|
|
615
623
|
self.evaluate_line_format()
|
|
624
|
+
if self._can_use_fast_csv_reader():
|
|
625
|
+
yield from self._fast_reader(conf)
|
|
626
|
+
else:
|
|
627
|
+
yield from self._slow_reader(conf)
|
|
628
|
+
|
|
629
|
+
def _fast_reader(self, conf: Any) -> Any:
|
|
630
|
+
"""Read using Python's csv module (fast path for standard delimited formats)."""
|
|
631
|
+
import csv
|
|
632
|
+
|
|
633
|
+
f = self.openclean("rt")
|
|
634
|
+
try:
|
|
635
|
+
csv_reader = csv.reader(
|
|
636
|
+
f,
|
|
637
|
+
delimiter=self.delimiter,
|
|
638
|
+
quotechar=self.quotechar,
|
|
639
|
+
doublequote=True,
|
|
640
|
+
strict=False,
|
|
641
|
+
)
|
|
642
|
+
for elements in csv_reader:
|
|
643
|
+
if len(elements) == 0:
|
|
644
|
+
break
|
|
645
|
+
# Normalize empty strings to None for parity with the slow reader.
|
|
646
|
+
elements = [e if e != "" else None for e in elements]
|
|
647
|
+
if conf.del_empty_cols and len(self.blank_cols) > 0:
|
|
648
|
+
blanks = copy.copy(self.blank_cols)
|
|
649
|
+
while len(blanks) > 0:
|
|
650
|
+
b = blanks.pop()
|
|
651
|
+
del elements[b]
|
|
652
|
+
yield elements
|
|
653
|
+
finally:
|
|
654
|
+
f.close()
|
|
655
|
+
|
|
656
|
+
def _slow_reader(self, conf: Any) -> Any:
|
|
657
|
+
"""Read using the character-at-a-time state machine (fallback for non-standard formats)."""
|
|
616
658
|
f = self.openclean("rt")
|
|
617
659
|
line_no = 0
|
|
618
660
|
try:
|
|
@@ -241,6 +241,10 @@ def x_cd(**kwargs: Any) -> None:
|
|
|
241
241
|
os.chdir(new_dir)
|
|
242
242
|
script, lno = current_script_line()
|
|
243
243
|
_state.exec_log.log_status_info(f"Current directory changed to {new_dir} at line {lno} of {script}")
|
|
244
|
+
if _state.subvars is not None:
|
|
245
|
+
from execsql.script.engine import set_static_system_vars
|
|
246
|
+
|
|
247
|
+
set_static_system_vars()
|
|
244
248
|
return None
|
|
245
249
|
|
|
246
250
|
|
execsql/script/__init__.py
CHANGED
|
@@ -63,6 +63,8 @@ from execsql.script.engine import (
|
|
|
63
63
|
read_sqlfile,
|
|
64
64
|
read_sqlstring,
|
|
65
65
|
runscripts,
|
|
66
|
+
set_dynamic_system_vars,
|
|
67
|
+
set_static_system_vars,
|
|
66
68
|
set_system_vars,
|
|
67
69
|
substitute_vars,
|
|
68
70
|
)
|
|
@@ -86,6 +88,8 @@ __all__ = [
|
|
|
86
88
|
"CommandListUntilLoop",
|
|
87
89
|
"ScriptFile",
|
|
88
90
|
"ScriptExecSpec",
|
|
91
|
+
"set_dynamic_system_vars",
|
|
92
|
+
"set_static_system_vars",
|
|
89
93
|
"set_system_vars",
|
|
90
94
|
"substitute_vars",
|
|
91
95
|
"runscripts",
|
execsql/script/engine.py
CHANGED
|
@@ -704,9 +704,45 @@ class ScriptExecSpec:
|
|
|
704
704
|
# ---------------------------------------------------------------------------
|
|
705
705
|
|
|
706
706
|
|
|
707
|
-
def
|
|
708
|
-
"""
|
|
709
|
-
|
|
707
|
+
def set_static_system_vars() -> None:
|
|
708
|
+
"""Set system substitution variables that only change on CONNECT or CHDIR.
|
|
709
|
+
|
|
710
|
+
Called once before the execution loop. These values are expensive to compute
|
|
711
|
+
(filesystem syscalls, database pool lookups) but rarely change — only on
|
|
712
|
+
``CONNECT``, ``USE``, or ``CHDIR`` metacommands. The ``runscripts()`` loop
|
|
713
|
+
calls this once up front; metacommand handlers that change the connection or
|
|
714
|
+
working directory should call it again afterward.
|
|
715
|
+
"""
|
|
716
|
+
import random
|
|
717
|
+
|
|
718
|
+
cwd = str(Path(".").resolve())
|
|
719
|
+
_state.subvars.add_substitution("$CURRENT_DIR", cwd)
|
|
720
|
+
_state.subvars.add_substitution("$CURRENT_PATH", cwd + os.sep)
|
|
721
|
+
_state.subvars.add_substitution("$CURRENT_ALIAS", _state.dbs.current_alias())
|
|
722
|
+
db = _state.dbs.current()
|
|
723
|
+
_state.subvars.add_substitution("$DB_USER", db.user if db.user else "")
|
|
724
|
+
_state.subvars.add_substitution(
|
|
725
|
+
"$DB_SERVER",
|
|
726
|
+
db.server_name if db.server_name else "",
|
|
727
|
+
)
|
|
728
|
+
_state.subvars.add_substitution("$DB_NAME", db.db_name)
|
|
729
|
+
_state.subvars.add_substitution("$DB_NEED_PWD", "TRUE" if db.need_passwd else "FALSE")
|
|
730
|
+
_state.subvars.add_substitution("$VERSION1", str(_state.primary_vno))
|
|
731
|
+
_state.subvars.add_substitution("$VERSION2", str(_state.secondary_vno))
|
|
732
|
+
_state.subvars.add_substitution("$VERSION3", str(_state.tertiary_vno))
|
|
733
|
+
# Register lazy providers for $RANDOM and $UUID — computed only when referenced.
|
|
734
|
+
_state.subvars.register_lazy("$random", lambda: str(random.random()))
|
|
735
|
+
_state.subvars.register_lazy("$uuid", lambda: str(uuid.uuid4()))
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
def set_dynamic_system_vars() -> None:
|
|
739
|
+
"""Refresh system substitution variables that change every statement.
|
|
740
|
+
|
|
741
|
+
Called once per statement in the execution loop. Includes cheap boolean-to-string
|
|
742
|
+
conversions for halt states and autocommit (which can change on any CONFIG or
|
|
743
|
+
AUTOCOMMIT metacommand) plus ``$TIMER`` and lazy-variable cache reset.
|
|
744
|
+
"""
|
|
745
|
+
# Halt/config state vars — cheap to set, can change on any CONFIG metacommand.
|
|
710
746
|
_state.subvars.add_substitution("$CANCEL_HALT_STATE", "ON" if _state.status.cancel_halt else "OFF")
|
|
711
747
|
_state.subvars.add_substitution("$ERROR_HALT_STATE", "ON" if _state.status.halt_on_err else "OFF")
|
|
712
748
|
_state.subvars.add_substitution(
|
|
@@ -718,27 +754,22 @@ def set_system_vars() -> None:
|
|
|
718
754
|
"ON" if _state.conf.gui_wait_on_error_halt else "OFF",
|
|
719
755
|
)
|
|
720
756
|
_state.subvars.add_substitution("$CONSOLE_WAIT_WHEN_DONE_STATE", "ON" if _state.conf.gui_wait_on_exit else "OFF")
|
|
721
|
-
# $CURRENT_TIME is set per-statement in run_and_increment() for accuracy.
|
|
722
|
-
_state.subvars.add_substitution("$CURRENT_DIR", str(Path(".").resolve()))
|
|
723
|
-
_state.subvars.add_substitution("$CURRENT_PATH", str(Path(".").resolve()) + os.sep)
|
|
724
|
-
_state.subvars.add_substitution("$CURRENT_ALIAS", _state.dbs.current_alias())
|
|
725
757
|
db = _state.dbs.current()
|
|
726
758
|
_state.subvars.add_substitution("$AUTOCOMMIT_STATE", "ON" if db.autocommit else "OFF")
|
|
759
|
+
# $CURRENT_TIME is set per-statement in run_and_increment() for accuracy.
|
|
727
760
|
_state.subvars.add_substitution("$TIMER", str(datetime.timedelta(seconds=_state.timer.elapsed())))
|
|
728
|
-
_state.subvars.
|
|
729
|
-
_state.subvars.add_substitution(
|
|
730
|
-
"$DB_SERVER",
|
|
731
|
-
db.server_name if db.server_name else "",
|
|
732
|
-
)
|
|
733
|
-
_state.subvars.add_substitution("$DB_NAME", db.db_name)
|
|
734
|
-
_state.subvars.add_substitution("$DB_NEED_PWD", "TRUE" if db.need_passwd else "FALSE")
|
|
735
|
-
import random
|
|
761
|
+
_state.subvars.clear_lazy_cache()
|
|
736
762
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
763
|
+
|
|
764
|
+
def set_system_vars() -> None:
|
|
765
|
+
"""Refresh all built-in system substitution variables.
|
|
766
|
+
|
|
767
|
+
Convenience wrapper that calls both :func:`set_static_system_vars` and
|
|
768
|
+
:func:`set_dynamic_system_vars`. Retained for backward compatibility with
|
|
769
|
+
tests and any external callers.
|
|
770
|
+
"""
|
|
771
|
+
set_static_system_vars()
|
|
772
|
+
set_dynamic_system_vars()
|
|
742
773
|
|
|
743
774
|
|
|
744
775
|
_MAX_SUBSTITUTION_DEPTH = 100
|
|
@@ -779,11 +810,12 @@ def substitute_vars(command_str: str, localvars: SubVarSet | None = None) -> str
|
|
|
779
810
|
|
|
780
811
|
def runscripts() -> None:
|
|
781
812
|
"""Drive execution until the command-list stack is empty."""
|
|
782
|
-
#
|
|
783
|
-
#
|
|
813
|
+
# Set static vars once before the loop; they are refreshed by metacommand
|
|
814
|
+
# handlers (CONNECT, CONFIG, AUTOCOMMIT, CHDIR) when state changes.
|
|
815
|
+
set_static_system_vars()
|
|
784
816
|
while len(_state.commandliststack) > 0:
|
|
785
817
|
current_cmds = _state.commandliststack[-1]
|
|
786
|
-
|
|
818
|
+
set_dynamic_system_vars()
|
|
787
819
|
try:
|
|
788
820
|
current_cmds.run_next()
|
|
789
821
|
except StopIteration:
|
execsql/script/variables.py
CHANGED
|
@@ -89,6 +89,7 @@ class SubVarSet:
|
|
|
89
89
|
# compatibility with external code.
|
|
90
90
|
def __init__(self) -> None:
|
|
91
91
|
self._subs_dict: dict[str, Any] = {}
|
|
92
|
+
self._lazy_providers: dict[str, Any] = {}
|
|
92
93
|
self.prefix_list: list[str] = ["$", "&", "@"]
|
|
93
94
|
# Don't construct/compile on init because deepcopy() can't handle compiled regexes.
|
|
94
95
|
self.var_rx = None
|
|
@@ -120,6 +121,30 @@ class SubVarSet:
|
|
|
120
121
|
if not self.var_name_ok(varname.lower()):
|
|
121
122
|
raise ErrInfo("error", other_msg=f"Invalid variable name ({varname}) in this context.")
|
|
122
123
|
|
|
124
|
+
def register_lazy(self, varname: str, provider: Any) -> None:
|
|
125
|
+
"""Register a lazy variable whose value is computed on first access per cycle.
|
|
126
|
+
|
|
127
|
+
The *provider* callable is invoked only when the variable is actually
|
|
128
|
+
referenced (via :meth:`substitute`, :meth:`varvalue`, etc.). The result
|
|
129
|
+
is cached in ``_subs_dict`` until :meth:`clear_lazy_cache` is called.
|
|
130
|
+
"""
|
|
131
|
+
self.check_var_name(varname)
|
|
132
|
+
self._lazy_providers[varname.lower()] = provider
|
|
133
|
+
|
|
134
|
+
def clear_lazy_cache(self) -> None:
|
|
135
|
+
"""Remove materialized lazy values so they regenerate on next access."""
|
|
136
|
+
for key in self._lazy_providers:
|
|
137
|
+
self._subs_dict.pop(key, None)
|
|
138
|
+
|
|
139
|
+
def _materialize_lazy(self, varname: str) -> str | None:
|
|
140
|
+
"""If *varname* has a lazy provider, invoke it, cache the result, and return it."""
|
|
141
|
+
provider = self._lazy_providers.get(varname)
|
|
142
|
+
if provider is not None:
|
|
143
|
+
value = str(provider())
|
|
144
|
+
self._subs_dict[varname] = value
|
|
145
|
+
return value
|
|
146
|
+
return None
|
|
147
|
+
|
|
123
148
|
def remove_substitution(self, template_str: str) -> None:
|
|
124
149
|
"""Remove the variable named *template_str* from the substitution pool."""
|
|
125
150
|
self.check_var_name(template_str)
|
|
@@ -143,7 +168,11 @@ class SubVarSet:
|
|
|
143
168
|
def varvalue(self, varname: str) -> str | None:
|
|
144
169
|
"""Return the value of *varname*, or ``None`` if it is not defined."""
|
|
145
170
|
self.check_var_name(varname)
|
|
146
|
-
|
|
171
|
+
key = varname.lower()
|
|
172
|
+
val = self._subs_dict.get(key)
|
|
173
|
+
if val is None and key in self._lazy_providers:
|
|
174
|
+
return self._materialize_lazy(key)
|
|
175
|
+
return val
|
|
147
176
|
|
|
148
177
|
def increment_by(self, varname: str, numeric_increment: Any) -> None:
|
|
149
178
|
self.check_var_name(varname)
|
|
@@ -165,13 +194,15 @@ class SubVarSet:
|
|
|
165
194
|
def sub_exists(self, template_str: str) -> bool:
|
|
166
195
|
"""Return True if the variable named *template_str* is defined."""
|
|
167
196
|
self.check_var_name(template_str)
|
|
168
|
-
|
|
197
|
+
key = template_str.lower()
|
|
198
|
+
return key in self._subs_dict or key in self._lazy_providers
|
|
169
199
|
|
|
170
200
|
def merge(self, other_subvars: SubVarSet | None) -> SubVarSet:
|
|
171
201
|
"""Return a new SubVarSet with this object's variables merged with other_subvars."""
|
|
172
202
|
if other_subvars is not None:
|
|
173
203
|
newsubs = SubVarSet()
|
|
174
204
|
newsubs._subs_dict = {**self._subs_dict, **other_subvars._subs_dict}
|
|
205
|
+
newsubs._lazy_providers = {**self._lazy_providers, **other_subvars._lazy_providers}
|
|
175
206
|
newsubs.prefix_list = list(set(self.prefix_list + other_subvars.prefix_list))
|
|
176
207
|
newsubs.compile_var_rx()
|
|
177
208
|
return newsubs
|
|
@@ -201,6 +232,8 @@ class SubVarSet:
|
|
|
201
232
|
m = self._TOKEN_RX.search(command_str)
|
|
202
233
|
while m:
|
|
203
234
|
varname = m.group("varname").lower()
|
|
235
|
+
if varname not in self._subs_dict and varname in self._lazy_providers:
|
|
236
|
+
self._materialize_lazy(varname)
|
|
204
237
|
if varname in self._subs_dict:
|
|
205
238
|
sub = self._subs_dict[varname]
|
|
206
239
|
if sub is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.12.
|
|
3
|
+
Version: 2.12.3
|
|
4
4
|
Summary: Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, 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.
|
|
5
5
|
Project-URL: Homepage, https://execsql2.readthedocs.io
|
|
6
6
|
Project-URL: Repository, https://github.com/geocoug/execsql
|
|
@@ -16,7 +16,7 @@ execsql/cli/lint.py,sha256=XWuVcEsheZ8ql48VFWqICWEkAUezB2nIePX6SUiKSg8,16109
|
|
|
16
16
|
execsql/cli/run.py,sha256=JGfndnBnJMkEqbz26pflhEdXDScZNIdGu6b6jTRLYl8,30681
|
|
17
17
|
execsql/db/__init__.py,sha256=jTbuafuKOqYtXFR1wvCOoKK5Lr3l1uErfaIbIr6UywI,1063
|
|
18
18
|
execsql/db/access.py,sha256=L79gUnAnnM9EJ_f4k42jr7DI0qGcKtLOnJTlBC7uPm0,17879
|
|
19
|
-
execsql/db/base.py,sha256=
|
|
19
|
+
execsql/db/base.py,sha256=Gywel7cnF9vWdDGENYZ_psNOg339z3-Mro5pwGyly4I,31256
|
|
20
20
|
execsql/db/dsn.py,sha256=TgQUedVCxnEYA3vae7JETyhb8kK23qkNbPxsMQrNUN8,5368
|
|
21
21
|
execsql/db/duckdb.py,sha256=cKeMwiSlYPyPDn1VLaJgbUD6_IEEaNqtUToLcmq7QaE,3189
|
|
22
22
|
execsql/db/factory.py,sha256=YR1m_c2Hhj_GXVGGkWoSEPZBpgNu_c4FxRnbp-xV3rs,5230
|
|
@@ -30,7 +30,7 @@ execsql/debug/__init__.py,sha256=j6EGUR0dHzUhWN1mHHtf1-Lhjq3Sb1V-vmnq2Ztgj1M,178
|
|
|
30
30
|
execsql/debug/repl.py,sha256=HeQ9emFKUjo7UTouxuTcmpGCTJIR1nOLxKkRJ5mvd2c,16669
|
|
31
31
|
execsql/exporters/__init__.py,sha256=-Cnji-OgodJV8ftcDcOyTof0kQMy9J5kKVC8GVFpc3o,670
|
|
32
32
|
execsql/exporters/base.py,sha256=W9USFyk_2eztjJ51X6CJh7-chE1i3cSx-STOtbHXCNI,6373
|
|
33
|
-
execsql/exporters/delimited.py,sha256=
|
|
33
|
+
execsql/exporters/delimited.py,sha256=URvEQo1IRF_tfdVHL3uBwEonihC-XfDm0f1argQPf4M,32088
|
|
34
34
|
execsql/exporters/duckdb.py,sha256=Wc9I5uiV4MzmVQzCX-vgVHQUL7U3ZWdOkFVFWBv5SXM,2911
|
|
35
35
|
execsql/exporters/feather.py,sha256=w2qZAnewzeiRMnmPXECvkgD-6KtyxaiQwjokRT7Awrc,4167
|
|
36
36
|
execsql/exporters/html.py,sha256=ISQBOr7AJ5koKlebXSvWqzEvl1nXriCRGeKmk-bzkrc,9335
|
|
@@ -70,16 +70,16 @@ execsql/metacommands/debug.py,sha256=pnT24dfvfOx8xFu86mO5czfVCGKbcvgBLyXnqaMWO4w
|
|
|
70
70
|
execsql/metacommands/dispatch.py,sha256=OQwLOo9XT3N9C96wsRt0zmu1Nn4HL-7cSBOsGCfp5V4,84041
|
|
71
71
|
execsql/metacommands/io.py,sha256=Duh60caM4go9JczbGYNMKKYpcMimwPzF6EQ_tshKxdE,2971
|
|
72
72
|
execsql/metacommands/io_export.py,sha256=7lkCSnPhXy9FVau9_hT1u68NOVdG2DsWmvUh9hM1QWI,18359
|
|
73
|
-
execsql/metacommands/io_fileops.py,sha256=
|
|
73
|
+
execsql/metacommands/io_fileops.py,sha256=RrcJTh_cgj7bJ-bezjo0yNl-fN3CoWV-aZ71z1KHYZs,9803
|
|
74
74
|
execsql/metacommands/io_import.py,sha256=wyxJJdlW07P5ZIhweejhXyyGANAvEhY5uMjKZ200Jyc,12983
|
|
75
75
|
execsql/metacommands/io_write.py,sha256=NpL2aYGfBpbqmPpYsqniYltYfd_SCA1EQz3_4qSdNbo,8279
|
|
76
76
|
execsql/metacommands/prompt.py,sha256=xd3mAkdbn4AE4hUPuSfN5DgZGUZmk-Db23iL-JJPwXs,36918
|
|
77
77
|
execsql/metacommands/script_ext.py,sha256=TUgAldB2LSJAwZrCvDDi804hQ1d9BDQD2GDqHNPVOcM,2280
|
|
78
78
|
execsql/metacommands/system.py,sha256=sUR5kLL7idTVg8WXIMdd-Kv7nkERIiaeL0beWsz8NyY,7293
|
|
79
|
-
execsql/script/__init__.py,sha256=
|
|
79
|
+
execsql/script/__init__.py,sha256=HbVQmQEVn4gBtzwy5_nlbDGuRnbWd4dI4nG-q1KyBxs,3498
|
|
80
80
|
execsql/script/control.py,sha256=s-1eZdGARM6H1FwZ6VDdO_f50j7bvvRtTHesfUm9tbc,6144
|
|
81
|
-
execsql/script/engine.py,sha256=
|
|
82
|
-
execsql/script/variables.py,sha256=
|
|
81
|
+
execsql/script/engine.py,sha256=6LYabzy1LI-_ISjYzTJos0BrLO62QF6FEKdqcN0YzK4,42995
|
|
82
|
+
execsql/script/variables.py,sha256=gTCCWY64LFmQUna-63CM1GAbupcaOTSS4cn6HDaHk9Q,11923
|
|
83
83
|
execsql/utils/__init__.py,sha256=0uR6JwVJQRX3vceByNBduCAf5dd5assKjeqJUWvpZoA,278
|
|
84
84
|
execsql/utils/auth.py,sha256=onXzNkNZQZxGC5w7eey06sjvAIAX_Lf9g7nUJtcsel0,7009
|
|
85
85
|
execsql/utils/crypto.py,sha256=2OnBWwn9bCBGc1ZkyRv16TvhottoCNYtXqgbE3mG3Sg,2960
|
|
@@ -92,24 +92,24 @@ execsql/utils/numeric.py,sha256=xh02ANSRk3nUpQ-rtm66ILoMqoi7HtzCoRMIOT9U8QI,1570
|
|
|
92
92
|
execsql/utils/regex.py,sha256=diEzTZqU_HHwVMadPAvN1Vgzhl7I03eVaEFGCXyGGL8,3770
|
|
93
93
|
execsql/utils/strings.py,sha256=5Dvzrk-9SIw2lpxXZQkiJbNyo1sy7iXXAtSULlZ0KG8,8488
|
|
94
94
|
execsql/utils/timer.py,sha256=eDYf5VzCNFk7oo90InJucUm3XcBdhYMogjZMqeg9xzc,1899
|
|
95
|
-
execsql2-2.12.
|
|
96
|
-
execsql2-2.12.
|
|
97
|
-
execsql2-2.12.
|
|
98
|
-
execsql2-2.12.
|
|
99
|
-
execsql2-2.12.
|
|
100
|
-
execsql2-2.12.
|
|
101
|
-
execsql2-2.12.
|
|
102
|
-
execsql2-2.12.
|
|
103
|
-
execsql2-2.12.
|
|
104
|
-
execsql2-2.12.
|
|
105
|
-
execsql2-2.12.
|
|
106
|
-
execsql2-2.12.
|
|
107
|
-
execsql2-2.12.
|
|
108
|
-
execsql2-2.12.
|
|
109
|
-
execsql2-2.12.
|
|
110
|
-
execsql2-2.12.
|
|
111
|
-
execsql2-2.12.
|
|
112
|
-
execsql2-2.12.
|
|
113
|
-
execsql2-2.12.
|
|
114
|
-
execsql2-2.12.
|
|
115
|
-
execsql2-2.12.
|
|
95
|
+
execsql2-2.12.3.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
|
|
96
|
+
execsql2-2.12.3.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
|
|
97
|
+
execsql2-2.12.3.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
|
|
98
|
+
execsql2-2.12.3.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
|
|
99
|
+
execsql2-2.12.3.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
|
|
100
|
+
execsql2-2.12.3.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
|
|
101
|
+
execsql2-2.12.3.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
|
|
102
|
+
execsql2-2.12.3.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
|
|
103
|
+
execsql2-2.12.3.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
|
|
104
|
+
execsql2-2.12.3.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
|
|
105
|
+
execsql2-2.12.3.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
|
|
106
|
+
execsql2-2.12.3.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
|
|
107
|
+
execsql2-2.12.3.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
|
|
108
|
+
execsql2-2.12.3.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
|
|
109
|
+
execsql2-2.12.3.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
|
|
110
|
+
execsql2-2.12.3.dist-info/METADATA,sha256=snFjAb6heF3pzQ-Yyxwmip-LgS0aH3OPjkQ_FXQucj8,17436
|
|
111
|
+
execsql2-2.12.3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
112
|
+
execsql2-2.12.3.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
|
|
113
|
+
execsql2-2.12.3.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
|
|
114
|
+
execsql2-2.12.3.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
|
|
115
|
+
execsql2-2.12.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{execsql2-2.12.2.data → execsql2-2.12.3.data}/data/execsql2_extras/example_config_prompt.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|