execsql2 2.5.0__py3-none-any.whl → 2.7.1__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 (32) hide show
  1. execsql/exporters/__init__.py +3 -3
  2. execsql/exporters/delimited.py +2 -2
  3. execsql/exporters/markdown.py +126 -0
  4. execsql/exporters/xlsx.py +317 -0
  5. execsql/exporters/yaml.py +87 -0
  6. execsql/gui/tui.py +132 -0
  7. execsql/metacommands/__init__.py +203 -182
  8. execsql/metacommands/dispatch.py +11 -0
  9. execsql/metacommands/io.py +2 -0
  10. execsql/metacommands/io_export.py +75 -0
  11. execsql/state.py +261 -200
  12. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/METADATA +5 -2
  13. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/RECORD +32 -29
  14. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/README.md +0 -0
  15. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  16. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  17. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/execsql.conf +0 -0
  18. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/make_config_db.sql +0 -0
  19. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/md_compare.sql +0 -0
  20. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/md_glossary.sql +0 -0
  21. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/md_upsert.sql +0 -0
  22. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/pg_compare.sql +0 -0
  23. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  24. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  25. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/script_template.sql +0 -0
  26. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/ss_compare.sql +0 -0
  27. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  28. {execsql2-2.5.0.data → execsql2-2.7.1.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  29. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/WHEEL +0 -0
  30. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/entry_points.txt +0 -0
  31. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/licenses/LICENSE.txt +0 -0
  32. {execsql2-2.5.0.dist-info → execsql2-2.7.1.dist-info}/licenses/NOTICE +0 -0
@@ -10,207 +10,208 @@ 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_xlsx_multiple,
109
+ x_export_metadata,
110
+ x_export_metadata_table,
111
+ x_import,
112
+ x_import_file,
113
+ x_import_ods,
114
+ x_import_ods_pattern,
115
+ x_import_xls,
116
+ x_import_xls_pattern,
117
+ x_import_parquet,
118
+ x_import_feather,
119
+ x_import_row_buffer,
120
+ x_show_progress,
121
+ x_export_row_buffer,
122
+ x_write,
123
+ x_write_create_table,
124
+ x_write_create_table_ods,
125
+ x_write_create_table_xls,
126
+ x_write_create_table_alias,
127
+ x_write_prefix,
128
+ x_write_suffix,
129
+ x_writescript,
130
+ x_include,
131
+ x_copy,
132
+ x_copy_query,
133
+ x_zip,
134
+ x_zip_buffer_mb,
135
+ x_rm_file,
136
+ x_make_export_dirs,
137
+ x_cd,
138
+ x_scan_lines,
139
+ x_hdf5_text_len,
140
+ x_serve,
140
141
  )
141
142
  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
143
+ x_prompt,
144
+ x_prompt_enter,
145
+ x_prompt_entryform,
146
+ x_prompt_pause,
147
+ x_prompt_compare,
148
+ x_prompt_ask_compare,
149
+ x_prompt_ask,
150
+ x_prompt_map,
151
+ x_prompt_action,
152
+ x_prompt_savefile,
153
+ x_prompt_openfile,
154
+ x_prompt_directory,
155
+ x_prompt_select_rows,
156
+ x_prompt_credentials,
157
+ x_prompt_connect,
158
+ x_ask,
159
+ x_pause,
160
+ x_msg,
161
+ x_reset_dialog_canceled,
161
162
  )
162
163
  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
164
+ x_extendscript,
165
+ x_extendscript_metacommand,
166
+ x_extendscript_sql,
167
+ x_executescript,
167
168
  )
168
169
  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
