execsql2 2.23.1__py3-none-any.whl → 2.25.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/api.py +169 -160
- execsql/cli/__init__.py +19 -586
- execsql/cli/application.py +309 -0
- execsql/cli/commands/__init__.py +13 -0
- execsql/cli/commands/config.py +205 -0
- execsql/cli/commands/format.py +100 -0
- execsql/cli/commands/init.py +135 -0
- execsql/cli/commands/lint.py +225 -0
- execsql/cli/commands/listing.py +81 -0
- execsql/cli/commands/run.py +459 -0
- execsql/cli/dispatch.py +66 -0
- execsql/cli/dsn.py +11 -4
- execsql/cli/help.py +175 -24
- execsql/cli/lint.py +780 -100
- execsql/cli/options.py +108 -0
- execsql/cli/run.py +96 -32
- execsql/config.py +256 -173
- execsql/config_validation.py +282 -0
- execsql/data/execsql.conf.template +38 -5
- execsql/data/script_header.sql +23 -0
- execsql/db/access.py +29 -8
- execsql/db/base.py +40 -8
- execsql/db/dsn.py +13 -4
- execsql/db/duckdb.py +3 -1
- execsql/db/factory.py +13 -4
- execsql/db/firebird.py +21 -7
- execsql/db/mysql.py +37 -16
- execsql/db/oracle.py +49 -16
- execsql/db/postgres.py +30 -6
- execsql/db/sqlite.py +7 -9
- execsql/db/sqlserver.py +25 -8
- execsql/debug/repl.py +51 -193
- execsql/exceptions.py +9 -0
- execsql/exporters/delimited.py +87 -28
- execsql/exporters/xlsx.py +24 -9
- execsql/exporters/zip.py +1 -2
- execsql/format.py +115 -76
- execsql/gui/desktop.py +1 -3
- execsql/gui/tui.py +2 -2
- execsql/importers/base.py +35 -1
- execsql/importers/csv.py +3 -1
- execsql/interactive.py +232 -0
- execsql/manifest.py +200 -0
- execsql/metacommands/conditions.py +7 -8
- execsql/metacommands/control.py +2 -3
- execsql/metacommands/data.py +4 -1
- execsql/metacommands/debug.py +2 -4
- execsql/metacommands/effects.py +124 -0
- execsql/metacommands/io_fileops.py +62 -37
- execsql/metacommands/io_import.py +0 -1
- execsql/metacommands/prompt.py +2 -0
- execsql/metacommands/upsert.py +5 -2
- execsql/models.py +3 -2
- execsql/parser.py +14 -5
- execsql/plugins.py +24 -0
- execsql/script/__init__.py +0 -9
- execsql/script/ast.py +1 -1
- execsql/script/engine.py +46 -104
- execsql/script/executor.py +162 -39
- execsql/script/parser.py +167 -118
- execsql/state.py +34 -11
- execsql/state.pyi +11 -0
- execsql/types.py +22 -13
- execsql/utils/auth.py +169 -24
- execsql/utils/color.py +18 -0
- execsql/utils/datetime.py +55 -17
- execsql/utils/errors.py +82 -10
- execsql/utils/fileio.py +404 -117
- execsql/utils/gui.py +3 -0
- execsql/utils/mail.py +37 -12
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/README.md +1 -1
- {execsql2-2.23.1.dist-info → execsql2-2.25.0.dist-info}/METADATA +122 -63
- execsql2-2.25.0.dist-info/RECORD +140 -0
- execsql2-2.25.0.dist-info/entry_points.txt +2 -0
- execsql2-2.23.1.dist-info/RECORD +0 -124
- execsql2-2.23.1.dist-info/entry_points.txt +0 -3
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/md_compare.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/md_glossary.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/md_upsert.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/pg_compare.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/pg_glossary.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/pg_upsert.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/script_template.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/ss_compare.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/ss_glossary.sql +0 -0
- {execsql2-2.23.1.data → execsql2-2.25.0.data}/data/execsql2_extras/ss_upsert.sql +0 -0
- {execsql2-2.23.1.dist-info → execsql2-2.25.0.dist-info}/WHEEL +0 -0
- {execsql2-2.23.1.dist-info → execsql2-2.25.0.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.23.1.dist-info → execsql2-2.25.0.dist-info}/licenses/NOTICE +0 -0
execsql/utils/gui.py
CHANGED
|
@@ -533,6 +533,9 @@ def gui_credentials(
|
|
|
533
533
|
_state.subvars.add_substitution(username, uname)
|
|
534
534
|
if pwtext:
|
|
535
535
|
_state.subvars.add_substitution(pwtext, passwd)
|
|
536
|
+
from execsql.utils.fileio import register_secret
|
|
537
|
+
|
|
538
|
+
register_secret(passwd)
|
|
536
539
|
|
|
537
540
|
|
|
538
541
|
# ---------------------------------------------------------------------------
|
execsql/utils/mail.py
CHANGED
|
@@ -12,6 +12,7 @@ metacommand and the halt/cancel email-notification hooks.
|
|
|
12
12
|
|
|
13
13
|
import re
|
|
14
14
|
import smtplib
|
|
15
|
+
import ssl
|
|
15
16
|
from email import encoders
|
|
16
17
|
from email.mime.base import MIMEBase
|
|
17
18
|
from email.mime.multipart import MIMEMultipart
|
|
@@ -25,6 +26,20 @@ from execsql.exceptions import ErrInfo
|
|
|
25
26
|
__all__ = ["MailSpec", "Mailer"]
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
def _tls_context(conf: object) -> ssl.SSLContext:
|
|
30
|
+
"""The TLS context for the SMTP connection: verifying, unless ``[email] verify_certificate`` is off.
|
|
31
|
+
|
|
32
|
+
``smtplib`` given no context uses an unverified one, which accepts any
|
|
33
|
+
certificate and hands the SMTP password to whoever answers.
|
|
34
|
+
"""
|
|
35
|
+
if not getattr(conf, "smtp_verify_certificate", True):
|
|
36
|
+
ctx = ssl.create_default_context()
|
|
37
|
+
ctx.check_hostname = False
|
|
38
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
39
|
+
return ctx
|
|
40
|
+
return ssl.create_default_context(cafile=getattr(conf, "smtp_ca_file", None))
|
|
41
|
+
|
|
42
|
+
|
|
28
43
|
class Mailer:
|
|
29
44
|
def __repr__(self) -> str:
|
|
30
45
|
return "Mailer()"
|
|
@@ -56,20 +71,30 @@ class Mailer:
|
|
|
56
71
|
# 30 s connect/read timeout matches the DB-adapter default so a
|
|
57
72
|
# silently-dropped SMTP peer can't hang a script (or a CI run).
|
|
58
73
|
smtp_timeout = 30
|
|
59
|
-
|
|
74
|
+
port = conf.smtp_port or 0
|
|
75
|
+
try:
|
|
60
76
|
if conf.smtp_ssl:
|
|
61
|
-
self.smtpconn = smtplib.SMTP_SSL(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
self.smtpconn = smtplib.SMTP_SSL(
|
|
78
|
+
conf.smtp_host,
|
|
79
|
+
port,
|
|
80
|
+
timeout=smtp_timeout,
|
|
81
|
+
context=_tls_context(conf),
|
|
82
|
+
)
|
|
67
83
|
else:
|
|
68
|
-
self.smtpconn = smtplib.SMTP(conf.smtp_host,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
self.smtpconn = smtplib.SMTP(conf.smtp_host, port, timeout=smtp_timeout)
|
|
85
|
+
self.smtpconn.ehlo_or_helo_if_needed()
|
|
86
|
+
if conf.smtp_tls:
|
|
87
|
+
self.smtpconn.starttls(context=_tls_context(conf))
|
|
88
|
+
self.smtpconn.ehlo(conf.smtp_host)
|
|
89
|
+
except ssl.SSLCertVerificationError as exc:
|
|
90
|
+
raise ErrInfo(
|
|
91
|
+
type="error",
|
|
92
|
+
other_msg=(
|
|
93
|
+
f"Can't send email; the certificate of SMTP server {conf.smtp_host} could not be verified "
|
|
94
|
+
f"({exc.verify_message}). For a server with an internal or self-signed certificate, set "
|
|
95
|
+
"[email] ca_file to its CA certificate, or set verify_certificate = No."
|
|
96
|
+
),
|
|
97
|
+
) from exc
|
|
73
98
|
if conf.smtp_username:
|
|
74
99
|
if not conf.smtp_password:
|
|
75
100
|
# smtplib.login() requires a password; calling it with only a
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Several types of templates are provided that may be useful in conjunction with execsql. These are:
|
|
4
4
|
|
|
5
|
-
- **execsql.conf** — An annotated reference of every configuration setting with notes on its usage. Generate a fresh copy in any directory with `execsql --init
|
|
5
|
+
- **execsql.conf** — An annotated reference of every configuration setting with notes on its usage. Generate a fresh copy in any directory with `execsql config --init > execsql.conf`; the canonical content ships inside the installed package and is loaded via `importlib.resources` (no need to find or copy a source file).
|
|
6
6
|
|
|
7
7
|
- **script_template.sql** — A framework for SQL scripts that make use of several execsql features. It includes sections for custom configuration settings, custom logfile creation, and reporting of unexpected script exits (through user cancellation or errors).
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.25.0
|
|
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
|
|
@@ -42,7 +42,7 @@ Requires-Python: >=3.10
|
|
|
42
42
|
Requires-Dist: python-dateutil>=2.8
|
|
43
43
|
Requires-Dist: rich>=13.0
|
|
44
44
|
Requires-Dist: textual>=1.0
|
|
45
|
-
Requires-Dist: typer>=0.
|
|
45
|
+
Requires-Dist: typer>=0.26
|
|
46
46
|
Provides-Extra: all
|
|
47
47
|
Requires-Dist: defusedxml>=0.7; extra == 'all'
|
|
48
48
|
Requires-Dist: duckdb>=1.0; extra == 'all'
|
|
@@ -52,7 +52,7 @@ Requires-Dist: keyring>=25.0; extra == 'all'
|
|
|
52
52
|
Requires-Dist: odfpy>=1.4; extra == 'all'
|
|
53
53
|
Requires-Dist: openpyxl>=3.1; extra == 'all'
|
|
54
54
|
Requires-Dist: oracledb>=3.0; extra == 'all'
|
|
55
|
-
Requires-Dist: pg-upsert>=1.
|
|
55
|
+
Requires-Dist: pg-upsert>=1.25.0; extra == 'all'
|
|
56
56
|
Requires-Dist: polars>=1.0; extra == 'all'
|
|
57
57
|
Requires-Dist: psycopg[binary]<4,>=3.1; extra == 'all'
|
|
58
58
|
Requires-Dist: pymysql>=1.1; extra == 'all'
|
|
@@ -126,7 +126,7 @@ Requires-Dist: oracledb>=3.0; extra == 'oracle'
|
|
|
126
126
|
Provides-Extra: postgres
|
|
127
127
|
Requires-Dist: psycopg[binary]<4,>=3.1; extra == 'postgres'
|
|
128
128
|
Provides-Extra: upsert
|
|
129
|
-
Requires-Dist: pg-upsert>=1.
|
|
129
|
+
Requires-Dist: pg-upsert>=1.25.0; extra == 'upsert'
|
|
130
130
|
Description-Content-Type: text/markdown
|
|
131
131
|
|
|
132
132
|
> [!NOTE]
|
|
@@ -154,7 +154,54 @@ Description-Content-Type: text/markdown
|
|
|
154
154
|
|
|
155
155
|
## Overview
|
|
156
156
|
|
|
157
|
-
*execsql*
|
|
157
|
+
*execsql* is a toolchain for SQL scripts: **write** them with editor support, **format** them consistently, **lint** them without a database, and **run** them against nine DBMSs.
|
|
158
|
+
|
|
159
|
+
Scripts are ordinary SQL plus metacommands embedded in comments (`-- !x!`), which add importing and exporting data, copying between databases, conditional execution, looping, substitution variables, and interactive prompts. Because the metacommands live in comments, the scripts stay valid SQL and other tools (`psql`, `sqlcmd`, your editor) ignore them.
|
|
160
|
+
|
|
161
|
+
| Command | What it does | Needs a database? |
|
|
162
|
+
| ------------------------------------------ | ----------------------------------------------------------------------- | ----------------- |
|
|
163
|
+
| `execsql format` | Normalize keywords, indentation, and SQL layout | No |
|
|
164
|
+
| `execsql lint` | Static analysis: structure, unknown metacommands, variables, targets | No |
|
|
165
|
+
| `execsql run` | Run the script against PostgreSQL, MySQL, SQLite, DuckDB, … | Yes |
|
|
166
|
+
| `execsql config` | Show every config option, its value, and the file that set it | No |
|
|
167
|
+
| `execsql list` | Metacommands, encodings, plugins, or the keyword vocabulary | No |
|
|
168
|
+
| `execsql init` | Set up a project: config file, a script with a header, pre-commit hooks | No |
|
|
169
|
+
| [VS Code extension](extras/vscode-execsql) | Syntax highlighting for metacommands and variables | No |
|
|
170
|
+
|
|
171
|
+
`format` and `lint` take files or directories.
|
|
172
|
+
|
|
173
|
+
> [!WARNING]
|
|
174
|
+
> The original positional form, `execsql script.sql myserver mydb`, still works
|
|
175
|
+
> but is deprecated: it prints a warning and stops working in execsql2 3.0. Use
|
|
176
|
+
> `execsql run script.sql myserver mydb`.
|
|
177
|
+
|
|
178
|
+
## Quick start: no database required
|
|
179
|
+
|
|
180
|
+
`format` and `lint` work on a bare `.sql` file, with no server and no config. Try them first:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
uv tool install "execsql2[formatter]" # or: pipx install "execsql2[formatter]"
|
|
184
|
+
|
|
185
|
+
execsql format --check scripts/ # is it formatted?
|
|
186
|
+
execsql format -i scripts/ # format it
|
|
187
|
+
execsql lint scripts/ # find problems before they cost you a run
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`lint` reports unmatched blocks, misspelled or malformed metacommands and conditions, undefined and unused substitution variables, unreachable branches, and `INCLUDE`/`SCRIPT` targets that do not exist: the failures that otherwise surface halfway through a run against a live database:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
$ execsql lint load_data.sql
|
|
194
|
+
load_data.sql
|
|
195
|
+
1 warning V002 variable !!site_cd!! is never used
|
|
196
|
+
2 warning I001 INCLUDE file does not exist: common/setup.sql
|
|
197
|
+
3 warning V001 undefined variable !!site_code!!
|
|
198
|
+
|
|
199
|
+
Found 3 issues in 1 file: 3 warnings (1 file checked)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`V002` and `V001` together point at a typo: `site_cd` is defined and `site_code` is used. Every issue has a rule code for `--select` and `--ignore`; `--output-format concise` prints one `path:line` line per issue and `json` feeds CI tools. The [lint rules](https://execsql2.readthedocs.io/en/latest/reference/lint/) page explains each one.
|
|
203
|
+
|
|
204
|
+
`execsql format` also runs as a [pre-commit hook](#formatting-scripts), so formatting is enforced without anyone remembering to run it.
|
|
158
205
|
|
|
159
206
|
## Example
|
|
160
207
|
|
|
@@ -197,49 +244,59 @@ The `PROMPT` metacommand produces a GUI display of the data:
|
|
|
197
244
|
## Installation
|
|
198
245
|
|
|
199
246
|
```bash
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
247
|
+
uv tool install execsql2 # core: SQLite works with no extras
|
|
248
|
+
uv tool install "execsql2[postgres]" # with a driver: postgres, mysql, mssql, duckdb, firebird, oracle, odbc
|
|
249
|
+
uv tool install "execsql2[all]" # everything: all drivers plus all feature extras
|
|
203
250
|
```
|
|
204
251
|
|
|
205
|
-
|
|
252
|
+
`pipx install` takes the same arguments. Quote the name when it has extras
|
|
253
|
+
(zsh reports `no matches found` otherwise). To call execsql from Python code,
|
|
254
|
+
add it to that project instead: `uv add "execsql2[postgres]"` or
|
|
255
|
+
`pip install "execsql2[postgres]"` in its virtual environment.
|
|
256
|
+
|
|
257
|
+
Feature extras cover spreadsheet and Parquet/Feather formats, keyring authentication, PostgreSQL upsert, and more. See the [installation guide](https://execsql2.readthedocs.io/en/latest/getting-started/installation/) for the full list.
|
|
206
258
|
|
|
207
259
|
## Usage
|
|
208
260
|
|
|
209
261
|
```text
|
|
210
|
-
execsql [OPTIONS] SQL_SCRIPT [SERVER DATABASE | DATABASE_FILE]
|
|
262
|
+
execsql run [OPTIONS] SQL_SCRIPT [SERVER DATABASE | DATABASE_FILE]
|
|
263
|
+
execsql format [--check | -i] [--indent N] FILE_OR_DIR...
|
|
264
|
+
execsql lint [OPTIONS] FILE_OR_DIR...
|
|
265
|
+
execsql config [SQL_SCRIPT] [--init] [--config FILE]
|
|
266
|
+
execsql list metacommands|encodings|plugins|keywords
|
|
267
|
+
execsql init [DIR] [--script NAME] [--no-script] [--no-config] [--no-pre-commit]
|
|
211
268
|
```
|
|
212
269
|
|
|
213
270
|
Examples:
|
|
214
271
|
|
|
215
272
|
```bash
|
|
216
|
-
execsql -tp script.sql myserver mydb # PostgreSQL
|
|
217
|
-
execsql -tm script.sql myserver mydb # MySQL / MariaDB
|
|
218
|
-
execsql -ts script.sql myserver mydb # SQL Server
|
|
219
|
-
execsql -tl script.sql mydb.sqlite # SQLite
|
|
220
|
-
execsql -tk script.sql mydb.duckdb # DuckDB
|
|
221
|
-
execsql -to script.sql myserver myservice # Oracle
|
|
222
|
-
execsql script.sql # read connection from config file
|
|
273
|
+
execsql run -tp script.sql myserver mydb # PostgreSQL
|
|
274
|
+
execsql run -tm script.sql myserver mydb # MySQL / MariaDB
|
|
275
|
+
execsql run -ts script.sql myserver mydb # SQL Server
|
|
276
|
+
execsql run -tl script.sql mydb.sqlite # SQLite
|
|
277
|
+
execsql run -tk script.sql mydb.duckdb # DuckDB
|
|
278
|
+
execsql run -to script.sql myserver myservice # Oracle
|
|
279
|
+
execsql run script.sql # read connection from config file
|
|
223
280
|
```
|
|
224
281
|
|
|
225
282
|
### Supported Databases
|
|
226
283
|
|
|
227
|
-
| Flag | Database | Support
|
|
228
|
-
| ---- | --------------- |
|
|
229
|
-
| `p` | PostgreSQL | Supported
|
|
230
|
-
| `m` | MySQL / MariaDB | Supported
|
|
231
|
-
| `s` | MS SQL Server | Supported
|
|
232
|
-
| `l` | SQLite | Supported
|
|
233
|
-
| `k` | DuckDB | Supported
|
|
234
|
-
| `a` | MS Access | Best effort
|
|
235
|
-
| `f` | Firebird | Best effort
|
|
236
|
-
| `o` | Oracle | Best effort
|
|
237
|
-
| `d` | ODBC DSN | Best effort
|
|
284
|
+
| Flag | Database | Support |
|
|
285
|
+
| ---- | --------------- | ----------------------------------------------- |
|
|
286
|
+
| `p` | PostgreSQL | Supported: verified against a live server in CI |
|
|
287
|
+
| `m` | MySQL / MariaDB | Supported: verified against a live server in CI |
|
|
288
|
+
| `s` | MS SQL Server | Supported: verified against a live server in CI |
|
|
289
|
+
| `l` | SQLite | Supported: verified against real files in CI |
|
|
290
|
+
| `k` | DuckDB | Supported: verified against real files in CI |
|
|
291
|
+
| `a` | MS Access | Best effort: not verified in CI |
|
|
292
|
+
| `f` | Firebird | Best effort: not verified in CI |
|
|
293
|
+
| `o` | Oracle | Best effort: not verified in CI |
|
|
294
|
+
| `d` | ODBC DSN | Best effort: not verified in CI |
|
|
238
295
|
|
|
239
296
|
**Supported** adapters run against a live server or a real database file on
|
|
240
297
|
every CI run; a regression blocks the release and bugs get fixed. **Best
|
|
241
298
|
effort** adapters are carried forward from the upstream monolith and are not
|
|
242
|
-
exercised anywhere in CI
|
|
299
|
+
exercised anywhere in CI. The code is there and may work, but nothing proves
|
|
243
300
|
it still does. Issues and pull requests are welcome for them; no guarantee is
|
|
244
301
|
made. Opening a best-effort connection prints one informational line, which
|
|
245
302
|
`support_tier_notice=No` in the `[interface]` section of `execsql.conf`
|
|
@@ -247,24 +304,24 @@ silences.
|
|
|
247
304
|
|
|
248
305
|
### Common options
|
|
249
306
|
|
|
250
|
-
| Flag | Description
|
|
251
|
-
| ------------------------------------------------- |
|
|
252
|
-
| `-t {p,m,s,l,k,a,f,o,d}` | Database type
|
|
253
|
-
| `-u USER` | Database username
|
|
254
|
-
| `-p PORT` | Server port
|
|
255
|
-
| `--dsn URL` | Connection string (e.g. `postgresql://user:pass@host/db`)
|
|
256
|
-
| `-n` | Create a new SQLite or PostgreSQL database if it does not exist
|
|
257
|
-
| `-c SCRIPT` | Execute inline SQL or metacommand string
|
|
258
|
-
| `-a VALUE` | Set substitution variable `$ARG_x`
|
|
259
|
-
|
|
|
260
|
-
|
|
|
261
|
-
| `--
|
|
262
|
-
| `--
|
|
263
|
-
| `--
|
|
264
|
-
| `--debug` | Start in step-through debug mode (REPL pauses before each stmt)
|
|
265
|
-
| `--no-system-cmd` / `--no-rm-file` / `--no-serve` | Disable the `SYSTEM_CMD` / `RM_FILE` / `SERVE` metacommands
|
|
266
|
-
|
|
267
|
-
See the [full options reference](https://execsql2.readthedocs.io/en/latest/getting-started/syntax/#options) or run `execsql --help` for the complete list, and `execsql
|
|
307
|
+
| Flag | Description |
|
|
308
|
+
| ------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
309
|
+
| `-t {p,m,s,l,k,a,f,o,d}` | Database type |
|
|
310
|
+
| `-u USER` | Database username |
|
|
311
|
+
| `-p PORT` | Server port |
|
|
312
|
+
| `--dsn URL` | Connection string (e.g. `postgresql://user:pass@host/db`) |
|
|
313
|
+
| `-n` | Create a new SQLite or PostgreSQL database if it does not exist |
|
|
314
|
+
| `-c SCRIPT` | Execute inline SQL or metacommand string |
|
|
315
|
+
| `-a VALUE` | Set substitution variable `$ARG_x` |
|
|
316
|
+
| `--var NAME=VALUE` | Set the substitution variable `!!NAME!!` |
|
|
317
|
+
| `-v {0,1,2,3}` | GUI level (0=none, 1=password/PAUSE, 2=+HALT and DB selection, 3=console) |
|
|
318
|
+
| `--config FILE` | Load an explicit config file |
|
|
319
|
+
| `--dry-run` | Parse the script and report commands without executing |
|
|
320
|
+
| `--manifest FILE` | Write a JSON record of the run: files read and written, statements, errors |
|
|
321
|
+
| `--debug` | Start in step-through debug mode (REPL pauses before each stmt) |
|
|
322
|
+
| `--no-system-cmd` / `--no-rm-file` / `--no-serve` | Disable the `SYSTEM_CMD` / `RM_FILE` / `SERVE` metacommands |
|
|
323
|
+
|
|
324
|
+
See the [full options reference](https://execsql2.readthedocs.io/en/latest/getting-started/syntax/#options) or run `execsql run --help` for the complete list, `execsql run --ping` to test a connection, `execsql config` to see which config files set what, and `execsql list metacommands` for all metacommands.
|
|
268
325
|
|
|
269
326
|
## Features
|
|
270
327
|
|
|
@@ -279,7 +336,7 @@ See the [full options reference](https://execsql2.readthedocs.io/en/latest/getti
|
|
|
279
336
|
- Conditionally execute SQL and metacommands using `IF`/`ELSE`/`ENDIF` based on data values, DBMS type, or user input.
|
|
280
337
|
- Loop over blocks of SQL and metacommands using `LOOP`/`ENDLOOP`; include or chain scripts with `INCLUDE` and `SCRIPT`.
|
|
281
338
|
- Use substitution variables (`SUB`, `$ARG_x`, built-in variables like `$date_tag`) to parameterize scripts.
|
|
282
|
-
- Validate data with `ASSERT
|
|
339
|
+
- Validate data with `ASSERT`: halt the script with a clear error message if a condition is false (ideal for CI pipelines).
|
|
283
340
|
|
|
284
341
|
**Interaction & observability**
|
|
285
342
|
|
|
@@ -308,7 +365,8 @@ result = run(
|
|
|
308
365
|
new_db=True,
|
|
309
366
|
)
|
|
310
367
|
|
|
311
|
-
# With substitution variables
|
|
368
|
+
# With substitution variables: each key becomes a $ variable,
|
|
369
|
+
# so the script refers to these as !!$SCHEMA!! and !!$DATE!!
|
|
312
370
|
result = run(
|
|
313
371
|
script="etl.sql",
|
|
314
372
|
dsn="sqlite:///data.db",
|
|
@@ -319,7 +377,7 @@ result = run(
|
|
|
319
377
|
print(result.success) # True
|
|
320
378
|
print(result.commands_run) # 2
|
|
321
379
|
print(result.elapsed) # 0.003 (seconds)
|
|
322
|
-
print(result.variables) # {"
|
|
380
|
+
print(result.variables) # {"schema": "public", ...} (names lower-cased, no $)
|
|
323
381
|
```
|
|
324
382
|
|
|
325
383
|
Error handling:
|
|
@@ -334,7 +392,7 @@ if not result.success:
|
|
|
334
392
|
result.raise_on_error() # raises ExecSqlError
|
|
335
393
|
```
|
|
336
394
|
|
|
337
|
-
Use a pre-existing database connection instead of a DSN
|
|
395
|
+
Use a pre-existing database connection instead of a DSN. This is useful for reusing one connection across multiple `run()` calls, or when connection parameters come from your application's configuration rather than a URL:
|
|
338
396
|
|
|
339
397
|
```python
|
|
340
398
|
from execsql import run
|
|
@@ -357,7 +415,7 @@ loaded = run(
|
|
|
357
415
|
variables={"RUN_DATE": "2026-07-03"},
|
|
358
416
|
)
|
|
359
417
|
|
|
360
|
-
# run() does NOT close the connection
|
|
418
|
+
# run() does NOT close the connection; you manage its lifecycle
|
|
361
419
|
conn.close()
|
|
362
420
|
|
|
363
421
|
# SQLite works the same way
|
|
@@ -366,43 +424,44 @@ result = run(sql="SELECT 1;", connection=conn)
|
|
|
366
424
|
conn.close()
|
|
367
425
|
```
|
|
368
426
|
|
|
369
|
-
Factory functions exist for every supported backend (`db_Postgres`, `db_MySQL`, `db_SQLite`, `db_DuckDB`, `db_SqlServer`, `db_Oracle`, `db_Firebird`, `db_Access`, `db_Dsn`)
|
|
427
|
+
Factory functions exist for every supported backend (`db_Postgres`, `db_MySQL`, `db_SQLite`, `db_DuckDB`, `db_SqlServer`, `db_Oracle`, `db_Firebird`, `db_Access`, `db_Dsn`). See [`execsql.db.factory`](https://execsql2.readthedocs.io/en/latest/api/db/).
|
|
370
428
|
|
|
371
429
|
Each call to `run()` uses an isolated `RuntimeContext`, so multiple calls do not share state.
|
|
372
430
|
|
|
373
431
|
## Formatting Scripts
|
|
374
432
|
|
|
375
|
-
The `execsql
|
|
433
|
+
The `execsql format` command normalizes execsql script files: it uppercases metacommand keywords, corrects block indentation, and optionally reformats SQL via `sqlglot`. The metacommand / indent / keyword reformatting is built into `execsql2`; SQL reformatting requires the `[formatter]` extra (or pass `--no-sql` to skip it):
|
|
376
434
|
|
|
377
435
|
```bash
|
|
378
436
|
# Install with the SQL-reformatting extra
|
|
379
|
-
|
|
437
|
+
uv tool install "execsql2[formatter]"
|
|
380
438
|
|
|
381
439
|
# Format files in place
|
|
382
|
-
execsql
|
|
440
|
+
execsql format --in-place scripts/
|
|
383
441
|
|
|
384
442
|
# Check formatting without writing (useful in CI)
|
|
385
|
-
execsql
|
|
443
|
+
execsql format --check scripts/
|
|
386
444
|
|
|
387
|
-
# Run the formatter without sqlglot
|
|
388
|
-
execsql
|
|
445
|
+
# Run the formatter without sqlglot: keyword/indent normalization only
|
|
446
|
+
execsql format --no-sql --in-place scripts/
|
|
389
447
|
```
|
|
390
448
|
|
|
391
|
-
`execsql
|
|
449
|
+
`execsql format` and `execsql lint` are also available as [pre-commit](https://pre-commit.com/) hooks. The format hook id is unchanged, so existing configs keep working:
|
|
392
450
|
|
|
393
451
|
```yaml
|
|
394
452
|
repos:
|
|
395
453
|
- repo: https://github.com/geocoug/execsql
|
|
396
|
-
rev: v2.
|
|
454
|
+
rev: v2.25.0
|
|
397
455
|
hooks:
|
|
398
456
|
- id: execsql-format
|
|
457
|
+
- id: execsql-lint
|
|
399
458
|
```
|
|
400
459
|
|
|
401
|
-
The hook rewrites `*.sql` files in place by default. See the [formatter documentation](https://execsql2.readthedocs.io/en/latest/guides/formatter/) for `--check`, `--indent`, and other options.
|
|
460
|
+
The format hook rewrites `*.sql` files in place by default; the lint hook fails the commit when a script has a lint error. See the [formatter documentation](https://execsql2.readthedocs.io/en/latest/guides/formatter/) for `--check`, `--indent`, and other options.
|
|
402
461
|
|
|
403
462
|
## VS Code Syntax Highlighting
|
|
404
463
|
|
|
405
|
-
A VS Code extension for execsql syntax highlighting is included in [`extras/vscode-execsql`](extras/vscode-execsql). It injects a TextMate grammar into `.sql` files, adding highlighting for `-- !x!` metacommand markers, keywords (control flow, block, action, directive), variable substitutions (`!!var!!`, `!{var}!`), built-in functions, export formats, and config options
|
|
464
|
+
A VS Code extension for execsql syntax highlighting is included in [`extras/vscode-execsql`](extras/vscode-execsql). It injects a TextMate grammar into `.sql` files, adding highlighting for `-- !x!` metacommand markers, keywords (control flow, block, action, directive), variable substitutions (`!!var!!`, `!{var}!`), built-in functions, export formats, and config options, all layered on top of standard SQL highlighting.
|
|
406
465
|
|
|
407
466
|
To install, symlink the extension folder into your VS Code extensions directory:
|
|
408
467
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
execsql/__init__.py,sha256=ZeVnpEWu8M2bn3qLmVM72NhWRueUGNbsX8UAPTermo0,901
|
|
2
|
+
execsql/__main__.py,sha256=HdbK-SAhyUmfB6xINY5AzxdMSxGzWSGEG_2dv42Jn64,315
|
|
3
|
+
execsql/api.py,sha256=UJJSlFHySuINeoExaMXqhl00hVSPH1s7G4m8T0NX_xI,26484
|
|
4
|
+
execsql/config.py,sha256=f9UMX5LECVL6KnvvTmIIAMrqOfYe_elQxjW1TOSt4fA,38040
|
|
5
|
+
execsql/config_validation.py,sha256=a4ZszyJFGTNgs1jkvXE3yMCaYFtF1Uqih2ojMDVh1v8,10556
|
|
6
|
+
execsql/exceptions.py,sha256=aHavdblmP7m5ZLxyyKKmPSwwbdmP962j4ShP1Gd9r64,9651
|
|
7
|
+
execsql/format.py,sha256=rpe-eB7V9J2z7Itr_MFtdUeU2-sR8F6B7a3vYmHXKd0,54253
|
|
8
|
+
execsql/interactive.py,sha256=7vm7NAlcarBJJOIffcLOcJqH9ZCInvHB_CmC2sQsXf8,8241
|
|
9
|
+
execsql/manifest.py,sha256=ibceEZtH2FqsUiujbTGy5D3W0WgO4tFCs7bjIHVdep4,8062
|
|
10
|
+
execsql/models.py,sha256=yXR9FMCSCRonfyiuWlYwqLBMLzWQcvFQOjGHogM8Veg,15556
|
|
11
|
+
execsql/parser.py,sha256=bw26e1lD-PZscV11VtBdqSLkjpcYfNLQC2EYfYD5UwU,16012
|
|
12
|
+
execsql/plugins.py,sha256=RykMlIjTyWcnQc9ygjLErS3wdcsZSsG9QTIvg4DwfAI,13626
|
|
13
|
+
execsql/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
execsql/state.py,sha256=NDAtv38b2cmknz-jEgOaOeqZCc6GdxN6mz-KCqb9pqg,23263
|
|
15
|
+
execsql/state.pyi,sha256=pEuTT4G6VNiwy4Ii7OUXc1RvzcQvjFkeFazSGEOprs0,4300
|
|
16
|
+
execsql/types.py,sha256=qUJ5kVKz_Crc9hti5u9_VnVzLBQ2n5Jtbje5hSwxGzE,32809
|
|
17
|
+
execsql/cli/__init__.py,sha256=8wDwIAFq7AI9iSGuw-Xfky-izN_7oHjUegr_brEBot0,3197
|
|
18
|
+
execsql/cli/application.py,sha256=qKjkhDMWB7fEjEbqOLZ3pNFw80piBnRSeW_DfZg-9MA,12448
|
|
19
|
+
execsql/cli/dispatch.py,sha256=ew10mZNXsFHwiNd_etvpSQYD3T8CiexXkjC3Ja94C4w,2697
|
|
20
|
+
execsql/cli/dsn.py,sha256=uBspf8DXCn2pXmT1Ug1c4IG7IgR5IFGKp9138puaubo,3289
|
|
21
|
+
execsql/cli/help.py,sha256=Edr3d2ahKv387a6WGgyJi5vKIFe39tGPgTv1GKp3itE,10848
|
|
22
|
+
execsql/cli/lint.py,sha256=7t4HXMqPCxHR6PoRxna0X3myu9hlxuK1rbPn5h2tX1Y,43390
|
|
23
|
+
execsql/cli/options.py,sha256=Srhf1gEOB5yy_7PxkTKBv07xK8Qzw8H-z7PUUnItpwE,2916
|
|
24
|
+
execsql/cli/run.py,sha256=5f0SX6QyNl8Ur2MwuW2GaN1OqVpWbEI8CQV3k-hBwH8,41987
|
|
25
|
+
execsql/cli/commands/__init__.py,sha256=wN5sbhKs11S8EZOTBd_GPP6TPjhYfiQkrI48Sy8n6U0,521
|
|
26
|
+
execsql/cli/commands/config.py,sha256=V7CGGkhSCqeJIlAXxAYyG_xNhnsORiwqth2XWEVPzss,8213
|
|
27
|
+
execsql/cli/commands/format.py,sha256=2pftY7nl8FexJ5tnvncxRG-7UjQ_NO0mHxmqAOKd-Nw,3948
|
|
28
|
+
execsql/cli/commands/init.py,sha256=kmuFgGz8sv_1KfiNh190E3A23evqkgYZeBRTU6vdjbs,5465
|
|
29
|
+
execsql/cli/commands/lint.py,sha256=Lba5IDsXtiUbQ6DkhC9fdLnoSpfoaewoAWF-ei3h59s,8189
|
|
30
|
+
execsql/cli/commands/listing.py,sha256=gWnjkgcw7uF-DJw3cMZbttOKdplDwAMlhmaBoI5drVw,2511
|
|
31
|
+
execsql/cli/commands/run.py,sha256=sGFDku66CazJrorr0mmrhUI3QDvQVSMEYlU8G1Pd5fQ,16492
|
|
32
|
+
execsql/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
execsql/data/execsql.conf.template,sha256=fTxA6Y01D-7BFABPgnJbEfPD5SSQ-l1xnaptMEBXuzc,12326
|
|
34
|
+
execsql/data/script_header.sql,sha256=a7WKScekNgJoxVEmMRTkWv8NsAzW1jJ4vJfGy9HVy0g,349
|
|
35
|
+
execsql/db/__init__.py,sha256=jTbuafuKOqYtXFR1wvCOoKK5Lr3l1uErfaIbIr6UywI,1063
|
|
36
|
+
execsql/db/access.py,sha256=O19alGOCjhBtVFaCnGN8zwVZ2wR57h1spizAF5dhUOg,21207
|
|
37
|
+
execsql/db/base.py,sha256=K_NJ5Tpn68qUyc5epnT3V3jUxkv1lCAXF0rGul-8otc,42264
|
|
38
|
+
execsql/db/dsn.py,sha256=a3_q7oucR37CMCKNO9S5ShsB_JDwmZY4d8QI1aqeFSU,6893
|
|
39
|
+
execsql/db/duckdb.py,sha256=h62nEuwNl8Bz8ZcJJNIAfFK1o91KXxAeh8unlwTivKc,7047
|
|
40
|
+
execsql/db/factory.py,sha256=cMptU3BL1Nsilo7LKLAI5RR-LiC9RTH-3UC9rHT2JLQ,5519
|
|
41
|
+
execsql/db/firebird.py,sha256=sU2XqYV0U6hTgUuetFfMdlZwlBlXgPVXXn_wi1XCy1U,10196
|
|
42
|
+
execsql/db/mysql.py,sha256=ooH4uNomr_VatEldJ70ynsOth4_STa8-761O33NfndY,21496
|
|
43
|
+
execsql/db/oracle.py,sha256=-n8CgbZd9zaGnbfQQmWAdFgPA_B-HkLNC6yvENbzqyc,13720
|
|
44
|
+
execsql/db/postgres.py,sha256=QXL34lyg6w7zj2S-1AAlyswPGjbXZz7GZS2qFB4pANY,23604
|
|
45
|
+
execsql/db/sqlite.py,sha256=fEpNPkfJGnqm1Wx_rZK5SEqaWsBqLy85Jxk_5NsnqgM,12109
|
|
46
|
+
execsql/db/sqlserver.py,sha256=e4UP2Ps0EXjVjX4TOYNslsviBF2dorx8TEvPhxb9rrY,9503
|
|
47
|
+
execsql/db/tiers.py,sha256=PH2sUYwlYqcANGVKXprWQKVIlM6fpWU9q74djn8oFwc,2924
|
|
48
|
+
execsql/debug/__init__.py,sha256=j6EGUR0dHzUhWN1mHHtf1-Lhjq3Sb1V-vmnq2Ztgj1M,178
|
|
49
|
+
execsql/debug/repl.py,sha256=jnwrqRac4krc1pES7Ni-j1Dyw3mJIcWl5LQQIX1GkRw,20753
|
|
50
|
+
execsql/exporters/__init__.py,sha256=-Cnji-OgodJV8ftcDcOyTof0kQMy9J5kKVC8GVFpc3o,670
|
|
51
|
+
execsql/exporters/base.py,sha256=_GoO0YqwlTxrjogxHI3CxxRR64sMgIEjRogt0KCqzoY,6402
|
|
52
|
+
execsql/exporters/delimited.py,sha256=N0cP_CNlb_LLCUqbHmTQsOGufWnD_ddGdeFnXPE8Erc,35606
|
|
53
|
+
execsql/exporters/duckdb.py,sha256=912TMdYaSVD-kb-_oebTBHQp8FvYMbWTDEDD80w5Z50,3455
|
|
54
|
+
execsql/exporters/feather.py,sha256=tah48aep0cQRikZcmADXUPTzFddgDUT78Ndw_l0Hsj4,4178
|
|
55
|
+
execsql/exporters/html.py,sha256=hwf9UHs7EZ7xiP3p9ilBIsAukXcDu-KO2dcQHVh2z30,10111
|
|
56
|
+
execsql/exporters/json.py,sha256=wWGT6zjvIdWlO5FmXbaEw1xOhy23f1YY6bm5uQD_NS0,4393
|
|
57
|
+
execsql/exporters/latex.py,sha256=bdUN3GwfENUZHgpw6bvjsjfivDgzyf-HRkYTP-eH-pM,5480
|
|
58
|
+
execsql/exporters/markdown.py,sha256=FuMGFxm9uZUOrdEuXT2ZZLCqmVDly7SMrFlrjP6kVEI,4827
|
|
59
|
+
execsql/exporters/ods.py,sha256=Ke9pfcyT6R85LWIWcMI6pzRzkKir5w_gmiptCeeuoBc,20730
|
|
60
|
+
execsql/exporters/parquet.py,sha256=mbCo2Wlit1lkXmyo5EyLd_ATIHSICS49bouiBT2kdAs,1121
|
|
61
|
+
execsql/exporters/pretty.py,sha256=SiJHBXIjoFsOHegXcdrtxYa6xSIPga1U0DQEy7pK4QY,4145
|
|
62
|
+
execsql/exporters/protocol.py,sha256=BxATgz0xKHbB2FpZBeNg7wZfIiCohhD1awlr3JCec0c,4372
|
|
63
|
+
execsql/exporters/raw.py,sha256=9o3BMt7UYmnjbP8OEzmM2kNKfwwERi2yDcuNfUoEfuQ,2530
|
|
64
|
+
execsql/exporters/sqlite.py,sha256=QjP_W90S-hecNqp2A-Vy58DD8MZitME1sTq4lqIS43w,3401
|
|
65
|
+
execsql/exporters/templates.py,sha256=nRFurwTb5nxoyHpx609FGIp3MDbX_mYQ3IvgswaEbyA,7054
|
|
66
|
+
execsql/exporters/values.py,sha256=UPxN5IprasBZLqM5jfUXQihjdTeBFTxbJslOEtmGOcY,3384
|
|
67
|
+
execsql/exporters/xls.py,sha256=iZ_N7hneyfaDKbO1XdYv6doJCFPqJWEJql5rduoNyRU,11197
|
|
68
|
+
execsql/exporters/xlsx.py,sha256=hmL0i-2HweXFenl5uXjM3-w2DW2Ky8DeYTcZnFzmeOU,12708
|
|
69
|
+
execsql/exporters/xml.py,sha256=t1PSr3i8xvTCWzd9jaxxAy5NcRpl6sqjnZALafKCqpM,2575
|
|
70
|
+
execsql/exporters/yaml.py,sha256=R61Rs_0rd5G3bg344L4hC84GM79IfYXaDO2tkF-BluY,3121
|
|
71
|
+
execsql/exporters/zip.py,sha256=0vDkXB19WzLzgCACBVNnGJYxacgBwEehQDL7Inl-rgw,5002
|
|
72
|
+
execsql/gui/__init__.py,sha256=oCb-cyhLZzVpWJ4WU5HbqEDBrV-lm0ytEwxemrOZyqs,2048
|
|
73
|
+
execsql/gui/base.py,sha256=DMTqHLlpZlGCsNKyrLlJPbaxvukC0n1YmR4aHEN3jPY,14983
|
|
74
|
+
execsql/gui/console.py,sha256=dzdSl4NJNvRd9VvlwRCXHvfnXjQPimyTx7NcibcUZC8,18305
|
|
75
|
+
execsql/gui/desktop.py,sha256=y-T317NzSs9kcA4-NZW-Dx2cZ4Bv1mPoCr7hwQCJYoo,59467
|
|
76
|
+
execsql/gui/tui.py,sha256=VoUtjSMopYtbtc8_-qV7YQAFvc-bS7zrZ5J2hl1cPxM,66853
|
|
77
|
+
execsql/importers/__init__.py,sha256=zZwdQxMaValCNqUrVdvaA7XPU3J8NmqVJ4uolNWY2iU,299
|
|
78
|
+
execsql/importers/base.py,sha256=ikvJ98vVCcDBqp5ZdwwHwf-6zQCO4f8uI355VCVukHo,5783
|
|
79
|
+
execsql/importers/csv.py,sha256=4zIv-K02fuHKxnbqS5iTvLOeVnfssLYYJrs0Gh3qv7I,5021
|
|
80
|
+
execsql/importers/feather.py,sha256=g2B69d2uv9vmnXcmjFyTVsMP40LYEzFYkhk3gD26mGw,1900
|
|
81
|
+
execsql/importers/json.py,sha256=fL47h09Zzx4Qw3TTQRQJbdPdD3qVMiU-kK9C7j1IQzg,5534
|
|
82
|
+
execsql/importers/ods.py,sha256=VsxIkr7opBamB0PbSFmMWt7G11w8lLUH1k_kRwz28zw,2847
|
|
83
|
+
execsql/importers/xls.py,sha256=D7Ul42gIRYZZC5QxD35ft_wmqQv2f1jNMSbnqlzV0ZA,3851
|
|
84
|
+
execsql/metacommands/__init__.py,sha256=H_D1Z5kN6zfYtxatejQhQhQV1tlVZ7rcdFZ_9uhXu2Q,13010
|
|
85
|
+
execsql/metacommands/conditions.py,sha256=4DsMXr6vnfbtcKqgnxYV4UK4NmAfE_hpfgkFjlH0bjo,29844
|
|
86
|
+
execsql/metacommands/connect.py,sha256=SPk4h9yiUgTD3w1gNOT_oYx8VShggsO357by5Hoy6OI,15344
|
|
87
|
+
execsql/metacommands/control.py,sha256=9swW6X8jXDUpu5cHiAnQVx1ahFyWxlx7mjg4dqYfX5Y,9355
|
|
88
|
+
execsql/metacommands/data.py,sha256=gaKJ0xA-maFnezT9TJv-q4G4Etn-kJnF7vZWZoG4UqI,12305
|
|
89
|
+
execsql/metacommands/debug.py,sha256=XyMoKnQKyYHdzcfGUGFEaecIlDOi1LMirwbbpbiRO7I,12922
|
|
90
|
+
execsql/metacommands/dispatch.py,sha256=t7x0xWHJA0PeCrYf7jYeSMJgf0yxcZ_xh-_YAtBPHLw,87192
|
|
91
|
+
execsql/metacommands/effects.py,sha256=cRSo48R4nRJzkRR3OGHLhJzofcdAaNIobaxmn1N9TGw,3813
|
|
92
|
+
execsql/metacommands/io.py,sha256=vlGBje5sgnqeilooMdhJDgSRIhysHy5_7LrKtik9Xjs,3011
|
|
93
|
+
execsql/metacommands/io_export.py,sha256=YamxQwURRjZRpCG2z8W3QurncCmEmAyLFqDkxtHo5dY,14434
|
|
94
|
+
execsql/metacommands/io_fileops.py,sha256=uXP5PdHOc8yi1rPo8PbWmvAx_yp69ozCkK_SHYoL0NE,12646
|
|
95
|
+
execsql/metacommands/io_import.py,sha256=gJICeK1MOfG6D73I7m8zBCalvr_ZJzD-QBKOpKYeYXo,15684
|
|
96
|
+
execsql/metacommands/io_write.py,sha256=yXDkMbQ3haDARVATVUYZprakyJHSyk1NywdKkFLpQ14,12783
|
|
97
|
+
execsql/metacommands/prompt.py,sha256=PlXhtBYCembG_1SSCrwpQR10mGF3_jXodu4aCSHlSCM,37950
|
|
98
|
+
execsql/metacommands/script_ext.py,sha256=CsUbyq8QFPnnvfX_k7fPlYNvvRw1xLmAWER4Exo5pwc,3658
|
|
99
|
+
execsql/metacommands/system.py,sha256=6X2qmMpGUHDzyEluEotXt0Ks9jKQTpc2x0eoYNgN12M,7997
|
|
100
|
+
execsql/metacommands/upsert.py,sha256=qez06e41ivxsLlB-Af91fkVzD6XhHVxpvv5sLMPul6M,20429
|
|
101
|
+
execsql/script/__init__.py,sha256=I7hVO6wm3iOocxRRGEcFHhjdtL1moKbUYLB-wKbjPdk,3267
|
|
102
|
+
execsql/script/ast.py,sha256=WqCpFxhxrT2IIGvbArTp3QS0BZryRZAb7IL4ri3I6xg,20591
|
|
103
|
+
execsql/script/control.py,sha256=WqLy-HLPqHG3vEzYpKMiIJsD7LpORjyQuUWzFzcGz4w,2327
|
|
104
|
+
execsql/script/engine.py,sha256=wjXKwPIis-T2Y8rLnRXQ_ymUFdXff1MlI2IIYmxihKo,18448
|
|
105
|
+
execsql/script/executor.py,sha256=lvMFjKe2h4fafhKNiuoXAYpDe8pLHHuYMiwPkLYJe9I,41527
|
|
106
|
+
execsql/script/parser.py,sha256=z73v6t6ZbPUKkRu-UOIL6q1cCRDeoRvG2aXXC8NpMvE,37162
|
|
107
|
+
execsql/script/variables.py,sha256=_hklqCeqPbdOT646Yg3ZcpmPke38_8bukMG3eZMTKZw,16384
|
|
108
|
+
execsql/utils/__init__.py,sha256=0uR6JwVJQRX3vceByNBduCAf5dd5assKjeqJUWvpZoA,278
|
|
109
|
+
execsql/utils/auth.py,sha256=BV7VtLM-ID8jNB42vx7GEz8yb3Z1Qs9xCr4cUMqL864,14539
|
|
110
|
+
execsql/utils/color.py,sha256=goQqhnLg8yERpFolQikA9zYSVcuAm0unKTJiWTbQm-U,634
|
|
111
|
+
execsql/utils/crypto.py,sha256=KlT6lPk-v0-qQQfAMfWvT9Q6kRdCD3_5JVaLajNocKM,3051
|
|
112
|
+
execsql/utils/datetime.py,sha256=rqtGrc0t37V00mvirJ8wJKHmDtDSYzTg_UgCyIBzv9E,5583
|
|
113
|
+
execsql/utils/errors.py,sha256=JqV5mDKJnsYF8Uam6iLE3HNqkL1cUiiP8ExHpBBFnC8,11630
|
|
114
|
+
execsql/utils/fileio.py,sha256=ADp8Iltf_zfv0PL0VRdO0BDIHkVpKVVh59_5zmkTfkw,47564
|
|
115
|
+
execsql/utils/gui.py,sha256=1iiupP9AsLdR6ST0gcLE143o6y6YGUFlNv_pdVPxfCE,23943
|
|
116
|
+
execsql/utils/mail.py,sha256=4RiKtXa_sqij_YGdYmjQ3PG0u3G9qjs-9caQwBErtBw,7278
|
|
117
|
+
execsql/utils/numeric.py,sha256=_7bi5R6pHjMCkOPne_Sh5nUj-B8e9g6WFmjptFHaunA,1573
|
|
118
|
+
execsql/utils/regex.py,sha256=B3mSBhRRx_DpUnX_t9IoYd05KvWAebiLMCZqQAmEwcw,3885
|
|
119
|
+
execsql/utils/strings.py,sha256=UQNjpRCEFa1UO6feU-M-9e24wWAvizs_iu_4fFusLxo,8516
|
|
120
|
+
execsql/utils/timer.py,sha256=eDYf5VzCNFk7oo90InJucUm3XcBdhYMogjZMqeg9xzc,1899
|
|
121
|
+
execsql2-2.25.0.data/data/execsql2_extras/README.md,sha256=7SG9FbBpdqkgQTTt1aBTbCgymBZyV0rLrQMQrendzxs,5032
|
|
122
|
+
execsql2-2.25.0.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
|
|
123
|
+
execsql2-2.25.0.data/data/execsql2_extras/example_config_prompt.sql,sha256=2e8KzzVWhho8KxYVHETSVmZdhW7wodioDsqBLSL6m4s,7487
|
|
124
|
+
execsql2-2.25.0.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
|
|
125
|
+
execsql2-2.25.0.data/data/execsql2_extras/md_compare.sql,sha256=qYYVAjSeHZzjszxV3Bv6bg8Ckbq2kMHl87_gh4sywMU,24140
|
|
126
|
+
execsql2-2.25.0.data/data/execsql2_extras/md_glossary.sql,sha256=hkZ2Onn57LAKKsuXxzhR8tPtcWXkmWEQkwPE58-Tm2k,10796
|
|
127
|
+
execsql2-2.25.0.data/data/execsql2_extras/md_upsert.sql,sha256=_CAK4BzEboRXTNy03SJR-oOjcEdSNMuRBPL6noWUptY,112560
|
|
128
|
+
execsql2-2.25.0.data/data/execsql2_extras/pg_compare.sql,sha256=1zJd4hVUKHR0tncc2qTBC9B4qVV4Us2ITkJpsjN3tMw,24352
|
|
129
|
+
execsql2-2.25.0.data/data/execsql2_extras/pg_glossary.sql,sha256=IKuwna-_8b20ljSkXZruuiQigrCpo7ueQdUqd1MXiuI,9908
|
|
130
|
+
execsql2-2.25.0.data/data/execsql2_extras/pg_upsert.sql,sha256=HpPJtTHvpEjQy03j-3iPxDEOHMRkudOg7O4D4YR38UI,108315
|
|
131
|
+
execsql2-2.25.0.data/data/execsql2_extras/script_template.sql,sha256=2J35ddZPguJ-vwTsz83wErv0jiWUyJcdW_JM0mNKDXA,11155
|
|
132
|
+
execsql2-2.25.0.data/data/execsql2_extras/ss_compare.sql,sha256=j1qVNUPXQsEU7-DoVgDJCGcE0EuIl7whLBT3fgeiMAo,24833
|
|
133
|
+
execsql2-2.25.0.data/data/execsql2_extras/ss_glossary.sql,sha256=2gLxv34xzKt0vy7hSzJH7a9JiMC3ETrv9MofxQwAibU,13065
|
|
134
|
+
execsql2-2.25.0.data/data/execsql2_extras/ss_upsert.sql,sha256=G_8rQ0VzuKIZHWs24O_WrfzpC5S27R1JsL-bFBR3SUQ,117730
|
|
135
|
+
execsql2-2.25.0.dist-info/METADATA,sha256=8-U51LILehuLSC5E0zYP_tYCuJEtff0DkTsMSQ4RvHg,25703
|
|
136
|
+
execsql2-2.25.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
137
|
+
execsql2-2.25.0.dist-info/entry_points.txt,sha256=jOf53-4IVGjEZeNYUOF1GGaiPNfVZcNKxP3vDFKEyMA,58
|
|
138
|
+
execsql2-2.25.0.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
|
|
139
|
+
execsql2-2.25.0.dist-info/licenses/NOTICE,sha256=McYzgxYav3U1OaVsY4Su1sfBrfmplpRdA9b6-gCDQCg,342
|
|
140
|
+
execsql2-2.25.0.dist-info/RECORD,,
|