execsql2 2.1.2__py3-none-any.whl → 2.4.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.
- execsql/cli/__init__.py +436 -0
- execsql/cli/dsn.py +86 -0
- execsql/cli/help.py +140 -0
- execsql/{cli.py → cli/run.py} +14 -589
- execsql/config.py +65 -1
- execsql/db/access.py +27 -15
- execsql/db/base.py +328 -215
- execsql/db/dsn.py +10 -5
- execsql/db/duckdb.py +6 -2
- execsql/db/factory.py +21 -0
- execsql/db/firebird.py +27 -19
- execsql/db/mysql.py +12 -7
- execsql/db/oracle.py +15 -11
- execsql/db/postgres.py +31 -16
- execsql/db/sqlite.py +15 -11
- execsql/db/sqlserver.py +16 -5
- execsql/exceptions.py +25 -7
- execsql/exporters/base.py +12 -1
- execsql/exporters/delimited.py +80 -35
- execsql/exporters/duckdb.py +6 -2
- execsql/exporters/feather.py +10 -6
- execsql/exporters/html.py +89 -69
- execsql/exporters/json.py +52 -45
- execsql/exporters/latex.py +37 -27
- execsql/exporters/ods.py +32 -11
- execsql/exporters/parquet.py +5 -2
- execsql/exporters/pretty.py +16 -9
- execsql/exporters/raw.py +22 -16
- execsql/exporters/sqlite.py +6 -2
- execsql/exporters/templates.py +39 -21
- execsql/exporters/values.py +26 -20
- execsql/exporters/xls.py +30 -11
- execsql/exporters/xml.py +31 -13
- execsql/exporters/zip.py +15 -0
- execsql/importers/base.py +6 -4
- execsql/importers/csv.py +8 -6
- execsql/importers/feather.py +6 -4
- execsql/importers/ods.py +6 -4
- execsql/importers/xls.py +6 -4
- execsql/metacommands/__init__.py +208 -1548
- execsql/metacommands/conditions.py +101 -27
- execsql/metacommands/control.py +8 -4
- execsql/metacommands/data.py +6 -6
- execsql/metacommands/debug.py +6 -2
- execsql/metacommands/dispatch.py +2011 -0
- execsql/metacommands/io.py +67 -1310
- execsql/metacommands/io_export.py +442 -0
- execsql/metacommands/io_fileops.py +287 -0
- execsql/metacommands/io_import.py +398 -0
- execsql/metacommands/io_write.py +248 -0
- execsql/metacommands/prompt.py +22 -66
- execsql/metacommands/system.py +7 -2
- execsql/models.py +7 -0
- execsql/parser.py +10 -0
- execsql/py.typed +0 -0
- execsql/script/__init__.py +95 -0
- execsql/script/control.py +162 -0
- execsql/{script.py → script/engine.py} +184 -402
- execsql/script/variables.py +281 -0
- execsql/types.py +49 -20
- execsql/utils/auth.py +2 -0
- execsql/utils/crypto.py +4 -6
- execsql/utils/datetime.py +1 -0
- execsql/utils/errors.py +11 -0
- execsql/utils/fileio.py +33 -8
- execsql/utils/gui.py +46 -0
- execsql/utils/mail.py +7 -17
- execsql/utils/numeric.py +2 -0
- execsql/utils/regex.py +9 -0
- execsql/utils/strings.py +16 -0
- execsql/utils/timer.py +2 -0
- execsql2-2.4.0.data/data/execsql2_extras/README.md +65 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/execsql.conf +1 -1
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/METADATA +13 -6
- execsql2-2.4.0.dist-info/RECORD +108 -0
- execsql2-2.1.2.data/data/execsql2_extras/READ_ME.rst +0 -127
- execsql2-2.1.2.dist-info/RECORD +0 -96
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.1.2.data → execsql2-2.4.0.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/WHEEL +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/entry_points.txt +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.1.2.dist-info → execsql2-2.4.0.dist-info}/licenses/NOTICE +0 -0
execsql/metacommands/io.py
CHANGED
|
@@ -1,1313 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"""Input/output metacommand handlers for execsql.
|
|
2
|
+
|
|
3
|
+
This module is a **re-export façade**: the actual implementations live in
|
|
4
|
+
the sibling submodules listed below. All public names are imported here so
|
|
5
|
+
that existing ``from execsql.metacommands.io import x_*`` paths continue to
|
|
6
|
+
work without changes.
|
|
7
|
+
|
|
8
|
+
Submodules
|
|
9
|
+
----------
|
|
10
|
+
- :mod:`~execsql.metacommands.io_export` — EXPORT handlers
|
|
11
|
+
- :mod:`~execsql.metacommands.io_import` — IMPORT handlers
|
|
12
|
+
- :mod:`~execsql.metacommands.io_write` — WRITE / WRITESCRIPT handlers
|
|
13
|
+
- :mod:`~execsql.metacommands.io_fileops` — file ops, COPY, ZIP, INCLUDE, SERVE, etc.
|
|
4
14
|
"""
|
|
5
|
-
Input/output metacommand handlers for execsql.
|
|
6
|
-
|
|
7
|
-
Implements the ``x_*`` handler functions for all output and I/O-related
|
|
8
|
-
metacommands:
|
|
9
|
-
|
|
10
|
-
- ``x_write`` / ``x_writeln`` — WRITE messages to log or console
|
|
11
|
-
- ``x_copy_file`` — COPY FILE
|
|
12
|
-
- ``x_delete_file`` / ``x_rename_file`` — file management
|
|
13
|
-
- ``x_pause`` — PAUSE execution until user input
|
|
14
|
-
- ``x_tee_log`` — TEE LOG on/off
|
|
15
|
-
- ``x_log`` — LOG to file
|
|
16
|
-
- ``x_set_write_output`` — redirect WRITE output
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
import os
|
|
20
|
-
import sys
|
|
21
|
-
from pathlib import Path
|
|
22
|
-
from shutil import copyfileobj
|
|
23
|
-
from typing import Any
|
|
24
|
-
|
|
25
|
-
import execsql.state as _state
|
|
26
|
-
from execsql.exporters.base import ExportRecord
|
|
27
|
-
from execsql.exporters.delimited import CsvFile, write_delimited_file
|
|
28
|
-
from execsql.exporters.duckdb import write_query_to_duckdb
|
|
29
|
-
from execsql.exporters.feather import write_query_to_feather, write_query_to_hdf5
|
|
30
|
-
from execsql.exporters.parquet import write_query_to_parquet
|
|
31
|
-
from execsql.exporters.html import write_query_to_cgi_html, write_query_to_html
|
|
32
|
-
from execsql.exporters.json import write_query_to_json, write_query_to_json_ts
|
|
33
|
-
from execsql.exporters.latex import write_query_to_latex
|
|
34
|
-
from execsql.exporters.ods import OdsFile, write_queries_to_ods, write_query_to_ods
|
|
35
|
-
from execsql.exporters.pretty import prettyprint_query, prettyprint_rowset
|
|
36
|
-
from execsql.exporters.raw import write_query_b64, write_query_raw
|
|
37
|
-
from execsql.exporters.sqlite import write_query_to_sqlite
|
|
38
|
-
from execsql.exporters.templates import report_query
|
|
39
|
-
from execsql.exporters.values import write_query_to_values
|
|
40
|
-
from execsql.exporters.xls import XlsFile, XlsxFile
|
|
41
|
-
from execsql.exporters.xml import write_query_to_xml
|
|
42
|
-
from execsql.importers.base import import_data_table
|
|
43
|
-
from execsql.importers.csv import importfile, importtable
|
|
44
|
-
from execsql.importers.feather import import_feather, import_parquet
|
|
45
|
-
from execsql.importers.ods import importods, ods_data
|
|
46
|
-
from execsql.importers.xls import importxls, xls_data
|
|
47
|
-
from execsql.models import DataTable
|
|
48
|
-
from execsql.script import current_script_line, read_sqlfile, substitute_vars
|
|
49
|
-
from execsql.types import dbt_firebird
|
|
50
|
-
from execsql.utils.errors import exception_desc
|
|
51
|
-
from execsql.utils.fileio import check_dir, filewriter_close, filewriter_open_as_new, filewriter_write
|
|
52
|
-
from execsql.utils.gui import ConsoleUIError
|
|
53
|
-
from execsql.utils.strings import clean_words, fold_words, unquoted
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _apply_output_dir(path: str) -> str:
|
|
57
|
-
"""Prepend the configured --output-dir to *path* if it is a relative path.
|
|
58
|
-
|
|
59
|
-
If ``conf.export_output_dir`` is set and *path* is not absolute (and not
|
|
60
|
-
``stdout``), the base directory is joined to *path* so that all EXPORT
|
|
61
|
-
output lands in the same directory without requiring scripts to hard-code
|
|
62
|
-
absolute paths.
|
|
63
|
-
"""
|
|
64
|
-
output_dir = getattr(_state.conf, "export_output_dir", None)
|
|
65
|
-
if not output_dir:
|
|
66
|
-
return path
|
|
67
|
-
if path.lower() == "stdout":
|
|
68
|
-
return path
|
|
69
|
-
if Path(path).is_absolute():
|
|
70
|
-
return path
|
|
71
|
-
# Windows drive-letter paths are also absolute
|
|
72
|
-
if len(path) > 1 and path[1] == ":":
|
|
73
|
-
return path
|
|
74
|
-
return str(Path(output_dir) / path)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def x_export(**kwargs: Any) -> None:
|
|
78
|
-
schema = kwargs["schema"]
|
|
79
|
-
table = kwargs["table"]
|
|
80
|
-
queryname = _state.dbs.current().schema_qualified_table_name(schema, table)
|
|
81
|
-
select_stmt = f"select * from {queryname};"
|
|
82
|
-
outfile = _apply_output_dir(kwargs["filename"])
|
|
83
|
-
description = kwargs["description"]
|
|
84
|
-
tee = kwargs["tee"]
|
|
85
|
-
tee = bool(tee)
|
|
86
|
-
append = kwargs["append"]
|
|
87
|
-
append = bool(append)
|
|
88
|
-
filefmt = kwargs["format"].lower()
|
|
89
|
-
zipfilename = _apply_output_dir(kwargs["zipfilename"]) if kwargs["zipfilename"] else None
|
|
90
|
-
if zipfilename is not None:
|
|
91
|
-
if outfile.lower() == "stdout":
|
|
92
|
-
raise ErrInfo("error", other_msg="Cannot write stdout to a zipfile.")
|
|
93
|
-
elif len(outfile) > 1 and outfile[1] == ":":
|
|
94
|
-
raise ErrInfo("error", other_msg="Cannot use a drive letter for a file path within a zipfile.")
|
|
95
|
-
if filefmt == "duckdb":
|
|
96
|
-
raise ErrInfo("error", other_msg="Cannot export to the DuckDB format within a zipfile.")
|
|
97
|
-
if filefmt == "sqlite":
|
|
98
|
-
raise ErrInfo("error", other_msg="Cannot export to the SQLite format within a zipfile.")
|
|
99
|
-
if filefmt == "latex":
|
|
100
|
-
raise ErrInfo("error", other_msg="Cannot export to the LaTeX format within a zipfile.")
|
|
101
|
-
if filefmt == "feather":
|
|
102
|
-
raise ErrInfo("error", other_msg="Cannot export to the feather format within a zipfile.")
|
|
103
|
-
if filefmt == "parquet":
|
|
104
|
-
raise ErrInfo("error", other_msg="Cannot export to the parquet format within a zipfile.")
|
|
105
|
-
if filefmt == "hdf5":
|
|
106
|
-
raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
|
|
107
|
-
if filefmt == "ods":
|
|
108
|
-
raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
|
|
109
|
-
notype = bool(kwargs.get("notype"))
|
|
110
|
-
if zipfilename is not None:
|
|
111
|
-
check_dir(zipfilename)
|
|
112
|
-
else:
|
|
113
|
-
check_dir(outfile)
|
|
114
|
-
if tee and outfile.lower() != "stdout":
|
|
115
|
-
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False, desc=description)
|
|
116
|
-
if filefmt in ("txt", "text"):
|
|
117
|
-
prettyprint_query(
|
|
118
|
-
select_stmt,
|
|
119
|
-
_state.dbs.current(),
|
|
120
|
-
outfile,
|
|
121
|
-
append,
|
|
122
|
-
desc=description,
|
|
123
|
-
zipfile=zipfilename,
|
|
124
|
-
)
|
|
125
|
-
elif filefmt in ("txt-and", "text-and"):
|
|
126
|
-
prettyprint_query(
|
|
127
|
-
select_stmt,
|
|
128
|
-
_state.dbs.current(),
|
|
129
|
-
outfile,
|
|
130
|
-
append,
|
|
131
|
-
and_val="AND",
|
|
132
|
-
desc=description,
|
|
133
|
-
zipfile=zipfilename,
|
|
134
|
-
)
|
|
135
|
-
elif filefmt == "ods":
|
|
136
|
-
write_query_to_ods(
|
|
137
|
-
select_stmt,
|
|
138
|
-
_state.dbs.current(),
|
|
139
|
-
outfile,
|
|
140
|
-
append,
|
|
141
|
-
sheetname=queryname,
|
|
142
|
-
desc=description,
|
|
143
|
-
)
|
|
144
|
-
elif filefmt == "duckdb":
|
|
145
|
-
write_query_to_duckdb(select_stmt, _state.dbs.current(), outfile, append, tablename=queryname)
|
|
146
|
-
elif filefmt == "sqlite":
|
|
147
|
-
write_query_to_sqlite(select_stmt, _state.dbs.current(), outfile, append, tablename=queryname)
|
|
148
|
-
elif filefmt == "xml":
|
|
149
|
-
write_query_to_xml(
|
|
150
|
-
select_stmt,
|
|
151
|
-
table,
|
|
152
|
-
_state.dbs.current(),
|
|
153
|
-
outfile,
|
|
154
|
-
append,
|
|
155
|
-
desc=description,
|
|
156
|
-
zipfile=zipfilename,
|
|
157
|
-
)
|
|
158
|
-
elif filefmt == "json":
|
|
159
|
-
write_query_to_json(
|
|
160
|
-
select_stmt,
|
|
161
|
-
_state.dbs.current(),
|
|
162
|
-
outfile,
|
|
163
|
-
append,
|
|
164
|
-
desc=description,
|
|
165
|
-
zipfile=zipfilename,
|
|
166
|
-
)
|
|
167
|
-
elif filefmt in ("json_ts", "json_tableschema"):
|
|
168
|
-
write_query_to_json_ts(
|
|
169
|
-
select_stmt,
|
|
170
|
-
_state.dbs.current(),
|
|
171
|
-
outfile,
|
|
172
|
-
append,
|
|
173
|
-
not notype,
|
|
174
|
-
desc=description,
|
|
175
|
-
zipfile=zipfilename,
|
|
176
|
-
)
|
|
177
|
-
elif filefmt == "values":
|
|
178
|
-
write_query_to_values(
|
|
179
|
-
select_stmt,
|
|
180
|
-
_state.dbs.current(),
|
|
181
|
-
outfile,
|
|
182
|
-
append,
|
|
183
|
-
desc=description,
|
|
184
|
-
zipfile=zipfilename,
|
|
185
|
-
)
|
|
186
|
-
elif filefmt == "html":
|
|
187
|
-
write_query_to_html(
|
|
188
|
-
select_stmt,
|
|
189
|
-
_state.dbs.current(),
|
|
190
|
-
outfile,
|
|
191
|
-
append,
|
|
192
|
-
desc=description,
|
|
193
|
-
zipfile=zipfilename,
|
|
194
|
-
)
|
|
195
|
-
elif filefmt == "cgi-html":
|
|
196
|
-
write_query_to_cgi_html(
|
|
197
|
-
select_stmt,
|
|
198
|
-
_state.dbs.current(),
|
|
199
|
-
outfile,
|
|
200
|
-
append,
|
|
201
|
-
desc=description,
|
|
202
|
-
zipfile=zipfilename,
|
|
203
|
-
)
|
|
204
|
-
elif filefmt == "latex":
|
|
205
|
-
write_query_to_latex(
|
|
206
|
-
select_stmt,
|
|
207
|
-
_state.dbs.current(),
|
|
208
|
-
outfile,
|
|
209
|
-
append,
|
|
210
|
-
desc=description,
|
|
211
|
-
zipfile=zipfilename,
|
|
212
|
-
)
|
|
213
|
-
elif filefmt == "hdf5":
|
|
214
|
-
write_query_to_hdf5(table, select_stmt, _state.dbs.current(), outfile, append, desc=description)
|
|
215
|
-
else:
|
|
216
|
-
try:
|
|
217
|
-
hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
|
|
218
|
-
except ErrInfo:
|
|
219
|
-
raise
|
|
220
|
-
except Exception:
|
|
221
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
222
|
-
if filefmt == "raw":
|
|
223
|
-
write_query_raw(outfile, rows, _state.dbs.current().encoding, append, zipfile=zipfilename)
|
|
224
|
-
elif filefmt == "b64":
|
|
225
|
-
write_query_b64(outfile, rows, append)
|
|
226
|
-
elif filefmt == "feather":
|
|
227
|
-
write_query_to_feather(outfile, hdrs, rows)
|
|
228
|
-
elif filefmt == "parquet":
|
|
229
|
-
write_query_to_parquet(outfile, hdrs, rows)
|
|
230
|
-
else:
|
|
231
|
-
write_delimited_file(outfile, filefmt, hdrs, rows, _state.conf.output_encoding, append, zipfilename)
|
|
232
|
-
_state.export_metadata.add(ExportRecord(queryname, outfile, zipfilename, description))
|
|
233
|
-
return None
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def x_export_query(**kwargs: Any) -> None:
|
|
237
|
-
select_stmt = kwargs["query"]
|
|
238
|
-
outfile = kwargs["filename"]
|
|
239
|
-
description = kwargs["description"]
|
|
240
|
-
tee = kwargs["tee"]
|
|
241
|
-
tee = bool(tee)
|
|
242
|
-
append = kwargs["append"]
|
|
243
|
-
append = bool(append)
|
|
244
|
-
filefmt = kwargs["format"].lower()
|
|
245
|
-
zipfilename = kwargs["zipfilename"]
|
|
246
|
-
if zipfilename is not None:
|
|
247
|
-
if outfile == "stdout":
|
|
248
|
-
raise ErrInfo("error", other_msg="Cannot write stdout to a zipfile.")
|
|
249
|
-
elif len(outfile) > 1 and outfile[1] == ":":
|
|
250
|
-
raise ErrInfo("error", other_msg="Cannot use a drive letter for a file path within a zipfile.")
|
|
251
|
-
if filefmt == "latex":
|
|
252
|
-
raise ErrInfo("error", other_msg="Cannot export to the LaTeX format within a zipfile.")
|
|
253
|
-
if filefmt == "feather":
|
|
254
|
-
raise ErrInfo("error", other_msg="Cannot export to the feather format within a zipfile.")
|
|
255
|
-
if filefmt == "parquet":
|
|
256
|
-
raise ErrInfo("error", other_msg="Cannot export to the parquet format within a zipfile.")
|
|
257
|
-
if filefmt == "hdf5":
|
|
258
|
-
raise ErrInfo("error", other_msg="Cannot export to the HDF5 format within a zipfile.")
|
|
259
|
-
if filefmt == "ods":
|
|
260
|
-
raise ErrInfo("error", other_msg="Cannot export to an ODS workbook within a zipfile.")
|
|
261
|
-
notype = bool(kwargs.get("notype"))
|
|
262
|
-
check_dir(outfile)
|
|
263
|
-
if tee and outfile.lower() != "stdout":
|
|
264
|
-
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False, desc=description)
|
|
265
|
-
if filefmt in ("txt", "text"):
|
|
266
|
-
prettyprint_query(
|
|
267
|
-
select_stmt,
|
|
268
|
-
_state.dbs.current(),
|
|
269
|
-
outfile,
|
|
270
|
-
append,
|
|
271
|
-
desc=description,
|
|
272
|
-
zipfile=zipfilename,
|
|
273
|
-
)
|
|
274
|
-
elif filefmt in ("txt-and", "text-and"):
|
|
275
|
-
prettyprint_query(
|
|
276
|
-
select_stmt,
|
|
277
|
-
_state.dbs.current(),
|
|
278
|
-
outfile,
|
|
279
|
-
append,
|
|
280
|
-
and_val="AND",
|
|
281
|
-
desc=description,
|
|
282
|
-
zipfile=zipfilename,
|
|
283
|
-
)
|
|
284
|
-
elif filefmt == "ods":
|
|
285
|
-
script_name, lno = current_script_line()
|
|
286
|
-
write_query_to_ods(
|
|
287
|
-
select_stmt,
|
|
288
|
-
_state.dbs.current(),
|
|
289
|
-
outfile,
|
|
290
|
-
append,
|
|
291
|
-
sheetname=f"Query_{lno}",
|
|
292
|
-
desc=description,
|
|
293
|
-
)
|
|
294
|
-
elif filefmt == "json":
|
|
295
|
-
write_query_to_json(
|
|
296
|
-
select_stmt,
|
|
297
|
-
_state.dbs.current(),
|
|
298
|
-
outfile,
|
|
299
|
-
append,
|
|
300
|
-
desc=description,
|
|
301
|
-
zipfile=zipfilename,
|
|
302
|
-
)
|
|
303
|
-
elif filefmt in ("json_ts", "json_tableschema"):
|
|
304
|
-
write_query_to_json_ts(
|
|
305
|
-
select_stmt,
|
|
306
|
-
_state.dbs.current(),
|
|
307
|
-
outfile,
|
|
308
|
-
append,
|
|
309
|
-
not notype,
|
|
310
|
-
desc=description,
|
|
311
|
-
zipfile=zipfilename,
|
|
312
|
-
)
|
|
313
|
-
elif filefmt == "values":
|
|
314
|
-
write_query_to_values(
|
|
315
|
-
select_stmt,
|
|
316
|
-
_state.dbs.current(),
|
|
317
|
-
outfile,
|
|
318
|
-
append,
|
|
319
|
-
desc=description,
|
|
320
|
-
zipfile=zipfilename,
|
|
321
|
-
)
|
|
322
|
-
elif filefmt == "html":
|
|
323
|
-
write_query_to_html(
|
|
324
|
-
select_stmt,
|
|
325
|
-
_state.dbs.current(),
|
|
326
|
-
outfile,
|
|
327
|
-
append,
|
|
328
|
-
desc=description,
|
|
329
|
-
zipfile=zipfilename,
|
|
330
|
-
)
|
|
331
|
-
elif filefmt == "cgi-html":
|
|
332
|
-
write_query_to_cgi_html(
|
|
333
|
-
select_stmt,
|
|
334
|
-
_state.dbs.current(),
|
|
335
|
-
outfile,
|
|
336
|
-
append,
|
|
337
|
-
desc=description,
|
|
338
|
-
zipfile=zipfilename,
|
|
339
|
-
)
|
|
340
|
-
elif filefmt == "latex":
|
|
341
|
-
write_query_to_latex(
|
|
342
|
-
select_stmt,
|
|
343
|
-
_state.dbs.current(),
|
|
344
|
-
outfile,
|
|
345
|
-
append,
|
|
346
|
-
desc=description,
|
|
347
|
-
zipfile=zipfilename,
|
|
348
|
-
)
|
|
349
|
-
else:
|
|
350
|
-
try:
|
|
351
|
-
hdrs, rows = _state.dbs.current().select_rowsource(select_stmt)
|
|
352
|
-
except ErrInfo:
|
|
353
|
-
raise
|
|
354
|
-
except Exception:
|
|
355
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
356
|
-
if filefmt == "raw":
|
|
357
|
-
write_query_raw(outfile, rows, _state.dbs.current().encoding, append, zipfile=zipfilename)
|
|
358
|
-
elif filefmt == "b64":
|
|
359
|
-
write_query_b64(outfile, rows, append, zipfile=zipfilename)
|
|
360
|
-
elif filefmt == "feather":
|
|
361
|
-
write_query_to_feather(outfile, hdrs, rows)
|
|
362
|
-
elif filefmt == "parquet":
|
|
363
|
-
write_query_to_parquet(outfile, hdrs, rows)
|
|
364
|
-
else:
|
|
365
|
-
write_delimited_file(
|
|
366
|
-
outfile,
|
|
367
|
-
filefmt,
|
|
368
|
-
hdrs,
|
|
369
|
-
rows,
|
|
370
|
-
_state.conf.output_encoding,
|
|
371
|
-
append,
|
|
372
|
-
zipfile=zipfilename,
|
|
373
|
-
)
|
|
374
|
-
_state.export_metadata.add(ExportRecord(select_stmt, outfile, zipfilename, description))
|
|
375
|
-
return None
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
def x_export_query_with_template(**kwargs: Any) -> None:
|
|
379
|
-
select_stmt = kwargs["query"]
|
|
380
|
-
outfile = kwargs["filename"]
|
|
381
|
-
template_file = kwargs["template"]
|
|
382
|
-
tee = kwargs["tee"]
|
|
383
|
-
tee = bool(tee)
|
|
384
|
-
append = kwargs["append"]
|
|
385
|
-
append = bool(append)
|
|
386
|
-
zipfilename = kwargs["zipfilename"]
|
|
387
|
-
check_dir(outfile)
|
|
388
|
-
if tee and outfile.lower() != "stdout":
|
|
389
|
-
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False)
|
|
390
|
-
report_query(select_stmt, _state.dbs.current(), outfile, template_file, append, zipfile=zipfilename)
|
|
391
|
-
_state.export_metadata.add(ExportRecord(select_stmt, outfile, zipfilename))
|
|
392
|
-
return None
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
def x_export_with_template(**kwargs: Any) -> None:
|
|
396
|
-
schema = kwargs["schema"]
|
|
397
|
-
table = kwargs["table"]
|
|
398
|
-
queryname = _state.dbs.current().schema_qualified_table_name(schema, table)
|
|
399
|
-
select_stmt = f"select * from {queryname};"
|
|
400
|
-
outfile = kwargs["filename"]
|
|
401
|
-
template_file = kwargs["template"]
|
|
402
|
-
tee = kwargs["tee"]
|
|
403
|
-
tee = bool(tee)
|
|
404
|
-
append = kwargs["append"]
|
|
405
|
-
append = bool(append)
|
|
406
|
-
zipfilename = kwargs["zipfilename"]
|
|
407
|
-
check_dir(outfile)
|
|
408
|
-
if tee and outfile.lower() != "stdout":
|
|
409
|
-
prettyprint_query(select_stmt, _state.dbs.current(), "stdout", False)
|
|
410
|
-
report_query(select_stmt, _state.dbs.current(), outfile, template_file, append, zipfile=zipfilename)
|
|
411
|
-
_state.export_metadata.add(ExportRecord(queryname, outfile, zipfilename))
|
|
412
|
-
return None
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
def x_export_ods_multiple(**kwargs: Any) -> None:
|
|
416
|
-
table_list = kwargs["tables"]
|
|
417
|
-
outfile = kwargs["filename"]
|
|
418
|
-
description = kwargs["description"]
|
|
419
|
-
tee = kwargs["tee"]
|
|
420
|
-
tee = bool(tee)
|
|
421
|
-
append = kwargs["append"]
|
|
422
|
-
append = append is not None
|
|
423
|
-
check_dir(outfile)
|
|
424
|
-
write_queries_to_ods(table_list, _state.dbs.current(), outfile, append, tee, desc=description)
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
def x_export_metadata(**kwargs: Any) -> None:
|
|
428
|
-
outfile = kwargs["filename"]
|
|
429
|
-
append = kwargs["append"] is not None
|
|
430
|
-
xall = kwargs["all"] is not None
|
|
431
|
-
zipfilename = kwargs["zipfilename"]
|
|
432
|
-
filefmt = kwargs["format"].lower()
|
|
433
|
-
if xall:
|
|
434
|
-
hdrs, rows = _state.export_metadata.get_all()
|
|
435
|
-
else:
|
|
436
|
-
hdrs, rows = _state.export_metadata.get()
|
|
437
|
-
if outfile.lower() != "stdout":
|
|
438
|
-
check_dir(outfile)
|
|
439
|
-
if filefmt in ("txt", "text"):
|
|
440
|
-
prettyprint_rowset(hdrs, rows, outfile, append, and_val="", zipfile=zipfilename)
|
|
441
|
-
else:
|
|
442
|
-
write_delimited_file(outfile, filefmt, hdrs, rows, _state.conf.output_encoding, append, zipfilename)
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
def x_export_metadata_table(**kwargs: Any) -> None:
|
|
446
|
-
xall = kwargs["all"] is not None
|
|
447
|
-
schemaname = kwargs["schema"]
|
|
448
|
-
tablename = kwargs["table"]
|
|
449
|
-
newstr = kwargs["new"]
|
|
450
|
-
if newstr:
|
|
451
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
452
|
-
else:
|
|
453
|
-
is_new = 0
|
|
454
|
-
if xall:
|
|
455
|
-
hdrs, rows = _state.export_metadata.get_all()
|
|
456
|
-
else:
|
|
457
|
-
hdrs, rows = _state.export_metadata.get()
|
|
458
|
-
import_data_table(_state.dbs.current(), schemaname, tablename, is_new, hdrs, rows)
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
def x_import(**kwargs: Any) -> None:
|
|
462
|
-
newstr = kwargs["new"]
|
|
463
|
-
if newstr:
|
|
464
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
465
|
-
else:
|
|
466
|
-
is_new = 0
|
|
467
|
-
schemaname = kwargs["schema"]
|
|
468
|
-
tablename = kwargs["table"]
|
|
469
|
-
filename = kwargs["filename"]
|
|
470
|
-
if len(filename) > 1 and filename[0] == "~" and filename[1] == os.sep:
|
|
471
|
-
filename = str(Path.home() / filename[2:])
|
|
472
|
-
if not Path(filename).exists():
|
|
473
|
-
raise ErrInfo(
|
|
474
|
-
type="cmd",
|
|
475
|
-
command_text=kwargs["metacommandline"],
|
|
476
|
-
other_msg=f"Input file {filename} does not exist",
|
|
477
|
-
)
|
|
478
|
-
quotechar = kwargs["quotechar"]
|
|
479
|
-
if quotechar:
|
|
480
|
-
quotechar = quotechar.lower()
|
|
481
|
-
delimchar = kwargs["delimchar"]
|
|
482
|
-
if delimchar:
|
|
483
|
-
if delimchar.lower() == "tab":
|
|
484
|
-
delimchar = chr(9)
|
|
485
|
-
elif delimchar.lower() in ("unitsep", "us"):
|
|
486
|
-
delimchar = chr(31)
|
|
487
|
-
enc = kwargs["encoding"]
|
|
488
|
-
junk_hdrs = kwargs["skip"]
|
|
489
|
-
if not junk_hdrs:
|
|
490
|
-
junk_hdrs = 0
|
|
491
|
-
else:
|
|
492
|
-
junk_hdrs = int(junk_hdrs)
|
|
493
|
-
from execsql.metacommands.conditions import file_size_date
|
|
494
|
-
|
|
495
|
-
sz, dt = file_size_date(filename)
|
|
496
|
-
_state.exec_log.log_status_info(f"IMPORTing {filename} ({sz}, {dt})")
|
|
497
|
-
try:
|
|
498
|
-
importtable(
|
|
499
|
-
_state.dbs.current(),
|
|
500
|
-
schemaname,
|
|
501
|
-
tablename,
|
|
502
|
-
filename,
|
|
503
|
-
is_new,
|
|
504
|
-
skip_header_line=True,
|
|
505
|
-
quotechar=quotechar,
|
|
506
|
-
delimchar=delimchar,
|
|
507
|
-
encoding=enc,
|
|
508
|
-
junk_header_lines=junk_hdrs,
|
|
509
|
-
)
|
|
510
|
-
except ErrInfo:
|
|
511
|
-
raise
|
|
512
|
-
except Exception:
|
|
513
|
-
raise ErrInfo(
|
|
514
|
-
"exception",
|
|
515
|
-
exception_msg=exception_desc(),
|
|
516
|
-
other_msg=f"Can't import data from tabular text file {filename}",
|
|
517
|
-
)
|
|
518
|
-
return None
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
def x_import_file(**kwargs: Any) -> None:
|
|
522
|
-
schemaname = kwargs["schema"]
|
|
523
|
-
tablename = kwargs["table"]
|
|
524
|
-
columnname = kwargs["columnname"]
|
|
525
|
-
filename = kwargs["filename"]
|
|
526
|
-
if not Path(filename).exists():
|
|
527
|
-
raise ErrInfo(
|
|
528
|
-
type="cmd",
|
|
529
|
-
command_text=kwargs["metacommandline"],
|
|
530
|
-
other_msg=f"Input file {filename} does not exist",
|
|
531
|
-
)
|
|
532
|
-
from execsql.metacommands.conditions import file_size_date
|
|
533
|
-
|
|
534
|
-
sz, dt = file_size_date(filename)
|
|
535
|
-
_state.exec_log.log_status_info(f"IMPORTing_FILE {filename} ({sz}, {dt})")
|
|
536
|
-
try:
|
|
537
|
-
importfile(_state.dbs.current(), schemaname, tablename, columnname, filename)
|
|
538
|
-
except ErrInfo:
|
|
539
|
-
raise
|
|
540
|
-
except Exception:
|
|
541
|
-
raise ErrInfo(
|
|
542
|
-
"exception",
|
|
543
|
-
exception_msg=exception_desc(),
|
|
544
|
-
other_msg=f"Can't import file {filename}",
|
|
545
|
-
)
|
|
546
|
-
return None
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
def x_import_ods(**kwargs: Any) -> None:
|
|
550
|
-
newstr = kwargs["new"]
|
|
551
|
-
if newstr:
|
|
552
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
553
|
-
else:
|
|
554
|
-
is_new = 0
|
|
555
|
-
schemaname = kwargs["schema"]
|
|
556
|
-
tablename = kwargs["table"]
|
|
557
|
-
filename = kwargs["filename"]
|
|
558
|
-
sheetname = kwargs["sheetname"]
|
|
559
|
-
hdr_rows = kwargs["skip"]
|
|
560
|
-
if not hdr_rows:
|
|
561
|
-
hdr_rows = 0
|
|
562
|
-
else:
|
|
563
|
-
hdr_rows = int(hdr_rows)
|
|
564
|
-
if not Path(filename).exists():
|
|
565
|
-
raise ErrInfo(
|
|
566
|
-
type="cmd",
|
|
567
|
-
command_text=kwargs["metacommandline"],
|
|
568
|
-
other_msg="Input file does not exist",
|
|
569
|
-
)
|
|
570
|
-
try:
|
|
571
|
-
importods(_state.dbs.current(), schemaname, tablename, is_new, filename, sheetname, hdr_rows)
|
|
572
|
-
except ErrInfo:
|
|
573
|
-
raise
|
|
574
|
-
except Exception:
|
|
575
|
-
raise ErrInfo(
|
|
576
|
-
"exception",
|
|
577
|
-
exception_msg=exception_desc(),
|
|
578
|
-
other_msg=f"Can't import data from ODS file {filename}",
|
|
579
|
-
)
|
|
580
|
-
return None
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
def x_import_ods_pattern(**kwargs: Any) -> None:
|
|
584
|
-
import re
|
|
585
|
-
|
|
586
|
-
newstr = kwargs["new"]
|
|
587
|
-
if newstr:
|
|
588
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
589
|
-
else:
|
|
590
|
-
is_new = 0
|
|
591
|
-
schemaname = kwargs["schema"]
|
|
592
|
-
filename = kwargs["filename"]
|
|
593
|
-
rx = re.compile(kwargs["patn"], re.I)
|
|
594
|
-
hdr_rows = kwargs["skip"]
|
|
595
|
-
if not hdr_rows:
|
|
596
|
-
hdr_rows = 0
|
|
597
|
-
else:
|
|
598
|
-
hdr_rows = int(hdr_rows)
|
|
599
|
-
if not Path(filename).exists():
|
|
600
|
-
raise ErrInfo(
|
|
601
|
-
type="cmd",
|
|
602
|
-
command_text=kwargs["metacommandline"],
|
|
603
|
-
other_msg="Input file does not exist",
|
|
604
|
-
)
|
|
605
|
-
wbk = OdsFile()
|
|
606
|
-
try:
|
|
607
|
-
wbk.open(filename)
|
|
608
|
-
except Exception:
|
|
609
|
-
raise ErrInfo(type="cmd", other_msg=f"{filename} is not a valid OpenDocument spreadsheet.")
|
|
610
|
-
sheets = wbk.sheetnames()
|
|
611
|
-
impsheets = [s for s in sheets if rx.search(s)]
|
|
612
|
-
tables = list(impsheets)
|
|
613
|
-
if _state.conf.clean_col_hdrs:
|
|
614
|
-
tables = clean_words(tables)
|
|
615
|
-
if _state.conf.fold_col_hdrs != "no":
|
|
616
|
-
tables = fold_words(tables, _state.conf.fold_col_hdrs)
|
|
617
|
-
for ix in range(len(impsheets)):
|
|
618
|
-
sheetname = impsheets[ix]
|
|
619
|
-
tablename = tables[ix]
|
|
620
|
-
try:
|
|
621
|
-
importods(_state.dbs.current(), schemaname, tablename, is_new, filename, sheetname, hdr_rows)
|
|
622
|
-
except ErrInfo:
|
|
623
|
-
raise
|
|
624
|
-
except Exception:
|
|
625
|
-
raise ErrInfo(
|
|
626
|
-
"exception",
|
|
627
|
-
exception_msg=exception_desc(),
|
|
628
|
-
other_msg=f"Can't import data from ODS file {filename}",
|
|
629
|
-
)
|
|
630
|
-
_state.subvars.add_substitution("$SHEETS_IMPORTED", ",".join(impsheets))
|
|
631
|
-
_state.subvars.add_substitution("$SHEETS_TABLES", ",".join(tables))
|
|
632
|
-
if schemaname is None:
|
|
633
|
-
_state.subvars.add_substitution("$SHEETS_TABLES_VALUES", ",".join([f"('{t}')" for t in tables]))
|
|
634
|
-
else:
|
|
635
|
-
_state.subvars.add_substitution("$SHEETS_TABLES_VALUES", ",".join([f"('{schemaname}.{t}')" for t in tables]))
|
|
636
|
-
return None
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
def x_import_xls(**kwargs: Any) -> None:
|
|
640
|
-
newstr = kwargs["new"]
|
|
641
|
-
if newstr:
|
|
642
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
643
|
-
else:
|
|
644
|
-
is_new = 0
|
|
645
|
-
schemaname = kwargs["schema"]
|
|
646
|
-
tablename = kwargs["table"]
|
|
647
|
-
filename = kwargs["filename"]
|
|
648
|
-
sheetname = kwargs["sheetname"]
|
|
649
|
-
junk_hdrs = kwargs["skip"]
|
|
650
|
-
encoding = kwargs["encoding"]
|
|
651
|
-
if not junk_hdrs:
|
|
652
|
-
junk_hdrs = 0
|
|
653
|
-
else:
|
|
654
|
-
junk_hdrs = int(junk_hdrs)
|
|
655
|
-
if not Path(filename).exists():
|
|
656
|
-
raise ErrInfo(
|
|
657
|
-
type="cmd",
|
|
658
|
-
command_text=kwargs["metacommandline"],
|
|
659
|
-
other_msg="Input file does not exist",
|
|
660
|
-
)
|
|
661
|
-
try:
|
|
662
|
-
importxls(_state.dbs.current(), schemaname, tablename, is_new, filename, sheetname, junk_hdrs, encoding)
|
|
663
|
-
except ErrInfo:
|
|
664
|
-
raise
|
|
665
|
-
except Exception:
|
|
666
|
-
raise ErrInfo(
|
|
667
|
-
"exception",
|
|
668
|
-
exception_msg=exception_desc(),
|
|
669
|
-
other_msg=f"Can't import data from Excel file {filename}",
|
|
670
|
-
)
|
|
671
|
-
return None
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
def x_import_xls_pattern(**kwargs: Any) -> None:
|
|
675
|
-
import re
|
|
676
|
-
|
|
677
|
-
newstr = kwargs["new"]
|
|
678
|
-
if newstr:
|
|
679
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
680
|
-
else:
|
|
681
|
-
is_new = 0
|
|
682
|
-
schemaname = kwargs["schema"]
|
|
683
|
-
filename = kwargs["filename"]
|
|
684
|
-
rx = re.compile(kwargs["patn"], re.I)
|
|
685
|
-
hdr_rows = kwargs["skip"]
|
|
686
|
-
encoding = kwargs["encoding"]
|
|
687
|
-
if not hdr_rows:
|
|
688
|
-
hdr_rows = 0
|
|
689
|
-
else:
|
|
690
|
-
hdr_rows = int(hdr_rows)
|
|
691
|
-
if not Path(filename).exists():
|
|
692
|
-
raise ErrInfo(
|
|
693
|
-
type="cmd",
|
|
694
|
-
command_text=kwargs["metacommandline"],
|
|
695
|
-
other_msg="Input file does not exist",
|
|
696
|
-
)
|
|
697
|
-
if len(filename) < 4:
|
|
698
|
-
raise ErrInfo(type="cmd", other_msg=f"{filename} is not a recognizable Excel spreadsheet name.")
|
|
699
|
-
ext3 = filename[-3:].lower()
|
|
700
|
-
if ext3 == "xls":
|
|
701
|
-
wbk = XlsFile()
|
|
702
|
-
elif ext3 == "lsx":
|
|
703
|
-
wbk = XlsxFile()
|
|
704
|
-
else:
|
|
705
|
-
raise ErrInfo(type="cmd", other_msg=f"{filename} is not a recognizable Excel spreadsheet name.")
|
|
706
|
-
try:
|
|
707
|
-
wbk.open(filename, encoding, read_only=True)
|
|
708
|
-
except Exception:
|
|
709
|
-
raise ErrInfo(type="cmd", other_msg=f"{filename} is not a valid Excel spreadsheet.")
|
|
710
|
-
sheets = wbk.sheetnames()
|
|
711
|
-
impsheets = [s for s in sheets if rx.search(s)]
|
|
712
|
-
tables = list(impsheets)
|
|
713
|
-
if _state.conf.clean_col_hdrs:
|
|
714
|
-
tables = clean_words(tables)
|
|
715
|
-
if _state.conf.fold_col_hdrs != "no":
|
|
716
|
-
tables = fold_words(tables, _state.conf.fold_col_hdrs)
|
|
717
|
-
for ix in range(len(impsheets)):
|
|
718
|
-
sheetname = impsheets[ix]
|
|
719
|
-
tablename = tables[ix]
|
|
720
|
-
try:
|
|
721
|
-
importxls(
|
|
722
|
-
_state.dbs.current(),
|
|
723
|
-
schemaname,
|
|
724
|
-
tablename,
|
|
725
|
-
is_new,
|
|
726
|
-
filename,
|
|
727
|
-
sheetname,
|
|
728
|
-
hdr_rows,
|
|
729
|
-
encoding,
|
|
730
|
-
)
|
|
731
|
-
except ErrInfo:
|
|
732
|
-
raise
|
|
733
|
-
except Exception:
|
|
734
|
-
raise ErrInfo(
|
|
735
|
-
"exception",
|
|
736
|
-
exception_msg=exception_desc(),
|
|
737
|
-
other_msg=f"Can't import data from ODS file {filename}",
|
|
738
|
-
)
|
|
739
|
-
_state.subvars.add_substitution("$SHEETS_IMPORTED", ",".join(impsheets))
|
|
740
|
-
_state.subvars.add_substitution("$SHEETS_TABLES", ",".join(tables))
|
|
741
|
-
if schemaname is None:
|
|
742
|
-
_state.subvars.add_substitution("$SHEETS_TABLES_VALUES", ",".join([f"('{t}')" for t in tables]))
|
|
743
|
-
else:
|
|
744
|
-
_state.subvars.add_substitution("$SHEETS_TABLES_VALUES", ",".join([f"('{schemaname}.{t}')" for t in tables]))
|
|
745
|
-
return None
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
def x_import_parquet(**kwargs: Any) -> None:
|
|
749
|
-
newstr = kwargs["new"]
|
|
750
|
-
if newstr:
|
|
751
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
752
|
-
else:
|
|
753
|
-
is_new = 0
|
|
754
|
-
schemaname = kwargs["schema"]
|
|
755
|
-
tablename = kwargs["table"]
|
|
756
|
-
filename = kwargs["filename"]
|
|
757
|
-
if len(filename) > 1 and filename[0] == "~" and filename[1] == os.sep:
|
|
758
|
-
filename = str(Path.home() / filename[2:])
|
|
759
|
-
if not Path(filename).exists():
|
|
760
|
-
raise ErrInfo(
|
|
761
|
-
type="cmd",
|
|
762
|
-
command_text=kwargs["metacommandline"],
|
|
763
|
-
other_msg=f"Input file {filename} does not exist",
|
|
764
|
-
)
|
|
765
|
-
from execsql.metacommands.conditions import file_size_date
|
|
766
|
-
|
|
767
|
-
sz, dt = file_size_date(filename)
|
|
768
|
-
_state.exec_log.log_status_info(f"IMPORTing from Parquet file {filename} ({sz}, {dt})")
|
|
769
|
-
try:
|
|
770
|
-
import_parquet(_state.dbs.current(), schemaname, tablename, filename, is_new)
|
|
771
|
-
except ErrInfo:
|
|
772
|
-
raise
|
|
773
|
-
except Exception:
|
|
774
|
-
raise ErrInfo(
|
|
775
|
-
"exception",
|
|
776
|
-
exception_msg=exception_desc(),
|
|
777
|
-
other_msg=f"Can't import data from Parquet data file {filename}",
|
|
778
|
-
)
|
|
779
|
-
return None
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
def x_import_feather(**kwargs: Any) -> None:
|
|
783
|
-
newstr = kwargs["new"]
|
|
784
|
-
if newstr:
|
|
785
|
-
is_new = 1 + ["new", "replacement"].index(newstr.lower())
|
|
786
|
-
else:
|
|
787
|
-
is_new = 0
|
|
788
|
-
schemaname = kwargs["schema"]
|
|
789
|
-
tablename = kwargs["table"]
|
|
790
|
-
filename = kwargs["filename"]
|
|
791
|
-
if len(filename) > 1 and filename[0] == "~" and filename[1] == os.sep:
|
|
792
|
-
filename = str(Path.home() / filename[2:])
|
|
793
|
-
if not Path(filename).exists():
|
|
794
|
-
raise ErrInfo(
|
|
795
|
-
type="cmd",
|
|
796
|
-
command_text=kwargs["metacommandline"],
|
|
797
|
-
other_msg=f"Input file {filename} does not exist",
|
|
798
|
-
)
|
|
799
|
-
from execsql.metacommands.conditions import file_size_date
|
|
800
|
-
|
|
801
|
-
sz, dt = file_size_date(filename)
|
|
802
|
-
_state.exec_log.log_status_info(f"IMPORTing from Feather file {filename} ({sz}, {dt})")
|
|
803
|
-
try:
|
|
804
|
-
import_feather(_state.dbs.current(), schemaname, tablename, filename, is_new)
|
|
805
|
-
except ErrInfo:
|
|
806
|
-
raise
|
|
807
|
-
except Exception:
|
|
808
|
-
raise ErrInfo(
|
|
809
|
-
"exception",
|
|
810
|
-
exception_msg=exception_desc(),
|
|
811
|
-
other_msg=f"Can't import data from Feather data file {filename}",
|
|
812
|
-
)
|
|
813
|
-
return None
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
def x_import_row_buffer(**kwargs: Any) -> None:
|
|
817
|
-
rows = kwargs["rows"]
|
|
818
|
-
_state.conf.import_row_buffer = int(rows)
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
def x_export_row_buffer(**kwargs: Any) -> None:
|
|
822
|
-
rows = kwargs["rows"]
|
|
823
|
-
_state.conf.export_row_buffer = int(rows)
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
def x_write(**kwargs: Any) -> None:
|
|
827
|
-
msg = f"{kwargs['text']}\n"
|
|
828
|
-
tee = kwargs["tee"]
|
|
829
|
-
tee = bool(tee)
|
|
830
|
-
outf = kwargs["filename"]
|
|
831
|
-
if _state.conf.write_prefix is not None:
|
|
832
|
-
msg = substitute_vars(_state.conf.write_prefix) + " " + msg
|
|
833
|
-
if _state.conf.write_suffix is not None:
|
|
834
|
-
msg = msg[:-1] + " " + substitute_vars(_state.conf.write_suffix) + "\n"
|
|
835
|
-
if outf:
|
|
836
|
-
check_dir(outf)
|
|
837
|
-
filewriter_write(outf, msg)
|
|
838
|
-
if (not outf) or tee:
|
|
839
|
-
try:
|
|
840
|
-
_state.output.write(msg)
|
|
841
|
-
except TypeError:
|
|
842
|
-
raise ErrInfo(
|
|
843
|
-
type="other",
|
|
844
|
-
command_text=kwargs["metacommandline"],
|
|
845
|
-
other_msg="TypeError in 'write' metacommand.",
|
|
846
|
-
)
|
|
847
|
-
except ConsoleUIError as e:
|
|
848
|
-
_state.output.reset()
|
|
849
|
-
_state.exec_log.log_status_info(f"Console UI write failed (message {{{e.value}}}); output reset to stdout.")
|
|
850
|
-
_state.output.write(msg.encode(_state.conf.output_encoding))
|
|
851
|
-
if _state.conf.tee_write_log:
|
|
852
|
-
_state.exec_log.log_user_msg(msg)
|
|
853
|
-
return None
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
def x_write_create_table(**kwargs: Any) -> None:
|
|
857
|
-
filename = kwargs["filename"]
|
|
858
|
-
if not Path(filename).exists():
|
|
859
|
-
raise ErrInfo(
|
|
860
|
-
type="cmd",
|
|
861
|
-
command_text=kwargs["metacommandline"],
|
|
862
|
-
other_msg="Input file does not exist",
|
|
863
|
-
)
|
|
864
|
-
quotechar = kwargs["quotechar"]
|
|
865
|
-
delimchar = kwargs["delimchar"]
|
|
866
|
-
encoding = kwargs["encoding"]
|
|
867
|
-
if delimchar:
|
|
868
|
-
if delimchar.lower() == "tab":
|
|
869
|
-
delimchar = chr(9)
|
|
870
|
-
elif delimchar.lower() in ("unitsep", "us"):
|
|
871
|
-
delimchar = chr(31)
|
|
872
|
-
junk_hdrs = kwargs["skip"]
|
|
873
|
-
if not junk_hdrs:
|
|
874
|
-
junk_hdrs = 0
|
|
875
|
-
else:
|
|
876
|
-
junk_hdrs = int(junk_hdrs)
|
|
877
|
-
enc = encoding if encoding else _state.conf.import_encoding
|
|
878
|
-
inf = CsvFile(filename, enc, junk_header_lines=junk_hdrs)
|
|
879
|
-
if quotechar and delimchar:
|
|
880
|
-
inf.lineformat(delimchar, quotechar, None)
|
|
881
|
-
inf.evaluate_column_types()
|
|
882
|
-
sql = inf.create_table(_state.dbs.current().type, kwargs["schema"], kwargs["table"], pretty=True)
|
|
883
|
-
inf.close()
|
|
884
|
-
comment = kwargs["comment"]
|
|
885
|
-
outfile = kwargs["outfile"]
|
|
886
|
-
|
|
887
|
-
def write(txt: str) -> None:
|
|
888
|
-
if outfile is None or outfile == "stdout":
|
|
889
|
-
_state.output.write(txt)
|
|
890
|
-
else:
|
|
891
|
-
filewriter_write(outfile, txt)
|
|
892
|
-
|
|
893
|
-
if outfile:
|
|
894
|
-
check_dir(outfile)
|
|
895
|
-
if comment:
|
|
896
|
-
write(f"-- {comment}\n")
|
|
897
|
-
write(f"{sql}\n")
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
def x_write_create_table_ods(**kwargs: Any) -> None:
|
|
901
|
-
schemaname = kwargs["schema"]
|
|
902
|
-
tablename = kwargs["table"]
|
|
903
|
-
filename = kwargs["filename"]
|
|
904
|
-
sheetname = kwargs["sheet"]
|
|
905
|
-
hdr_rows = kwargs["skip"]
|
|
906
|
-
if not hdr_rows:
|
|
907
|
-
hdr_rows = 0
|
|
908
|
-
else:
|
|
909
|
-
hdr_rows = int(hdr_rows)
|
|
910
|
-
comment = kwargs["comment"]
|
|
911
|
-
outfile = kwargs["outfile"]
|
|
912
|
-
if not Path(filename).exists():
|
|
913
|
-
raise ErrInfo(
|
|
914
|
-
type="cmd",
|
|
915
|
-
command_text=kwargs["metacommandline"],
|
|
916
|
-
other_msg="Input file does not exist",
|
|
917
|
-
)
|
|
918
|
-
hdrs, data = ods_data(filename, sheetname, hdr_rows)
|
|
919
|
-
tablespec = DataTable(hdrs, data)
|
|
920
|
-
sql = tablespec.create_table(_state.dbs.current().type, schemaname, tablename, pretty=True)
|
|
921
|
-
if outfile:
|
|
922
|
-
if comment:
|
|
923
|
-
filewriter_write(outfile, f"-- {comment}\n")
|
|
924
|
-
filewriter_write(outfile, sql)
|
|
925
|
-
filewriter_close(outfile)
|
|
926
|
-
else:
|
|
927
|
-
if comment:
|
|
928
|
-
_state.output.write(f"-- {comment}\n")
|
|
929
|
-
_state.output.write(f"{sql}\n")
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
def x_write_create_table_xls(**kwargs: Any) -> None:
|
|
933
|
-
schemaname = kwargs["schema"]
|
|
934
|
-
tablename = kwargs["table"]
|
|
935
|
-
filename = kwargs["filename"]
|
|
936
|
-
sheetname = kwargs["sheet"]
|
|
937
|
-
junk_hdrs = kwargs["skip"]
|
|
938
|
-
encoding = kwargs["encoding"]
|
|
939
|
-
enc = encoding if encoding else _state.conf.import_encoding
|
|
940
|
-
if not junk_hdrs:
|
|
941
|
-
junk_hdrs = 0
|
|
942
|
-
else:
|
|
943
|
-
junk_hdrs = int(junk_hdrs)
|
|
944
|
-
comment = kwargs["comment"]
|
|
945
|
-
outfile = kwargs["outfile"]
|
|
946
|
-
if not Path(filename).exists():
|
|
947
|
-
raise ErrInfo(
|
|
948
|
-
type="cmd",
|
|
949
|
-
command_text=kwargs["metacommandline"],
|
|
950
|
-
other_msg="Input file does not exist",
|
|
951
|
-
)
|
|
952
|
-
hdrs, data = xls_data(filename, sheetname, junk_hdrs, enc)
|
|
953
|
-
tablespec = DataTable(hdrs, data)
|
|
954
|
-
sql = tablespec.create_table(_state.dbs.current().type, schemaname, tablename, pretty=True)
|
|
955
|
-
if outfile:
|
|
956
|
-
if comment:
|
|
957
|
-
filewriter_write(outfile, f"-- {comment}\n")
|
|
958
|
-
filewriter_write(outfile, sql)
|
|
959
|
-
filewriter_close(outfile)
|
|
960
|
-
else:
|
|
961
|
-
if comment:
|
|
962
|
-
_state.output.write(f"-- {comment}\n")
|
|
963
|
-
_state.output.write(f"{sql}\n")
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
def x_write_create_table_alias(**kwargs: Any) -> None:
|
|
967
|
-
alias = kwargs["alias"].lower()
|
|
968
|
-
schema = kwargs["schema"]
|
|
969
|
-
table = kwargs["table"]
|
|
970
|
-
comment = kwargs["comment"]
|
|
971
|
-
outfile = kwargs["filename"]
|
|
972
|
-
if alias not in _state.dbs.aliases():
|
|
973
|
-
raise ErrInfo(
|
|
974
|
-
type="cmd",
|
|
975
|
-
command_text=kwargs["metacommandline"],
|
|
976
|
-
other_msg=f"Unrecognized database alias: {alias}.",
|
|
977
|
-
)
|
|
978
|
-
db = _state.dbs.aliased_as(alias)
|
|
979
|
-
tbl = db.schema_qualified_table_name(schema, table)
|
|
980
|
-
try:
|
|
981
|
-
if not db.table_exists(table, schema):
|
|
982
|
-
raise ErrInfo(
|
|
983
|
-
type="cmd",
|
|
984
|
-
command_text=kwargs["metacommandline"],
|
|
985
|
-
other_msg=f"Table {tbl} does not exist",
|
|
986
|
-
)
|
|
987
|
-
except Exception:
|
|
988
|
-
pass # Best-effort check; some adapters lack information_schema.
|
|
989
|
-
select_stmt = f"select * from {tbl};"
|
|
990
|
-
try:
|
|
991
|
-
hdrs, rows = db.select_rowsource(select_stmt)
|
|
992
|
-
except ErrInfo:
|
|
993
|
-
raise
|
|
994
|
-
except Exception:
|
|
995
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
996
|
-
tablespec = DataTable(hdrs, rows)
|
|
997
|
-
sql = tablespec.create_table(_state.dbs.current().type, kwargs["schema1"], kwargs["table1"], pretty=True)
|
|
998
|
-
if outfile:
|
|
999
|
-
if comment:
|
|
1000
|
-
filewriter_write(outfile, f"-- {comment}\n")
|
|
1001
|
-
filewriter_write(outfile, sql)
|
|
1002
|
-
filewriter_close(outfile)
|
|
1003
|
-
else:
|
|
1004
|
-
if comment:
|
|
1005
|
-
_state.output.write(f"-- {comment}\n")
|
|
1006
|
-
_state.output.write(f"{sql}\n")
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
def x_write_prefix(**kwargs: Any) -> None:
|
|
1010
|
-
pf = kwargs["prefix"]
|
|
1011
|
-
if pf.lower() == "clear":
|
|
1012
|
-
_state.conf.write_prefix = None
|
|
1013
|
-
else:
|
|
1014
|
-
_state.conf.write_prefix = pf
|
|
1015
|
-
return None
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
def x_write_suffix(**kwargs: Any) -> None:
|
|
1019
|
-
sf = kwargs["suffix"]
|
|
1020
|
-
if sf.lower() == "clear":
|
|
1021
|
-
_state.conf.write_suffix = None
|
|
1022
|
-
else:
|
|
1023
|
-
_state.conf.write_suffix = sf
|
|
1024
|
-
return None
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
def x_writescript(**kwargs: Any) -> None:
|
|
1028
|
-
script_id = kwargs["script_id"]
|
|
1029
|
-
output_dest = kwargs["filename"]
|
|
1030
|
-
append = kwargs["append"]
|
|
1031
|
-
|
|
1032
|
-
def write(txt: str) -> None:
|
|
1033
|
-
if output_dest is None or output_dest == "stdout":
|
|
1034
|
-
_state.output.write(txt)
|
|
1035
|
-
else:
|
|
1036
|
-
filewriter_write(output_dest, txt)
|
|
1037
|
-
|
|
1038
|
-
if output_dest is not None and output_dest != "stdout":
|
|
1039
|
-
check_dir(output_dest)
|
|
1040
|
-
if not append:
|
|
1041
|
-
filewriter_open_as_new(output_dest)
|
|
1042
|
-
script = _state.savedscripts[script_id]
|
|
1043
|
-
if script.paramnames is not None and len(script.paramnames) > 0:
|
|
1044
|
-
write(f"BEGIN SCRIPT {script_id} ({', '.join(script.paramnames)})\n")
|
|
1045
|
-
else:
|
|
1046
|
-
write(f"BEGIN SCRIPT {script_id}\n")
|
|
1047
|
-
lines = [c.commandline() for c in script.cmdlist]
|
|
1048
|
-
for line in lines:
|
|
1049
|
-
write(f"{line}\n")
|
|
1050
|
-
write(f"END SCRIPT {script_id}\n")
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
def x_include(**kwargs: Any) -> None:
|
|
1054
|
-
filename = kwargs["filename"]
|
|
1055
|
-
if len(filename) > 1 and filename[0] == "~" and filename[1] == os.sep:
|
|
1056
|
-
filename = str(Path.home() / filename[2:])
|
|
1057
|
-
exists = kwargs["exists"]
|
|
1058
|
-
if exists is not None:
|
|
1059
|
-
if Path(filename).is_file():
|
|
1060
|
-
read_sqlfile(filename)
|
|
1061
|
-
else:
|
|
1062
|
-
if not Path(filename).is_file():
|
|
1063
|
-
raise ErrInfo(type="error", other_msg=f"File {filename} does not exist.")
|
|
1064
|
-
read_sqlfile(filename)
|
|
1065
|
-
return None
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
def x_copy(**kwargs: Any) -> None:
|
|
1069
|
-
alias1 = kwargs["alias1"].lower()
|
|
1070
|
-
schema1 = kwargs["schema1"]
|
|
1071
|
-
table1 = kwargs["table1"]
|
|
1072
|
-
new = kwargs["new"]
|
|
1073
|
-
new_tbl2 = new.lower() if new else None
|
|
1074
|
-
alias2 = kwargs["alias2"].lower()
|
|
1075
|
-
schema2 = kwargs["schema2"]
|
|
1076
|
-
table2 = kwargs["table2"]
|
|
1077
|
-
if alias1 not in _state.dbs.aliases():
|
|
1078
|
-
raise ErrInfo(
|
|
1079
|
-
type="cmd",
|
|
1080
|
-
command_text=kwargs["metacommandline"],
|
|
1081
|
-
other_msg=f"Unrecognized database alias: {alias1}.",
|
|
1082
|
-
)
|
|
1083
|
-
if alias2 not in _state.dbs.aliases():
|
|
1084
|
-
raise ErrInfo(
|
|
1085
|
-
type="cmd",
|
|
1086
|
-
command_text=kwargs["metacommandline"],
|
|
1087
|
-
other_msg=f"Unrecognized database alias: {alias2}.",
|
|
1088
|
-
)
|
|
1089
|
-
db1 = _state.dbs.aliased_as(alias1)
|
|
1090
|
-
db2 = _state.dbs.aliased_as(alias2)
|
|
1091
|
-
tbl1 = db1.schema_qualified_table_name(schema1, table1)
|
|
1092
|
-
tbl2 = db2.schema_qualified_table_name(schema2, table2)
|
|
1093
|
-
try:
|
|
1094
|
-
if not db1.table_exists(table1, schema1):
|
|
1095
|
-
raise ErrInfo(
|
|
1096
|
-
type="cmd",
|
|
1097
|
-
command_text=kwargs["metacommandline"],
|
|
1098
|
-
other_msg=f"Table {tbl1} does not exist",
|
|
1099
|
-
)
|
|
1100
|
-
except Exception:
|
|
1101
|
-
pass # Best-effort check; some adapters lack information_schema.
|
|
1102
|
-
if new_tbl2 and new_tbl2 == "new":
|
|
1103
|
-
try:
|
|
1104
|
-
if db2.table_exists(table2, schema2):
|
|
1105
|
-
raise ErrInfo(
|
|
1106
|
-
type="cmd",
|
|
1107
|
-
command_text=kwargs["metacommandline"],
|
|
1108
|
-
other_msg=f"Table {tbl2} already exists",
|
|
1109
|
-
)
|
|
1110
|
-
except Exception:
|
|
1111
|
-
pass # Best-effort check; some adapters lack information_schema.
|
|
1112
|
-
select_stmt = f"select * from {tbl1};"
|
|
1113
|
-
|
|
1114
|
-
def get_ts() -> DataTable:
|
|
1115
|
-
if get_ts.tablespec is None:
|
|
1116
|
-
hdrs, rows = db1.select_rowsource(select_stmt)
|
|
1117
|
-
get_ts.tablespec = DataTable(hdrs, rows)
|
|
1118
|
-
return get_ts.tablespec
|
|
1119
|
-
|
|
1120
|
-
get_ts.tablespec = None
|
|
1121
|
-
|
|
1122
|
-
if new_tbl2:
|
|
1123
|
-
tbl_desc = get_ts()
|
|
1124
|
-
create_tbl = tbl_desc.create_table(db2.type, schema2, table2)
|
|
1125
|
-
if new_tbl2 == "replacement":
|
|
1126
|
-
try:
|
|
1127
|
-
db2.drop_table(tbl2)
|
|
1128
|
-
except Exception:
|
|
1129
|
-
_state.exec_log.log_status_info(f"Could not drop existing table ({tbl2}) for COPY metacommand")
|
|
1130
|
-
db2.execute(create_tbl)
|
|
1131
|
-
if db2.type == dbt_firebird:
|
|
1132
|
-
db2.execute("COMMIT;")
|
|
1133
|
-
try:
|
|
1134
|
-
hdrs, rows = db1.select_rowsource(select_stmt)
|
|
1135
|
-
except ErrInfo:
|
|
1136
|
-
raise
|
|
1137
|
-
except Exception:
|
|
1138
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
1139
|
-
try:
|
|
1140
|
-
db2.populate_table(schema2, table2, rows, hdrs, get_ts)
|
|
1141
|
-
db2.commit()
|
|
1142
|
-
except ErrInfo:
|
|
1143
|
-
raise
|
|
1144
|
-
except Exception:
|
|
1145
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
def x_copy_query(**kwargs: Any) -> None:
|
|
1149
|
-
alias1 = kwargs["alias1"].lower()
|
|
1150
|
-
select_stmt = kwargs["query"]
|
|
1151
|
-
new = kwargs["new"]
|
|
1152
|
-
new_tbl2 = new.lower() if new else None
|
|
1153
|
-
alias2 = kwargs["alias2"].lower()
|
|
1154
|
-
schema2 = kwargs["schema"]
|
|
1155
|
-
table2 = kwargs["table"]
|
|
1156
|
-
if alias1 not in _state.dbs.aliases():
|
|
1157
|
-
raise ErrInfo(
|
|
1158
|
-
type="cmd",
|
|
1159
|
-
command_text=kwargs["metacommandline"],
|
|
1160
|
-
other_msg=f"Unrecognized database alias: {alias1}.",
|
|
1161
|
-
)
|
|
1162
|
-
if alias2 not in _state.dbs.aliases():
|
|
1163
|
-
raise ErrInfo(
|
|
1164
|
-
type="cmd",
|
|
1165
|
-
command_text=kwargs["metacommandline"],
|
|
1166
|
-
other_msg=f"Unrecognized database alias: {alias2}.",
|
|
1167
|
-
)
|
|
1168
|
-
db1 = _state.dbs.aliased_as(alias1)
|
|
1169
|
-
db2 = _state.dbs.aliased_as(alias2)
|
|
1170
|
-
tbl2 = db2.schema_qualified_table_name(schema2, table2)
|
|
1171
|
-
if new_tbl2 and new_tbl2 == "new":
|
|
1172
|
-
try:
|
|
1173
|
-
if db2.table_exists(table2, schema2):
|
|
1174
|
-
raise ErrInfo(
|
|
1175
|
-
type="cmd",
|
|
1176
|
-
command_text=kwargs["metacommandline"],
|
|
1177
|
-
other_msg=f"Table {tbl2} already exists",
|
|
1178
|
-
)
|
|
1179
|
-
except Exception:
|
|
1180
|
-
pass # Best-effort check; some adapters lack information_schema.
|
|
1181
|
-
|
|
1182
|
-
def get_ts() -> DataTable:
|
|
1183
|
-
if not get_ts.tablespec:
|
|
1184
|
-
hdrs, rows = db1.select_rowsource(select_stmt)
|
|
1185
|
-
get_ts.tablespec = DataTable(hdrs, rows)
|
|
1186
|
-
return get_ts.tablespec
|
|
1187
|
-
|
|
1188
|
-
get_ts.tablespec = None
|
|
1189
|
-
|
|
1190
|
-
if new_tbl2:
|
|
1191
|
-
try:
|
|
1192
|
-
hdrs, rows = db1.select_rowsource(select_stmt)
|
|
1193
|
-
except ErrInfo:
|
|
1194
|
-
raise
|
|
1195
|
-
except Exception:
|
|
1196
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
1197
|
-
get_ts.tablespec = DataTable(hdrs, rows)
|
|
1198
|
-
tbl_desc = get_ts.tablespec
|
|
1199
|
-
create_tbl = tbl_desc.create_table(db2.type, schema2, table2)
|
|
1200
|
-
if new_tbl2 == "replacement":
|
|
1201
|
-
try:
|
|
1202
|
-
db2.drop_table(tbl2)
|
|
1203
|
-
except Exception:
|
|
1204
|
-
_state.exec_log.log_status_info(f"Could not drop existing table ({tbl2}) for COPY metacommand")
|
|
1205
|
-
db2.execute(create_tbl)
|
|
1206
|
-
if db2.type == dbt_firebird:
|
|
1207
|
-
db2.execute("COMMIT;")
|
|
1208
|
-
try:
|
|
1209
|
-
hdrs, rows = db1.select_rowsource(select_stmt)
|
|
1210
|
-
except ErrInfo:
|
|
1211
|
-
raise
|
|
1212
|
-
except Exception:
|
|
1213
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
1214
|
-
try:
|
|
1215
|
-
db2.populate_table(schema2, table2, rows, hdrs, get_ts)
|
|
1216
|
-
db2.commit()
|
|
1217
|
-
except ErrInfo:
|
|
1218
|
-
raise
|
|
1219
|
-
except Exception:
|
|
1220
|
-
raise ErrInfo("db", select_stmt, exception_msg=exception_desc())
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
def x_zip(**kwargs: Any) -> None:
|
|
1224
|
-
import zipfile as _zipfile
|
|
1225
|
-
import glob as _glob
|
|
1226
|
-
|
|
1227
|
-
files = kwargs["filename"].strip(' "')
|
|
1228
|
-
zipfile_name = kwargs["zipfilename"].strip(' "')
|
|
1229
|
-
append = kwargs["append"]
|
|
1230
|
-
zmode = "a" if append is not None else "w"
|
|
1231
|
-
zf = _zipfile.ZipFile(zipfile_name, mode=zmode, compression=_zipfile.ZIP_BZIP2, compresslevel=9)
|
|
1232
|
-
fnlist = _glob.glob(files)
|
|
1233
|
-
for f in fnlist:
|
|
1234
|
-
if Path(f).is_file():
|
|
1235
|
-
zf.write(f)
|
|
1236
|
-
zf.close()
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
def x_zip_buffer_mb(**kwargs: Any) -> None:
|
|
1240
|
-
size_mb = kwargs["size"]
|
|
1241
|
-
_state.conf.zip_buffer_mb = int(size_mb)
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
def x_rm_file(**kwargs: Any) -> None:
|
|
1245
|
-
import glob as _glob
|
|
1246
|
-
|
|
1247
|
-
fn = kwargs["filename"].strip(' "')
|
|
1248
|
-
fnlist = _glob.glob(fn)
|
|
1249
|
-
for f in fnlist:
|
|
1250
|
-
if Path(f).is_file():
|
|
1251
|
-
filewriter_close(f)
|
|
1252
|
-
os.unlink(f)
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
def x_make_export_dirs(**kwargs: Any) -> None:
|
|
1256
|
-
setting = kwargs["setting"].lower()
|
|
1257
|
-
_state.conf.make_export_dirs = setting in ("yes", "on", "true", "1")
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
def x_cd(**kwargs: Any) -> None:
|
|
1261
|
-
new_dir = unquoted(kwargs["dir"])
|
|
1262
|
-
if not Path(new_dir).is_dir():
|
|
1263
|
-
raise ErrInfo(
|
|
1264
|
-
type="cmd",
|
|
1265
|
-
command_text=kwargs["metacommandline"],
|
|
1266
|
-
other_msg="Directory does not exist",
|
|
1267
|
-
)
|
|
1268
|
-
os.chdir(new_dir)
|
|
1269
|
-
script, lno = current_script_line()
|
|
1270
|
-
_state.exec_log.log_status_info(f"Current directory changed to {new_dir} at line {lno} of {script}")
|
|
1271
|
-
return None
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
def x_scan_lines(**kwargs: Any) -> None:
|
|
1275
|
-
_state.conf.scan_lines = int(kwargs["scanlines"])
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
def x_hdf5_text_len(**kwargs: Any) -> None:
|
|
1279
|
-
_state.conf.hdf5_text_len = int(kwargs["textlen"])
|
|
1280
15
|
|
|
16
|
+
from __future__ import annotations
|
|
1281
17
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
18
|
+
# -- export handlers ---------------------------------------------------------
|
|
19
|
+
from execsql.metacommands.io_export import ( # noqa: F401
|
|
20
|
+
_apply_output_dir,
|
|
21
|
+
x_export,
|
|
22
|
+
x_export_metadata,
|
|
23
|
+
x_export_metadata_table,
|
|
24
|
+
x_export_ods_multiple,
|
|
25
|
+
x_export_query,
|
|
26
|
+
x_export_query_with_template,
|
|
27
|
+
x_export_row_buffer,
|
|
28
|
+
x_export_with_template,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# -- import handlers ---------------------------------------------------------
|
|
32
|
+
from execsql.metacommands.io_import import ( # noqa: F401
|
|
33
|
+
x_import,
|
|
34
|
+
x_import_feather,
|
|
35
|
+
x_import_file,
|
|
36
|
+
x_import_ods,
|
|
37
|
+
x_import_ods_pattern,
|
|
38
|
+
x_import_parquet,
|
|
39
|
+
x_import_row_buffer,
|
|
40
|
+
x_import_xls,
|
|
41
|
+
x_show_progress,
|
|
42
|
+
x_import_xls_pattern,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# -- write handlers ----------------------------------------------------------
|
|
46
|
+
from execsql.metacommands.io_write import ( # noqa: F401
|
|
47
|
+
x_write,
|
|
48
|
+
x_write_create_table,
|
|
49
|
+
x_write_create_table_alias,
|
|
50
|
+
x_write_create_table_ods,
|
|
51
|
+
x_write_create_table_xls,
|
|
52
|
+
x_write_prefix,
|
|
53
|
+
x_write_suffix,
|
|
54
|
+
x_writescript,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# -- file / system operation handlers ----------------------------------------
|
|
58
|
+
from execsql.metacommands.io_fileops import ( # noqa: F401
|
|
59
|
+
x_cd,
|
|
60
|
+
x_copy,
|
|
61
|
+
x_copy_query,
|
|
62
|
+
x_hdf5_text_len,
|
|
63
|
+
x_include,
|
|
64
|
+
x_make_export_dirs,
|
|
65
|
+
x_rm_file,
|
|
66
|
+
x_scan_lines,
|
|
67
|
+
x_serve,
|
|
68
|
+
x_zip,
|
|
69
|
+
x_zip_buffer_mb,
|
|
70
|
+
)
|