170
+ x_system_cmd,
171
+ x_email,
172
+ x_timer,
173
+ x_log,
174
+ x_logwritemessages,
175
+ x_log_datavars,
176
+ x_log_sql,
177
+ x_console,
178
+ x_consoleprogress,
179
+ x_consolewait,
180
+ x_consolewait_onerror,
181
+ x_consolewait_whendone,
182
+ x_console_hideshow,
183
+ x_consolewidth,
184
+ x_consoleheight,
185
+ x_consolestatus,
186
+ x_consolesave,
187
+ x_cancel_halt,
188
+ x_cancel_halt_write_clear,
189
+ x_cancel_halt_write,
190
+ x_cancel_halt_email_clear,
191
+ x_cancel_halt_email,
192
+ x_cancel_halt_exec,
193
+ x_cancel_halt_exec_clear,
194
+ x_error_halt_write_clear,
195
+ x_error_halt_write,
196
+ x_error_halt_email_clear,
197
+ x_error_halt_email,
198
+ x_error_halt_exec,
199
+ x_error_halt_exec_clear,
200
+ x_write_warnings,
201
+ x_gui_level,
202
+ x_execute,
202
203
  )
203
204
 
204
205
  # Regex helper functions (from utils/regex.py)
205
206
  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
207
+ ins_rxs,
208
+ ins_quoted_rx,
209
+ ins_schema_rxs,
210
+ ins_table_rxs,
211
+ ins_table_list_rxs,
212
+ ins_fn_rxs,
212
213
  )
213
- from execsql.script import MetaCommandList # noqa: F401
214
+ from execsql.script import MetaCommandList
214
215
 
