execsql2 2.23.0__tar.gz → 2.24.0__tar.gz
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.
- {execsql2-2.23.0 → execsql2-2.24.0}/.github/workflows/ci-cd.yml +107 -2
- execsql2-2.24.0/.pre-commit-hooks.yaml +17 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/CHANGELOG.md +61 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/PKG-INFO +111 -58
- {execsql2-2.23.0 → execsql2-2.24.0}/README.md +107 -54
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/about/divergence.md +74 -36
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/adding_db_adapters.md +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/adding_metacommands.md +9 -9
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/architecture.md +28 -25
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/getting-started/installation.md +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/getting-started/requirements.md +3 -3
- execsql2-2.24.0/docs/getting-started/syntax.md +513 -0
- execsql2-2.24.0/docs/guides/debugging.md +121 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/examples.md +20 -16
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/formatter.md +70 -24
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/usage.md +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/reference/configuration.md +48 -1
- execsql2-2.24.0/docs/reference/lint.md +266 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/reference/metacommands.md +57 -10
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/reference/security.md +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/reference/substitution_vars.md +3 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/plugin-template/README.md +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/plugin-template/tests/test_plugin.py.example +3 -2
- execsql2-2.24.0/extras/vscode-execsql/.vscodeignore +3 -0
- execsql2-2.24.0/extras/vscode-execsql/LICENSE.txt +12 -0
- execsql2-2.24.0/extras/vscode-execsql/icon.png +0 -0
- execsql2-2.24.0/extras/vscode-execsql/package.json +46 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/justfile +29 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/pyproject.toml +17 -7
- {execsql2-2.23.0 → execsql2-2.24.0}/scripts/benchmarks/run_benchmarks.py +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/scripts/generate_vscode_grammar.py +6 -6
- execsql2-2.24.0/src/execsql/cli/__init__.py +81 -0
- execsql2-2.24.0/src/execsql/cli/application.py +309 -0
- execsql2-2.24.0/src/execsql/cli/commands/__init__.py +13 -0
- execsql2-2.24.0/src/execsql/cli/commands/config.py +205 -0
- execsql2-2.24.0/src/execsql/cli/commands/format.py +100 -0
- execsql2-2.24.0/src/execsql/cli/commands/init.py +135 -0
- execsql2-2.24.0/src/execsql/cli/commands/lint.py +233 -0
- execsql2-2.24.0/src/execsql/cli/commands/listing.py +81 -0
- execsql2-2.24.0/src/execsql/cli/commands/run.py +451 -0
- execsql2-2.24.0/src/execsql/cli/dispatch.py +66 -0
- execsql2-2.24.0/src/execsql/cli/help.py +302 -0
- execsql2-2.24.0/src/execsql/cli/lint.py +943 -0
- execsql2-2.24.0/src/execsql/cli/options.py +108 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/cli/run.py +41 -14
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/config.py +251 -154
- execsql2-2.24.0/src/execsql/config_validation.py +282 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/data/execsql.conf.template +24 -1
- execsql2-2.24.0/src/execsql/data/script_header.sql +23 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/access.py +22 -6
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/base.py +105 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/dsn.py +2 -0
- execsql2-2.24.0/src/execsql/db/duckdb.py +182 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/factory.py +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/mysql.py +11 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/oracle.py +12 -4
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/sqlite.py +16 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/debug/repl.py +51 -193
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exceptions.py +9 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/format.py +87 -75
- execsql2-2.24.0/src/execsql/interactive.py +232 -0
- execsql2-2.24.0/src/execsql/manifest.py +189 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/conditions.py +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/control.py +2 -3
- execsql2-2.24.0/src/execsql/metacommands/effects.py +124 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/__init__.py +0 -9
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/ast.py +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/engine.py +6 -93
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/executor.py +153 -34
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/state.py +11 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/state.pyi +3 -0
- execsql2-2.24.0/src/execsql/utils/color.py +18 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/errors.py +11 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/README.md +1 -1
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/test_cli.py +28 -21
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/test_cli_e2e.py +8 -3
- execsql2-2.24.0/tests/cli/test_cli_surface.py +232 -0
- execsql2-2.24.0/tests/cli/test_commands.py +577 -0
- execsql2-2.24.0/tests/cli/test_config_validate.py +294 -0
- execsql2-2.24.0/tests/cli/test_dispatch.py +456 -0
- execsql2-2.24.0/tests/cli/test_init.py +119 -0
- execsql2-2.24.0/tests/cli/test_lint.py +923 -0
- execsql2-2.24.0/tests/cli/test_manifest.py +172 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/test_ping.py +3 -3
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/test_profile.py +6 -4
- execsql2-2.24.0/tests/cli/test_undeclared_imports.py +45 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/conftest.py +50 -0
- execsql2-2.24.0/tests/data/formatter_shapes/escapes_and_literals.sql +58 -0
- execsql2-2.24.0/tests/data/formatter_shapes/substitution_and_metacommands.sql +43 -0
- execsql2-2.24.0/tests/data/formatter_shapes/unparsable_sql.sql +41 -0
- execsql2-2.24.0/tests/db/test_transactions.py +372 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/test_postgres.py +91 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_breakpoint.py +1 -101
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/test_sql_scripts.py +2 -2
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_bundled_templates.py +3 -3
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_debug_repl.py +2 -171
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_engine.py +10 -81
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_error_messages.py +3 -3
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_executor_inprocess.py +52 -18
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_format.py +37 -15
- execsql2-2.24.0/tests/test_interactive.py +260 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_registry.py +6 -6
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_script.py +0 -49
- {execsql2-2.23.0 → execsql2-2.24.0}/uv.lock +30 -21
- {execsql2-2.23.0 → execsql2-2.24.0}/zensical.toml +2 -1
- execsql2-2.23.0/.pre-commit-hooks.yaml +0 -9
- execsql2-2.23.0/docs/getting-started/syntax.md +0 -270
- execsql2-2.23.0/docs/guides/debugging.md +0 -110
- execsql2-2.23.0/extras/vscode-execsql/package.json +0 -24
- execsql2-2.23.0/src/execsql/cli/__init__.py +0 -650
- execsql2-2.23.0/src/execsql/cli/help.py +0 -151
- execsql2-2.23.0/src/execsql/cli/lint.py +0 -506
- execsql2-2.23.0/src/execsql/db/duckdb.py +0 -89
- execsql2-2.23.0/tests/cli/test_lint.py +0 -329
- {execsql2-2.23.0 → execsql2-2.24.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.github/dependabot.yml +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.gitignore +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.pre-commit-config.yaml +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.python-version +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/.readthedocs.yaml +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/CONTRIBUTING.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/LICENSE.txt +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/NOTICE +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/SECURITY.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/about/contributors.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/about/copyright.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/cli.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/db.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/exporters.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/importers.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/index.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/api/metacommands.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/adding_exporters.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/adding_importers.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/dev/releasing.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/documentation.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/encoding.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/logging.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/sql_syntax.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/guides/using_scripts.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/Compare_planets.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/actions.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/actions2.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/checkboxes.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/connect.b64 +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/connect.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/create_conf.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/data_error1_screenshot.jpg +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/entry_form.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/execsql_console.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/execsql_logo_01.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/fatals.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/logo_small.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/pause_terminal.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/pause_terminal_sm.b64 +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/pause_terminal_sm.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/prompt_compare.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/set_build_commands.jpg +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/unit_conversions.b64 +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/unit_conversions_029.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/unmatched.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/images/vim_execsql_highlight.png +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/docs/index.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/plugin-template/pyproject.toml +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/vscode-execsql/README.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/scripts/benchmarks/README.md +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/scripts/benchmarks/results/.gitignore +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/__main__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/api.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/cli/dsn.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/data/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/firebird.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/postgres.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/sqlserver.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/db/tiers.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/debug/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/base.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/delimited.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/duckdb.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/feather.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/html.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/json.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/latex.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/markdown.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/ods.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/parquet.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/pretty.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/protocol.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/raw.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/sqlite.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/templates.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/values.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/xls.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/xlsx.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/xml.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/yaml.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/exporters/zip.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/gui/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/gui/base.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/gui/console.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/gui/desktop.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/gui/tui.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/base.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/csv.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/feather.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/json.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/ods.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/importers/xls.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/connect.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/data.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/debug.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/dispatch.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/io.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/io_export.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/io_fileops.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/io_import.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/io_write.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/prompt.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/script_ext.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/system.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/metacommands/upsert.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/models.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/parser.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/plugins.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/py.typed +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/control.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/parser.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/script/variables.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/types.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/auth.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/crypto.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/datetime.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/fileio.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/gui.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/mail.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/numeric.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/regex.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/strings.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/src/execsql/utils/timer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/config_settings.sqlite +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/example_config_prompt.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/make_config_db.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/md_compare.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/md_glossary.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/md_upsert.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/pg_compare.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/pg_glossary.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/pg_upsert.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/script_template.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/ss_compare.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/ss_glossary.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/templates/ss_upsert.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/cli/test_cli_run.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/data/formatter_shapes/comment_anchoring.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_access_windows.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_base.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_db_adapters_mocked.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_db_adapters_mocked_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_dsn.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_duckdb.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_factory.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_mysql_case_folding.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_mysql_inprocess.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_postgres.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_postgres_inprocess.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_roundtrip_adapters.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_sqlite.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_sqlite_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_sqlserver_inprocess.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/db/test_tiers.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/conftest.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_base.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_db.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_delimited.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_duckdb_exporter.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_exporters.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_feather.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_html_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_html_latex.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_json.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_json_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_latex_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_markdown.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_ods.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_ods_export.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_parquet.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_pretty_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_raw_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_columnar.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_dbfile.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_delimited.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_json.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_latex_xml.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_markup.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_ods.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_pretty_raw.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_template.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_values.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_roundtrip_xlsx.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_sqlite_exporter.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_templates.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_templates_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_values_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_xls_xlsx.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_xlsx.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_xml.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_yaml.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/exporters/test_zip.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_backends.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_backends_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_compare_stats.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_compute_row_diffs.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_desktop_dialogs.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_format_table.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_tui_pilot.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_tui_pilot_complex.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/gui/test_utils_gui_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/conftest.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_base_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_csv_edge_cases.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_csv_importer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_feather_importer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_json_importer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_ods_importer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_roundtrip_csv.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/importers/test_xls_importer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/conftest.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/test_dsn.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/test_duckdb.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/test_mysql.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/integration/test_sqlite.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/live_db.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_assert.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_conditions_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_connect.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_io_export.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_io_import.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_connect.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_data.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_fileops_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_io.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_script_ext.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_system.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_metacommands_system_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_pg_upsert.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_prompt.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_row_count.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/metacommands/test_show_scripts.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/audit_lint_bad.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/audit_smoke/sample.json +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/audit_smoke/sample.jsonl +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/audit_smoke.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/config_runtime.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/control_flow.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/counters_and_locals.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/error_handling.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/import_options/has_comments.csv +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/import_options.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/includes/helper.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/includes.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/io_formats.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/multi_db.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/parquet_feather_roundtrip.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/predicates.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/scripts.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/smoke.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/subroutine_loops.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/subvars_advanced.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/template_export/greeting.tmpl +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/template_export.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/timer.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/transactions.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/write_create_table.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/scripts/fixtures/xlsx_ods_roundtrip.sql +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_env_detection.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_expansion_bomb.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_import_regex_hardening.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_log_redaction.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_odbc_injection.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_path_containment.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_substitution_injection.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/security/test_zip_bomb.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_api.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_api_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_api_filewriter.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_ast.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_ast_parser.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_config.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_config_data.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_config_extended.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_exceptions.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_executor.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_mail.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_models.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_package.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_parser.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_parser_params.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_plugins.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_state.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/test_types.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/__init__.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_auth.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_auth_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_crypto.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_datetime.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_encodedfile_context.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_errors.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_errors_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_fileio.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_fileio_extra.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_numeric.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_regex.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_strings.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_timer.py +0 -0
- {execsql2-2.23.0 → execsql2-2.24.0}/tests/utils/test_timer_extra.py +0 -0
|
@@ -43,6 +43,47 @@ jobs:
|
|
|
43
43
|
- run: python -m pip install ".[dev]"
|
|
44
44
|
- run: mypy src/execsql/
|
|
45
45
|
|
|
46
|
+
formatter-corpus:
|
|
47
|
+
name: formatter-corpus
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
permissions:
|
|
50
|
+
contents: read
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
53
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
54
|
+
with:
|
|
55
|
+
python-version: "3.13"
|
|
56
|
+
cache: "pip"
|
|
57
|
+
- run: python -m pip install --upgrade pip
|
|
58
|
+
- run: python -m pip install ".[dev]"
|
|
59
|
+
# Every formatter bug to date came from real SQL containing a
|
|
60
|
+
# construct the project's own scripts lack. This gate runs those
|
|
61
|
+
# checks under their own name so a corpus failure is legible
|
|
62
|
+
# without reading a 6,000-test log.
|
|
63
|
+
- run: pytest tests/test_format.py -k corpus --no-cov -q
|
|
64
|
+
|
|
65
|
+
typer-floor:
|
|
66
|
+
name: typer-floor
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
permissions:
|
|
69
|
+
contents: read
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
72
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
73
|
+
with:
|
|
74
|
+
python-version: "3.10"
|
|
75
|
+
cache: "pip"
|
|
76
|
+
- run: python -m pip install --upgrade pip
|
|
77
|
+
# Help rendering and flag parsing lean on Typer internals that
|
|
78
|
+
# move between releases, and every other job runs the newest
|
|
79
|
+
# Typer. Install the declared minimum, read from pyproject.toml so
|
|
80
|
+
# the two cannot drift, and run the CLI tests against it.
|
|
81
|
+
- run: |
|
|
82
|
+
floor=$(grep -oP '"typer>=\K[0-9.]+' pyproject.toml)
|
|
83
|
+
echo "Typer floor: $floor"
|
|
84
|
+
python -m pip install ".[dev]" "typer==$floor"
|
|
85
|
+
- run: pytest tests/cli --no-cov -q
|
|
86
|
+
|
|
46
87
|
pre-commit:
|
|
47
88
|
name: pre-commit
|
|
48
89
|
runs-on: ubuntu-latest
|
|
@@ -213,7 +254,7 @@ jobs:
|
|
|
213
254
|
- name: Install dependencies
|
|
214
255
|
run: |
|
|
215
256
|
python -m pip install --upgrade pip
|
|
216
|
-
python -m pip install ".[dev,postgres,mysql,mssql]"
|
|
257
|
+
python -m pip install ".[dev,postgres,mysql,mssql,upsert]"
|
|
217
258
|
- name: Run subprocess integration tests
|
|
218
259
|
run: |
|
|
219
260
|
python -m pytest tests/integration/test_postgres.py tests/integration/test_mysql.py -v --override-ini="addopts="
|
|
@@ -289,7 +330,7 @@ jobs:
|
|
|
289
330
|
build:
|
|
290
331
|
name: Build distribution 📦
|
|
291
332
|
runs-on: ubuntu-latest
|
|
292
|
-
needs: [ lint, typecheck, pre-commit, docs, tests, integration-tests ]
|
|
333
|
+
needs: [ lint, typecheck, pre-commit, formatter-corpus, typer-floor, docs, tests, integration-tests ]
|
|
293
334
|
# Deliberately NOT gated on tags: packaging breaks must surface on a PR,
|
|
294
335
|
# not at release time. Only publish/generate-release below are tag-gated.
|
|
295
336
|
permissions:
|
|
@@ -364,3 +405,67 @@ jobs:
|
|
|
364
405
|
generate_release_notes: true
|
|
365
406
|
files: |
|
|
366
407
|
dist/*
|
|
408
|
+
|
|
409
|
+
publish-vscode:
|
|
410
|
+
name: Publish VS Code extension 🧩
|
|
411
|
+
needs: [ build ]
|
|
412
|
+
# Only on a version tag, and only when a Marketplace token is configured.
|
|
413
|
+
# Without VSCE_PAT the job is skipped rather than failed, so a release
|
|
414
|
+
# still completes for anyone who has not set the secret up.
|
|
415
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
416
|
+
runs-on: ubuntu-latest
|
|
417
|
+
permissions:
|
|
418
|
+
contents: read
|
|
419
|
+
steps:
|
|
420
|
+
- name: Checkout
|
|
421
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
422
|
+
- name: Check for a Marketplace token
|
|
423
|
+
id: gate
|
|
424
|
+
# Read through env, never interpolated into the command line.
|
|
425
|
+
env:
|
|
426
|
+
VSCE_PAT: ${{ secrets.VSCE_PAT }}
|
|
427
|
+
run: |
|
|
428
|
+
if [ -n "$VSCE_PAT" ]; then
|
|
429
|
+
echo "ready=true" >> "$GITHUB_OUTPUT"
|
|
430
|
+
else
|
|
431
|
+
echo "ready=false" >> "$GITHUB_OUTPUT"
|
|
432
|
+
echo "VSCE_PAT is not set — skipping the Marketplace publish." >> "$GITHUB_STEP_SUMMARY"
|
|
433
|
+
fi
|
|
434
|
+
- name: Setup Python
|
|
435
|
+
if: steps.gate.outputs.ready == 'true'
|
|
436
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
437
|
+
with:
|
|
438
|
+
python-version: "3.13"
|
|
439
|
+
# The grammar is generated from the metacommand dispatch table, so it
|
|
440
|
+
# is rebuilt here rather than trusted to be current in the tree.
|
|
441
|
+
- name: Regenerate the TextMate grammar
|
|
442
|
+
if: steps.gate.outputs.ready == 'true'
|
|
443
|
+
run: |
|
|
444
|
+
python -m pip install --upgrade pip
|
|
445
|
+
python -m pip install .
|
|
446
|
+
python scripts/generate_vscode_grammar.py
|
|
447
|
+
- name: Fail if the committed grammar is stale
|
|
448
|
+
if: steps.gate.outputs.ready == 'true'
|
|
449
|
+
run: git diff --exit-code -- extras/vscode-execsql/syntaxes/
|
|
450
|
+
# The Marketplace refuses a version it already has, so the
|
|
451
|
+
# extension version tracks the tag rather than being bumped by hand
|
|
452
|
+
# in a second place.
|
|
453
|
+
- name: Set the extension version from the tag
|
|
454
|
+
if: steps.gate.outputs.ready == 'true'
|
|
455
|
+
working-directory: extras/vscode-execsql
|
|
456
|
+
run: |
|
|
457
|
+
version="${GITHUB_REF_NAME#v}"
|
|
458
|
+
python - "$version" <<'PY'
|
|
459
|
+
import json, pathlib, sys
|
|
460
|
+
p = pathlib.Path("package.json")
|
|
461
|
+
data = json.loads(p.read_text())
|
|
462
|
+
data["version"] = sys.argv[1]
|
|
463
|
+
p.write_text(json.dumps(data, indent=2) + "\n")
|
|
464
|
+
print("extension version set to", sys.argv[1])
|
|
465
|
+
PY
|
|
466
|
+
- name: Publish
|
|
467
|
+
if: steps.gate.outputs.ready == 'true'
|
|
468
|
+
working-directory: extras/vscode-execsql
|
|
469
|
+
run: npx --yes @vscode/vsce@latest publish
|
|
470
|
+
env:
|
|
471
|
+
VSCE_PAT: ${{ secrets.VSCE_PAT }}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
- id: execsql-format
|
|
2
|
+
name: execsql-format
|
|
3
|
+
description: Format execsql SQL scripts — normalize metacommand indentation and uppercase keywords.
|
|
4
|
+
entry: execsql format
|
|
5
|
+
language: python
|
|
6
|
+
types: [file]
|
|
7
|
+
files: \.sql$
|
|
8
|
+
args: [--in-place]
|
|
9
|
+
additional_dependencies: ["sqlglot>=25.0,<31"]
|
|
10
|
+
|
|
11
|
+
- id: execsql-lint
|
|
12
|
+
name: execsql-lint
|
|
13
|
+
description: Statically check execsql SQL scripts without a database — unclosed blocks, undefined or unused variables, missing INCLUDE targets, unreachable code.
|
|
14
|
+
entry: execsql lint
|
|
15
|
+
language: python
|
|
16
|
+
types: [file]
|
|
17
|
+
files: \.sql$
|
|
@@ -13,6 +13,67 @@ ______________________________________________________________________
|
|
|
13
13
|
|
|
14
14
|
______________________________________________________________________
|
|
15
15
|
|
|
16
|
+
## [2.24.0] - 2026-10-01
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Commands:** `execsql run`, `format`, `lint`, `config`, `list` and `init`. `format` and `lint` take files or directories and need no database, so a whole script library can be linted at once. See [Commands](https://execsql2.readthedocs.io/en/latest/getting-started/syntax/#commands).
|
|
21
|
+
- **`run`:** `--manifest FILE` writes a JSON record of the run (files read and written, connections, statement counts and any error), even when the run fails. `--var NAME=VALUE` sets `!!NAME!!` from the command line.
|
|
22
|
+
- **`lint`:** every issue has a rule code (`V001`, `F002`, …) that `--select` and `--ignore` filter on. `--output-format json|concise|github`, `--statistics`, and `--strict` to fail on warnings. New checks for a `SUB` variable nothing reads, an `IF` whose condition never changes, and statements after `HALT`. See the [lint rules reference](https://execsql2.readthedocs.io/en/latest/reference/lint/).
|
|
23
|
+
- **`execsql-lint` pre-commit hook**, alongside `execsql-format`.
|
|
24
|
+
- **`format`:** `--diff` shows what would change without writing. `--sql` and `--no-leading-comma` override the config for one run.
|
|
25
|
+
- **`format` and `lint`:** read a script from stdin with `-`, and take `-f`/`--script-encoding` and `--config`.
|
|
26
|
+
- **`[format]` and `[lint]` config sections** set project defaults; a command-line flag wins.
|
|
27
|
+
- **`config`:** lists every option with its value, its default and the file that set it, with passwords shown as `***`. `--validate` reports every problem in every config file with its file and line. `--init` prints the config template.
|
|
28
|
+
- **`init`:** creates `execsql.conf`, a starter script and the pre-commit hooks. Existing files are kept unless you pass `--force`.
|
|
29
|
+
- **`list`:** `metacommands`, `encodings`, `plugins` and `keywords`, as text or JSON.
|
|
30
|
+
- **`PG_UPSERT` character-length check:** a staging value longer than its `varchar(n)` or `char(n)` base column fails QA and appears in the `EXPORT_FAILURES` fix sheet.
|
|
31
|
+
|
|
32
|
+
### Deprecated
|
|
33
|
+
|
|
34
|
+
- Running a script without a command (`execsql script.sql myserver mydb`) prints a warning and stops working in execsql2 3.0. Put `run` first: `execsql run script.sql myserver mydb`. `-m`, `-y`, `--list-plugins`, `--dump-keywords`, `--init-config` and `--ping` without a command warn the same way and name their replacement; see [Flags that became commands](https://execsql2.readthedocs.io/en/latest/getting-started/syntax/#former_flags). After `run` they still work without a warning, but `execsql run --help` no longer lists them.
|
|
35
|
+
|
|
36
|
+
### Removed
|
|
37
|
+
|
|
38
|
+
- `--lint`: use `execsql lint`. `execsql run --lint` now exits with status 2 without running the script, so update CI steps and hooks that call it.
|
|
39
|
+
- The `execsql-format` command: use `execsql format`, which takes the same options. Pre-commit users need no change, because the hook id is still `execsql-format`. Shell scripts, Makefiles and CI steps that call `execsql-format` must be updated.
|
|
40
|
+
- `SqlStmt`, `MetacommandStmt` and `ScriptCmd` from `execsql.script`. Only Python code that imports them is affected; scripts are not.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- **`PG_UPSERT` QA follows `METHOD` and `EXCLUDE`:** all three modes check only the staging rows the load would write, so pass `PG_UPSERT QA` the same `METHOD` and `EXCLUDE` as the load that follows it. `CHECK ... METHOD update` treats a missing `NOT NULL` column as a warning. The `upsert` extra now requires pg-upsert 1.25.0 or newer. See [QA follows METHOD and EXCLUDE](https://execsql2.readthedocs.io/en/latest/reference/metacommands/#pg_upsert_qa_method).
|
|
45
|
+
- **`PG_UPSERT` QA can fail where it passed before:** it now catches a unique key that collides with an existing base row, a foreign key parent that is not in `TABLES`, and an excluded `NOT NULL` column on an inserted row, all of which used to fail during the load.
|
|
46
|
+
- A script named exactly like a command (`run`, `format`, `lint`, `config`, `list` or `init`, with no extension) must be run as `execsql run NAME`.
|
|
47
|
+
- `execsql format --encoding` is now `-f`/`--script-encoding`, matching `run`. `--encoding` still works.
|
|
48
|
+
- The debug REPL (`BREAKPOINT`, `--debug`) runs metacommands and blocks as well as SQL, as if they were the next lines of the script where it paused: a `SUB` stays set when the script resumes, and SQL is committed as the script's own SQL would be. See [Debugging](https://execsql2.readthedocs.io/en/latest/guides/debugging/).
|
|
49
|
+
- CLI help is plain text, colored on a terminal (`NO_COLOR` or `EXECSQL_NO_COLOR` turns color off), and uses the terminal's full width. `execsql` with no arguments prints it and exits with status 2.
|
|
50
|
+
- Lint output groups issues under each file in line order, with one summary line. A script that fails to parse is reported on one line with its line number.
|
|
51
|
+
- Error messages name the fix: a missing SQLite or DuckDB file suggests `-n`/`--new-db`, and a config file error names the file and line and suggests `execsql config --validate`.
|
|
52
|
+
- Requires Typer 0.26 or newer (previously 0.12).
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- `execsql format` without the `[formatter]` extra says sqlglot is needed and how to install it, instead of an uncaught `ImportError`.
|
|
57
|
+
- `-h` works as a short form of `--help`, as it did in upstream execsql.
|
|
58
|
+
- The debug REPL's `.set VAR VALUE` keeps the value's case instead of lowercasing it, and `.vars all` lists environment variables instead of looking up a variable named `all`.
|
|
59
|
+
|
|
60
|
+
______________________________________________________________________
|
|
61
|
+
|
|
62
|
+
## [2.23.1] - 2026-09-29
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- A warning when MySQL, MariaDB or Oracle commits a statement on its own while `AUTOCOMMIT` is `OFF` or a batch is open — `CREATE TABLE`, `DROP`, `TRUNCATE` and other DDL, which the server commits together with everything before it, so none of it can be rolled back.
|
|
67
|
+
- A warning when `AUTOCOMMIT OFF` or `BEGIN BATCH` cannot hold statements at all: an ODBC DSN whose driver has no transactions, or an MS Access `CREATE TEMPORARY QUERY`, which reopens the connection and rolls back what was not yet committed.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- SQLite: `CREATE TABLE`, `DROP` and other DDL run while `AUTOCOMMIT` is `OFF` or inside `BEGIN BATCH` are held until commit. They were committed at once, so `AUTOCOMMIT ON WITH ROLLBACK` and `ROLLBACK BATCH` left them in place.
|
|
72
|
+
- DuckDB: `AUTOCOMMIT OFF` and `BEGIN BATCH` hold statements until commit. Every statement, rows included, was committed as it ran, so nothing could be rolled back. A script's own `BEGIN;` and `COMMIT;` now work too; `COMMIT;` failed with "no transaction is active".
|
|
73
|
+
- DuckDB: `$LAST_ROWCOUNT` holds the number of rows an `INSERT`, `UPDATE` or `DELETE` changed. It was always `-1`.
|
|
74
|
+
|
|
75
|
+
______________________________________________________________________
|
|
76
|
+
|
|
16
77
|
## [2.23.0] - 2026-09-29
|
|
17
78
|
|
|
18
79
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.24.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, undefined variables, bad 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
|
+
pip 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, 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,54 @@ The `PROMPT` metacommand produces a GUI display of the data:
|
|
|
197
244
|
## Installation
|
|
198
245
|
|
|
199
246
|
```bash
|
|
200
|
-
pip install execsql2 # core
|
|
247
|
+
pip install execsql2 # core: SQLite works with no extras
|
|
201
248
|
pip install "execsql2[postgres]" # add a driver: postgres, mysql, mssql, duckdb, firebird, oracle, odbc
|
|
202
249
|
pip install "execsql2[all]" # everything: all drivers plus all feature extras
|
|
203
250
|
```
|
|
204
251
|
|
|
205
|
-
Feature extras cover spreadsheet and Parquet/Feather formats, keyring authentication, PostgreSQL upsert, and more
|
|
252
|
+
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
253
|
|
|
207
254
|
## Usage
|
|
208
255
|
|
|
209
256
|
```text
|
|
210
|
-
execsql [OPTIONS] SQL_SCRIPT [SERVER DATABASE | DATABASE_FILE]
|
|
257
|
+
execsql run [OPTIONS] SQL_SCRIPT [SERVER DATABASE | DATABASE_FILE]
|
|
258
|
+
execsql format [--check | -i] [--indent N] FILE_OR_DIR...
|
|
259
|
+
execsql lint [OPTIONS] FILE_OR_DIR...
|
|
260
|
+
execsql config [SQL_SCRIPT] [--init] [--config FILE]
|
|
261
|
+
execsql list metacommands|encodings|plugins|keywords
|
|
262
|
+
execsql init [DIR] [--script NAME] [--no-script] [--no-config] [--no-pre-commit]
|
|
211
263
|
```
|
|
212
264
|
|
|
213
265
|
Examples:
|
|
214
266
|
|
|
215
267
|
```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
|
|
268
|
+
execsql run -tp script.sql myserver mydb # PostgreSQL
|
|
269
|
+
execsql run -tm script.sql myserver mydb # MySQL / MariaDB
|
|
270
|
+
execsql run -ts script.sql myserver mydb # SQL Server
|
|
271
|
+
execsql run -tl script.sql mydb.sqlite # SQLite
|
|
272
|
+
execsql run -tk script.sql mydb.duckdb # DuckDB
|
|
273
|
+
execsql run -to script.sql myserver myservice # Oracle
|
|
274
|
+
execsql run script.sql # read connection from config file
|
|
223
275
|
```
|
|
224
276
|
|
|
225
277
|
### Supported Databases
|
|
226
278
|
|
|
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
|
|
279
|
+
| Flag | Database | Support |
|
|
280
|
+
| ---- | --------------- | ----------------------------------------------- |
|
|
281
|
+
| `p` | PostgreSQL | Supported: verified against a live server in CI |
|
|
282
|
+
| `m` | MySQL / MariaDB | Supported: verified against a live server in CI |
|
|
283
|
+
| `s` | MS SQL Server | Supported: verified against a live server in CI |
|
|
284
|
+
| `l` | SQLite | Supported: verified against real files in CI |
|
|
285
|
+
| `k` | DuckDB | Supported: verified against real files in CI |
|
|
286
|
+
| `a` | MS Access | Best effort: not verified in CI |
|
|
287
|
+
| `f` | Firebird | Best effort: not verified in CI |
|
|
288
|
+
| `o` | Oracle | Best effort: not verified in CI |
|
|
289
|
+
| `d` | ODBC DSN | Best effort: not verified in CI |
|
|
238
290
|
|
|
239
291
|
**Supported** adapters run against a live server or a real database file on
|
|
240
292
|
every CI run; a regression blocks the release and bugs get fixed. **Best
|
|
241
293
|
effort** adapters are carried forward from the upstream monolith and are not
|
|
242
|
-
exercised anywhere in CI
|
|
294
|
+
exercised anywhere in CI. The code is there and may work, but nothing proves
|
|
243
295
|
it still does. Issues and pull requests are welcome for them; no guarantee is
|
|
244
296
|
made. Opening a best-effort connection prints one informational line, which
|
|
245
297
|
`support_tier_notice=No` in the `[interface]` section of `execsql.conf`
|
|
@@ -247,24 +299,24 @@ silences.
|
|
|
247
299
|
|
|
248
300
|
### Common options
|
|
249
301
|
|
|
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
|
|
302
|
+
| Flag | Description |
|
|
303
|
+
| ------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
304
|
+
| `-t {p,m,s,l,k,a,f,o,d}` | Database type |
|
|
305
|
+
| `-u USER` | Database username |
|
|
306
|
+
| `-p PORT` | Server port |
|
|
307
|
+
| `--dsn URL` | Connection string (e.g. `postgresql://user:pass@host/db`) |
|
|
308
|
+
| `-n` | Create a new SQLite or PostgreSQL database if it does not exist |
|
|
309
|
+
| `-c SCRIPT` | Execute inline SQL or metacommand string |
|
|
310
|
+
| `-a VALUE` | Set substitution variable `$ARG_x` |
|
|
311
|
+
| `--var NAME=VALUE` | Set the substitution variable `!!NAME!!` |
|
|
312
|
+
| `-v {0,1,2,3}` | GUI level (0=none, 1=password, 2=selection, 3=full) |
|
|
313
|
+
| `--config FILE` | Load an explicit config file |
|
|
314
|
+
| `--dry-run` | Parse the script and report commands without executing |
|
|
315
|
+
| `--manifest FILE` | Write a JSON record of the run: files read and written, statements, errors |
|
|
316
|
+
| `--debug` | Start in step-through debug mode (REPL pauses before each stmt) |
|
|
317
|
+
| `--no-system-cmd` / `--no-rm-file` / `--no-serve` | Disable the `SYSTEM_CMD` / `RM_FILE` / `SERVE` metacommands |
|
|
318
|
+
|
|
319
|
+
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
320
|
|
|
269
321
|
## Features
|
|
270
322
|
|
|
@@ -279,7 +331,7 @@ See the [full options reference](https://execsql2.readthedocs.io/en/latest/getti
|
|
|
279
331
|
- Conditionally execute SQL and metacommands using `IF`/`ELSE`/`ENDIF` based on data values, DBMS type, or user input.
|
|
280
332
|
- Loop over blocks of SQL and metacommands using `LOOP`/`ENDLOOP`; include or chain scripts with `INCLUDE` and `SCRIPT`.
|
|
281
333
|
- Use substitution variables (`SUB`, `$ARG_x`, built-in variables like `$date_tag`) to parameterize scripts.
|
|
282
|
-
- Validate data with `ASSERT
|
|
334
|
+
- Validate data with `ASSERT`: halt the script with a clear error message if a condition is false (ideal for CI pipelines).
|
|
283
335
|
|
|
284
336
|
**Interaction & observability**
|
|
285
337
|
|
|
@@ -334,7 +386,7 @@ if not result.success:
|
|
|
334
386
|
result.raise_on_error() # raises ExecSqlError
|
|
335
387
|
```
|
|
336
388
|
|
|
337
|
-
Use a pre-existing database connection instead of a DSN
|
|
389
|
+
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
390
|
|
|
339
391
|
```python
|
|
340
392
|
from execsql import run
|
|
@@ -357,7 +409,7 @@ loaded = run(
|
|
|
357
409
|
variables={"RUN_DATE": "2026-07-03"},
|
|
358
410
|
)
|
|
359
411
|
|
|
360
|
-
# run() does NOT close the connection
|
|
412
|
+
# run() does NOT close the connection; you manage its lifecycle
|
|
361
413
|
conn.close()
|
|
362
414
|
|
|
363
415
|
# SQLite works the same way
|
|
@@ -366,43 +418,44 @@ result = run(sql="SELECT 1;", connection=conn)
|
|
|
366
418
|
conn.close()
|
|
367
419
|
```
|
|
368
420
|
|
|
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`)
|
|
421
|
+
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
422
|
|
|
371
423
|
Each call to `run()` uses an isolated `RuntimeContext`, so multiple calls do not share state.
|
|
372
424
|
|
|
373
425
|
## Formatting Scripts
|
|
374
426
|
|
|
375
|
-
The `execsql
|
|
427
|
+
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
428
|
|
|
377
429
|
```bash
|
|
378
430
|
# Install with the SQL-reformatting extra
|
|
379
431
|
pip install execsql2[formatter]
|
|
380
432
|
|
|
381
433
|
# Format files in place
|
|
382
|
-
execsql
|
|
434
|
+
execsql format --in-place scripts/
|
|
383
435
|
|
|
384
436
|
# Check formatting without writing (useful in CI)
|
|
385
|
-
execsql
|
|
437
|
+
execsql format --check scripts/
|
|
386
438
|
|
|
387
|
-
# Run the formatter without sqlglot
|
|
388
|
-
execsql
|
|
439
|
+
# Run the formatter without sqlglot: keyword/indent normalization only
|
|
440
|
+
execsql format --no-sql --in-place scripts/
|
|
389
441
|
```
|
|
390
442
|
|
|
391
|
-
`execsql
|
|
443
|
+
`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
444
|
|
|
393
445
|
```yaml
|
|
394
446
|
repos:
|
|
395
447
|
- repo: https://github.com/geocoug/execsql
|
|
396
|
-
rev: v2.
|
|
448
|
+
rev: v2.24.0
|
|
397
449
|
hooks:
|
|
398
450
|
- id: execsql-format
|
|
451
|
+
- id: execsql-lint
|
|
399
452
|
```
|
|
400
453
|
|
|
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.
|
|
454
|
+
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
455
|
|
|
403
456
|
## VS Code Syntax Highlighting
|
|
404
457
|
|
|
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
|
|
458
|
+
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
459
|
|
|
407
460
|
To install, symlink the extension folder into your VS Code extensions directory:
|
|
408
461
|
|