execsql2 2.5.0__py3-none-any.whl → 2.6.0__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.
Files changed (24) hide show
  1. execsql/gui/tui.py +132 -0
  2. execsql/metacommands/__init__.py +180 -180
  3. execsql/state.py +261 -200
  4. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/METADATA +1 -1
  5. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/RECORD +24 -24
  6. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/README.md +0 -0
  7. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  8. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  9. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/execsql.conf +0 -0
  10. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/make_config_db.sql +0 -0
  11. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/md_compare.sql +0 -0
  12. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/md_glossary.sql +0 -0
  13. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/md_upsert.sql +0 -0
  14. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/pg_compare.sql +0 -0
  15. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  16. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  17. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/script_template.sql +0 -0
  18. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/ss_compare.sql +0 -0
  19. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  20. {execsql2-2.5.0.data → execsql2-2.6.0.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  21. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/WHEEL +0 -0
  22. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/entry_points.txt +0 -0
  23. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/licenses/LICENSE.txt +0 -0
  24. {execsql2-2.5.0.dist-info → execsql2-2.6.0.dist-info}/licenses/NOTICE +0 -0
execsql/gui/tui.py CHANGED
@@ -101,6 +101,10 @@ def _button_row(button_list: list) -> list[Button]:
101
101
  class _BaseDialog(ModalScreen):
102
102
  """Common infrastructure for all execsql dialog screens."""
103
103
 
104
+ BINDINGS = [
105
+ Binding("escape", "cancel", "Cancel", show=True),
106
+ ]
107
+
104
108
  DEFAULT_CSS = """
105
109
  _BaseDialog {
106
110
  align: center middle;
@@ -151,6 +155,11 @@ class _BaseDialog(ModalScreen):
151
155
  def result(self) -> dict:
152
156
  return self._result
153
157
 
158
+ def action_cancel(self) -> None:
159
+ """Dismiss the dialog as cancelled (triggered by Escape key)."""
160
+ self._result = {"button": None, "cancelled": True}
161
+ self.dismiss(self._result)
162
+
154
163
  @on(Button.Pressed, "#btn_cancel_exit")
155
164
  def _on_cancel_exit(self, event: Button.Pressed) -> None:
156
165
  """Universal Cancel handler — dismisses with cancelled=True so the sync queue can exit."""
@@ -167,6 +176,11 @@ class _BaseDialog(ModalScreen):
167
176
  class MsgScreen(_BaseDialog):
168
177
  """Simple message dialog with Continue and Cancel buttons."""
169
178
 
179
+ BINDINGS = [
180
+ *_BaseDialog.BINDINGS,
181
+ Binding("enter", "submit", "Continue", show=True),
182
+ ]
183
+
170
184
  def compose(self) -> ComposeResult:
171
185
  title = self.args.get("title", "Message")
172
186
  message = self.args.get("message", "")
@@ -176,6 +190,12 @@ class MsgScreen(_BaseDialog):
176
190
  with Horizontal(id="buttons"):
177
191
  yield Button("Cancel", id="btn_cancel_exit", variant="warning")
178
192
  yield Button("Continue", id="btn_close", variant="primary")
193
+ yield Footer()
194
+
195
+ def action_submit(self) -> None:
196
+ """Continue the dialog (triggered by Enter key)."""
197
+ self._result = {"button": 1}
198
+ self.dismiss(self._result)
179
199
 
180
200
  def on_button_pressed(self, event: Button.Pressed) -> None:
181
201
  if event.button.id == "btn_close":
@@ -191,6 +211,11 @@ class MsgScreen(_BaseDialog):
191
211
  class PauseScreen(_BaseDialog):
192
212
  """Pause dialog with optional countdown and Continue/Cancel buttons."""
193
213
 
214
+ BINDINGS = [
215
+ *_BaseDialog.BINDINGS,
216
+ Binding("enter", "submit", "Continue", show=True),
217
+ ]
218
+
194
219
  def compose(self) -> ComposeResult:
195
220
  title = self.args.get("title", "Pause")
196
221
  message = self.args.get("message", "")
@@ -200,6 +225,7 @@ class PauseScreen(_BaseDialog):
200
225
  with Horizontal(id="buttons"):
201
226
  yield Button("Cancel", id="btn_cancel_exit", variant="warning")
202
227
  yield Button("Continue", id="btn_continue", variant="primary")
228
+ yield Footer()
203
229
 
204
230
  def on_mount(self) -> None:
205
231
  countdown = self.args.get("countdown")
@@ -210,6 +236,11 @@ class PauseScreen(_BaseDialog):
210
236
  self._result = {"quit": False}
211
237
  self.dismiss(self._result)
212
238
 
239
+ def action_submit(self) -> None:
240
+ """Continue the dialog (triggered by Enter key)."""
241
+ self._result = {"quit": False}
242
+ self.dismiss(self._result)
243
+
213
244
  def on_button_pressed(self, event: Button.Pressed) -> None:
214
245
  if event.button.id == "btn_continue":
215
246
  self._result = {"quit": False}
@@ -224,6 +255,11 @@ class PauseScreen(_BaseDialog):
224
255
  class DisplayScreen(_BaseDialog):
225
256
  """Data display dialog: title, message, optional table, optional text entry, buttons."""
226
257
 
258
+ BINDINGS = [
259
+ *_BaseDialog.BINDINGS,
260
+ Binding("enter", "submit", "Submit", show=True),
261
+ ]
262
+
227
263
  def compose(self) -> ComposeResult:
228
264
  title = self.args.get("title", "")
229
265
  message = self.args.get("message", "")
@@ -251,6 +287,23 @@ class DisplayScreen(_BaseDialog):
251
287
  )
252
288
  with Horizontal(id="buttons"):
253
289
  yield from _button_row(button_list)
290
+ yield Footer()
291
+
292
+ def action_submit(self) -> None:
293
+ """Submit the first primary button value (triggered by Enter key)."""
294
+ button_list = self.args.get("button_list", [("Continue", 1)])
295
+ # Find the first non-cancel button value.
296
+ value = None
297
+ for btn in button_list:
298
+ if btn[1]:
299
+ value = btn[1]
300
+ break
301
+ if value is None:
302
+ return
303
+ text_input = self.query_one("#text_input", Input) if self.args.get("textentry") else None
304
+ return_value = text_input.value if text_input else None
305
+ self._result = {"button": value, "return_value": return_value}
306
+ self.dismiss(self._result)
254
307
 
255
308
  def on_button_pressed(self, event: Button.Pressed) -> None:
256
309
  btn_id = event.button.id
@@ -272,6 +325,11 @@ class DisplayScreen(_BaseDialog):
272
325
  class EntryFormScreen(_BaseDialog):
273
326
  """Multi-field entry form dialog."""
274
327
 
328
+ BINDINGS = [
329
+ *_BaseDialog.BINDINGS,
330
+ Binding("enter", "submit", "OK", show=True),
331
+ ]
332
+
275
333
  DEFAULT_CSS = (
276
334
  _BaseDialog.DEFAULT_CSS
277
335
  + """
@@ -337,9 +395,26 @@ class EntryFormScreen(_BaseDialog):
337
395
  with Horizontal(id="buttons"):
338
396
  yield Button("Cancel", id="btn_cancel_exit", variant="warning")
339
397
  yield Button("OK", id="btn_ok", variant="primary")
398
+ yield Footer()
340
399
 
341
400
  self._specs = specs
342
401
 
402
+ def action_submit(self) -> None:
403
+ """Submit the form (triggered by Enter key)."""
404
+ for spec in self._specs:
405
+ widget = self._inputs.get(spec.varname)
406
+ if widget is None:
407
+ continue
408
+ etype = (spec.entry_type or "text").lower()
409
+ if etype == "checkbox":
410
+ spec.value = "True" if widget.value else "False"
411
+ elif etype in ("dropdown", "select"):
412
+ spec.value = str(widget.value) if widget.value is not None else ""
413
+ else:
414
+ spec.value = widget.value
415
+ self._result = {"button": 1, "return_value": self._specs}
416
+ self.dismiss(self._result)
417
+
343
418
  def on_button_pressed(self, event: Button.Pressed) -> None:
344
419
  if event.button.id == "btn_ok":
345
420
  for spec in self._specs:
@@ -365,6 +440,11 @@ class EntryFormScreen(_BaseDialog):
365
440
  class CompareScreen(_BaseDialog):
366
441
  """Side-by-side table comparison dialog."""
367
442
 
443
+ BINDINGS = [
444
+ *_BaseDialog.BINDINGS,
445
+ Binding("enter", "submit", "Continue", show=True),
446
+ ]
447
+
368
448
  DEFAULT_CSS = (
369
449
  _BaseDialog.DEFAULT_CSS
370
450
  + """
@@ -412,6 +492,7 @@ class CompareScreen(_BaseDialog):
412
492
  yield _make_table_widget("table2", headers2, rows2)
413
493
  with Horizontal(id="buttons"):
414
494
  yield from _button_row(button_list)
495
+ yield Footer()
415
496
 
416
497
  def on_mount(self) -> None:
417
498
  keylist = [str(k) for k in self.args.get("keylist", [])]
@@ -461,6 +542,15 @@ class CompareScreen(_BaseDialog):
461
542
  finally:
462
543
  self._syncing = False
463
544
 
545
+ def action_submit(self) -> None:
546
+ """Submit the first primary button value (triggered by Enter key)."""
547
+ button_list = self.args.get("button_list", [("Continue", 1)])
548
+ for btn in button_list:
549
+ if btn[1]:
550
+ self._result = {"button": btn[1]}
551
+ self.dismiss(self._result)
552
+ return
553
+
464
554
  def on_button_pressed(self, event: Button.Pressed) -> None:
465
555
  btn_id = event.button.id
466
556
  if btn_id and btn_id.startswith("btn_") and btn_id[4:].isdigit():
@@ -478,6 +568,11 @@ class CompareScreen(_BaseDialog):
478
568
  class SelectRowsScreen(_BaseDialog):
479
569
  """Row selection dialog: pick rows from source table and add to target."""
480
570
 
571
+ BINDINGS = [
572
+ *_BaseDialog.BINDINGS,
573
+ Binding("enter", "submit", "Continue", show=True),
574
+ ]
575
+
481
576
  DEFAULT_CSS = (
482
577
  _BaseDialog.DEFAULT_CSS
483
578
  + """
@@ -516,6 +611,7 @@ class SelectRowsScreen(_BaseDialog):
516
611
  yield _make_table_widget("dest_table", headers2, rows2)
517
612
  with Horizontal(id="buttons"):
518
613
  yield from _button_row(button_list)
614
+ yield Footer()
519
615
 
520
616
  def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
521
617
  if event.data_table.id == "source_table":
@@ -525,6 +621,15 @@ class SelectRowsScreen(_BaseDialog):
525
621
  values = [src.get_cell(row_key, col) for col in src.columns]
526
622
  dest.add_row(*values)
527
623
 
624
+ def action_submit(self) -> None:
625
+ """Submit the first primary button value (triggered by Enter key)."""
626
+ button_list = self.args.get("button_list", [("Continue", 1)])
627
+ for btn in button_list:
628
+ if btn[1]:
629
+ self._result = {"button": btn[1]}
630
+ self.dismiss(self._result)
631
+ return
632
+
528
633
  def on_button_pressed(self, event: Button.Pressed) -> None:
529
634
  btn_id = event.button.id
530
635
  if btn_id and btn_id.startswith("btn_") and btn_id[4:].isdigit():
@@ -588,6 +693,10 @@ class SelectSubScreen(_BaseDialog):
588
693
  class ActionScreen(_BaseDialog):
589
694
  """Action button grid dialog."""
590
695
 
696
+ BINDINGS = [
697
+ *_BaseDialog.BINDINGS,
698
+ ]
699
+
591
700
  def compose(self) -> ComposeResult:
592
701
  title = self.args.get("title", "Actions")
593
702
  message = self.args.get("message", "")
@@ -609,6 +718,7 @@ class ActionScreen(_BaseDialog):
609
718
  yield Button(f"{spec.label} — {spec.prompt}", id=f"action_{i}", variant="primary")
610
719
  if include_continue:
611
720
  yield Button("Continue", id="action_continue", variant="default")
721
+ yield Footer()
612
722
 
613
723
  self._button_specs = button_specs
614
724
 
@@ -1045,6 +1155,7 @@ class ConsoleApp(App):
1045
1155
  self._script_thread: threading.Thread | None = None
1046
1156
  self._script_exception: BaseException | None = None
1047
1157
  self._screen_map: dict | None = None
1158
+ self._console_lines: list[str] = []
1048
1159
 
1049
1160
  def compose(self) -> ComposeResult:
1050
1161
  yield Header(show_clock=False)
@@ -1118,11 +1229,19 @@ class ConsoleApp(App):
1118
1229
  self.call_from_thread(self._append_console, text)
1119
1230
 
1120
1231
  def _append_console(self, text: str) -> None:
1232
+ self._console_lines.append(text)
1121
1233
  try:
1122
1234
  self.query_one("#console_log", RichLog).write(text)
1123
1235
  except Exception:
1124
1236
  pass # Widget may not be mounted yet.
1125
1237
 
1238
+ def save(self, outfile: str, append: bool = False) -> None:
1239
+ """Save the console text contents to *outfile*."""
1240
+ mode = "a" if append else "w"
1241
+ with open(outfile, mode, encoding="utf-8") as fh:
1242
+ for line in self._console_lines:
1243
+ fh.write(line if line.endswith("\n") else line + "\n")
1244
+
1126
1245
  def set_status(self, msg: str) -> None:
1127
1246
  """Thread-safe status bar update."""
1128
1247
  self.call_from_thread(self._update_status, msg)
@@ -1199,6 +1318,19 @@ class TextualBackend(GuiBackend):
1199
1318
  pct = (num / total * 100.0) if total else num
1200
1319
  self._console_app.set_progress(pct)
1201
1320
 
1321
+ def console_save(self, outfile: str, append: bool = False) -> None:
1322
+ """Save console text contents to *outfile*."""
1323
+ if self._console_app is not None:
1324
+ self._console_app.save(outfile, append)
1325
+
1326
+ def console_hide(self) -> None:
1327
+ """Hide the console (minimize) — Textual has no window-level hide,
1328
+ so this is a no-op in a terminal environment."""
1329
+
1330
+ def console_show(self) -> None:
1331
+ """Show the console — Textual has no window-level show,
1332
+ so this is a no-op in a terminal environment."""
1333
+
1202
1334
  def console_wait_user(self, message: str = "") -> None:
1203
1335
  # ConsoleApp exits when the script is done; nothing extra needed here.
1204
1336
  pass
@@ -10,207 +10,207 @@ Handler functions live in the sibling modules:
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- import execsql.state as _state # noqa: F401
13
+ import execsql.state as _state
14
14
 
15
15
  # Handler imports — grouped by module for readability.
16
16
  from execsql.metacommands.connect import (
17
- x_connect_pg, # noqa: F401
18
- x_connect_user_pg, # noqa: F401
19
- x_connect_ssvr, # noqa: F401
20
- x_connect_user_ssvr, # noqa: F401
21
- x_connect_mysql, # noqa: F401
22
- x_connect_user_mysql, # noqa: F401
23
- x_connect_access, # noqa: F401
24
- x_connect_fb, # noqa: F401
25
- x_connect_user_fb, # noqa: F401
26
- x_connect_ora, # noqa: F401
27
- x_connect_user_ora, # noqa: F401
28
- x_connect_duckdb, # noqa: F401
29
- x_connect_sqlite, # noqa: F401
30
- x_connect_dsn, # noqa: F401
31
- x_use, # noqa: F401
32
- x_disconnect, # noqa: F401
33
- x_autocommit_on, # noqa: F401
34
- x_autocommit_off, # noqa: F401
35
- x_pg_vacuum, # noqa: F401
36
- x_daoflushdelay, # noqa: F401
17
+ x_connect_pg,
18
+ x_connect_user_pg,
19
+ x_connect_ssvr,
20
+ x_connect_user_ssvr,
21
+ x_connect_mysql,
22
+ x_connect_user_mysql,
23
+ x_connect_access,
24
+ x_connect_fb,
25
+ x_connect_user_fb,
26
+ x_connect_ora,
27
+ x_connect_user_ora,
28
+ x_connect_duckdb,
29
+ x_connect_sqlite,
30
+ x_connect_dsn,
31
+ x_use,
32
+ x_disconnect,
33
+ x_autocommit_on,
34
+ x_autocommit_off,
35
+ x_pg_vacuum,
36
+ x_daoflushdelay,
37
37
  )
38
38
  from execsql.metacommands.control import (
39
- x_if, # noqa: F401
40
- x_if_orif, # noqa: F401
41
- x_if_andif, # noqa: F401
42
- x_if_elseif, # noqa: F401
43
- x_if_else, # noqa: F401
44
- x_if_block, # noqa: F401
45
- x_if_end, # noqa: F401
46
- x_loop, # noqa: F401
47
- x_halt, # noqa: F401
48
- x_halt_msg, # noqa: F401
49
- x_error_halt, # noqa: F401
50
- x_metacommand_error_halt, # noqa: F401
51
- x_begin_batch, # noqa: F401
52
- x_end_batch, # noqa: F401
53
- x_rollback, # noqa: F401
54
- x_break, # noqa: F401
55
- x_wait_until, # noqa: F401
39
+ x_if,
40
+ x_if_orif,
41
+ x_if_andif,
42
+ x_if_elseif,
43
+ x_if_else,
44
+ x_if_block,
45
+ x_if_end,
46
+ x_loop,
47
+ x_halt,
48
+ x_halt_msg,
49
+ x_error_halt,
50
+ x_metacommand_error_halt,
51
+ x_begin_batch,
52
+ x_end_batch,
53
+ x_rollback,
54
+ x_break,
55
+ x_wait_until,
56
56
  )
57
57
  from execsql.metacommands.data import (
58
- x_sub, # noqa: F401
59
- x_sub_add, # noqa: F401
60
- x_sub_append, # noqa: F401
61
- x_sub_empty, # noqa: F401
62
- x_rm_sub, # noqa: F401
63
- x_sub_local, # noqa: F401
64
- x_sub_tempfile, # noqa: F401
65
- x_sub_ini, # noqa: F401
66
- x_sub_querystring, # noqa: F401
67
- x_sub_encrypt, # noqa: F401
68
- x_sub_decrypt, # noqa: F401
69
- x_subdata, # noqa: F401
70
- x_selectsub, # noqa: F401
71
- x_prompt_selectsub, # noqa: F401
72
- x_empty_strings, # noqa: F401
73
- x_trim_strings, # noqa: F401
74
- x_replace_newlines, # noqa: F401
75
- x_empty_rows, # noqa: F401
76
- x_only_strings, # noqa: F401
77
- x_boolean_int, # noqa: F401
78
- x_boolean_words, # noqa: F401
79
- x_fold_col_hdrs, # noqa: F401
80
- x_trim_col_hdrs, # noqa: F401
81
- x_clean_col_hdrs, # noqa: F401
82
- x_del_empty_cols, # noqa: F401
83
- x_create_col_hdrs, # noqa: F401
84
- x_dedup_col_hdrs, # noqa: F401
85
- x_import_common_cols_only, # noqa: F401
86
- x_quote_all_text, # noqa: F401
87
- x_reset_counter, # noqa: F401
88
- x_reset_counters, # noqa: F401
89
- x_set_counter, # noqa: F401
90
- x_max_int, # noqa: F401
58
+ x_sub,
59
+ x_sub_add,
60
+ x_sub_append,
61
+ x_sub_empty,
62
+ x_rm_sub,
63
+ x_sub_local,
64
+ x_sub_tempfile,
65
+ x_sub_ini,
66
+ x_sub_querystring,
67
+ x_sub_encrypt,
68
+ x_sub_decrypt,
69
+ x_subdata,
70
+ x_selectsub,
71
+ x_prompt_selectsub,
72
+ x_empty_strings,
73
+ x_trim_strings,
74
+ x_replace_newlines,
75
+ x_empty_rows,
76
+ x_only_strings,
77
+ x_boolean_int,
78
+ x_boolean_words,
79
+ x_fold_col_hdrs,
80
+ x_trim_col_hdrs,
81
+ x_clean_col_hdrs,
82
+ x_del_empty_cols,
83
+ x_create_col_hdrs,
84
+ x_dedup_col_hdrs,
85
+ x_import_common_cols_only,
86
+ x_quote_all_text,
87
+ x_reset_counter,
88
+ x_reset_counters,
89
+ x_set_counter,
90
+ x_max_int,
91
91
  )
92
92
  from execsql.metacommands.debug import (
93
- x_debug_write_metacommands, # noqa: F401
94
- x_debug_commandliststack, # noqa: F401
95
- x_debug_iflevels, # noqa: F401
96
- x_debug_write_odbc_drivers, # noqa: F401
97
- x_debug_log_subvars, # noqa: F401
98
- x_debug_log_config, # noqa: F401
99
- x_debug_write_subvars, # noqa: F401
100
- x_debug_write_config, # noqa: F401
93
+ x_debug_write_metacommands,
94
+ x_debug_commandliststack,
95
+ x_debug_iflevels,
96
+ x_debug_write_odbc_drivers,
97
+ x_debug_log_subvars,
98
+ x_debug_log_config,
99
+ x_debug_write_subvars,
100
+ x_debug_write_config,
101
101
  )
102
102
  from execsql.metacommands.io import (
103
- x_export, # noqa: F401
104
- x_export_query, # noqa: F401
105
- x_export_query_with_template, # noqa: F401
106
- x_export_with_template, # noqa: F401
107
- x_export_ods_multiple, # noqa: F401
108
- x_export_metadata, # noqa: F401
109
- x_export_metadata_table, # noqa: F401
110
- x_import, # noqa: F401
111
- x_import_file, # noqa: F401
112
- x_import_ods, # noqa: F401
113
- x_import_ods_pattern, # noqa: F401
114
- x_import_xls, # noqa: F401
115
- x_import_xls_pattern, # noqa: F401
116
- x_import_parquet, # noqa: F401
117
- x_import_feather, # noqa: F401
118
- x_import_row_buffer, # noqa: F401
119
- x_show_progress, # noqa: F401
120
- x_export_row_buffer, # noqa: F401
121
- x_write, # noqa: F401
122
- x_write_create_table, # noqa: F401
123
- x_write_create_table_ods, # noqa: F401
124
- x_write_create_table_xls, # noqa: F401
125
- x_write_create_table_alias, # noqa: F401
126
- x_write_prefix, # noqa: F401
127
- x_write_suffix, # noqa: F401
128
- x_writescript, # noqa: F401
129
- x_include, # noqa: F401
130
- x_copy, # noqa: F401
131
- x_copy_query, # noqa: F401
132
- x_zip, # noqa: F401
133
- x_zip_buffer_mb, # noqa: F401
134
- x_rm_file, # noqa: F401
135
- x_make_export_dirs, # noqa: F401
136
- x_cd, # noqa: F401
137
- x_scan_lines, # noqa: F401
138
- x_hdf5_text_len, # noqa: F401
139
- x_serve, # noqa: F401
103
+ x_export,
104
+ x_export_query,
105
+ x_export_query_with_template,
106
+ x_export_with_template,
107
+ x_export_ods_multiple,
108
+ x_export_metadata,
109
+ x_export_metadata_table,
110
+ x_import,
111
+ x_import_file,
112
+ x_import_ods,
113
+ x_import_ods_pattern,
114
+ x_import_xls,
115
+ x_import_xls_pattern,
116
+ x_import_parquet,
117
+ x_import_feather,
118
+ x_import_row_buffer,
119
+ x_show_progress,
120
+ x_export_row_buffer,
121
+ x_write,
122
+ x_write_create_table,
123
+ x_write_create_table_ods,
124
+ x_write_create_table_xls,
125
+ x_write_create_table_alias,
126
+ x_write_prefix,
127
+ x_write_suffix,
128
+ x_writescript,
129
+ x_include,
130
+ x_copy,
131
+ x_copy_query,
132
+ x_zip,
133
+ x_zip_buffer_mb,
134
+ x_rm_file,
135
+ x_make_export_dirs,
136
+ x_cd,
137
+ x_scan_lines,
138
+ x_hdf5_text_len,
139
+ x_serve,
140
140
  )
141
141
  from execsql.metacommands.prompt import (
142
- x_prompt, # noqa: F401
143
- x_prompt_enter, # noqa: F401
144
- x_prompt_entryform, # noqa: F401
145
- x_prompt_pause, # noqa: F401
146
- x_prompt_compare, # noqa: F401
147
- x_prompt_ask_compare, # noqa: F401
148
- x_prompt_ask, # noqa: F401
149
- x_prompt_map, # noqa: F401
150
- x_prompt_action, # noqa: F401
151
- x_prompt_savefile, # noqa: F401
152
- x_prompt_openfile, # noqa: F401
153
- x_prompt_directory, # noqa: F401
154
- x_prompt_select_rows, # noqa: F401
155
- x_prompt_credentials, # noqa: F401
156
- x_prompt_connect, # noqa: F401
157
- x_ask, # noqa: F401
158
- x_pause, # noqa: F401
159
- x_msg, # noqa: F401
160
- x_reset_dialog_canceled, # noqa: F401
142
+ x_prompt,
143
+ x_prompt_enter,
144
+ x_prompt_entryform,
145
+ x_prompt_pause,
146
+ x_prompt_compare,
147
+ x_prompt_ask_compare,
148
+ x_prompt_ask,
149
+ x_prompt_map,
150
+ x_prompt_action,
151
+ x_prompt_savefile,
152
+ x_prompt_openfile,
153
+ x_prompt_directory,
154
+ x_prompt_select_rows,
155
+ x_prompt_credentials,
156
+ x_prompt_connect,
157
+ x_ask,
158
+ x_pause,
159
+ x_msg,
160
+ x_reset_dialog_canceled,
161
161
  )
162
162
  from execsql.metacommands.script_ext import (
163
- x_extendscript, # noqa: F401
164
- x_extendscript_metacommand, # noqa: F401
165
- x_extendscript_sql, # noqa: F401
166
- x_executescript, # noqa: F401
163
+ x_extendscript,
164
+ x_extendscript_metacommand,
165
+ x_extendscript_sql,
166
+ x_executescript,
167
167
  )
168
168
  from execsql.metacommands.system import (
169
- x_system_cmd, # noqa: F401
170
- x_email, # noqa: F401
171
- x_timer, # noqa: F401
172
- x_log, # noqa: F401
173
- x_logwritemessages, # noqa: F401
174
- x_log_datavars, # noqa: F401
175
- x_log_sql, # noqa: F401
176
- x_console, # noqa: F401
177
- x_consoleprogress, # noqa: F401
178
- x_consolewait, # noqa: F401
179
- x_consolewait_onerror, # noqa: F401
180
- x_consolewait_whendone, # noqa: F401
181
- x_console_hideshow, # noqa: F401
182
- x_consolewidth, # noqa: F401
183
- x_consoleheight, # noqa: F401
184
- x_consolestatus, # noqa: F401
185
- x_consolesave, # noqa: F401
186
- x_cancel_halt, # noqa: F401
187
- x_cancel_halt_write_clear, # noqa: F401
188
- x_cancel_halt_write, # noqa: F401
189
- x_cancel_halt_email_clear, # noqa: F401
190
- x_cancel_halt_email, # noqa: F401
191
- x_cancel_halt_exec, # noqa: F401
192
- x_cancel_halt_exec_clear, # noqa: F401
193
- x_error_halt_write_clear, # noqa: F401
194
- x_error_halt_write, # noqa: F401
195
- x_error_halt_email_clear, # noqa: F401
196
- x_error_halt_email, # noqa: F401
197
- x_error_halt_exec, # noqa: F401
198
- x_error_halt_exec_clear, # noqa: F401
199
- x_write_warnings, # noqa: F401
200
- x_gui_level, # noqa: F401
201
- x_execute, # noqa: F401
169
+ x_system_cmd,
170
+ x_email,
171
+ x_timer,
172
+ x_log,
173
+ x_logwritemessages,
174
+ x_log_datavars,
175
+ x_log_sql,
176
+ x_console,
177
+ x_consoleprogress,
178
+ x_consolewait,
179
+ x_consolewait_onerror,
180
+ x_consolewait_whendone,
181
+ x_console_hideshow,
182
+ x_consolewidth,
183
+ x_consoleheight,
184
+ x_consolestatus,
185
+ x_consolesave,
186
+ x_cancel_halt,
187
+ x_cancel_halt_write_clear,
188
+ x_cancel_halt_write,
189
+ x_cancel_halt_email_clear,
190
+ x_cancel_halt_email,
191
+ x_cancel_halt_exec,
192
+ x_cancel_halt_exec_clear,
193
+ x_error_halt_write_clear,
194
+ x_error_halt_write,
195
+ x_error_halt_email_clear,
196
+ x_error_halt_email,
197
+ x_error_halt_exec,
198
+ x_error_halt_exec_clear,
199
+ x_write_warnings,
200
+ x_gui_level,
201
+ x_execute,
202
202
  )
203
203
 
204
204
  # Regex helper functions (from utils/regex.py)
205
205
  from execsql.utils.regex import (
206
- ins_rxs, # noqa: F401
207
- ins_quoted_rx, # noqa: F401
208
- ins_schema_rxs, # noqa: F401
209
- ins_table_rxs, # noqa: F401
210
- ins_table_list_rxs, # noqa: F401
211
- ins_fn_rxs, # noqa: F401
206
+ ins_rxs,
207
+ ins_quoted_rx,
208
+ ins_schema_rxs,
209
+ ins_table_rxs,
210
+ ins_table_list_rxs,
211
+ ins_fn_rxs,
212
212
  )
213
- from execsql.script import MetaCommandList # noqa: F401
213
+ from execsql.script import MetaCommandList
214
214
 
215
215
  __all__ = [
216
216
  # execsql.state
@@ -457,6 +457,6 @@ DATABASE_TYPES = [
457
457
  # ---------------------------------------------------------------------------
458
458
  # Module-level DISPATCH_TABLE — built once at import time.
459
459
  # ---------------------------------------------------------------------------
460
- from execsql.metacommands.dispatch import build_dispatch_table # noqa: E402
460
+ from execsql.metacommands.dispatch import build_dispatch_table
461
461
 
462
462
  DISPATCH_TABLE = build_dispatch_table()