215
216
  __all__ = [
216
217
  # execsql.state
@@ -303,6 +304,7 @@ __all__ = [
303
304
  "x_export_query_with_template",
304
305
  "x_export_with_template",
305
306
  "x_export_ods_multiple",
307
+ "x_export_xlsx_multiple",
306
308
  "x_export_metadata",
307
309
  "x_export_metadata_table",
308
310
  "x_import",
@@ -427,12 +429,31 @@ TEXT_FORMATS = ["TXT", "TXT-AND", "PLAIN"]
427
429
  JSON_VARIANT_FORMATS = ["JSON_TS", "JSON_TABLESCHEMA"]
428
430
 
429
431
  QUERY_EXPORT_FORMATS = (
430
- DELIMITED_FORMATS + TEXT_FORMATS + ["ODS", "JSON", "HTML", "CGI-HTML", "VALUES", "LATEX", "RAW", "B64", "FEATHER"]
432
+ DELIMITED_FORMATS
433
+ + TEXT_FORMATS
434
+ + ["ODS", "XLSX", "JSON", "HTML", "CGI-HTML", "VALUES", "LATEX", "RAW", "B64", "FEATHER", "YAML", "MARKDOWN", "MD"]
431
435
  )
432
436
  TABLE_EXPORT_FORMATS = (
433
437
  DELIMITED_FORMATS
434
438
  + TEXT_FORMATS
435
- + ["JSON", "XML", "VALUES", "HTML", "CGI-HTML", "SQLITE", "DUCKDB", "LATEX", "RAW", "B64", "FEATHER", "HDF5"]
439
+ + [
440
+ "JSON",
441
+ "XML",
442
+ "VALUES",
443
+ "HTML",
444
+ "CGI-HTML",
445
+ "SQLITE",
446
+ "DUCKDB",
447
+ "LATEX",
448
+ "RAW",
449
+ "B64",
450
+ "FEATHER",
451
+ "HDF5",
452
+ "XLSX",
453
+ "YAML",
454
+ "MARKDOWN",
455
+ "MD",
456
+ ]
436
457
  )
437
458
  SERVE_FORMATS = ["BINARY", "CSV", "TXT", "TEXT", "ODS", "JSON", "HTML", "PDF", "ZIP"]
438
459
  METADATA_FORMATS = ["CSV", "TAB", "TSV", "TABQ", "TSVQ", "TXT", "TEXT"]
@@ -457,6 +478,6 @@ DATABASE_TYPES = [
457
478
  # ---------------------------------------------------------------------------
458
479
  # Module-level DISPATCH_TABLE — built once at import time.
459
480
  # ---------------------------------------------------------------------------
460
- from execsql.metacommands.dispatch import build_dispatch_table # noqa: E402
481
+ from execsql.metacommands.dispatch import build_dispatch_table
461
482
 
462
483
  DISPATCH_TABLE = build_dispatch_table()
@@ -107,6 +107,7 @@ from execsql.metacommands.io import (
107
107
  x_export_metadata,
108
108
  x_export_metadata_table,
109
109
  x_export_ods_multiple,
110
+ x_export_xlsx_multiple,
110
111
  x_export_query,
111
112
  x_export_query_with_template,
112
113
  x_export_row_buffer,
@@ -395,6 +396,16 @@ def build_dispatch_table() -> MetaCommandList:
395
396
  ),
396
397
  x_export_ods_multiple,
397
398
  )
399
+ mcl.add(
400
+ ins_table_list_rxs(
401
+ r"^\s*EXPORT\s+",
402
+ ins_fn_rxs(
403
+ r"\s+(?P<tee>TEE\s+)?(?P<append>APPEND\s+)?TO\s+",
404
+ r'\s+AS\s+XLSX(?:\s+DESCRIP(?:TION)?\s+"(?P<description>[^"]*)")?\s*$',
405
+ ),
406
+ ),
407
+ x_export_xlsx_multiple,
408
+ )
398
409
 
399
410
  # ------------------------------------------------------------------
400
411
  # IMPORT_FILE
@@ -22,6 +22,7 @@ from execsql.metacommands.io_export import ( # noqa: F401
22
22
  x_export_metadata,
23
23
  x_export_metadata_table,
24
24
  x_export_ods_multiple,
25
+ x_export_xlsx_multiple,
25
26
  x_export_query,
26
27
  x_export_query_with_template,
27
28
  x_export_row_buffer,
@@ -78,6 +79,7 @@ __all__ = [
78
79
  "x_export_metadata",
79
80
  "x_export_metadata_table",
80
81
  "x_export_ods_multiple",
82
+ "x_export_xlsx_multiple",
81
83
  "x_export_query",
82
84
  "x_export_query_with_template",
83
85
  "x_export_row_buffer",
@@ -19,6 +19,7 @@ from execsql.exporters.html import write_query_to_cgi_html, write_query_to_html
19
19
  from execsql.exporters.json import write_query_to_json, write_query_to_json_ts
20
20
  from execsql.exporters.latex import write_query_to_latex
21
21
  from execsql.exporters.ods import write_queries_to_ods, write_query_to_ods
22
+ from execsql.exporters.xlsx import write_queries_to_xlsx, write_query_to_xlsx
22
23
  from execsql.exporters.parquet import write_query_to_parquet
23
24
  from execsql.exporters.pretty import prettyprint_query, prettyprint_rowset
24
25
  from execsql.exporters.raw import write_query_b64, write_query_raw
@@ -26,6 +27,8 @@ from execsql.exporters.sqlite import write_query_to_sqlite
26
27
  from execsql.exporters.templates import report_query
27
28
  from execsql.exporters.values import write_query_to_values
28
29
  from execsql.exporters.xml import write_query_to_xml
30
+ from execsql.exporters.markdown import write_query_to_markdown
31
+ from execsql.exporters.yaml import write_query_to_yaml
29
32
  from execsql.importers.base import import_data_table
30
33
  from execsql.script import current_script_line
31
34
  from execsql.utils.errors import exception_desc
@@ -85,6 +88,8 @@ def x_export(**kwargs: Any) -> None:
85
88
  raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
86
89
  if filefmt == "ods":
87
90
  raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
91
+ if filefmt == "xlsx":
92
+ raise ErrInfo("error", other_msg="Cannot export to an XLSX workbook within a zipfile.")
88
93
  notype = bool(kwargs.get("notype"))
89
94
  if zipfilename is not None:
90
95
  check_dir(zipfilename)
@@ -120,6 +125,15 @@ def x_export(**kwargs: Any) -> None:
120
125
  sheetname=queryname,
121
126
  desc=description,
122
127
  )
128
+ elif filefmt == "xlsx":
129
+ write_query_to_xlsx(
130
+ select_stmt,
131
+ _state.dbs.current(),
132
+ outfile,
133
+ append,
134
+ sheetname=queryname,
135
+ desc=description,
136
+ )
123
137
  elif filefmt == "duckdb":
124
138
  write_query_to_duckdb(select_stmt, _state.dbs.current(), outfile, append, tablename=queryname)
125
139
  elif filefmt == "sqlite":
@@ -191,6 +205,24 @@ def x_export(**kwargs: Any) -> None:
191
205
  )
192
206
  elif filefmt == "hdf5":
193
207
  write_query_to_hdf5(table, select_stmt, _state.dbs.current(), outfile, append, desc=description)
208
+ elif filefmt == "yaml":
209
+ write_query_to_yaml(
210
+ select_stmt,
211
+ _state.dbs.current(),
212
+ outfile,
213
+ append,
214
+ desc=description,
215
+ zipfile=zipfilename,
216
+ )
217
+ elif filefmt in ("markdown", "md"):
218
+ write_query_to_markdown(
219
+ select_stmt,
220
+ _state.dbs.current(),
221
+ outfile,
222
+ append,
223
+ desc=description,
224
+ zipfile=zipfilename,
225
+ )
194
226
  else:
195
227
  try:
196
228
  hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
@@ -237,6 +269,8 @@ def x_export_query(**kwargs: Any) -> None:
237
269
  raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
238
270
  if filefmt == "ods":
239
271
  raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
272
+ if filefmt == "xlsx":
273
+ raise ErrInfo("error", other_msg="Cannot export to an XLSX workbook within a zipfile.")
240
274
  notype = bool(kwargs.get("notype"))
241
275
  check_dir(outfile)
242
276
  if tee and outfile.lower() != "stdout":
@@ -270,6 +304,16 @@ def x_export_query(**kwargs: Any) -> None:
270
304
  sheetname=f"Query_{lno}",
271
305
  desc=description,
272
306
  )
307
+ elif filefmt == "xlsx":
308
+ script_name, lno = current_script_line()
309
+ write_query_to_xlsx(
310
+ select_stmt,
311
+ _state.dbs.current(),
312
+ outfile,
313
+ append,
314
+ sheetname=f"Query_{lno}",
315
+ desc=description,
316
+ )
273
317
  elif filefmt == "json":
274
318
  write_query_to_json(
275
319
  select_stmt,
@@ -325,6 +369,24 @@ def x_export_query(**kwargs: Any) -> None:
325
369
  desc=description,
326
370
  zipfile=zipfilename,
327
371
  )
372
+ elif filefmt == "yaml":
373
+ write_query_to_yaml(
374
+ select_stmt,
375
+ _state.dbs.current(),
376
+ outfile,
377
+ append,
378
+ desc=description,
379
+ zipfile=zipfilename,
380
+ )
381
+ elif filefmt in ("markdown", "md"):
382
+ write_query_to_markdown(
383
+ select_stmt,
384
+ _state.dbs.current(),
385
+ outfile,
386
+ append,
387
+ desc=description,
388
+ zipfile=zipfilename,
389
+ )
328
390
  else:
329
391
  try:
330
392
  hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
@@ -403,6 +465,19 @@ def x_export_ods_multiple(**kwargs: Any) -> None:
403
465
  write_queries_to_ods(table_list, _state.dbs.current(), outfile, append, tee, desc=description)
404
466
 
405
467
 
468
+ def x_export_xlsx_multiple(**kwargs: Any) -> None:
469
+ """Export multiple tables to separate worksheets in a single XLSX workbook."""
470
+ table_list = kwargs["tables"]
471
+ outfile = kwargs["filename"]
472
+ description = kwargs["description"]
473
+ tee = kwargs["tee"]
474
+ tee = bool(tee)
475
+ append = kwargs["append"]
476
+ append = append is not None
477
+ check_dir(outfile)
478
+ write_queries_to_xlsx(table_list, _state.dbs.current(), outfile, append, tee, desc=description)
479
+
480
+
406
481
  def x_export_metadata(**kwargs: Any) -> None:
407
482
  outfile = kwargs["filename"]
408
483
  append = kwargs["append"] is not None