execsql2 2.22.9__py3-none-any.whl → 2.23.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. execsql/api.py +71 -0
  2. execsql/config.py +2 -0
  3. execsql/data/execsql.conf.template +5 -0
  4. execsql/db/access.py +34 -10
  5. execsql/db/base.py +120 -2
  6. execsql/db/dsn.py +14 -7
  7. execsql/db/duckdb.py +102 -10
  8. execsql/db/firebird.py +12 -7
  9. execsql/db/mysql.py +55 -10
  10. execsql/db/oracle.py +24 -11
  11. execsql/db/postgres.py +17 -9
  12. execsql/db/sqlite.py +23 -8
  13. execsql/db/sqlserver.py +7 -7
  14. execsql/db/tiers.py +79 -0
  15. execsql/exporters/delimited.py +15 -1
  16. execsql/exporters/html.py +8 -2
  17. execsql/exporters/latex.py +35 -2
  18. execsql/exporters/markdown.py +9 -3
  19. execsql/exporters/ods.py +22 -4
  20. execsql/exporters/pretty.py +13 -0
  21. execsql/exporters/templates.py +18 -1
  22. execsql/exporters/values.py +25 -4
  23. execsql/exporters/xlsx.py +7 -1
  24. execsql/state.py +5 -0
  25. execsql/state.pyi +3 -1
  26. execsql/types.py +4 -1
  27. execsql/utils/fileio.py +47 -2
  28. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/METADATA +22 -13
  29. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/RECORD +47 -46
  30. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/README.md +0 -0
  31. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  32. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  33. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/make_config_db.sql +0 -0
  34. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/md_compare.sql +0 -0
  35. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/md_glossary.sql +0 -0
  36. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/md_upsert.sql +0 -0
  37. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/pg_compare.sql +0 -0
  38. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  39. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  40. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/script_template.sql +0 -0
  41. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/ss_compare.sql +0 -0
  42. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  43. {execsql2-2.22.9.data → execsql2-2.23.1.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  44. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/WHEEL +0 -0
  45. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/entry_points.txt +0 -0
  46. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/licenses/LICENSE.txt +0 -0
  47. {execsql2-2.22.9.dist-info → execsql2-2.23.1.dist-info}/licenses/NOTICE +0 -0
execsql/exporters/xlsx.py CHANGED
@@ -9,6 +9,7 @@ Provides :func:`write_query_to_xlsx` (single-sheet export) and
9
9
  """
10
10
 
11
11
  import datetime
12
+ import decimal
12
13
  import getpass
13
14
  import os
14
15
  from pathlib import Path
@@ -52,7 +53,12 @@ def _cell_value(item: Any) -> Any:
52
53
  if isinstance(item, bool):
53
54
  # bool must be checked before int — bool is a subclass of int.
54
55
  return item
55
- if isinstance(item, int | float):
56
+ if isinstance(item, int | float | decimal.Decimal):
57
+ # Decimal is in openpyxl's NUMERIC_TYPES and becomes a real numeric
58
+ # cell. Without it, every ``numeric``/``decimal`` column — which is
59
+ # what PostgreSQL, MySQL and DuckDB return for measurements — fell
60
+ # through to str() below and arrived in Excel as text: no sums, no
61
+ # sorting, no charts.
56
62
  return item
57
63
  if isinstance(item, datetime.datetime):
58
64
  return item
execsql/state.py CHANGED
@@ -222,6 +222,7 @@ _CONTEXT_ATTRS: frozenset[str] = frozenset(
222
222
  "status",
223
223
  "output",
224
224
  "filewriter",
225
+ "tier_notices_shown",
225
226
  # Lazy singletons
226
227
  "counters",
227
228
  "timer",
@@ -275,6 +276,7 @@ class RuntimeContext:
275
276
  "status",
276
277
  "output",
277
278
  "filewriter",
279
+ "tier_notices_shown",
278
280
  # Lazy singletons
279
281
  "counters",
280
282
  "timer",
@@ -321,6 +323,9 @@ class RuntimeContext:
321
323
  self.status: StatObj | None = None
322
324
  self.output: WriteHooks | None = None
323
325
  self.filewriter: FileWriter | None = None
326
+ # DBMS names whose best-effort support notice has already been shown,
327
+ # so repeated connections to the same backend announce it only once.
328
+ self.tier_notices_shown: set[str] = set()
324
329
 
325
330
  # Lazy singletons
326
331
  self.counters: CounterVars | None = None
execsql/state.pyi CHANGED
@@ -51,7 +51,8 @@ exec_log: Logger
51
51
  subvars: SubVarSet
52
52
  status: StatObj
53
53
  output: Any
54
- filewriter: FileWriter
54
+ tier_notices_shown: set[str]
55
+ filewriter: FileWriter | None
55
56
  counters: CounterVars
56
57
  timer: Timer
57
58
  dbs: DatabasePool
@@ -84,6 +85,7 @@ class RuntimeContext:
84
85
  subvars: SubVarSet | None
85
86
  status: StatObj | None
86
87
  output: Any
88
+ tier_notices_shown: set[str]
87
89
  filewriter: FileWriter | None
88
90
  counters: CounterVars | None
89
91
  timer: Timer | None
execsql/types.py CHANGED
@@ -773,7 +773,10 @@ dbt_duckdb.name_datatype(DT_Date, "DATE")
773
773
  dbt_duckdb.name_datatype(DT_Time, "TIME")
774
774
  dbt_duckdb.name_datatype(DT_Integer, "INTEGER")
775
775
  dbt_duckdb.name_datatype(DT_Long, "BIGINT")
776
- dbt_duckdb.name_datatype(DT_Float, "REAL")
776
+ # DOUBLE, not REAL: DT_Float is IEEE double precision and a Python float
777
+ # always is one. DuckDB's REAL is single precision, so 1234.567 came back
778
+ # as 1234.5670166015625. Every other backend maps DT_Float to a double.
779
+ dbt_duckdb.name_datatype(DT_Float, "DOUBLE")
777
780
  dbt_duckdb.name_datatype(DT_Decimal, "NUMERIC")
778
781
  dbt_duckdb.name_datatype(DT_Boolean, "BOOLEAN")
779
782
  dbt_duckdb.name_datatype(DT_Character, "TEXT")
execsql/utils/fileio.py CHANGED
@@ -435,8 +435,40 @@ def filewriter_filestatus(filename: str) -> int:
435
435
  return cast(int, fw_output.get())
436
436
 
437
437
 
438
+ #: Set once the first dropped write has been reported, so a script writing
439
+ #: thousands of lines warns once rather than per line.
440
+ _drop_warned = False
441
+
442
+
443
+ def _warn_write_dropped(filename: str) -> None:
444
+ """Report, once per process, that file output is being discarded.
445
+
446
+ Silently dropping a write is not a safe default: a script's logfile simply
447
+ comes back empty and the run still reports success. The guard itself has
448
+ to stay — putting on a queue no subprocess is draining fills the OS pipe
449
+ buffer and deadlocks the caller — so the write is still dropped, but no
450
+ longer without saying so.
451
+ """
452
+ global _drop_warned
453
+ if _drop_warned:
454
+ return
455
+ _drop_warned = True
456
+ try:
457
+ from execsql.utils.errors import write_warning
458
+
459
+ write_warning(
460
+ f'no file writer is running; output to "{filename}" and any later file '
461
+ "is discarded. Start one with execsql.utils.fileio.FileWriter, or run "
462
+ "the script through the CLI or execsql.api.run().",
463
+ always=True,
464
+ )
465
+ except Exception:
466
+ pass # Never let the warning path break the caller.
467
+
468
+
438
469
  def filewriter_write(filename: str, message: str) -> None:
439
470
  if not _writer_alive():
471
+ _warn_write_dropped(filename)
440
472
  return
441
473
  fw_input.put((FileWriter.CMD_WRITE, (filename, message)))
442
474
 
@@ -445,6 +477,7 @@ def filewriter_open_as_new(filename: str) -> None:
445
477
  # FileWriter opens files in append mode ("a") by default. This ensures that it
446
478
  # will be opened in write mode ("w") instead. If the file is open, it will be closed.
447
479
  if not _writer_alive():
480
+ _warn_write_dropped(filename)
448
481
  return
449
482
  fw_input.put((FileWriter.CMD_OPEN_AS_NEW, (filename,)))
450
483
 
@@ -537,7 +570,19 @@ class EncodedFile:
537
570
  self.encoding, self.bom_length = detect_by_bom(filename, file_encoding)
538
571
  self.fo: io.TextIOWrapper | None = None
539
572
 
540
- def open(self, mode: str = "r") -> io.TextIOWrapper:
573
+ def open(self, mode: str = "r", newline: str | None = None) -> io.TextIOWrapper:
574
+ """Open the file in text mode.
575
+
576
+ Args:
577
+ mode: Any mode accepted by :func:`open`.
578
+ newline: Passed straight to :func:`open`. The default ``None``
579
+ enables universal-newline translation, which rewrites every
580
+ ``\n`` written as ``os.linesep`` — ``\r\n`` on Windows. That
581
+ is right for line terminators and wrong for data: a newline
582
+ *inside* a quoted field is rewritten too, so the value read
583
+ back is not the value exported. Writers whose output can
584
+ carry an embedded newline pass ``""`` to disable it.
585
+ """
541
586
  import execsql.state as _state
542
587
 
543
588
  conf = _state.conf
@@ -548,7 +593,7 @@ class EncodedFile:
548
593
  mode=mode,
549
594
  encoding=self.encoding,
550
595
  errors=conf.enc_err_disposition,
551
- newline=None,
596
+ newline=newline,
552
597
  ),
553
598
  )
554
599
  assert self.fo is not None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execsql2
3
- Version: 2.22.9
3
+ Version: 2.23.1
4
4
  Summary: Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables.
5
5
  Project-URL: Homepage, https://execsql2.readthedocs.io
6
6
  Project-URL: Repository, https://github.com/geocoug/execsql
@@ -224,17 +224,26 @@ execsql script.sql # read connection from config file
224
224
 
225
225
  ### Supported Databases
226
226
 
227
- | Flag | Database |
228
- | ---- | --------------- |
229
- | `p` | PostgreSQL |
230
- | `m` | MySQL / MariaDB |
231
- | `s` | MS SQL Server |
232
- | `l` | SQLite |
233
- | `k` | DuckDB |
234
- | `a` | MS Access |
235
- | `f` | Firebird |
236
- | `o` | Oracle |
237
- | `d` | ODBC DSN |
227
+ | Flag | Database | Support |
228
+ | ---- | --------------- | ------------------------------------------------ |
229
+ | `p` | PostgreSQL | Supported — verified against a live server in CI |
230
+ | `m` | MySQL / MariaDB | Supported — verified against a live server in CI |
231
+ | `s` | MS SQL Server | Supported — verified against a live server in CI |
232
+ | `l` | SQLite | Supported — verified against real files in CI |
233
+ | `k` | DuckDB | Supported — verified against real files in CI |
234
+ | `a` | MS Access | Best effort — not verified in CI |
235
+ | `f` | Firebird | Best effort — not verified in CI |
236
+ | `o` | Oracle | Best effort — not verified in CI |
237
+ | `d` | ODBC DSN | Best effort — not verified in CI |
238
+
239
+ **Supported** adapters run against a live server or a real database file on
240
+ every CI run; a regression blocks the release and bugs get fixed. **Best
241
+ effort** adapters are carried forward from the upstream monolith and are not
242
+ exercised anywhere in CI — the code is there and may work, but nothing proves
243
+ it still does. Issues and pull requests are welcome for them; no guarantee is
244
+ made. Opening a best-effort connection prints one informational line, which
245
+ `support_tier_notice=No` in the `[interface]` section of `execsql.conf`
246
+ silences.
238
247
 
239
248
  ### Common options
240
249
 
@@ -384,7 +393,7 @@ execsql-format --no-sql --in-place scripts/
384
393
  ```yaml
385
394
  repos:
386
395
  - repo: https://github.com/geocoug/execsql
387
- rev: v2.22.9
396
+ rev: v2.23.1
388
397
  hooks:
389
398
  - id: execsql-format
390
399
  ```
@@ -1,56 +1,57 @@
1
1
  execsql/__init__.py,sha256=ZeVnpEWu8M2bn3qLmVM72NhWRueUGNbsX8UAPTermo0,901
2
2
  execsql/__main__.py,sha256=HdbK-SAhyUmfB6xINY5AzxdMSxGzWSGEG_2dv42Jn64,315
3
- execsql/api.py,sha256=EOtBwMnm-8fmB_KmvxyjglR6C7CjdYhCPBisJ9CFfJg,22227
4
- execsql/config.py,sha256=txKziUJLV7UPonj2sGFgkmlinDdSV50aHmR_cuCbEIo,34369
3
+ execsql/api.py,sha256=gBNEINlQSncfhO1tvc-qD1MBXTuhDVIP16LhiqfnzQI,25334
4
+ execsql/config.py,sha256=riUh3DVOoScpqF-GK2EAcycu_1Y9PhWTghDuJSSUJjs,34507
5
5
  execsql/exceptions.py,sha256=GlphAiR8iZu4UR4U50WgSqEUMd9_8AeQJ_hhPcJOeQU,9381
6
6
  execsql/format.py,sha256=OOxsOX6g7otVgL3gI6uGxa5WIh8GTvjJ8WO-_P91zXg,52886
7
7
  execsql/models.py,sha256=-DWTVrPNwM-n1h3e3rXMoBv9-wpWVdZahyy4RB7fRRE,15502
8
8
  execsql/parser.py,sha256=aOxZ7Mzgvk7G4-nvy9Bgz7xlaZm6oo81cffDeBk_LCk,15597
9
9
  execsql/plugins.py,sha256=l82VWa5NpvOQWD6vcO-WKP-vtn0wp9__wWDFAbwxZg0,12838
10
10
  execsql/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- execsql/state.py,sha256=T6UoXXxAkUP-4KKQpfFAlI3WMzm2xUi3LSplJDuRLY0,21965
12
- execsql/state.pyi,sha256=ES5xdoId-ALCGnLIQvQIGBZljZRB6aOOEMRLKXjO9hA,3770
13
- execsql/types.py,sha256=eKMF2kb5LHrEwKsiFpy6z_fEH05yC0Cpsg98Ea4SpVA,32231
11
+ execsql/state.py,sha256=wu7T1fkXROiQ2LoBYLONYj-1BkDUdoYzV425aCeAwm4,22230
12
+ execsql/state.pyi,sha256=YByEn5N7r0M4vDceOoDGTgb2tRJ_gNkYWGjlLiqQorI,3839
13
+ execsql/types.py,sha256=8rAoRaWwgBnR-ZhNEfahTTbZ_D4fB4vBuGeMEUnu7vE,32454
14
14
  execsql/cli/__init__.py,sha256=WPwEIELz-9XFG3Dpf-037eeYBdjtZStxWkT1bc3tMek,23112
15
15
  execsql/cli/dsn.py,sha256=svaZtrUXFRL2W5G6FRRiKtR6kehOp7urrVhIx_642Z8,2820
16
16
  execsql/cli/help.py,sha256=ThwdZuMIfLPxLAPpGWwXFY_UfyWvYOCjdlBNK20Vzd8,5718
17
17
  execsql/cli/lint.py,sha256=YqKzFNUhyb_Th69hYgKk1ZZVjCsZfJMIiUGqp06JwNs,17236
18
18
  execsql/cli/run.py,sha256=Yb-Ri3cds0st1hUn4_w-PHMphTsArHhC4fx919SW9gU,39390
19
19
  execsql/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- execsql/data/execsql.conf.template,sha256=zbjEluk6j9vnW74nlWpvopM6HDYe0rwJhsPVzU-e0Ss,11032
20
+ execsql/data/execsql.conf.template,sha256=qqH_G3SiKBepljY3Go4rDDlhe3pIM6gOgsjAnLn0arg,11244
21
21
  execsql/db/__init__.py,sha256=jTbuafuKOqYtXFR1wvCOoKK5Lr3l1uErfaIbIr6UywI,1063
22
- execsql/db/access.py,sha256=h2zAMr3mQrm6vFlOYaN7iaG19K7gitXDuonllelqbcE,19539
23
- execsql/db/base.py,sha256=0K6mSCqFcheg_T91VOwEnagqqP_eLL2dP5VN4yDz36Q,35414
24
- execsql/db/dsn.py,sha256=P17FwrjEkmhYiPCWZSRJuHYIQu_BCkumiXLkwZEMb4o,6334
25
- execsql/db/duckdb.py,sha256=YxtjWSzkbJEzZcfoYKfsA9QRrRL08A31GYzkolJiIw0,3229
22
+ execsql/db/access.py,sha256=2VlfEDXvV8xoi1t_hKzEaIidCJ1XGerYFPFvW5FqVBI,20489
23
+ execsql/db/base.py,sha256=2bK1TBU9IAHnQQcdgJ-wEwm5TzrhnwO6j6BGjR9VAHg,40656
24
+ execsql/db/dsn.py,sha256=hC_oWrBz2NSGyAOjZsROxGHs9eI_CSpnnken12wH1hU,6663
25
+ execsql/db/duckdb.py,sha256=h8fh_5Ps1UcXvfyG9UlSyP32Yoa0W8sn246RlQ4xOMU,6970
26
26
  execsql/db/factory.py,sha256=C_cyi3GjNx0opuwc6maFFeCSkjfOfoUjuf68YT4VAHE,5377
27
- execsql/db/firebird.py,sha256=cV5wUzQHoz7yugHdNxAn8IW7fL3v1riIsGLykCZhZwA,9480
28
- execsql/db/mysql.py,sha256=hv_OqoJBVIaCh5e2lMTVrgBTNljAaVnxwlAoQYff8c4,18026
29
- execsql/db/oracle.py,sha256=1_odb5xmlm8vjdJdQXz7SHm9dzIbZ5sxP_IxTklH3kA,12018
30
- execsql/db/postgres.py,sha256=LIZgx4T_UPZvOk_mn0l832ShNKgzculdOrVrFO7Rj8I,22045
31
- execsql/db/sqlite.py,sha256=mx56IDwLKAXdep--4C8j15qK22JkJjworSJkfnx1ZFw,11551
32
- execsql/db/sqlserver.py,sha256=j2ViLoBWzizgaL0u6V4iHfjinrlJ4rpBD3XZiKKdwSU,8968
27
+ execsql/db/firebird.py,sha256=fbzlGB6DeR-S9RFLUD4tJYPN-_76tyRLBkQl5LRJTDo,9640
28
+ execsql/db/mysql.py,sha256=vG_5NPoe82FLvdfY4e7ZnjX0-mgts4D3S40LwZKb7U8,20489
29
+ execsql/db/oracle.py,sha256=jjXwhk_og1qHqdAB16i_dZYXY0Ze7Bg5EvKdCKwjQtE,12667
30
+ execsql/db/postgres.py,sha256=HfrWuJ5-K5le1sY9iGv_E51JHciPIdA0UvyLsTKlnO4,22568
31
+ execsql/db/sqlite.py,sha256=zfe-KNAuTIHDh_qk3yzCo6fMerlmtt7UFmg-lbdZFm4,12167
32
+ execsql/db/sqlserver.py,sha256=O4E9OD3V3Xowsjl3KMdYHNCBeETlkJS9HUzNKEKuA9A,8943
33
+ execsql/db/tiers.py,sha256=PH2sUYwlYqcANGVKXprWQKVIlM6fpWU9q74djn8oFwc,2924
33
34
  execsql/debug/__init__.py,sha256=j6EGUR0dHzUhWN1mHHtf1-Lhjq3Sb1V-vmnq2Ztgj1M,178
34
35
  execsql/debug/repl.py,sha256=JObeoEXh15qyk4Q3WQCCqMcBtojlIcu_Xg-ZRDZJi5Q,25491
35
36
  execsql/exporters/__init__.py,sha256=-Cnji-OgodJV8ftcDcOyTof0kQMy9J5kKVC8GVFpc3o,670
36
37
  execsql/exporters/base.py,sha256=_GoO0YqwlTxrjogxHI3CxxRR64sMgIEjRogt0KCqzoY,6402
37
- execsql/exporters/delimited.py,sha256=vd9Q74TzeeWSPU03EboqqCBOWwOOeFVL544sPXINI0w,32755
38
+ execsql/exporters/delimited.py,sha256=v47Js8ZrQfTqx0aTDAD-9nkOx4ilAPnk_dZT3vAoCTw,33632
38
39
  execsql/exporters/duckdb.py,sha256=912TMdYaSVD-kb-_oebTBHQp8FvYMbWTDEDD80w5Z50,3455
39
40
  execsql/exporters/feather.py,sha256=tah48aep0cQRikZcmADXUPTzFddgDUT78Ndw_l0Hsj4,4178
40
- execsql/exporters/html.py,sha256=BPTGYODiC5_5zaQsVkZ9QVAl67yfCWFTsjK0D-QOJkM,9717
41
+ execsql/exporters/html.py,sha256=hwf9UHs7EZ7xiP3p9ilBIsAukXcDu-KO2dcQHVh2z30,10111
41
42
  execsql/exporters/json.py,sha256=wWGT6zjvIdWlO5FmXbaEw1xOhy23f1YY6bm5uQD_NS0,4393
42
- execsql/exporters/latex.py,sha256=TiHH9EO4eF2AgdUyjpbHNZhvKhIJl8Ew6NoO1z0YbB0,4484
43
- execsql/exporters/markdown.py,sha256=MOErBwkMHM552JE0QuNkCRyHpxTEI3Pw7o9bZOe3RE8,4447
44
- execsql/exporters/ods.py,sha256=oenUeZuC34Urlh7rI-PXIWOc-cuKMfUU4HfYj4xzvkQ,19521
43
+ execsql/exporters/latex.py,sha256=bdUN3GwfENUZHgpw6bvjsjfivDgzyf-HRkYTP-eH-pM,5480
44
+ execsql/exporters/markdown.py,sha256=FuMGFxm9uZUOrdEuXT2ZZLCqmVDly7SMrFlrjP6kVEI,4827
45
+ execsql/exporters/ods.py,sha256=Ke9pfcyT6R85LWIWcMI6pzRzkKir5w_gmiptCeeuoBc,20730
45
46
  execsql/exporters/parquet.py,sha256=mbCo2Wlit1lkXmyo5EyLd_ATIHSICS49bouiBT2kdAs,1121
46
- execsql/exporters/pretty.py,sha256=tG7Yr4lwFMs3a0Jrsq6qsNNkE8Q7sMePr61SS5QMaTs,3447
47
+ execsql/exporters/pretty.py,sha256=SiJHBXIjoFsOHegXcdrtxYa6xSIPga1U0DQEy7pK4QY,4145
47
48
  execsql/exporters/protocol.py,sha256=BxATgz0xKHbB2FpZBeNg7wZfIiCohhD1awlr3JCec0c,4372
48
49
  execsql/exporters/raw.py,sha256=9o3BMt7UYmnjbP8OEzmM2kNKfwwERi2yDcuNfUoEfuQ,2530
49
50
  execsql/exporters/sqlite.py,sha256=QjP_W90S-hecNqp2A-Vy58DD8MZitME1sTq4lqIS43w,3401
50
- execsql/exporters/templates.py,sha256=wXvN6HwOHbro6t306Dq7WcnxwGdJMF1veXry9hwuI3k,6016
51
- execsql/exporters/values.py,sha256=HIyud31aux_dbCphfKHEGeZB9fkIPE5PoGXQz817XIE,2520
51
+ execsql/exporters/templates.py,sha256=nRFurwTb5nxoyHpx609FGIp3MDbX_mYQ3IvgswaEbyA,7054
52
+ execsql/exporters/values.py,sha256=UPxN5IprasBZLqM5jfUXQihjdTeBFTxbJslOEtmGOcY,3384
52
53
  execsql/exporters/xls.py,sha256=iZ_N7hneyfaDKbO1XdYv6doJCFPqJWEJql5rduoNyRU,11197
53
- execsql/exporters/xlsx.py,sha256=0f-Gdp8DyB3muUdH6tyiGFKGx9UymZ4fL3ja6H0sBjI,11853
54
+ execsql/exporters/xlsx.py,sha256=5pTN8OsygLjk3MADJf8O7t3bdzSul7rrVO7SVSR581c,12223
54
55
  execsql/exporters/xml.py,sha256=t1PSr3i8xvTCWzd9jaxxAy5NcRpl6sqjnZALafKCqpM,2575
55
56
  execsql/exporters/yaml.py,sha256=R61Rs_0rd5G3bg344L4hC84GM79IfYXaDO2tkF-BluY,3121
56
57
  execsql/exporters/zip.py,sha256=341z4Z4MPtEkXJEtfiMSiuJigERh5_f8RDbNMBbt8KM,5078
@@ -94,30 +95,30 @@ execsql/utils/auth.py,sha256=8Wixkx5nayEBG7RT4WTUQpCiElIKS3yOTV_6_-hHTRs,8889
94
95
  execsql/utils/crypto.py,sha256=KlT6lPk-v0-qQQfAMfWvT9Q6kRdCD3_5JVaLajNocKM,3051
95
96
  execsql/utils/datetime.py,sha256=8BrD24KWeMoouJZiFaXK4HF7plc-O_xrzIw12qOEyp8,3629
96
97
  execsql/utils/errors.py,sha256=bDWooUmGdN8xqUt6csq466wPqKPLHHSi7U4hsmrFZxA,8577
97
- execsql/utils/fileio.py,sha256=_15UIdcRZxZn2R6YP4xQn-6C9CVK2yxj1oEfxULo2_c,33329
98
+ execsql/utils/fileio.py,sha256=ONLoXkq5PV4dvNc16UMgi9-EY2Wy4mNUFxneSrX91N0,35231
98
99
  execsql/utils/gui.py,sha256=X5aw6LVoeaAdHaQkymm4ba176jga0cS2GrqxSFWTWTg,23853
99
100
  execsql/utils/mail.py,sha256=SXZac24p62qxDbIviO8VdDZTbKljIoJWgWZfxIGu5zI,6260
100
101
  execsql/utils/numeric.py,sha256=_7bi5R6pHjMCkOPne_Sh5nUj-B8e9g6WFmjptFHaunA,1573
101
102
  execsql/utils/regex.py,sha256=B3mSBhRRx_DpUnX_t9IoYd05KvWAebiLMCZqQAmEwcw,3885
102
103
  execsql/utils/strings.py,sha256=UQNjpRCEFa1UO6feU-M-9e24wWAvizs_iu_4fFusLxo,8516
103
104
  execsql/utils/timer.py,sha256=eDYf5VzCNFk7oo90InJucUm3XcBdhYMogjZMqeg9xzc,1899
104
- execsql2-2.22.9.data/data/execsql2_extras/README.md,sha256=vX4NTL095dUoA_hesyRMGYBorEZ_Y_tJ9qrd-MVV09I,5032
105
- execsql2-2.22.9.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
106
- execsql2-2.22.9.data/data/execsql2_extras/example_config_prompt.sql,sha256=2e8KzzVWhho8KxYVHETSVmZdhW7wodioDsqBLSL6m4s,7487
107
- execsql2-2.22.9.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
108
- execsql2-2.22.9.data/data/execsql2_extras/md_compare.sql,sha256=qYYVAjSeHZzjszxV3Bv6bg8Ckbq2kMHl87_gh4sywMU,24140
109
- execsql2-2.22.9.data/data/execsql2_extras/md_glossary.sql,sha256=hkZ2Onn57LAKKsuXxzhR8tPtcWXkmWEQkwPE58-Tm2k,10796
110
- execsql2-2.22.9.data/data/execsql2_extras/md_upsert.sql,sha256=_CAK4BzEboRXTNy03SJR-oOjcEdSNMuRBPL6noWUptY,112560
111
- execsql2-2.22.9.data/data/execsql2_extras/pg_compare.sql,sha256=1zJd4hVUKHR0tncc2qTBC9B4qVV4Us2ITkJpsjN3tMw,24352
112
- execsql2-2.22.9.data/data/execsql2_extras/pg_glossary.sql,sha256=IKuwna-_8b20ljSkXZruuiQigrCpo7ueQdUqd1MXiuI,9908
113
- execsql2-2.22.9.data/data/execsql2_extras/pg_upsert.sql,sha256=HpPJtTHvpEjQy03j-3iPxDEOHMRkudOg7O4D4YR38UI,108315
114
- execsql2-2.22.9.data/data/execsql2_extras/script_template.sql,sha256=2J35ddZPguJ-vwTsz83wErv0jiWUyJcdW_JM0mNKDXA,11155
115
- execsql2-2.22.9.data/data/execsql2_extras/ss_compare.sql,sha256=j1qVNUPXQsEU7-DoVgDJCGcE0EuIl7whLBT3fgeiMAo,24833
116
- execsql2-2.22.9.data/data/execsql2_extras/ss_glossary.sql,sha256=2gLxv34xzKt0vy7hSzJH7a9JiMC3ETrv9MofxQwAibU,13065
117
- execsql2-2.22.9.data/data/execsql2_extras/ss_upsert.sql,sha256=G_8rQ0VzuKIZHWs24O_WrfzpC5S27R1JsL-bFBR3SUQ,117730
118
- execsql2-2.22.9.dist-info/METADATA,sha256=Ku6XhxrqV05mj1lvzrZEO6p4uKCa_PA2tbs43yBT9ew,20382
119
- execsql2-2.22.9.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
120
- execsql2-2.22.9.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
121
- execsql2-2.22.9.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
122
- execsql2-2.22.9.dist-info/licenses/NOTICE,sha256=McYzgxYav3U1OaVsY4Su1sfBrfmplpRdA9b6-gCDQCg,342
123
- execsql2-2.22.9.dist-info/RECORD,,
105
+ execsql2-2.23.1.data/data/execsql2_extras/README.md,sha256=vX4NTL095dUoA_hesyRMGYBorEZ_Y_tJ9qrd-MVV09I,5032
106
+ execsql2-2.23.1.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
107
+ execsql2-2.23.1.data/data/execsql2_extras/example_config_prompt.sql,sha256=2e8KzzVWhho8KxYVHETSVmZdhW7wodioDsqBLSL6m4s,7487
108
+ execsql2-2.23.1.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
109
+ execsql2-2.23.1.data/data/execsql2_extras/md_compare.sql,sha256=qYYVAjSeHZzjszxV3Bv6bg8Ckbq2kMHl87_gh4sywMU,24140
110
+ execsql2-2.23.1.data/data/execsql2_extras/md_glossary.sql,sha256=hkZ2Onn57LAKKsuXxzhR8tPtcWXkmWEQkwPE58-Tm2k,10796
111
+ execsql2-2.23.1.data/data/execsql2_extras/md_upsert.sql,sha256=_CAK4BzEboRXTNy03SJR-oOjcEdSNMuRBPL6noWUptY,112560
112
+ execsql2-2.23.1.data/data/execsql2_extras/pg_compare.sql,sha256=1zJd4hVUKHR0tncc2qTBC9B4qVV4Us2ITkJpsjN3tMw,24352
113
+ execsql2-2.23.1.data/data/execsql2_extras/pg_glossary.sql,sha256=IKuwna-_8b20ljSkXZruuiQigrCpo7ueQdUqd1MXiuI,9908
114
+ execsql2-2.23.1.data/data/execsql2_extras/pg_upsert.sql,sha256=HpPJtTHvpEjQy03j-3iPxDEOHMRkudOg7O4D4YR38UI,108315
115
+ execsql2-2.23.1.data/data/execsql2_extras/script_template.sql,sha256=2J35ddZPguJ-vwTsz83wErv0jiWUyJcdW_JM0mNKDXA,11155
116
+ execsql2-2.23.1.data/data/execsql2_extras/ss_compare.sql,sha256=j1qVNUPXQsEU7-DoVgDJCGcE0EuIl7whLBT3fgeiMAo,24833
117
+ execsql2-2.23.1.data/data/execsql2_extras/ss_glossary.sql,sha256=2gLxv34xzKt0vy7hSzJH7a9JiMC3ETrv9MofxQwAibU,13065
118
+ execsql2-2.23.1.data/data/execsql2_extras/ss_upsert.sql,sha256=G_8rQ0VzuKIZHWs24O_WrfzpC5S27R1JsL-bFBR3SUQ,117730
119
+ execsql2-2.23.1.dist-info/METADATA,sha256=Zp_UKzwuqCVFmA3-yQrsaenr3QI_sFkgWAtNAQpl-OE,21504
120
+ execsql2-2.23.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
121
+ execsql2-2.23.1.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
122
+ execsql2-2.23.1.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
123
+ execsql2-2.23.1.dist-info/licenses/NOTICE,sha256=McYzgxYav3U1OaVsY4Su1sfBrfmplpRdA9b6-gCDQCg,342
124
+ execsql2-2.23.1.dist-info/RECORD,,