execsql2 2.0.1__py3-none-any.whl → 2.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- execsql/cli.py +322 -108
- execsql/config.py +134 -114
- execsql/db/access.py +89 -65
- execsql/db/base.py +97 -68
- execsql/db/dsn.py +45 -29
- execsql/db/duckdb.py +4 -5
- execsql/db/factory.py +27 -27
- execsql/db/firebird.py +30 -18
- execsql/db/mysql.py +38 -14
- execsql/db/oracle.py +58 -33
- execsql/db/postgres.py +68 -28
- execsql/db/sqlite.py +36 -27
- execsql/db/sqlserver.py +45 -30
- execsql/exceptions.py +68 -64
- execsql/exporters/__init__.py +1 -1
- execsql/exporters/base.py +42 -17
- execsql/exporters/delimited.py +60 -59
- execsql/exporters/duckdb.py +8 -12
- execsql/exporters/feather.py +32 -24
- execsql/exporters/html.py +33 -30
- execsql/exporters/json.py +18 -17
- execsql/exporters/latex.py +11 -13
- execsql/exporters/ods.py +50 -46
- execsql/exporters/parquet.py +32 -0
- execsql/exporters/pretty.py +16 -15
- execsql/exporters/raw.py +9 -11
- execsql/exporters/sqlite.py +38 -38
- execsql/exporters/templates.py +15 -72
- execsql/exporters/values.py +13 -12
- execsql/exporters/xls.py +26 -26
- execsql/exporters/xml.py +12 -12
- execsql/exporters/zip.py +0 -3
- execsql/gui/__init__.py +2 -2
- execsql/gui/console.py +0 -1
- execsql/gui/desktop.py +6 -7
- execsql/gui/tui.py +8 -14
- execsql/importers/base.py +6 -9
- execsql/importers/csv.py +10 -17
- execsql/importers/feather.py +16 -22
- execsql/importers/ods.py +3 -4
- execsql/importers/xls.py +5 -6
- execsql/metacommands/__init__.py +8 -8
- execsql/metacommands/conditions.py +41 -33
- execsql/metacommands/connect.py +113 -99
- execsql/metacommands/control.py +38 -26
- execsql/metacommands/data.py +35 -33
- execsql/metacommands/debug.py +13 -9
- execsql/metacommands/io.py +288 -229
- execsql/metacommands/prompt.py +179 -157
- execsql/metacommands/script_ext.py +11 -9
- execsql/metacommands/system.py +44 -25
- execsql/models.py +9 -16
- execsql/parser.py +10 -10
- execsql/script.py +183 -157
- execsql/state.py +170 -208
- execsql/types.py +46 -81
- execsql/utils/auth.py +114 -14
- execsql/utils/crypto.py +31 -4
- execsql/utils/datetime.py +7 -7
- execsql/utils/errors.py +34 -29
- execsql/utils/fileio.py +90 -55
- execsql/utils/gui.py +22 -23
- execsql/utils/mail.py +15 -17
- execsql/utils/numeric.py +2 -3
- execsql/utils/regex.py +9 -12
- execsql/utils/strings.py +10 -12
- execsql/utils/timer.py +0 -2
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/execsql.conf +1 -1
- execsql2-2.1.2.dist-info/METADATA +300 -0
- execsql2-2.1.2.dist-info/RECORD +96 -0
- execsql2-2.0.1.dist-info/METADATA +0 -406
- execsql2-2.0.1.dist-info/RECORD +0 -95
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/READ_ME.rst +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/WHEEL +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/entry_points.txt +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/NOTICE +0 -0
execsql/metacommands/connect.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from execsql.db.access import AccessDatabase
|
|
2
3
|
|
|
3
4
|
"""
|
|
4
5
|
Database connection metacommand handlers for execsql.
|
|
@@ -19,30 +20,43 @@ database connections at script runtime:
|
|
|
19
20
|
- ``x_close_db`` — ``CLOSE DATABASE <alias>``
|
|
20
21
|
"""
|
|
21
22
|
|
|
23
|
+
from pathlib import Path
|
|
22
24
|
from typing import Any
|
|
23
25
|
|
|
24
26
|
import execsql.state as _state
|
|
27
|
+
from execsql.db.dsn import DsnDatabase
|
|
28
|
+
from execsql.db.duckdb import DuckDBDatabase
|
|
29
|
+
from execsql.db.firebird import FirebirdDatabase
|
|
30
|
+
from execsql.db.mysql import MySQLDatabase
|
|
31
|
+
from execsql.db.oracle import OracleDatabase
|
|
32
|
+
from execsql.db.postgres import PostgresDatabase
|
|
33
|
+
from execsql.db.sqlite import SQLiteDatabase
|
|
34
|
+
from execsql.db.sqlserver import SqlServerDatabase
|
|
35
|
+
from execsql.exceptions import ErrInfo
|
|
36
|
+
from execsql.types import dbt_postgres
|
|
37
|
+
from execsql.utils.fileio import check_dir
|
|
38
|
+
from execsql.utils.strings import unquoted2
|
|
25
39
|
|
|
26
40
|
|
|
27
41
|
def x_connect_pg(**kwargs: Any) -> None:
|
|
28
42
|
need_pwd = kwargs["need_pwd"]
|
|
29
43
|
if need_pwd:
|
|
30
|
-
need_pwd =
|
|
44
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
31
45
|
portno = kwargs["port"]
|
|
32
46
|
if portno:
|
|
33
|
-
portno = int(
|
|
34
|
-
server =
|
|
35
|
-
db_name =
|
|
47
|
+
portno = int(unquoted2(portno))
|
|
48
|
+
server = unquoted2(kwargs["server"])
|
|
49
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
36
50
|
user = kwargs["user"]
|
|
37
51
|
if user:
|
|
38
|
-
user =
|
|
52
|
+
user = unquoted2(user)
|
|
39
53
|
mk_new = kwargs["new"]
|
|
40
|
-
mk_new =
|
|
54
|
+
mk_new = unquoted2(mk_new).lower() == "new" if mk_new else False
|
|
41
55
|
pw = kwargs["password"]
|
|
42
56
|
enc = kwargs["encoding"]
|
|
43
57
|
if enc:
|
|
44
|
-
enc =
|
|
45
|
-
new_db =
|
|
58
|
+
enc = unquoted2(enc)
|
|
59
|
+
new_db = PostgresDatabase(
|
|
46
60
|
server,
|
|
47
61
|
db_name,
|
|
48
62
|
user,
|
|
@@ -53,7 +67,7 @@ def x_connect_pg(**kwargs: Any) -> None:
|
|
|
53
67
|
password=pw,
|
|
54
68
|
)
|
|
55
69
|
else:
|
|
56
|
-
new_db =
|
|
70
|
+
new_db = PostgresDatabase(
|
|
57
71
|
server,
|
|
58
72
|
db_name,
|
|
59
73
|
user,
|
|
@@ -69,15 +83,15 @@ def x_connect_pg(**kwargs: Any) -> None:
|
|
|
69
83
|
def x_connect_user_pg(**kwargs: Any) -> None:
|
|
70
84
|
portno = kwargs["port"]
|
|
71
85
|
if portno:
|
|
72
|
-
portno = int(
|
|
73
|
-
server =
|
|
74
|
-
db_name =
|
|
86
|
+
portno = int(unquoted2(portno))
|
|
87
|
+
server = unquoted2(kwargs["server"])
|
|
88
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
75
89
|
user = _state.dbs.current().user if _state.dbs.current().user else None
|
|
76
90
|
pw = _state.upass
|
|
77
91
|
enc = kwargs["encoding"]
|
|
78
92
|
if enc:
|
|
79
|
-
enc =
|
|
80
|
-
new_db =
|
|
93
|
+
enc = unquoted2(enc)
|
|
94
|
+
new_db = PostgresDatabase(
|
|
81
95
|
server,
|
|
82
96
|
db_name,
|
|
83
97
|
user,
|
|
@@ -88,7 +102,7 @@ def x_connect_user_pg(**kwargs: Any) -> None:
|
|
|
88
102
|
password=pw,
|
|
89
103
|
)
|
|
90
104
|
else:
|
|
91
|
-
new_db =
|
|
105
|
+
new_db = PostgresDatabase(
|
|
92
106
|
server,
|
|
93
107
|
db_name,
|
|
94
108
|
user,
|
|
@@ -102,24 +116,24 @@ def x_connect_user_pg(**kwargs: Any) -> None:
|
|
|
102
116
|
|
|
103
117
|
|
|
104
118
|
def x_connect_ssvr(**kwargs: Any) -> None:
|
|
105
|
-
server =
|
|
106
|
-
db_name =
|
|
119
|
+
server = unquoted2(kwargs["server"])
|
|
120
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
107
121
|
user = kwargs["user"]
|
|
108
122
|
if user:
|
|
109
|
-
user =
|
|
123
|
+
user = unquoted2(user)
|
|
110
124
|
need_pwd = kwargs["need_pwd"]
|
|
111
125
|
pw = kwargs["password"]
|
|
112
126
|
if pw is not None:
|
|
113
|
-
pw =
|
|
127
|
+
pw = unquoted2(pw)
|
|
114
128
|
if need_pwd:
|
|
115
|
-
need_pwd =
|
|
129
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
116
130
|
portno = kwargs["port"]
|
|
117
131
|
if portno:
|
|
118
|
-
portno = int(
|
|
132
|
+
portno = int(unquoted2(portno))
|
|
119
133
|
encoding = kwargs["encoding"]
|
|
120
134
|
if encoding:
|
|
121
|
-
encoding =
|
|
122
|
-
new_db =
|
|
135
|
+
encoding = unquoted2(encoding)
|
|
136
|
+
new_db = SqlServerDatabase(
|
|
123
137
|
server,
|
|
124
138
|
db_name,
|
|
125
139
|
user_name=user,
|
|
@@ -135,15 +149,15 @@ def x_connect_ssvr(**kwargs: Any) -> None:
|
|
|
135
149
|
def x_connect_user_ssvr(**kwargs: Any) -> None:
|
|
136
150
|
portno = kwargs["port"]
|
|
137
151
|
if portno:
|
|
138
|
-
portno = int(
|
|
139
|
-
server =
|
|
140
|
-
db_name =
|
|
152
|
+
portno = int(unquoted2(portno))
|
|
153
|
+
server = unquoted2(kwargs["server"])
|
|
154
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
141
155
|
user = _state.dbs.current().user if _state.dbs.current().user else None
|
|
142
156
|
pw = _state.upass
|
|
143
157
|
enc = kwargs["encoding"]
|
|
144
158
|
if enc:
|
|
145
|
-
enc =
|
|
146
|
-
new_db =
|
|
159
|
+
enc = unquoted2(enc)
|
|
160
|
+
new_db = SqlServerDatabase(
|
|
147
161
|
server,
|
|
148
162
|
db_name,
|
|
149
163
|
user,
|
|
@@ -153,7 +167,7 @@ def x_connect_user_ssvr(**kwargs: Any) -> None:
|
|
|
153
167
|
password=pw,
|
|
154
168
|
)
|
|
155
169
|
else:
|
|
156
|
-
new_db =
|
|
170
|
+
new_db = SqlServerDatabase(
|
|
157
171
|
server,
|
|
158
172
|
db_name,
|
|
159
173
|
user_name=user,
|
|
@@ -167,24 +181,24 @@ def x_connect_user_ssvr(**kwargs: Any) -> None:
|
|
|
167
181
|
|
|
168
182
|
|
|
169
183
|
def x_connect_mysql(**kwargs: Any) -> None:
|
|
170
|
-
server =
|
|
171
|
-
db_name =
|
|
184
|
+
server = unquoted2(kwargs["server"])
|
|
185
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
172
186
|
user = kwargs["user"]
|
|
173
187
|
if user:
|
|
174
|
-
user =
|
|
188
|
+
user = unquoted2(user)
|
|
175
189
|
need_pwd = kwargs["need_pwd"]
|
|
176
190
|
if need_pwd:
|
|
177
|
-
need_pwd =
|
|
191
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
178
192
|
portno = kwargs["port"]
|
|
179
193
|
if portno:
|
|
180
|
-
portno = int(
|
|
194
|
+
portno = int(unquoted2(portno))
|
|
181
195
|
pw = kwargs["password"]
|
|
182
196
|
if pw:
|
|
183
|
-
pw =
|
|
197
|
+
pw = unquoted2(pw)
|
|
184
198
|
enc = kwargs["encoding"]
|
|
185
199
|
if enc:
|
|
186
|
-
enc =
|
|
187
|
-
new_db =
|
|
200
|
+
enc = unquoted2(enc)
|
|
201
|
+
new_db = MySQLDatabase(
|
|
188
202
|
server,
|
|
189
203
|
db_name,
|
|
190
204
|
user,
|
|
@@ -194,7 +208,7 @@ def x_connect_mysql(**kwargs: Any) -> None:
|
|
|
194
208
|
password=pw,
|
|
195
209
|
)
|
|
196
210
|
else:
|
|
197
|
-
new_db =
|
|
211
|
+
new_db = MySQLDatabase(
|
|
198
212
|
server,
|
|
199
213
|
db_name,
|
|
200
214
|
user,
|
|
@@ -209,15 +223,15 @@ def x_connect_mysql(**kwargs: Any) -> None:
|
|
|
209
223
|
def x_connect_user_mysql(**kwargs: Any) -> None:
|
|
210
224
|
portno = kwargs["port"]
|
|
211
225
|
if portno:
|
|
212
|
-
portno = int(
|
|
213
|
-
server =
|
|
214
|
-
db_name =
|
|
226
|
+
portno = int(unquoted2(portno))
|
|
227
|
+
server = unquoted2(kwargs["server"])
|
|
228
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
215
229
|
user = _state.dbs.current().user if _state.dbs.current().user else None
|
|
216
230
|
pw = _state.upass
|
|
217
231
|
enc = kwargs["encoding"]
|
|
218
232
|
if enc:
|
|
219
|
-
enc =
|
|
220
|
-
new_db =
|
|
233
|
+
enc = unquoted2(enc)
|
|
234
|
+
new_db = MySQLDatabase(
|
|
221
235
|
server,
|
|
222
236
|
db_name,
|
|
223
237
|
user,
|
|
@@ -227,7 +241,7 @@ def x_connect_user_mysql(**kwargs: Any) -> None:
|
|
|
227
241
|
password=pw,
|
|
228
242
|
)
|
|
229
243
|
else:
|
|
230
|
-
new_db =
|
|
244
|
+
new_db = MySQLDatabase(
|
|
231
245
|
server,
|
|
232
246
|
db_name,
|
|
233
247
|
user,
|
|
@@ -240,39 +254,39 @@ def x_connect_user_mysql(**kwargs: Any) -> None:
|
|
|
240
254
|
|
|
241
255
|
|
|
242
256
|
def x_connect_access(**kwargs: Any) -> None:
|
|
243
|
-
db_file =
|
|
257
|
+
db_file = unquoted2(kwargs["filename"])
|
|
244
258
|
enc = kwargs["encoding"]
|
|
245
259
|
if enc:
|
|
246
|
-
enc =
|
|
260
|
+
enc = unquoted2(enc)
|
|
247
261
|
need_pwd = kwargs["need_pwd"]
|
|
248
262
|
password = kwargs["password"]
|
|
249
263
|
if password:
|
|
250
|
-
password =
|
|
264
|
+
password = unquoted2(password)
|
|
251
265
|
if need_pwd:
|
|
252
|
-
need_pwd =
|
|
253
|
-
new_db =
|
|
266
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
267
|
+
new_db = AccessDatabase(db_file, need_passwd=need_pwd, encoding=enc, password=password)
|
|
254
268
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
255
269
|
return None
|
|
256
270
|
|
|
257
271
|
|
|
258
272
|
def x_connect_fb(**kwargs: Any) -> None:
|
|
259
|
-
server =
|
|
260
|
-
db_name =
|
|
273
|
+
server = unquoted2(kwargs["server"])
|
|
274
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
261
275
|
user = kwargs["user"]
|
|
262
276
|
if user:
|
|
263
|
-
user =
|
|
277
|
+
user = unquoted2(user)
|
|
264
278
|
need_pwd = kwargs["need_pwd"]
|
|
265
279
|
if need_pwd:
|
|
266
|
-
need_pwd =
|
|
280
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
267
281
|
portno = kwargs["port"]
|
|
268
282
|
if portno:
|
|
269
|
-
portno = int(
|
|
283
|
+
portno = int(unquoted2(portno))
|
|
270
284
|
enc = kwargs["encoding"]
|
|
271
285
|
if enc:
|
|
272
|
-
enc =
|
|
273
|
-
new_db =
|
|
286
|
+
enc = unquoted2(enc)
|
|
287
|
+
new_db = FirebirdDatabase(server, db_name, user, need_passwd=need_pwd, port=portno, encoding=enc)
|
|
274
288
|
else:
|
|
275
|
-
new_db =
|
|
289
|
+
new_db = FirebirdDatabase(server, db_name, user, need_passwd=need_pwd, port=portno)
|
|
276
290
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
277
291
|
return None
|
|
278
292
|
|
|
@@ -280,40 +294,40 @@ def x_connect_fb(**kwargs: Any) -> None:
|
|
|
280
294
|
def x_connect_user_fb(**kwargs: Any) -> None:
|
|
281
295
|
portno = kwargs["port"]
|
|
282
296
|
if portno:
|
|
283
|
-
portno = int(
|
|
284
|
-
server =
|
|
285
|
-
db_name =
|
|
297
|
+
portno = int(unquoted2(portno))
|
|
298
|
+
server = unquoted2(kwargs["server"])
|
|
299
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
286
300
|
user = _state.dbs.current().user if _state.dbs.current().user else None
|
|
287
301
|
pw = _state.upass
|
|
288
302
|
enc = kwargs["encoding"]
|
|
289
303
|
if enc:
|
|
290
|
-
enc =
|
|
291
|
-
new_db =
|
|
304
|
+
enc = unquoted2(enc)
|
|
305
|
+
new_db = FirebirdDatabase(server, db_name, user, need_passwd=pw is not None, port=portno, encoding=enc)
|
|
292
306
|
else:
|
|
293
|
-
new_db =
|
|
307
|
+
new_db = FirebirdDatabase(server, db_name, user, need_passwd=pw is not None, port=portno)
|
|
294
308
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
295
309
|
return None
|
|
296
310
|
|
|
297
311
|
|
|
298
312
|
def x_connect_ora(**kwargs: Any) -> None:
|
|
299
|
-
server =
|
|
300
|
-
db_name =
|
|
313
|
+
server = unquoted2(kwargs["server"])
|
|
314
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
301
315
|
user = kwargs["user"]
|
|
302
316
|
if user:
|
|
303
|
-
user =
|
|
317
|
+
user = unquoted2(user)
|
|
304
318
|
need_pwd = kwargs["need_pwd"]
|
|
305
319
|
if need_pwd:
|
|
306
|
-
need_pwd =
|
|
320
|
+
need_pwd = unquoted2(need_pwd).lower() == "true"
|
|
307
321
|
portno = kwargs["port"]
|
|
308
322
|
if portno:
|
|
309
|
-
portno = int(
|
|
323
|
+
portno = int(unquoted2(portno))
|
|
310
324
|
pw = kwargs["password"]
|
|
311
325
|
if pw:
|
|
312
|
-
pw =
|
|
326
|
+
pw = unquoted2(pw)
|
|
313
327
|
enc = kwargs["encoding"]
|
|
314
328
|
if enc:
|
|
315
|
-
enc =
|
|
316
|
-
new_db =
|
|
329
|
+
enc = unquoted2(enc)
|
|
330
|
+
new_db = OracleDatabase(
|
|
317
331
|
server,
|
|
318
332
|
db_name,
|
|
319
333
|
user,
|
|
@@ -323,7 +337,7 @@ def x_connect_ora(**kwargs: Any) -> None:
|
|
|
323
337
|
password=pw,
|
|
324
338
|
)
|
|
325
339
|
else:
|
|
326
|
-
new_db =
|
|
340
|
+
new_db = OracleDatabase(server, db_name, user, need_passwd=need_pwd, port=portno, password=pw)
|
|
327
341
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
328
342
|
return None
|
|
329
343
|
|
|
@@ -331,15 +345,15 @@ def x_connect_ora(**kwargs: Any) -> None:
|
|
|
331
345
|
def x_connect_user_ora(**kwargs: Any) -> None:
|
|
332
346
|
portno = kwargs["port"]
|
|
333
347
|
if portno:
|
|
334
|
-
portno = int(
|
|
335
|
-
server =
|
|
336
|
-
db_name =
|
|
348
|
+
portno = int(unquoted2(portno))
|
|
349
|
+
server = unquoted2(kwargs["server"])
|
|
350
|
+
db_name = unquoted2(kwargs["db_name"])
|
|
337
351
|
user = _state.dbs.current().user if _state.dbs.current().user else None
|
|
338
352
|
pw = _state.upass
|
|
339
353
|
enc = kwargs["encoding"]
|
|
340
354
|
if enc:
|
|
341
|
-
enc =
|
|
342
|
-
new_db =
|
|
355
|
+
enc = unquoted2(enc)
|
|
356
|
+
new_db = OracleDatabase(
|
|
343
357
|
server,
|
|
344
358
|
db_name,
|
|
345
359
|
user,
|
|
@@ -349,7 +363,7 @@ def x_connect_user_ora(**kwargs: Any) -> None:
|
|
|
349
363
|
password=pw,
|
|
350
364
|
)
|
|
351
365
|
else:
|
|
352
|
-
new_db =
|
|
366
|
+
new_db = OracleDatabase(
|
|
353
367
|
server,
|
|
354
368
|
db_name,
|
|
355
369
|
user,
|
|
@@ -364,20 +378,20 @@ def x_connect_user_ora(**kwargs: Any) -> None:
|
|
|
364
378
|
def x_connect_duckdb(**kwargs: Any) -> None:
|
|
365
379
|
import os
|
|
366
380
|
|
|
367
|
-
db_file =
|
|
381
|
+
db_file = unquoted2(kwargs["filename"])
|
|
368
382
|
mk_new = kwargs["new"]
|
|
369
|
-
mk_new =
|
|
370
|
-
if not mk_new and not
|
|
371
|
-
raise
|
|
383
|
+
mk_new = unquoted2(mk_new).lower() == "new" if mk_new else False
|
|
384
|
+
if not mk_new and not Path(db_file).exists():
|
|
385
|
+
raise ErrInfo(
|
|
372
386
|
type="cmd",
|
|
373
387
|
command_text=kwargs["metacommandline"],
|
|
374
388
|
other_msg="DuckDB file does not exist.",
|
|
375
389
|
)
|
|
376
390
|
if mk_new:
|
|
377
|
-
|
|
378
|
-
if
|
|
391
|
+
check_dir(db_file)
|
|
392
|
+
if Path(db_file).exists():
|
|
379
393
|
os.unlink(db_file)
|
|
380
|
-
new_db =
|
|
394
|
+
new_db = DuckDBDatabase(db_file)
|
|
381
395
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
382
396
|
return None
|
|
383
397
|
|
|
@@ -385,20 +399,20 @@ def x_connect_duckdb(**kwargs: Any) -> None:
|
|
|
385
399
|
def x_connect_sqlite(**kwargs: Any) -> None:
|
|
386
400
|
import os
|
|
387
401
|
|
|
388
|
-
db_file =
|
|
402
|
+
db_file = unquoted2(kwargs["filename"])
|
|
389
403
|
mk_new = kwargs["new"]
|
|
390
|
-
mk_new =
|
|
391
|
-
if not mk_new and not
|
|
392
|
-
raise
|
|
404
|
+
mk_new = unquoted2(mk_new).lower() == "new" if mk_new else False
|
|
405
|
+
if not mk_new and not Path(db_file).exists():
|
|
406
|
+
raise ErrInfo(
|
|
393
407
|
type="cmd",
|
|
394
408
|
command_text=kwargs["metacommandline"],
|
|
395
409
|
other_msg="SQLite file does not exist.",
|
|
396
410
|
)
|
|
397
411
|
if mk_new:
|
|
398
|
-
|
|
399
|
-
if
|
|
412
|
+
check_dir(db_file)
|
|
413
|
+
if Path(db_file).exists():
|
|
400
414
|
os.unlink(db_file)
|
|
401
|
-
new_db =
|
|
415
|
+
new_db = SQLiteDatabase(db_file)
|
|
402
416
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
403
417
|
return None
|
|
404
418
|
|
|
@@ -410,9 +424,9 @@ def x_connect_dsn(**kwargs: Any) -> None:
|
|
|
410
424
|
pw = kwargs["password"]
|
|
411
425
|
enc = kwargs["encoding"]
|
|
412
426
|
if enc:
|
|
413
|
-
new_db =
|
|
427
|
+
new_db = DsnDatabase(kwargs["dsn"], kwargs["user"], need_passwd=need_pwd, encoding=enc, password=pw)
|
|
414
428
|
else:
|
|
415
|
-
new_db =
|
|
429
|
+
new_db = DsnDatabase(kwargs["dsn"], kwargs["user"], need_passwd=need_pwd, password=pw)
|
|
416
430
|
_state.dbs.add(kwargs["db_alias"].lower(), new_db)
|
|
417
431
|
return None
|
|
418
432
|
|
|
@@ -420,7 +434,7 @@ def x_connect_dsn(**kwargs: Any) -> None:
|
|
|
420
434
|
def x_use(**kwargs: Any) -> None:
|
|
421
435
|
db_alias = kwargs["db_alias"].lower()
|
|
422
436
|
if db_alias not in _state.dbs.aliases():
|
|
423
|
-
raise
|
|
437
|
+
raise ErrInfo(
|
|
424
438
|
type="cmd",
|
|
425
439
|
command_text=kwargs["metacommandline"],
|
|
426
440
|
other_msg=f"Unrecognized database alias: {db_alias}.",
|
|
@@ -439,9 +453,9 @@ def x_disconnect(**kwargs: Any) -> None:
|
|
|
439
453
|
if alias is None:
|
|
440
454
|
alias = _state.dbs.current_alias()
|
|
441
455
|
if alias.lower() == "initial":
|
|
442
|
-
raise
|
|
456
|
+
raise ErrInfo(type="error", other_msg="You may not disconnect from the initial database used.")
|
|
443
457
|
if _state.status.batch.uses_db(alias):
|
|
444
|
-
raise
|
|
458
|
+
raise ErrInfo(
|
|
445
459
|
type="error",
|
|
446
460
|
other_msg="You may not disconnect from a database that is currently used in a batch.",
|
|
447
461
|
)
|
|
@@ -471,7 +485,7 @@ def x_autocommit_off(**kwargs: Any) -> None:
|
|
|
471
485
|
|
|
472
486
|
def x_pg_vacuum(**kwargs: Any) -> None:
|
|
473
487
|
db = _state.dbs.current()
|
|
474
|
-
if db.type ==
|
|
488
|
+
if db.type == dbt_postgres:
|
|
475
489
|
args = kwargs["vacuum_args"]
|
|
476
490
|
db.vacuum(args)
|
|
477
491
|
|
|
@@ -479,5 +493,5 @@ def x_pg_vacuum(**kwargs: Any) -> None:
|
|
|
479
493
|
def x_daoflushdelay(**kwargs: Any) -> None:
|
|
480
494
|
delay = float(kwargs["secs"])
|
|
481
495
|
if delay < 5.0:
|
|
482
|
-
raise
|
|
496
|
+
raise ErrInfo(type="error", other_msg=f"Invalid DAO flush delay: {delay}; must be >= 5.0.")
|
|
483
497
|
_state.conf.dao_flush_delay_secs = delay
|
execsql/metacommands/control.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from execsql.exceptions import ErrInfo
|
|
2
3
|
|
|
3
4
|
"""
|
|
4
5
|
Control-flow metacommand handlers for execsql.
|
|
@@ -20,15 +21,26 @@ import time
|
|
|
20
21
|
from typing import Any
|
|
21
22
|
|
|
22
23
|
import execsql.state as _state
|
|
24
|
+
from execsql.script import (
|
|
25
|
+
CommandList,
|
|
26
|
+
CommandListUntilLoop,
|
|
27
|
+
CommandListWhileLoop,
|
|
28
|
+
MetacommandStmt,
|
|
29
|
+
ScriptCmd,
|
|
30
|
+
current_script_line,
|
|
31
|
+
)
|
|
32
|
+
from execsql.utils.errors import exit_now, write_warning
|
|
33
|
+
from execsql.utils.fileio import EncodedFile, check_dir
|
|
34
|
+
from execsql.utils.gui import GUI_HALT, GuiSpec, enable_gui, gui_console_isrunning
|
|
23
35
|
|
|
24
36
|
|
|
25
37
|
def x_if(**kwargs: Any) -> None:
|
|
26
38
|
tf_value = _state.xcmd_test(kwargs["condtest"])
|
|
27
39
|
if tf_value:
|
|
28
|
-
src, line_no =
|
|
29
|
-
metacmd =
|
|
30
|
-
script_cmd =
|
|
31
|
-
cmdlist =
|
|
40
|
+
src, line_no = current_script_line()
|
|
41
|
+
metacmd = MetacommandStmt(kwargs["condcmd"])
|
|
42
|
+
script_cmd = ScriptCmd(src, line_no, "cmd", metacmd)
|
|
43
|
+
cmdlist = CommandList([script_cmd], f"{src}_{line_no}")
|
|
32
44
|
_state.commandliststack.append(cmdlist)
|
|
33
45
|
return None
|
|
34
46
|
|
|
@@ -81,17 +93,17 @@ def x_loop(**kwargs: Any) -> None:
|
|
|
81
93
|
listname = "loop" + str(len(_state.loopcommandstack) + 1)
|
|
82
94
|
if looptype == "WHILE":
|
|
83
95
|
_state.loopcommandstack.append(
|
|
84
|
-
|
|
96
|
+
CommandListWhileLoop([], listname, paramnames=None, loopcondition=loopcond),
|
|
85
97
|
)
|
|
86
98
|
else:
|
|
87
99
|
_state.loopcommandstack.append(
|
|
88
|
-
|
|
100
|
+
CommandListUntilLoop([], listname, paramnames=None, loopcondition=loopcond),
|
|
89
101
|
)
|
|
90
102
|
|
|
91
103
|
|
|
92
104
|
def endloop() -> None:
|
|
93
105
|
if len(_state.loopcommandstack) == 0:
|
|
94
|
-
raise
|
|
106
|
+
raise ErrInfo("error", other_msg="END LOOP metacommand without a matching preceding LOOP metacommand.")
|
|
95
107
|
_state.compiling_loop = False
|
|
96
108
|
_state.commandliststack.append(_state.loopcommandstack[-1])
|
|
97
109
|
_state.loopcommandstack.pop()
|
|
@@ -100,18 +112,18 @@ def endloop() -> None:
|
|
|
100
112
|
def x_halt(**kwargs: Any) -> None:
|
|
101
113
|
errmsg = kwargs["errmsg"]
|
|
102
114
|
tee = kwargs["tee"]
|
|
103
|
-
tee =
|
|
115
|
+
tee = bool(tee)
|
|
104
116
|
outf = kwargs["filename"]
|
|
105
117
|
errlevel = kwargs["errorlevel"]
|
|
106
118
|
conf = _state.conf
|
|
107
119
|
if outf:
|
|
108
|
-
|
|
109
|
-
of =
|
|
120
|
+
check_dir(outf)
|
|
121
|
+
of = EncodedFile(outf, conf.output_encoding).open("a")
|
|
110
122
|
of.write(f"{errmsg}\n")
|
|
111
123
|
of.close()
|
|
112
124
|
if conf.tee_write_log:
|
|
113
125
|
_state.exec_log.log_user_msg(errmsg)
|
|
114
|
-
use_gui =
|
|
126
|
+
use_gui = gui_console_isrunning()
|
|
115
127
|
if errmsg and (use_gui or conf.gui_level > 1):
|
|
116
128
|
x_halt_msg(table=None, schema=None, **kwargs)
|
|
117
129
|
return
|
|
@@ -121,15 +133,15 @@ def x_halt(**kwargs: Any) -> None:
|
|
|
121
133
|
errlevel = 3
|
|
122
134
|
if errmsg:
|
|
123
135
|
_state.output.write_err(errmsg)
|
|
124
|
-
script, lno =
|
|
136
|
+
script, lno = current_script_line()
|
|
125
137
|
_state.exec_log.log_exit_halt(script, lno, msg=errmsg)
|
|
126
|
-
|
|
138
|
+
exit_now(errlevel, None)
|
|
127
139
|
|
|
128
140
|
|
|
129
141
|
def x_error_halt(**kwargs: Any) -> None:
|
|
130
142
|
flag = kwargs["onoff"].lower()
|
|
131
143
|
if flag not in ("on", "off", "yes", "no", "true", "false"):
|
|
132
|
-
raise
|
|
144
|
+
raise ErrInfo(
|
|
133
145
|
type="cmd",
|
|
134
146
|
command_text=kwargs["metacommandline"],
|
|
135
147
|
other_msg=f"Unrecognized flag for error handling: {flag}",
|
|
@@ -141,7 +153,7 @@ def x_error_halt(**kwargs: Any) -> None:
|
|
|
141
153
|
def x_metacommand_error_halt(**kwargs: Any) -> None:
|
|
142
154
|
flag = kwargs["onoff"].lower()
|
|
143
155
|
if flag not in ("on", "off", "yes", "no", "true", "false"):
|
|
144
|
-
raise
|
|
156
|
+
raise ErrInfo(
|
|
145
157
|
type="cmd",
|
|
146
158
|
command_text=kwargs["metacommandline"],
|
|
147
159
|
other_msg=f"Unrecognized flag for metacommand error handling: {flag}",
|
|
@@ -166,8 +178,8 @@ def x_rollback(**kwargs: Any) -> None:
|
|
|
166
178
|
|
|
167
179
|
def x_break(**kwargs: Any) -> None:
|
|
168
180
|
if len(_state.commandliststack) == 1:
|
|
169
|
-
src, line_no =
|
|
170
|
-
|
|
181
|
+
src, line_no = current_script_line()
|
|
182
|
+
write_warning(f"BREAK metacommand with no command nesting on line {line_no} of {src}")
|
|
171
183
|
else:
|
|
172
184
|
_state.if_stack.if_levels = _state.if_stack.if_levels[: _state.commandliststack[-1].init_if_level]
|
|
173
185
|
_state.commandliststack.pop()
|
|
@@ -183,10 +195,10 @@ def x_wait_until(**kwargs: Any) -> None:
|
|
|
183
195
|
countdown -= 1
|
|
184
196
|
if kwargs["end"].lower() == "halt":
|
|
185
197
|
_state.exec_log.log_exit_halt(
|
|
186
|
-
*
|
|
198
|
+
*current_script_line(),
|
|
187
199
|
msg="Halted at expiration of WAIT_UNTIL metacommand.",
|
|
188
200
|
)
|
|
189
|
-
|
|
201
|
+
exit_now(2, None)
|
|
190
202
|
return None
|
|
191
203
|
|
|
192
204
|
|
|
@@ -196,7 +208,7 @@ def x_halt_msg(**kwargs: Any) -> None:
|
|
|
196
208
|
|
|
197
209
|
errmsg = kwargs["errmsg"]
|
|
198
210
|
tee = kwargs["tee"]
|
|
199
|
-
tee =
|
|
211
|
+
tee = bool(tee)
|
|
200
212
|
outf = kwargs["filename"]
|
|
201
213
|
errlevel = kwargs["errorlevel"]
|
|
202
214
|
if errlevel:
|
|
@@ -205,8 +217,8 @@ def x_halt_msg(**kwargs: Any) -> None:
|
|
|
205
217
|
errlevel = 3
|
|
206
218
|
conf = _state.conf
|
|
207
219
|
if outf:
|
|
208
|
-
|
|
209
|
-
of =
|
|
220
|
+
check_dir(outf)
|
|
221
|
+
of = EncodedFile(outf, conf.output_encoding).open("a")
|
|
210
222
|
of.write(f"{errmsg}\n")
|
|
211
223
|
of.close()
|
|
212
224
|
schema = kwargs.get("schema")
|
|
@@ -218,7 +230,7 @@ def x_halt_msg(**kwargs: Any) -> None:
|
|
|
218
230
|
headers, rows = db.select_data(sql)
|
|
219
231
|
else:
|
|
220
232
|
headers, rows = None, None
|
|
221
|
-
|
|
233
|
+
enable_gui()
|
|
222
234
|
return_queue = _queue.Queue()
|
|
223
235
|
gui_args = {
|
|
224
236
|
"title": "HALT",
|
|
@@ -229,7 +241,7 @@ def x_halt_msg(**kwargs: Any) -> None:
|
|
|
229
241
|
"rowset": rows,
|
|
230
242
|
"help_url": None,
|
|
231
243
|
}
|
|
232
|
-
_state.gui_manager_queue.put(
|
|
244
|
+
_state.gui_manager_queue.put(GuiSpec(GUI_HALT, gui_args, return_queue))
|
|
233
245
|
return_queue.get(block=True)
|
|
234
|
-
_state.exec_log.log_exit_halt(*
|
|
235
|
-
|
|
246
|
+
_state.exec_log.log_exit_halt(*current_script_line(), msg=errmsg)
|
|
247
|
+
exit_now(errlevel, None)
|