execsql2 2.0.1__py3-none-any.whl → 2.1.2__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/cli.py +322 -108
- execsql/config.py +134 -114
- execsql/db/access.py +89 -65
- execsql/db/base.py +97 -68
- execsql/db/dsn.py +45 -29
- execsql/db/duckdb.py +4 -5
- execsql/db/factory.py +27 -27
- execsql/db/firebird.py +30 -18
- execsql/db/mysql.py +38 -14
- execsql/db/oracle.py +58 -33
- execsql/db/postgres.py +68 -28
- execsql/db/sqlite.py +36 -27
- execsql/db/sqlserver.py +45 -30
- execsql/exceptions.py +68 -64
- execsql/exporters/__init__.py +1 -1
- execsql/exporters/base.py +42 -17
- execsql/exporters/delimited.py +60 -59
- execsql/exporters/duckdb.py +8 -12
- execsql/exporters/feather.py +32 -24
- execsql/exporters/html.py +33 -30
- execsql/exporters/json.py +18 -17
- execsql/exporters/latex.py +11 -13
- execsql/exporters/ods.py +50 -46
- execsql/exporters/parquet.py +32 -0
- execsql/exporters/pretty.py +16 -15
- execsql/exporters/raw.py +9 -11
- execsql/exporters/sqlite.py +38 -38
- execsql/exporters/templates.py +15 -72
- execsql/exporters/values.py +13 -12
- execsql/exporters/xls.py +26 -26
- execsql/exporters/xml.py +12 -12
- execsql/exporters/zip.py +0 -3
- execsql/gui/__init__.py +2 -2
- execsql/gui/console.py +0 -1
- execsql/gui/desktop.py +6 -7
- execsql/gui/tui.py +8 -14
- execsql/importers/base.py +6 -9
- execsql/importers/csv.py +10 -17
- execsql/importers/feather.py +16 -22
- execsql/importers/ods.py +3 -4
- execsql/importers/xls.py +5 -6
- execsql/metacommands/__init__.py +8 -8
- execsql/metacommands/conditions.py +41 -33
- execsql/metacommands/connect.py +113 -99
- execsql/metacommands/control.py +38 -26
- execsql/metacommands/data.py +35 -33
- execsql/metacommands/debug.py +13 -9
- execsql/metacommands/io.py +288 -229
- execsql/metacommands/prompt.py +179 -157
- execsql/metacommands/script_ext.py +11 -9
- execsql/metacommands/system.py +44 -25
- execsql/models.py +9 -16
- execsql/parser.py +10 -10
- execsql/script.py +183 -157
- execsql/state.py +170 -208
- execsql/types.py +46 -81
- execsql/utils/auth.py +114 -14
- execsql/utils/crypto.py +31 -4
- execsql/utils/datetime.py +7 -7
- execsql/utils/errors.py +34 -29
- execsql/utils/fileio.py +90 -55
- execsql/utils/gui.py +22 -23
- execsql/utils/mail.py +15 -17
- execsql/utils/numeric.py +2 -3
- execsql/utils/regex.py +9 -12
- execsql/utils/strings.py +10 -12
- execsql/utils/timer.py +0 -2
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/execsql.conf +1 -1
- execsql2-2.1.2.dist-info/METADATA +300 -0
- execsql2-2.1.2.dist-info/RECORD +96 -0
- execsql2-2.0.1.dist-info/METADATA +0 -406
- execsql2-2.0.1.dist-info/RECORD +0 -95
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/READ_ME.rst +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/WHEEL +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/entry_points.txt +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/NOTICE +0 -0
execsql/state.py
CHANGED
|
@@ -28,24 +28,39 @@ Variable groups defined here:
|
|
|
28
28
|
- **Utility functions** — ``xcmd_test()`` (evaluate a conditional string),
|
|
29
29
|
``endloop()`` (finalise a compiled loop).
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
correctly even though those modules themselves import ``execsql.state``.
|
|
31
|
+
All re-exports have been removed. Each module now imports directly from
|
|
32
|
+
its source module rather than accessing names via ``_state``.
|
|
34
33
|
"""
|
|
35
34
|
|
|
36
|
-
import getpass
|
|
37
35
|
import re
|
|
38
|
-
from typing import TYPE_CHECKING, Any
|
|
36
|
+
from typing import TYPE_CHECKING, Any
|
|
39
37
|
|
|
40
38
|
if TYPE_CHECKING:
|
|
41
|
-
|
|
39
|
+
import multiprocessing as _mp
|
|
40
|
+
import threading as _threading
|
|
41
|
+
|
|
42
|
+
from execsql.config import ConfigData, StatObj, WriteHooks
|
|
43
|
+
from execsql.db.base import DatabasePool
|
|
44
|
+
from execsql.exporters.base import ExportMetadata, WriteSpec
|
|
45
|
+
from execsql.script import (
|
|
46
|
+
CommandList,
|
|
47
|
+
CounterVars,
|
|
48
|
+
IfLevels,
|
|
49
|
+
MetaCommandList,
|
|
50
|
+
ScriptCmd,
|
|
51
|
+
ScriptExecSpec,
|
|
52
|
+
SubVarSet,
|
|
53
|
+
)
|
|
54
|
+
from execsql.utils.fileio import FileWriter, Logger, TempFileMgr
|
|
55
|
+
from execsql.utils.mail import MailSpec
|
|
56
|
+
from execsql.utils.timer import Timer
|
|
42
57
|
|
|
43
58
|
# ---------------------------------------------------------------------------
|
|
44
59
|
# Configuration / encoding
|
|
45
60
|
# ---------------------------------------------------------------------------
|
|
46
61
|
|
|
47
62
|
# Configuration data, initialized in main()
|
|
48
|
-
conf:
|
|
63
|
+
conf: ConfigData | None = None
|
|
49
64
|
|
|
50
65
|
# Default encodings
|
|
51
66
|
logfile_encoding: str = "utf8" # Should never be changed; is not configurable.
|
|
@@ -55,41 +70,41 @@ logfile_encoding: str = "utf8" # Should never be changed; is not configurable.
|
|
|
55
70
|
# ---------------------------------------------------------------------------
|
|
56
71
|
|
|
57
72
|
# The last command run. This should be a ScriptCmd object.
|
|
58
|
-
last_command:
|
|
73
|
+
last_command: ScriptCmd | None = None
|
|
59
74
|
|
|
60
75
|
# The last user password entered via 'get_password()'
|
|
61
|
-
upass:
|
|
76
|
+
upass: str | None = None
|
|
62
77
|
|
|
63
78
|
# A compiled regex to match prefixed regular expressions, used to check
|
|
64
79
|
# for unsubstituted variables.
|
|
65
80
|
varlike = re.compile(r"!![$@&~#]?\w+!!", re.I)
|
|
66
81
|
|
|
67
82
|
# A WriteSpec object for messages to be written when the program halts due to an error.
|
|
68
|
-
err_halt_writespec:
|
|
83
|
+
err_halt_writespec: WriteSpec | None = None
|
|
69
84
|
|
|
70
85
|
# A MailSpec object for email to be sent when the program halts due to an error.
|
|
71
|
-
err_halt_email:
|
|
86
|
+
err_halt_email: MailSpec | None = None
|
|
72
87
|
|
|
73
88
|
# A ScriptExecSpec object for a script to be executed when the program halts due to an error.
|
|
74
|
-
err_halt_exec:
|
|
89
|
+
err_halt_exec: ScriptExecSpec | None = None
|
|
75
90
|
|
|
76
91
|
# A WriteSpec object for messages to be written when the program halts due to user cancellation.
|
|
77
|
-
cancel_halt_writespec:
|
|
92
|
+
cancel_halt_writespec: WriteSpec | None = None
|
|
78
93
|
|
|
79
94
|
# A MailSpec object for email to be sent when the program halts due to user cancellation.
|
|
80
|
-
cancel_halt_mailspec:
|
|
95
|
+
cancel_halt_mailspec: MailSpec | None = None
|
|
81
96
|
|
|
82
97
|
# A ScriptExecSpec object for a script to be executed when the program halts due to user cancellation.
|
|
83
|
-
cancel_halt_exec:
|
|
98
|
+
cancel_halt_exec: ScriptExecSpec | None = None
|
|
84
99
|
|
|
85
100
|
# A stack of the CommandList objects currently in the queue to be executed.
|
|
86
|
-
commandliststack: list = []
|
|
101
|
+
commandliststack: list[CommandList] = []
|
|
87
102
|
|
|
88
103
|
# A dictionary of CommandList objects (ordinarily created by BEGIN/END SCRIPT metacommands).
|
|
89
|
-
savedscripts: dict = {}
|
|
104
|
+
savedscripts: dict[str, CommandList] = {}
|
|
90
105
|
|
|
91
106
|
# A stack of CommandList objects used when compiling the statements within a loop.
|
|
92
|
-
loopcommandstack: list = []
|
|
107
|
+
loopcommandstack: list[CommandList] = []
|
|
93
108
|
|
|
94
109
|
# A global flag to indicate that commands should be compiled into the topmost entry
|
|
95
110
|
# in the loopcommandstack rather than executed.
|
|
@@ -114,54 +129,54 @@ defer_rx = re.compile(r"(!{([$@&~#]?[a-z0-9_]+)}!)", re.I)
|
|
|
114
129
|
stringtypes: type = str
|
|
115
130
|
|
|
116
131
|
# The execution log object; set at startup.
|
|
117
|
-
exec_log:
|
|
132
|
+
exec_log: Logger | None = None
|
|
118
133
|
|
|
119
134
|
# The substitution variable set; set at startup.
|
|
120
|
-
subvars:
|
|
135
|
+
subvars: SubVarSet | None = None
|
|
121
136
|
|
|
122
137
|
# The program execution status tracker; set at startup.
|
|
123
|
-
status:
|
|
138
|
+
status: StatObj | None = None
|
|
124
139
|
|
|
125
140
|
# ---------------------------------------------------------------------------
|
|
126
141
|
# Runtime objects — initialized in main() to avoid circular imports at load time.
|
|
127
142
|
# ---------------------------------------------------------------------------
|
|
128
143
|
|
|
129
144
|
# Stack-based conditional state (IfLevels instance).
|
|
130
|
-
if_stack:
|
|
145
|
+
if_stack: IfLevels | None = None
|
|
131
146
|
|
|
132
147
|
# Global counter variables (CounterVars instance).
|
|
133
|
-
counters:
|
|
148
|
+
counters: CounterVars | None = None
|
|
134
149
|
|
|
135
150
|
# Elapsed-time tracker (Timer instance).
|
|
136
|
-
timer:
|
|
151
|
+
timer: Timer | None = None
|
|
137
152
|
|
|
138
153
|
# Redirectable output (WriteHooks instance).
|
|
139
|
-
output:
|
|
154
|
+
output: WriteHooks | None = None
|
|
140
155
|
|
|
141
156
|
# Database connection pool (DatabasePool instance).
|
|
142
|
-
dbs:
|
|
157
|
+
dbs: DatabasePool | None = None
|
|
143
158
|
|
|
144
159
|
# Temporary file manager (TempFileMgr instance).
|
|
145
|
-
tempfiles:
|
|
160
|
+
tempfiles: TempFileMgr | None = None
|
|
146
161
|
|
|
147
162
|
# Export metadata tracker (ExportMetadata instance).
|
|
148
|
-
export_metadata:
|
|
163
|
+
export_metadata: ExportMetadata | None = None
|
|
149
164
|
|
|
150
165
|
# Metacommand dispatch table (MetaCommandList instance).
|
|
151
|
-
metacommandlist:
|
|
166
|
+
metacommandlist: MetaCommandList | None = None
|
|
152
167
|
|
|
153
168
|
# Conditional predicate dispatch table (MetaCommandList instance).
|
|
154
|
-
conditionallist:
|
|
169
|
+
conditionallist: MetaCommandList | None = None
|
|
155
170
|
|
|
156
171
|
# Asynchronous file-writer subprocess (FileWriter instance).
|
|
157
|
-
filewriter:
|
|
172
|
+
filewriter: FileWriter | None = None
|
|
158
173
|
|
|
159
174
|
# GUI console object.
|
|
160
|
-
gui_console: Any = None
|
|
175
|
+
gui_console: Any = None # Varies by backend (ConsoleUI, DesktopUI, TextualUI).
|
|
161
176
|
|
|
162
177
|
# Queue and thread used to communicate with the GUI manager.
|
|
163
|
-
gui_manager_queue:
|
|
164
|
-
gui_manager_thread:
|
|
178
|
+
gui_manager_queue: _mp.Queue | None = None
|
|
179
|
+
gui_manager_thread: _threading.Thread | None = None
|
|
165
180
|
|
|
166
181
|
# ---------------------------------------------------------------------------
|
|
167
182
|
# Version numbers (parsed from package __version__)
|
|
@@ -175,9 +190,9 @@ try:
|
|
|
175
190
|
secondary_vno: int = int(_vparts[1]) if len(_vparts) > 1 else 0
|
|
176
191
|
tertiary_vno: int = int(_vparts[2]) if len(_vparts) > 2 else 0
|
|
177
192
|
except Exception:
|
|
178
|
-
primary_vno =
|
|
179
|
-
secondary_vno =
|
|
180
|
-
tertiary_vno =
|
|
193
|
+
primary_vno = 0
|
|
194
|
+
secondary_vno = 0
|
|
195
|
+
tertiary_vno = 0
|
|
181
196
|
|
|
182
197
|
# ---------------------------------------------------------------------------
|
|
183
198
|
# Utility functions defined directly here to avoid circular imports.
|
|
@@ -186,192 +201,139 @@ except Exception:
|
|
|
186
201
|
|
|
187
202
|
def xcmd_test(teststr: str) -> bool:
|
|
188
203
|
"""Evaluate a conditional test string and return a boolean result."""
|
|
189
|
-
|
|
190
|
-
|
|
204
|
+
import execsql.parser as _parser
|
|
205
|
+
import execsql.exceptions as _exc
|
|
191
206
|
|
|
192
|
-
result = CondParser(teststr).parse().eval()
|
|
207
|
+
result = _parser.CondParser(teststr).parse().eval()
|
|
193
208
|
if result is not None:
|
|
194
209
|
return result
|
|
195
|
-
raise ErrInfo(type="cmd", command_text=teststr, other_msg="Unrecognized conditional")
|
|
210
|
+
raise _exc.ErrInfo(type="cmd", command_text=teststr, other_msg="Unrecognized conditional")
|
|
196
211
|
|
|
197
212
|
|
|
198
213
|
def endloop() -> None:
|
|
199
214
|
"""Complete the current loop being compiled and push it onto the command stack."""
|
|
200
|
-
|
|
215
|
+
import execsql.exceptions as _exc
|
|
201
216
|
|
|
202
217
|
global compiling_loop
|
|
203
218
|
if len(loopcommandstack) == 0:
|
|
204
|
-
raise ErrInfo("error", other_msg="END LOOP metacommand without a matching preceding LOOP metacommand.")
|
|
219
|
+
raise _exc.ErrInfo("error", other_msg="END LOOP metacommand without a matching preceding LOOP metacommand.")
|
|
205
220
|
compiling_loop = False
|
|
206
221
|
commandliststack.append(loopcommandstack[-1])
|
|
207
222
|
loopcommandstack.pop()
|
|
208
223
|
|
|
209
224
|
|
|
210
225
|
# ---------------------------------------------------------------------------
|
|
211
|
-
#
|
|
212
|
-
# Placed at the bottom so that circular imports resolve correctly:
|
|
213
|
-
# all state variables above are defined before any module below is loaded.
|
|
214
|
-
# Modules that `import execsql.state as _state` will receive a partial
|
|
215
|
-
# module (containing only the variables above) if they are themselves
|
|
216
|
-
# imported during this block — which is safe because those modules only
|
|
217
|
-
# access _state.X inside function/method bodies, never at class-definition time.
|
|
226
|
+
# Test-support utilities
|
|
218
227
|
# ---------------------------------------------------------------------------
|
|
219
228
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
from
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
#
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
#
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
from execsql.db.sqlserver import SqlServerDatabase # noqa: E402
|
|
332
|
-
from execsql.db.dsn import DsnDatabase # noqa: E402
|
|
333
|
-
|
|
334
|
-
# Database type descriptors
|
|
335
|
-
from execsql.types import dbt_postgres, dbt_firebird # noqa: E402
|
|
336
|
-
|
|
337
|
-
# GUI layer — pluggable backends: Textual (TUI), Tkinter (desktop), Console
|
|
338
|
-
from execsql.utils.gui import ( # noqa: E402
|
|
339
|
-
gui_console_isrunning,
|
|
340
|
-
enable_gui,
|
|
341
|
-
gui_console_on,
|
|
342
|
-
gui_console_off,
|
|
343
|
-
gui_console_hide,
|
|
344
|
-
gui_console_show,
|
|
345
|
-
gui_console_progress,
|
|
346
|
-
gui_console_save,
|
|
347
|
-
gui_console_status,
|
|
348
|
-
gui_console_wait_user,
|
|
349
|
-
gui_console_height,
|
|
350
|
-
gui_console_width,
|
|
351
|
-
gui_connect,
|
|
352
|
-
gui_credentials,
|
|
353
|
-
GuiSpec,
|
|
354
|
-
ConsoleUIError,
|
|
355
|
-
ActionSpec,
|
|
356
|
-
EntrySpec,
|
|
357
|
-
GUI_HALT,
|
|
358
|
-
GUI_MSG,
|
|
359
|
-
GUI_PAUSE,
|
|
360
|
-
GUI_DISPLAY,
|
|
361
|
-
GUI_ENTRY,
|
|
362
|
-
GUI_COMPARE,
|
|
363
|
-
GUI_SELECTROWS,
|
|
364
|
-
GUI_SELECTSUB,
|
|
365
|
-
GUI_ACTION,
|
|
366
|
-
GUI_MAP,
|
|
367
|
-
GUI_OPENFILE,
|
|
368
|
-
GUI_SAVEFILE,
|
|
369
|
-
GUI_DIRECTORY,
|
|
370
|
-
QUERY_CONSOLE,
|
|
371
|
-
GUI_CREDENTIALS,
|
|
372
|
-
GUI_CONNECT,
|
|
373
|
-
get_yn,
|
|
374
|
-
get_yn_win,
|
|
375
|
-
pause,
|
|
376
|
-
pause_win,
|
|
377
|
-
)
|
|
229
|
+
|
|
230
|
+
def reset() -> None:
|
|
231
|
+
"""Reset all module-level state to initial values.
|
|
232
|
+
|
|
233
|
+
Intended for use in tests. Clears mutable containers, resets counters,
|
|
234
|
+
and sets all lazy singletons back to ``None`` so that each test starts
|
|
235
|
+
from a clean slate.
|
|
236
|
+
"""
|
|
237
|
+
global compiling_loop, loop_nest_level, cmds_run
|
|
238
|
+
global conf, last_command, upass
|
|
239
|
+
global err_halt_writespec, err_halt_email, err_halt_exec
|
|
240
|
+
global cancel_halt_writespec, cancel_halt_mailspec, cancel_halt_exec
|
|
241
|
+
global exec_log, subvars, status, if_stack, counters, timer
|
|
242
|
+
global output, dbs, tempfiles, export_metadata
|
|
243
|
+
global metacommandlist, conditionallist, filewriter
|
|
244
|
+
global gui_console, gui_manager_queue, gui_manager_thread
|
|
245
|
+
|
|
246
|
+
# Mutable containers — clear in-place (no rebind needed)
|
|
247
|
+
commandliststack.clear()
|
|
248
|
+
loopcommandstack.clear()
|
|
249
|
+
savedscripts.clear()
|
|
250
|
+
|
|
251
|
+
# Scalar flags and counters
|
|
252
|
+
compiling_loop = False
|
|
253
|
+
loop_nest_level = 0
|
|
254
|
+
cmds_run = 0
|
|
255
|
+
|
|
256
|
+
# Close open database connections before discarding the pool.
|
|
257
|
+
if dbs is not None:
|
|
258
|
+
try:
|
|
259
|
+
dbs.closeall()
|
|
260
|
+
except Exception:
|
|
261
|
+
pass
|
|
262
|
+
|
|
263
|
+
# Lazy singletons — reset to None
|
|
264
|
+
conf = None
|
|
265
|
+
last_command = None
|
|
266
|
+
upass = None
|
|
267
|
+
err_halt_writespec = None
|
|
268
|
+
err_halt_email = None
|
|
269
|
+
err_halt_exec = None
|
|
270
|
+
cancel_halt_writespec = None
|
|
271
|
+
cancel_halt_mailspec = None
|
|
272
|
+
cancel_halt_exec = None
|
|
273
|
+
exec_log = None
|
|
274
|
+
subvars = None
|
|
275
|
+
status = None
|
|
276
|
+
if_stack = None
|
|
277
|
+
counters = None
|
|
278
|
+
timer = None
|
|
279
|
+
output = None
|
|
280
|
+
dbs = None
|
|
281
|
+
tempfiles = None
|
|
282
|
+
export_metadata = None
|
|
283
|
+
metacommandlist = None
|
|
284
|
+
conditionallist = None
|
|
285
|
+
# filewriter is a multiprocessing.Process managed by atexit — do NOT null
|
|
286
|
+
# it here. Nulling it while the subprocess is alive creates two competing
|
|
287
|
+
# consumers on the shared fw_input queue, causing test-to-test races.
|
|
288
|
+
gui_console = None
|
|
289
|
+
gui_manager_queue = None
|
|
290
|
+
gui_manager_thread = None
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def initialize(
|
|
294
|
+
config: ConfigData,
|
|
295
|
+
dispatch_table: object,
|
|
296
|
+
conditional_table: object,
|
|
297
|
+
) -> None:
|
|
298
|
+
"""Initialize the shared runtime singletons for a new execsql run.
|
|
299
|
+
|
|
300
|
+
Called once from :func:`execsql.cli._run` after configuration has been
|
|
301
|
+
loaded. Consolidates object construction in one place so that the
|
|
302
|
+
sequence is documented, testable, and not scattered across the CLI
|
|
303
|
+
entry-point.
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
config: A fully-populated :class:`execsql.config.ConfigData` instance.
|
|
307
|
+
dispatch_table: The metacommand dispatch table
|
|
308
|
+
(``execsql.metacommands.DISPATCH_TABLE``).
|
|
309
|
+
conditional_table: The conditional-predicate dispatch table
|
|
310
|
+
(``execsql.metacommands.conditions.CONDITIONAL_TABLE``).
|
|
311
|
+
|
|
312
|
+
Note:
|
|
313
|
+
``subvars``, ``status``, ``output``, ``filewriter``, and ``exec_log``
|
|
314
|
+
are **not** set here because they require CLI-specific arguments
|
|
315
|
+
(script path, subprocess queues, local class definitions). Those are
|
|
316
|
+
assigned directly in ``_run()`` before and after this call.
|
|
317
|
+
"""
|
|
318
|
+
global conf, if_stack, counters, timer, dbs, tempfiles
|
|
319
|
+
global export_metadata, metacommandlist, conditionallist
|
|
320
|
+
|
|
321
|
+
# These names are re-exported at the bottom of this module (after this
|
|
322
|
+
# function definition), so they are guaranteed to be available by the time
|
|
323
|
+
# initialize() is called from cli._run(). Using the module-level names
|
|
324
|
+
# avoids F811 "redefinition of unused name" from local imports.
|
|
325
|
+
import execsql.script as _script
|
|
326
|
+
import execsql.utils.timer as _timer_mod
|
|
327
|
+
import execsql.db.base as _db_base
|
|
328
|
+
import execsql.utils.fileio as _fileio_mod
|
|
329
|
+
import execsql.exporters.base as _exporters_base
|
|
330
|
+
|
|
331
|
+
conf = config
|
|
332
|
+
if_stack = _script.IfLevels()
|
|
333
|
+
counters = _script.CounterVars()
|
|
334
|
+
timer = _timer_mod.Timer()
|
|
335
|
+
dbs = _db_base.DatabasePool()
|
|
336
|
+
tempfiles = _fileio_mod.TempFileMgr()
|
|
337
|
+
export_metadata = _exporters_base.ExportMetadata()
|
|
338
|
+
metacommandlist = dispatch_table
|
|
339
|
+
conditionallist = conditional_table
|