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
|
@@ -65,8 +65,8 @@ def xf_hasrows(**kwargs: Any) -> bool:
|
|
|
65
65
|
hdrs, rec = _state.dbs.current().select_data(sql)
|
|
66
66
|
except ErrInfo:
|
|
67
67
|
raise
|
|
68
|
-
except Exception:
|
|
69
|
-
raise ErrInfo("db", sql, exception_msg=exception_desc())
|
|
68
|
+
except Exception as e:
|
|
69
|
+
raise ErrInfo("db", sql, exception_msg=exception_desc()) from e
|
|
70
70
|
nrows = rec[0][0]
|
|
71
71
|
return nrows > 0
|
|
72
72
|
|
|
@@ -180,12 +180,12 @@ def xf_iszero(**kwargs: Any) -> bool:
|
|
|
180
180
|
val = kwargs["value"].strip()
|
|
181
181
|
try:
|
|
182
182
|
v = float(val)
|
|
183
|
-
except Exception:
|
|
183
|
+
except Exception as e:
|
|
184
184
|
raise ErrInfo(
|
|
185
185
|
type="cmd",
|
|
186
186
|
command_text=kwargs["metacommandline"],
|
|
187
187
|
other_msg=f"The value {{{val}}} is not numeric.",
|
|
188
|
-
)
|
|
188
|
+
) from e
|
|
189
189
|
return v == 0
|
|
190
190
|
|
|
191
191
|
|
|
@@ -195,12 +195,12 @@ def xf_isgt(**kwargs: Any) -> bool:
|
|
|
195
195
|
try:
|
|
196
196
|
v1 = float(val1)
|
|
197
197
|
v2 = float(val2)
|
|
198
|
-
except Exception:
|
|
198
|
+
except Exception as e:
|
|
199
199
|
raise ErrInfo(
|
|
200
200
|
type="cmd",
|
|
201
201
|
command_text=kwargs["metacommandline"],
|
|
202
202
|
other_msg=f"Values {{{val1}}} and {{{val2}}} are not both numeric.",
|
|
203
|
-
)
|
|
203
|
+
) from e
|
|
204
204
|
return v1 > v2
|
|
205
205
|
|
|
206
206
|
|
|
@@ -210,12 +210,12 @@ def xf_isgte(**kwargs: Any) -> bool:
|
|
|
210
210
|
try:
|
|
211
211
|
v1 = float(val1)
|
|
212
212
|
v2 = float(val2)
|
|
213
|
-
except Exception:
|
|
213
|
+
except Exception as e:
|
|
214
214
|
raise ErrInfo(
|
|
215
215
|
type="cmd",
|
|
216
216
|
command_text=kwargs["metacommandline"],
|
|
217
217
|
other_msg=f"Values {{{val1}}} and {{{val2}}} are not both numeric.",
|
|
218
|
-
)
|
|
218
|
+
) from e
|
|
219
219
|
return v1 >= v2
|
|
220
220
|
|
|
221
221
|
|
|
@@ -291,6 +291,8 @@ def build_conditional_table() -> Any:
|
|
|
291
291
|
mcl.add(
|
|
292
292
|
r"^\s*CONTAINS\s*\(\s*(?P<string1>[^ )]+)\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)",
|
|
293
293
|
xf_contains,
|
|
294
|
+
description="CONTAINS",
|
|
295
|
+
category="condition",
|
|
294
296
|
)
|
|
295
297
|
mcl.add(
|
|
296
298
|
r'^\s*CONTAINS\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)',
|
|
@@ -357,6 +359,8 @@ def build_conditional_table() -> Any:
|
|
|
357
359
|
mcl.add(
|
|
358
360
|
r"^\s*STARTS_WITH\s*\(\s*(?P<string1>[^ )]+)\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)",
|
|
359
361
|
xf_startswith,
|
|
362
|
+
description="STARTS_WITH",
|
|
363
|
+
category="condition",
|
|
360
364
|
)
|
|
361
365
|
mcl.add(
|
|
362
366
|
r'^\s*STARTS_WITH\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)',
|
|
@@ -423,6 +427,8 @@ def build_conditional_table() -> Any:
|
|
|
423
427
|
mcl.add(
|
|
424
428
|
r"^\s*ENDS_WITH\s*\(\s*(?P<string1>[^ )]+)\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)",
|
|
425
429
|
xf_endswith,
|
|
430
|
+
description="ENDS_WITH",
|
|
431
|
+
category="condition",
|
|
426
432
|
)
|
|
427
433
|
mcl.add(
|
|
428
434
|
r'^\s*ENDS_WITH\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*(?P<string2>[^ )]+)(?:\s*,\s*(?P<ignorecase>I))?\s*\)',
|
|
@@ -486,18 +492,23 @@ def build_conditional_table() -> Any:
|
|
|
486
492
|
)
|
|
487
493
|
|
|
488
494
|
# HASROWS / HAS_ROWS
|
|
489
|
-
mcl.add(r"^\s*HASROWS\((?P<queryname>[^)]+)\)", xf_hasrows)
|
|
495
|
+
mcl.add(r"^\s*HASROWS\((?P<queryname>[^)]+)\)", xf_hasrows, description="HASROWS", category="condition")
|
|
490
496
|
mcl.add(r"^\s*HAS_ROWS\((?P<queryname>[^)]+)\)", xf_hasrows)
|
|
491
497
|
|
|
492
498
|
# Status predicates
|
|
493
|
-
mcl.add(r"^\s*sql_error\(\s*\)", xf_sqlerror)
|
|
494
|
-
mcl.add(r"^\s*dialog_canceled\(\s*\)", xf_dialogcanceled)
|
|
495
|
-
mcl.add(r"^\s*metacommand_error\(\s*\)", xf_metacommanderror)
|
|
496
|
-
mcl.add(r"^\s*CONSOLE_ON", xf_console)
|
|
499
|
+
mcl.add(r"^\s*sql_error\(\s*\)", xf_sqlerror, description="SQL_ERROR", category="condition")
|
|
500
|
+
mcl.add(r"^\s*dialog_canceled\(\s*\)", xf_dialogcanceled, description="DIALOG_CANCELED", category="condition")
|
|
501
|
+
mcl.add(r"^\s*metacommand_error\(\s*\)", xf_metacommanderror, description="METACOMMAND_ERROR", category="condition")
|
|
502
|
+
mcl.add(r"^\s*CONSOLE_ON", xf_console, description="CONSOLE_ON", category="condition")
|
|
497
503
|
|
|
498
504
|
# FILE / DIRECTORY
|
|
499
|
-
mcl.add(ins_fn_rxs(r"^FILE_EXISTS\(\s*", r"\)"), xf_fileexists)
|
|
500
|
-
mcl.add(
|
|
505
|
+
mcl.add(ins_fn_rxs(r"^FILE_EXISTS\(\s*", r"\)"), xf_fileexists, description="FILE_EXISTS", category="condition")
|
|
506
|
+
mcl.add(
|
|
507
|
+
r'^DIRECTORY_EXISTS\(\s*("?)(?P<dirname>[^")]+)\1\)',
|
|
508
|
+
xf_direxists,
|
|
509
|
+
description="DIRECTORY_EXISTS",
|
|
510
|
+
category="condition",
|
|
511
|
+
)
|
|
501
512
|
|
|
502
513
|
# Database object existence
|
|
503
514
|
mcl.add(
|
|
@@ -506,6 +517,8 @@ def build_conditional_table() -> Any:
|
|
|
506
517
|
r'^SCHEMA_EXISTS\(\s*"(?P<schema>[A-Za-z0-9_\-\: ]+)"\s*\)',
|
|
507
518
|
),
|
|
508
519
|
xf_schemaexists,
|
|
520
|
+
description="SCHEMA_EXISTS",
|
|
521
|
+
category="condition",
|
|
509
522
|
)
|
|
510
523
|
mcl.add(
|
|
511
524
|
(
|
|
@@ -515,6 +528,8 @@ def build_conditional_table() -> Any:
|
|
|
515
528
|
r"^TABLE_EXISTS\(\s*(?:(?P<schema>[A-Za-z0-9_\-\/]+)\.)?(?P<tablename>[A-Za-z0-9_\-\/]+)\)",
|
|
516
529
|
),
|
|
517
530
|
xf_tableexists,
|
|
531
|
+
description="TABLE_EXISTS",
|
|
532
|
+
category="condition",
|
|
518
533
|
)
|
|
519
534
|
mcl.add(
|
|
520
535
|
(
|
|
@@ -522,8 +537,15 @@ def build_conditional_table() -> Any:
|
|
|
522
537
|
r'^ROLE_EXISTS\(\s*"(?P<role>[A-Za-z0-9_\-\:\$ ]+)"\s*\)',
|
|
523
538
|
),
|
|
524
539
|
xf_roleexists,
|
|
540
|
+
description="ROLE_EXISTS",
|
|
541
|
+
category="condition",
|
|
542
|
+
)
|
|
543
|
+
mcl.add(
|
|
544
|
+
r'^\s*VIEW_EXISTS\(\s*("?)(?P<viewname>[^")]+)\1\)',
|
|
545
|
+
xf_viewexists,
|
|
546
|
+
description="VIEW_EXISTS",
|
|
547
|
+
category="condition",
|
|
525
548
|
)
|
|
526
|
-
mcl.add(r'^\s*VIEW_EXISTS\(\s*("?)(?P<viewname>[^")]+)\1\)', xf_viewexists)
|
|
527
549
|
mcl.add(
|
|
528
550
|
(
|
|
529
551
|
r"^COLUMN_EXISTS\(\s*(?P<columnname>[A-Za-z0-9_\-\:]+)\s+IN\s+(?:(?P<schema>[A-Za-z0-9_\-\: ]+)\.)?(?P<tablename>[A-Za-z0-9_\-\: ]+)\)",
|
|
@@ -534,28 +556,70 @@ def build_conditional_table() -> Any:
|
|
|
534
556
|
r'^COLUMN_EXISTS\(\s*"(?P<columnname>[A-Za-z0-9_\-\: ]+)"\s+IN\s+(?:"(?P<schema>[A-Za-z0-9_\-\: ]+)"\.)?"(?P<tablename>[A-Za-z0-9_\-\: ]+)"\)',
|
|
535
557
|
),
|
|
536
558
|
xf_columnexists,
|
|
559
|
+
description="COLUMN_EXISTS",
|
|
560
|
+
category="condition",
|
|
561
|
+
)
|
|
562
|
+
mcl.add(
|
|
563
|
+
r"^\s*ALIAS_DEFINED\s*\(\s*(?P<alias>\w+)\s*\)",
|
|
564
|
+
xf_aliasdefined,
|
|
565
|
+
description="ALIAS_DEFINED",
|
|
566
|
+
category="condition",
|
|
537
567
|
)
|
|
538
|
-
mcl.add(r"^\s*ALIAS_DEFINED\s*\(\s*(?P<alias>\w+)\s*\)", xf_aliasdefined)
|
|
539
568
|
|
|
540
569
|
# Substitution variable predicates
|
|
541
|
-
mcl.add(
|
|
542
|
-
|
|
543
|
-
|
|
570
|
+
mcl.add(
|
|
571
|
+
r"^SUB_DEFINED\s*\(\s*(?P<match_str>[\$&@~#]?\w+)\s*\)",
|
|
572
|
+
xf_sub_defined,
|
|
573
|
+
description="SUB_DEFINED",
|
|
574
|
+
category="condition",
|
|
575
|
+
)
|
|
576
|
+
mcl.add(
|
|
577
|
+
r"^SUB_EMPTY\s*\(\s*(?P<match_str>[\$&@~#]?\w+)\s*\)",
|
|
578
|
+
xf_sub_empty,
|
|
579
|
+
description="SUB_EMPTY",
|
|
580
|
+
category="condition",
|
|
581
|
+
)
|
|
582
|
+
mcl.add(
|
|
583
|
+
r"^\s*SCRIPT_EXISTS\s*\(\s*(?P<script_id>\w+)\s*\)",
|
|
584
|
+
xf_script_exists,
|
|
585
|
+
description="SCRIPT_EXISTS",
|
|
586
|
+
category="condition",
|
|
587
|
+
)
|
|
544
588
|
|
|
545
589
|
# Comparison predicates
|
|
546
|
-
mcl.add(
|
|
590
|
+
mcl.add(
|
|
591
|
+
r"^\s*EQUAL(S)?\s*\(\s*(?P<string1>[^ )]+)\s*,\s*(?P<string2>[^ )]+)\s*\)",
|
|
592
|
+
xf_equals,
|
|
593
|
+
description="EQUAL",
|
|
594
|
+
category="condition",
|
|
595
|
+
)
|
|
547
596
|
mcl.add(r'^\s*EQUAL(S)?\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*(?P<string2>[^ )]+)\s*\)', xf_equals)
|
|
548
597
|
mcl.add(r'^\s*EQUAL(S)?\s*\(\s*(?P<string1>[^ )]+)\s*,\s*"(?P<string2>[^"]+)"\s*\)', xf_equals)
|
|
549
598
|
mcl.add(r'^\s*EQUAL(S)?\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*"(?P<string2>[^"]+)"\s*\)', xf_equals)
|
|
550
|
-
mcl.add(
|
|
599
|
+
mcl.add(
|
|
600
|
+
r"^\s*IDENTICAL\s*\(\s*(?P<string1>[^ ,)]+)\s*,\s*(?P<string2>[^ )]+)\s*\)",
|
|
601
|
+
xf_identical,
|
|
602
|
+
description="IDENTICAL",
|
|
603
|
+
category="condition",
|
|
604
|
+
)
|
|
551
605
|
mcl.add(r'^\s*IDENTICAL\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*(?P<string2>[^ )]+)\s*\)', xf_identical)
|
|
552
606
|
mcl.add(r'^\s*IDENTICAL\s*\(\s*(?P<string1>[^ ,]+)\s*,\s*"(?P<string2>[^"]+)"\s*\)', xf_identical)
|
|
553
607
|
mcl.add(r'^\s*IDENTICAL\s*\(\s*"(?P<string1>[^"]+)"\s*,\s*"(?P<string2>[^"]+)"\s*\)', xf_identical)
|
|
554
|
-
mcl.add(r'^\s*IS_NULL\(\s*(?P<item>"[^"]*")\s*\)', xf_isnull)
|
|
555
|
-
mcl.add(r"^\s*IS_ZERO\(\s*(?P<value>[^)]*)\s*\)", xf_iszero)
|
|
556
|
-
mcl.add(
|
|
557
|
-
|
|
558
|
-
|
|
608
|
+
mcl.add(r'^\s*IS_NULL\(\s*(?P<item>"[^"]*")\s*\)', xf_isnull, description="IS_NULL", category="condition")
|
|
609
|
+
mcl.add(r"^\s*IS_ZERO\(\s*(?P<value>[^)]*)\s*\)", xf_iszero, description="IS_ZERO", category="condition")
|
|
610
|
+
mcl.add(
|
|
611
|
+
r"^\s*IS_GT\(\s*(?P<value1>[^)]*)\s*,\s*(?P<value2>[^)]*)\s*\)",
|
|
612
|
+
xf_isgt,
|
|
613
|
+
description="IS_GT",
|
|
614
|
+
category="condition",
|
|
615
|
+
)
|
|
616
|
+
mcl.add(
|
|
617
|
+
r"^\s*IS_GTE\(\s*(?P<value1>[^)]*)\s*,\s*(?P<value2>[^)]*)\s*\)",
|
|
618
|
+
xf_isgte,
|
|
619
|
+
description="IS_GTE",
|
|
620
|
+
category="condition",
|
|
621
|
+
)
|
|
622
|
+
mcl.add(r"^\s*IS_TRUE\(\s*(?P<value>[^)]*)\s*\)", xf_istrue, description="IS_TRUE", category="condition")
|
|
559
623
|
|
|
560
624
|
# Boolean literals
|
|
561
625
|
mcl.add(
|
|
@@ -574,6 +638,8 @@ def build_conditional_table() -> Any:
|
|
|
574
638
|
r"^\s*(?P<value>True)\s*",
|
|
575
639
|
),
|
|
576
640
|
xf_boolliteral,
|
|
641
|
+
description="IS_TRUE",
|
|
642
|
+
category="condition",
|
|
577
643
|
)
|
|
578
644
|
|
|
579
645
|
# Database type / name
|
|
@@ -583,6 +649,8 @@ def build_conditional_table() -> Any:
|
|
|
583
649
|
r'^\s*DBMS\(\s*"(?P<dbms>[A-Z0-9_\-\(\)\/\\\. ]+)"\s*\)',
|
|
584
650
|
),
|
|
585
651
|
xf_dbms,
|
|
652
|
+
description="DBMS",
|
|
653
|
+
category="condition",
|
|
586
654
|
)
|
|
587
655
|
mcl.add(
|
|
588
656
|
(
|
|
@@ -590,6 +658,8 @@ def build_conditional_table() -> Any:
|
|
|
590
658
|
r'^\s*DATABASE_NAME\(\s*"(?P<dbname>[A-Z0-9_;\-\(\)\/\\\. ]+)"\s*\)',
|
|
591
659
|
),
|
|
592
660
|
xf_dbname,
|
|
661
|
+
description="DATABASE_NAME",
|
|
662
|
+
category="condition",
|
|
593
663
|
)
|
|
594
664
|
|
|
595
665
|
# File modification time comparisons
|
|
@@ -600,6 +670,8 @@ def build_conditional_table() -> Any:
|
|
|
600
670
|
symbolicname="file1",
|
|
601
671
|
),
|
|
602
672
|
xf_newer_file,
|
|
673
|
+
description="NEWER_FILE",
|
|
674
|
+
category="condition",
|
|
603
675
|
)
|
|
604
676
|
mcl.add(
|
|
605
677
|
ins_fn_rxs(
|
|
@@ -608,6 +680,8 @@ def build_conditional_table() -> Any:
|
|
|
608
680
|
symbolicname="file1",
|
|
609
681
|
),
|
|
610
682
|
xf_newer_date,
|
|
683
|
+
description="NEWER_DATE",
|
|
684
|
+
category="condition",
|
|
611
685
|
)
|
|
612
686
|
|
|
613
687
|
return mcl
|
execsql/metacommands/control.py
CHANGED
|
@@ -119,8 +119,10 @@ def x_halt(**kwargs: Any) -> None:
|
|
|
119
119
|
if outf:
|
|
120
120
|
check_dir(outf)
|
|
121
121
|
of = EncodedFile(outf, conf.output_encoding).open("a")
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
try:
|
|
123
|
+
of.write(f"{errmsg}\n")
|
|
124
|
+
finally:
|
|
125
|
+
of.close()
|
|
124
126
|
if conf.tee_write_log:
|
|
125
127
|
_state.exec_log.log_user_msg(errmsg)
|
|
126
128
|
use_gui = gui_console_isrunning()
|
|
@@ -219,8 +221,10 @@ def x_halt_msg(**kwargs: Any) -> None:
|
|
|
219
221
|
if outf:
|
|
220
222
|
check_dir(outf)
|
|
221
223
|
of = EncodedFile(outf, conf.output_encoding).open("a")
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
try:
|
|
225
|
+
of.write(f"{errmsg}\n")
|
|
226
|
+
finally:
|
|
227
|
+
of.close()
|
|
224
228
|
schema = kwargs.get("schema")
|
|
225
229
|
table = kwargs.get("table")
|
|
226
230
|
if table:
|
execsql/metacommands/data.py
CHANGED
|
@@ -123,12 +123,12 @@ def x_subdata(**kwargs: Any) -> None:
|
|
|
123
123
|
_, rec = db.select_rowsource(sql)
|
|
124
124
|
except ErrInfo:
|
|
125
125
|
raise
|
|
126
|
-
except Exception:
|
|
126
|
+
except Exception as e:
|
|
127
127
|
raise ErrInfo(
|
|
128
128
|
type="exception",
|
|
129
129
|
exception_msg=exception_desc(),
|
|
130
130
|
other_msg=f"Can't get headers and rows from {sql}.",
|
|
131
|
-
)
|
|
131
|
+
) from e
|
|
132
132
|
try:
|
|
133
133
|
row1 = next(rec)
|
|
134
134
|
except Exception:
|
|
@@ -155,12 +155,12 @@ def x_selectsub(**kwargs: Any) -> None:
|
|
|
155
155
|
hdrs, rec = db.select_rowsource(sql)
|
|
156
156
|
except ErrInfo:
|
|
157
157
|
raise
|
|
158
|
-
except Exception:
|
|
158
|
+
except Exception as e:
|
|
159
159
|
raise ErrInfo(
|
|
160
160
|
type="exception",
|
|
161
161
|
exception_msg=exception_desc(),
|
|
162
162
|
other_msg=f"Can't get headers and rows from {sql}.",
|
|
163
|
-
)
|
|
163
|
+
) from e
|
|
164
164
|
for subvar in hdrs:
|
|
165
165
|
subvar = "@" + subvar
|
|
166
166
|
if _state.subvars.sub_exists(subvar):
|
|
@@ -171,8 +171,8 @@ def x_selectsub(**kwargs: Any) -> None:
|
|
|
171
171
|
row1 = next(rec)
|
|
172
172
|
except StopIteration:
|
|
173
173
|
row1 = None
|
|
174
|
-
except Exception:
|
|
175
|
-
raise ErrInfo(type="exception", exception_msg=exception_desc(), other_msg=nodatamsg)
|
|
174
|
+
except Exception as e:
|
|
175
|
+
raise ErrInfo(type="exception", exception_msg=exception_desc(), other_msg=nodatamsg) from e
|
|
176
176
|
if row1:
|
|
177
177
|
for i, item in enumerate(row1):
|
|
178
178
|
if item is None:
|
execsql/metacommands/debug.py
CHANGED
|
@@ -21,8 +21,12 @@ def x_debug_write_metacommands(**kwargs: Any) -> None:
|
|
|
21
21
|
ofile = _state.output
|
|
22
22
|
else:
|
|
23
23
|
ofile = EncodedFile(output_dest, _state.conf.output_encoding).open("w")
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
try:
|
|
25
|
+
for m in _state.metacommandlist:
|
|
26
|
+
ofile.write(f"({m.hitcount}) {m.rx.pattern}\n")
|
|
27
|
+
finally:
|
|
28
|
+
if output_dest is not None and output_dest != "stdout":
|
|
29
|
+
ofile.close()
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
def x_debug_commandliststack(**kwargs: Any) -> None:
|