execsql2 2.26.0__tar.gz → 2.28.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.26.0 → execsql2-2.28.0}/.github/dependabot.yml +9 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/.github/workflows/ci-cd.yml +38 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/.gitignore +4 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/.pre-commit-config.yaml +6 -6
- {execsql2-2.26.0 → execsql2-2.28.0}/.readthedocs.yaml +1 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/CHANGELOG.md +55 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/PKG-INFO +34 -18
- {execsql2-2.26.0 → execsql2-2.28.0}/README.md +18 -16
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/about/divergence.md +6 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/adding_metacommands.md +26 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/releasing.md +11 -10
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/getting-started/installation.md +19 -18
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/getting-started/syntax.md +19 -16
- execsql2-2.28.0/docs/guides/editors.md +229 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/formatter.md +11 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/reference/lint.md +1 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/reference/metacommands.md +5 -5
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/vscode-execsql/README.md +60 -4
- execsql2-2.28.0/extras/vscode-execsql/extension.js +135 -0
- execsql2-2.28.0/extras/vscode-execsql/package-lock.json +1901 -0
- execsql2-2.28.0/extras/vscode-execsql/package.json +87 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +1 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/justfile +4 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/pyproject.toml +21 -4
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/__init__.py +1 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/format.py +2 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/listing.py +32 -5
- execsql2-2.28.0/src/execsql/cli/commands/lsp.py +64 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/dispatch.py +1 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/help.py +44 -96
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/lint.py +58 -22
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/access.py +4 -4
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/base.py +17 -3
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/dsn.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/duckdb.py +14 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/firebird.py +2 -3
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/mysql.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/oracle.py +5 -5
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/postgres.py +2 -3
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/sqlserver.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/duckdb.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/ods.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/templates.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/xls.py +3 -3
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/xlsx.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/yaml.py +3 -4
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/format.py +71 -21
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/base.py +6 -10
- execsql2-2.28.0/src/execsql/lsp/__init__.py +6 -0
- execsql2-2.28.0/src/execsql/lsp/code_actions.py +217 -0
- execsql2-2.28.0/src/execsql/lsp/completion.py +203 -0
- execsql2-2.28.0/src/execsql/lsp/diagnostics.py +66 -0
- execsql2-2.28.0/src/execsql/lsp/document.py +210 -0
- execsql2-2.28.0/src/execsql/lsp/folding.py +59 -0
- execsql2-2.28.0/src/execsql/lsp/formatting.py +37 -0
- execsql2-2.28.0/src/execsql/lsp/hover.py +119 -0
- execsql2-2.28.0/src/execsql/lsp/navigation.py +169 -0
- execsql2-2.28.0/src/execsql/lsp/rename.py +91 -0
- execsql2-2.28.0/src/execsql/lsp/server.py +358 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/debug.py +2 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/dispatch.py +7 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/io_fileops.py +6 -6
- execsql2-2.28.0/src/execsql/metacommands/reference.py +1404 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/upsert.py +2 -5
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/models.py +11 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/errors.py +16 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_cli.py +2 -3
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_cli_surface.py +1 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_commands.py +28 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_lint.py +19 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_copy_new.py +37 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_duckdb.py +8 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_new_table_checks.py +24 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/test_postgres.py +26 -0
- execsql2-2.28.0/tests/lsp/test_code_actions.py +94 -0
- execsql2-2.28.0/tests/lsp/test_completion.py +112 -0
- execsql2-2.28.0/tests/lsp/test_diagnostics.py +63 -0
- execsql2-2.28.0/tests/lsp/test_document.py +101 -0
- execsql2-2.28.0/tests/lsp/test_folding.py +63 -0
- execsql2-2.28.0/tests/lsp/test_formatting.py +42 -0
- execsql2-2.28.0/tests/lsp/test_hover.py +83 -0
- execsql2-2.28.0/tests/lsp/test_lsp_command.py +71 -0
- execsql2-2.28.0/tests/lsp/test_navigation.py +103 -0
- execsql2-2.28.0/tests/lsp/test_rename.py +99 -0
- execsql2-2.28.0/tests/lsp/test_server.py +436 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_extended.py +11 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_fileops_extra.py +4 -2
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_pg_upsert.py +1 -1
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_format.py +60 -0
- execsql2-2.28.0/tests/test_reference.py +225 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_tooling_versions.py +9 -0
- execsql2-2.28.0/tests/utils/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_errors.py +27 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/uv.lock +162 -41
- {execsql2-2.26.0 → execsql2-2.28.0}/zensical.toml +1 -0
- execsql2-2.26.0/extras/vscode-execsql/package.json +0 -46
- {execsql2-2.26.0 → execsql2-2.28.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/.pre-commit-hooks.yaml +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/.python-version +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/CONTRIBUTING.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/LICENSE.txt +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/NOTICE +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/SECURITY.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/about/contributors.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/about/copyright.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/cli.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/db.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/exporters.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/importers.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/index.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/api/metacommands.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/adding_db_adapters.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/adding_exporters.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/adding_importers.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/dev/architecture.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/getting-started/requirements.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/debugging.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/documentation.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/encoding.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/examples.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/logging.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/sql_syntax.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/usage.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/guides/using_scripts.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/Compare_planets.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/actions.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/actions2.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/checkboxes.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/connect.b64 +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/connect.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/create_conf.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/data_error1_screenshot.jpg +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/entry_form.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/execsql_console.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/execsql_logo_01.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/fatals.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/logo_small.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/pause_terminal.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/pause_terminal_sm.b64 +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/pause_terminal_sm.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/prompt_compare.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/set_build_commands.jpg +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/unit_conversions.b64 +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/unit_conversions_029.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/unmatched.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/images/vim_execsql_highlight.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/index.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/reference/configuration.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/reference/security.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/docs/reference/substitution_vars.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/plugin-template/README.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/plugin-template/pyproject.toml +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/plugin-template/tests/test_plugin.py.example +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/vscode-execsql/.vscodeignore +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/vscode-execsql/LICENSE.txt +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/extras/vscode-execsql/icon.png +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/scripts/benchmarks/README.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/scripts/benchmarks/results/.gitignore +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/scripts/benchmarks/run_benchmarks.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/scripts/generate_vscode_grammar.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/__main__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/api.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/application.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/config.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/init.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/lint.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/commands/run.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/dsn.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/options.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/cli/run.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/config.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/config_validation.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/data/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/data/execsql.conf.template +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/data/script_header.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/factory.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/sqlite.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/db/tiers.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/debug/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/debug/repl.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exceptions.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/base.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/delimited.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/feather.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/html.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/json.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/latex.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/markdown.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/parquet.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/pretty.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/protocol.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/raw.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/sqlite.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/values.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/xml.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/exporters/zip.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/gui/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/gui/base.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/gui/console.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/gui/desktop.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/gui/tui.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/csv.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/feather.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/json.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/ods.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/importers/xls.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/interactive.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/manifest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/conditions.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/connect.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/control.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/data.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/effects.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/io.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/io_export.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/io_import.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/io_write.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/prompt.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/script_ext.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/metacommands/system.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/parser.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/plugins.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/py.typed +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/ast.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/control.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/engine.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/executor.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/parser.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/script/variables.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/state.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/state.pyi +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/types.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/auth.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/color.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/crypto.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/datetime.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/fileio.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/gui.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/mail.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/numeric.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/regex.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/strings.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/src/execsql/utils/timer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/README.md +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/config_settings.sqlite +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/example_config_prompt.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/make_config_db.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/md_compare.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/md_glossary.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/md_upsert.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/pg_compare.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/pg_glossary.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/pg_upsert.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/script_template.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/ss_compare.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/ss_glossary.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/templates/ss_upsert.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_cli_e2e.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_cli_run.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_config_validate.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_dispatch.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_error_location.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_init.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_lint_fixtures.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_log_exit_record.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_manifest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_ping.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_profile.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_sigterm.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/cli/test_undeclared_imports.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/conftest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/formatter_shapes/comment_anchoring.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/formatter_shapes/escapes_and_literals.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/formatter_shapes/substitution_and_metacommands.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/formatter_shapes/unparsable_sql.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/lint/conditions_and_blocks.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/lint/does_not_parse.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/lint/every_metacommand.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/data/lint/invalid.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_access_windows.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_base.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_db_adapters_mocked.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_db_adapters_mocked_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_dsn.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_factory.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_factory_postgres_encoding.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_import_atomic.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_import_replacement_quoted.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_import_short_rows.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_import_timezones.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_mysql_case_folding.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_mysql_inprocess.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_oracle_driver.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_postgres.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_postgres_inprocess.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_roundtrip_adapters.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_sqlite.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_sqlite_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_sqlserver_inprocess.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_tiers.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/db/test_transactions.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/conftest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_base.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_db.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_delimited.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_duckdb_exporter.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_exporters.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_feather.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_html_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_html_latex.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_json.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_json_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_latex_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_markdown.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_ods.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_ods_export.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_parquet.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_pretty_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_raw_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_columnar.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_dbfile.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_delimited.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_json.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_latex_xml.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_markup.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_ods.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_pretty_raw.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_template.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_values.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_roundtrip_xlsx.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_sqlite_exporter.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_templates.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_templates_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_values_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_xls_xlsx.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_xlsx.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_xml.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_yaml.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/exporters/test_zip.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_backends.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_backends_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_compare_stats.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_compute_row_diffs.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_desktop_dialogs.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_format_table.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_tui_pilot.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_tui_pilot_complex.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/gui/test_utils_gui_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/conftest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_base_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_csv_blank_lines.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_csv_edge_cases.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_csv_importer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_feather_importer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_json_importer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_ods_importer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_roundtrip_csv.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/importers/test_xls_importer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/conftest.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/test_dsn.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/test_duckdb.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/test_mysql.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/integration/test_sqlite.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/live_db.py +0 -0
- {execsql2-2.26.0/tests/metacommands → execsql2-2.28.0/tests/lsp}/__init__.py +0 -0
- {execsql2-2.26.0/tests/scripts → execsql2-2.28.0/tests/metacommands}/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_assert.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_breakpoint.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_conditions_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_connect.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_io_export.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_io_import.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_connect.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_data.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_io.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_script_ext.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_system.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_metacommands_system_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_prompt.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_row_count.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/metacommands/test_show_scripts.py +0 -0
- {execsql2-2.26.0/tests/security → execsql2-2.28.0/tests/scripts}/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/audit_lint_bad.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/audit_smoke/sample.json +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/audit_smoke/sample.jsonl +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/audit_smoke.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/config_runtime.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/control_flow.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/counters_and_locals.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/error_handling.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/import_options/has_comments.csv +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/import_options.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/includes/helper.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/includes.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/io_formats.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/multi_db.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/parquet_feather_roundtrip.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/predicates.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/scripts.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/smoke.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/subroutine_loops.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/subvars_advanced.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/template_export/greeting.tmpl +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/template_export.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/timer.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/transactions.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/write_create_table.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/fixtures/xlsx_ods_roundtrip.sql +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/scripts/test_sql_scripts.py +0 -0
- {execsql2-2.26.0/tests/utils → execsql2-2.28.0/tests/security}/__init__.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_env_detection.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_expansion_bomb.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_import_regex_hardening.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_log_redaction.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_log_secrets.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_odbc_injection.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_path_containment.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_substitution_injection.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/security/test_zip_bomb.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api_errors.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api_filewriter.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api_isolation.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_api_subprocess.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_ast.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_ast_parser.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_bundled_templates.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_config.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_config_data.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_config_extended.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_date_inference.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_debug_repl.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_engine.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_error_messages.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_exceptions.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_executor.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_executor_inprocess.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_interactive.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_mail.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_models.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_package.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_parser.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_parser_params.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_plugins.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_registry.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_script.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_state.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/test_types.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_auth.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_auth_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_crypto.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_datetime.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_encodedfile_context.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_errors_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_fileio.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_fileio_extra.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_keyring_rules.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_mail_tls.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_numeric.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_regex.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_strings.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_timer.py +0 -0
- {execsql2-2.26.0 → execsql2-2.28.0}/tests/utils/test_timer_extra.py +0 -0
|
@@ -51,3 +51,12 @@ updates:
|
|
|
51
51
|
pre-commit-hooks:
|
|
52
52
|
patterns:
|
|
53
53
|
- "*"
|
|
54
|
+
# The VS Code extension's language client and its packaging tool.
|
|
55
|
+
- package-ecosystem: npm
|
|
56
|
+
directory: /extras/vscode-execsql
|
|
57
|
+
schedule:
|
|
58
|
+
interval: weekly
|
|
59
|
+
groups:
|
|
60
|
+
vscode-extension:
|
|
61
|
+
patterns:
|
|
62
|
+
- "*"
|
|
@@ -110,6 +110,37 @@ jobs:
|
|
|
110
110
|
env:
|
|
111
111
|
SKIP: mypy
|
|
112
112
|
|
|
113
|
+
vscode-extension:
|
|
114
|
+
name: vscode-extension
|
|
115
|
+
runs-on: ubuntu-latest
|
|
116
|
+
permissions:
|
|
117
|
+
contents: read
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
120
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
121
|
+
with:
|
|
122
|
+
node-version: "22"
|
|
123
|
+
# Dependencies come from the committed package-lock.json, and no
|
|
124
|
+
# install script of any dependency runs.
|
|
125
|
+
- name: Install dependencies
|
|
126
|
+
working-directory: extras/vscode-execsql
|
|
127
|
+
run: npm ci --ignore-scripts --no-audit --no-fund
|
|
128
|
+
# A release's extension carries the release's version (VS Code
|
|
129
|
+
# versions are X.Y.Z, so a pre-release suffix is dropped).
|
|
130
|
+
- name: Set the extension version from the tag
|
|
131
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
132
|
+
working-directory: extras/vscode-execsql
|
|
133
|
+
run: |
|
|
134
|
+
version="$(echo "${GITHUB_REF_NAME#v}" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')"
|
|
135
|
+
npm pkg set version="$version"
|
|
136
|
+
- name: Package the .vsix
|
|
137
|
+
working-directory: extras/vscode-execsql
|
|
138
|
+
run: ./node_modules/.bin/vsce package --out "../../execsql-syntax.vsix"
|
|
139
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
140
|
+
with:
|
|
141
|
+
name: vscode-extension
|
|
142
|
+
path: execsql-syntax.vsix
|
|
143
|
+
|
|
113
144
|
docs:
|
|
114
145
|
name: docs
|
|
115
146
|
runs-on: ubuntu-latest
|
|
@@ -338,7 +369,7 @@ jobs:
|
|
|
338
369
|
build:
|
|
339
370
|
name: Build distribution 📦
|
|
340
371
|
runs-on: ubuntu-latest
|
|
341
|
-
needs: [ lint, typecheck, pre-commit, formatter-corpus, typer-floor, docs, tests, integration-tests ]
|
|
372
|
+
needs: [ lint, typecheck, pre-commit, formatter-corpus, typer-floor, docs, tests, integration-tests, vscode-extension ]
|
|
342
373
|
# Deliberately NOT gated on tags: packaging breaks must surface on a PR,
|
|
343
374
|
# not at release time. Only publish/generate-release below are tag-gated.
|
|
344
375
|
permissions:
|
|
@@ -403,7 +434,7 @@ jobs:
|
|
|
403
434
|
name: Generate GitHub Release
|
|
404
435
|
# After the PyPI upload, so a release is never announced for a
|
|
405
436
|
# version that pip cannot install.
|
|
406
|
-
needs: [ publish ]
|
|
437
|
+
needs: [ publish, vscode-extension ]
|
|
407
438
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
408
439
|
runs-on: ubuntu-latest
|
|
409
440
|
permissions:
|
|
@@ -416,6 +447,11 @@ jobs:
|
|
|
416
447
|
with:
|
|
417
448
|
name: ${{ github.event.repository.name }}
|
|
418
449
|
path: dist/
|
|
450
|
+
- name: Download the VS Code extension
|
|
451
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
452
|
+
with:
|
|
453
|
+
name: vscode-extension
|
|
454
|
+
path: dist/
|
|
419
455
|
- name: Detect pre-release tag
|
|
420
456
|
id: tag
|
|
421
457
|
# PEP 440 pre-release suffix (a1, b2, rc1) on the tag -> mark the
|
|
@@ -13,12 +13,12 @@ repos:
|
|
|
13
13
|
- id: check-hooks-apply
|
|
14
14
|
# Protect secrets using Gitleaks
|
|
15
15
|
- repo: https://github.com/zricethezav/gitleaks
|
|
16
|
-
rev: v8.30.
|
|
16
|
+
rev: v8.30.1
|
|
17
17
|
hooks:
|
|
18
18
|
- id: gitleaks
|
|
19
19
|
# uv lockfile management
|
|
20
20
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
21
|
-
rev: 0.
|
|
21
|
+
rev: 0.12.23
|
|
22
22
|
hooks:
|
|
23
23
|
- id: uv-lock
|
|
24
24
|
# Base hooks
|
|
@@ -44,7 +44,7 @@ repos:
|
|
|
44
44
|
- id: mdformat
|
|
45
45
|
language: python
|
|
46
46
|
additional_dependencies:
|
|
47
|
-
- mdformat-mkdocs==5.
|
|
47
|
+
- mdformat-mkdocs==5.3.0
|
|
48
48
|
exclude: |
|
|
49
49
|
(?x)^(
|
|
50
50
|
\.claude/.*|
|
|
@@ -56,7 +56,7 @@ repos:
|
|
|
56
56
|
)$
|
|
57
57
|
# Markdown lint
|
|
58
58
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
|
59
|
-
rev: v0.
|
|
59
|
+
rev: v0.49.1
|
|
60
60
|
hooks:
|
|
61
61
|
- id: markdownlint
|
|
62
62
|
types: [file]
|
|
@@ -64,13 +64,13 @@ repos:
|
|
|
64
64
|
args: [--disable, MD013]
|
|
65
65
|
# Spell check
|
|
66
66
|
- repo: https://github.com/crate-ci/typos
|
|
67
|
-
rev: v1.
|
|
67
|
+
rev: v1.51.0
|
|
68
68
|
hooks:
|
|
69
69
|
- id: typos
|
|
70
70
|
args: [--force-exclude]
|
|
71
71
|
# Lint & format with ruff
|
|
72
72
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
73
|
-
rev: v0.
|
|
73
|
+
rev: v0.16.10
|
|
74
74
|
hooks:
|
|
75
75
|
- id: ruff-check
|
|
76
76
|
args: [--config=pyproject.toml, --exit-non-zero-on-fix]
|
|
@@ -13,6 +13,61 @@ ______________________________________________________________________
|
|
|
13
13
|
|
|
14
14
|
______________________________________________________________________
|
|
15
15
|
|
|
16
|
+
## [2.28.0] - 2026-10-13
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **`execsql lsp --check`** reports whether the language server can start (exit 0) or what is missing (exit 1).
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **Missing-package messages** (database drivers, spreadsheet, YAML and template exports, `PG_UPSERT`, the formatter and the language server) name the execsql2 extra and show how to add it while keeping the extras already installed.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **`execsql format` keeps optimizer hints and MySQL executable comments:** a statement holding `/*+ ... */` or `/*! ... */` is left as written in both modes. It was rewritten to `/* + ... */` and the hint moved off its keyword, so MySQL skipped the `/*! */` SQL (for example a `WHERE` or `PARTITION BY`) and Oracle/MySQL ignored the hint; re-check files the formatter or its pre-commit hook rewrote.
|
|
29
|
+
- **`execsql format` no longer ends a final statement with a `;` the script did not have:** a script execsql refused for an unfinished last statement became one that ran it.
|
|
30
|
+
- **`execsql format`:** a statement kept as written after another on the same line no longer starts with a space.
|
|
31
|
+
- **`execsql format` without sqlglot** printed its `pip install` hint without the `[formatter]` extra.
|
|
32
|
+
- **`execsql lint` and the language server read a `SUB_INI` file once** however many lines name it; a script naming a large INI file on many lines took minutes to lint and froze the editor. V002 for a variable a `SUB_INI` defines is reported at the `SUB_INI` line, not line 0.
|
|
33
|
+
- **`execsql lsp` with an incompatible pygls** names the installed pygls version instead of saying the `lsp` extra is missing.
|
|
34
|
+
- **`COPY` keeps binary columns** (SQLite/DuckDB BLOB, PostgreSQL `bytea`) byte for byte, and `COPY ... TO NEW` creates them as binary columns. They were copied as escaped text (`\x89PNG...`), and into PostgreSQL as text.
|
|
35
|
+
- **DuckDB `TO NEW`** is no longer refused because a table of the same name exists in an `ATTACH`ed database; only the current database counts.
|
|
36
|
+
|
|
37
|
+
______________________________________________________________________
|
|
38
|
+
|
|
39
|
+
## [2.27.0] - 2026-10-12
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **`execsql lsp`**, a language server for editors. Install the new `lsp` extra (`uv tool install "execsql2[lsp]"`; to add it to an existing install, name the extras you already have, e.g. `"execsql2[postgres,lsp]"`); setup for VS Code, Neovim, Helix and other editors is in the new Editor Support guide. It provides:
|
|
44
|
+
|
|
45
|
+
- `execsql lint` findings as you type, using the workspace's `[lint]` settings;
|
|
46
|
+
- completion of metacommands (as fill-in templates of their documented syntax), conditional tests, variables and export formats;
|
|
47
|
+
- hover explanations of metacommands, conditional tests and variables;
|
|
48
|
+
- Go to Definition, Find All References, Rename Symbol (variables), the outline and `INCLUDE` links;
|
|
49
|
+
- folding of `IF` branches, `LOOP`, `SCRIPT`, `BATCH` and `SQL` blocks, multi-line statements and comments;
|
|
50
|
+
- quick fixes for misspelled metacommands, conditional tests and variables (P003, P004, V001) and split dollar-quoted bodies (P002);
|
|
51
|
+
- Format Document, the same as `execsql format` with the workspace's `[format]` settings;
|
|
52
|
+
- `execsql.conf` read again when it changes, and open scripts linted again when a file they `INCLUDE` changes;
|
|
53
|
+
- each folder of a multi-root workspace linted and formatted with its own `execsql.conf`.
|
|
54
|
+
|
|
55
|
+
The server never runs a script or connects to a database. It reads the open scripts, the files they `INCLUDE` or name in `SUB_INI` (regular files of bounded size), and the configuration files `execsql lint` reads.
|
|
56
|
+
|
|
57
|
+
- **VS Code extension** starts `execsql lsp` for `.sql` files, with `execsql.server.path` and `execsql.server.enabled` settings and an **execsql: Restart Language Server** command. Each GitHub release attaches it as `execsql-syntax.vsix`; install with `code --install-extension execsql-syntax.vsix`. The server starts only in a trusted folder; highlighting works in any. `execsql.server.path` is a command name looked up in PATH or an absolute path, and the extension never runs an `execsql` found in the open folder.
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- **`lsp` is a command name:** `execsql lsp` starts the language server. Run a script file named `lsp` (with no extension) as `execsql run lsp`.
|
|
62
|
+
- **`execsql list metacommands`** lists every metacommand (all 95; some were missing) with its category and a one-line summary, and `execsql list metacommands <KEYWORD>` shows that metacommand's syntax, as the reference docs write it, with a link. In `--output-format json`, `syntax` is now the full first syntax line, and each entry adds `forms`, `category`, `summary` and `url`. Read `forms` for every syntax line.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- **DuckDB `TIMESTAMPTZ` values** are read instead of stopping the script: the `duckdb` and `all-db` extras now install `pytz`, which duckdb needs for them.
|
|
67
|
+
- **`CONFIG MAX_INT <n>`** works as documented; it stopped with `Unknown metacommand`, and only the bare `MAX_INT <n>` (still accepted) was recognized.
|
|
68
|
+
|
|
69
|
+
______________________________________________________________________
|
|
70
|
+
|
|
16
71
|
## [2.26.0] - 2026-10-09
|
|
17
72
|
|
|
18
73
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.28.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
|
|
@@ -49,14 +49,17 @@ Requires-Dist: duckdb>=1.0; extra == 'all'
|
|
|
49
49
|
Requires-Dist: firebird-driver>=1.10; extra == 'all'
|
|
50
50
|
Requires-Dist: jinja2>=3.1; extra == 'all'
|
|
51
51
|
Requires-Dist: keyring>=25.0; extra == 'all'
|
|
52
|
+
Requires-Dist: lsprotocol>=2025.0.0; extra == 'all'
|
|
52
53
|
Requires-Dist: odfpy>=1.4; extra == 'all'
|
|
53
54
|
Requires-Dist: openpyxl>=3.1; extra == 'all'
|
|
54
55
|
Requires-Dist: oracledb>=3.0; extra == 'all'
|
|
55
56
|
Requires-Dist: pg-upsert>=1.25.0; extra == 'all'
|
|
56
57
|
Requires-Dist: polars>=1.0; extra == 'all'
|
|
57
58
|
Requires-Dist: psycopg[binary]<4,>=3.1; extra == 'all'
|
|
59
|
+
Requires-Dist: pygls<3,>=2.1; extra == 'all'
|
|
58
60
|
Requires-Dist: pymysql>=1.1; extra == 'all'
|
|
59
61
|
Requires-Dist: pyodbc>=5.0; extra == 'all'
|
|
62
|
+
Requires-Dist: pytz; extra == 'all'
|
|
60
63
|
Requires-Dist: pyyaml>=6.0; extra == 'all'
|
|
61
64
|
Requires-Dist: sqlglot<30.22,>=30.21.0; extra == 'all'
|
|
62
65
|
Requires-Dist: tables>=3.10; extra == 'all'
|
|
@@ -69,6 +72,7 @@ Requires-Dist: oracledb>=3.0; extra == 'all-db'
|
|
|
69
72
|
Requires-Dist: psycopg[binary]<4,>=3.1; extra == 'all-db'
|
|
70
73
|
Requires-Dist: pymysql>=1.1; extra == 'all-db'
|
|
71
74
|
Requires-Dist: pyodbc>=5.0; extra == 'all-db'
|
|
75
|
+
Requires-Dist: pytz; extra == 'all-db'
|
|
72
76
|
Provides-Extra: auth
|
|
73
77
|
Requires-Dist: keyring>=25.0; extra == 'auth'
|
|
74
78
|
Provides-Extra: auth-encrypted
|
|
@@ -83,13 +87,18 @@ Requires-Dist: build>=1.2.2.post1; extra == 'dev'
|
|
|
83
87
|
Requires-Dist: bump-my-version>=1.2.7; extra == 'dev'
|
|
84
88
|
Requires-Dist: defusedxml>=0.7; extra == 'dev'
|
|
85
89
|
Requires-Dist: jinja2>=3.1; extra == 'dev'
|
|
90
|
+
Requires-Dist: lsprotocol>=2025.0.0; extra == 'dev'
|
|
86
91
|
Requires-Dist: mkdocstrings-python>=2.0.3; extra == 'dev'
|
|
87
92
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
88
93
|
Requires-Dist: odfpy>=1.4; extra == 'dev'
|
|
89
94
|
Requires-Dist: openpyxl>=3.1; extra == 'dev'
|
|
90
95
|
Requires-Dist: polars>=1.0; extra == 'dev'
|
|
91
96
|
Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
|
|
97
|
+
Requires-Dist: pygls<3,>=2.1; extra == 'dev'
|
|
98
|
+
Requires-Dist: pytest-asyncio>=1.0; extra == 'dev'
|
|
92
99
|
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
100
|
+
Requires-Dist: pytest-lsp>=1.0; extra == 'dev'
|
|
101
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
93
102
|
Requires-Dist: pyyaml>=6.0; extra == 'dev'
|
|
94
103
|
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
95
104
|
Requires-Dist: sqlglot<30.22,>=30.21.0; extra == 'dev'
|
|
@@ -97,9 +106,10 @@ Requires-Dist: tables>=3.10; extra == 'dev'
|
|
|
97
106
|
Requires-Dist: tox-uv>=1.13.1; extra == 'dev'
|
|
98
107
|
Requires-Dist: twine>=6.1.0; extra == 'dev'
|
|
99
108
|
Requires-Dist: xlrd>=2.0; extra == 'dev'
|
|
100
|
-
Requires-Dist: zensical==0.0.
|
|
109
|
+
Requires-Dist: zensical==0.0.67; extra == 'dev'
|
|
101
110
|
Provides-Extra: duckdb
|
|
102
111
|
Requires-Dist: duckdb>=1.0; extra == 'duckdb'
|
|
112
|
+
Requires-Dist: pytz; extra == 'duckdb'
|
|
103
113
|
Provides-Extra: firebird
|
|
104
114
|
Requires-Dist: firebird-driver>=1.10; extra == 'firebird'
|
|
105
115
|
Provides-Extra: formats
|
|
@@ -113,6 +123,10 @@ Requires-Dist: tables>=3.10; extra == 'formats'
|
|
|
113
123
|
Requires-Dist: xlrd>=2.0; extra == 'formats'
|
|
114
124
|
Provides-Extra: formatter
|
|
115
125
|
Requires-Dist: sqlglot<30.22,>=30.21.0; extra == 'formatter'
|
|
126
|
+
Provides-Extra: lsp
|
|
127
|
+
Requires-Dist: lsprotocol>=2025.0.0; extra == 'lsp'
|
|
128
|
+
Requires-Dist: pygls<3,>=2.1; extra == 'lsp'
|
|
129
|
+
Requires-Dist: sqlglot<30.22,>=30.21.0; extra == 'lsp'
|
|
116
130
|
Provides-Extra: map
|
|
117
131
|
Requires-Dist: tkintermapview>=1.29; extra == 'map'
|
|
118
132
|
Provides-Extra: mssql
|
|
@@ -158,15 +172,16 @@ Description-Content-Type: text/markdown
|
|
|
158
172
|
|
|
159
173
|
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
174
|
|
|
161
|
-
| Command | What it does
|
|
162
|
-
| ------------------------------------------ |
|
|
163
|
-
| `execsql format` | Normalize keywords, indentation, and SQL layout
|
|
164
|
-
| `execsql lint` | Static analysis: structure, unknown metacommands, variables, targets
|
|
165
|
-
| `execsql run` | Run the script against PostgreSQL, MySQL, SQLite, DuckDB, …
|
|
166
|
-
| `execsql config` | Show every config option, its value, and the file that set it
|
|
167
|
-
| `execsql list` | Metacommands, encodings, plugins, or the keyword vocabulary
|
|
168
|
-
| `execsql init` | Set up a project: config file, a script with a header, pre-commit hooks
|
|
169
|
-
| [
|
|
175
|
+
| Command | What it does | Needs a database? |
|
|
176
|
+
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
|
|
177
|
+
| `execsql format` | Normalize keywords, indentation, and SQL layout | No |
|
|
178
|
+
| `execsql lint` | Static analysis: structure, unknown metacommands, variables, targets | No |
|
|
179
|
+
| `execsql run` | Run the script against PostgreSQL, MySQL, SQLite, DuckDB, … | Yes |
|
|
180
|
+
| `execsql config` | Show every config option, its value, and the file that set it | No |
|
|
181
|
+
| `execsql list` | Metacommands, encodings, plugins, or the keyword vocabulary | No |
|
|
182
|
+
| `execsql init` | Set up a project: config file, a script with a header, pre-commit hooks | No |
|
|
183
|
+
| `execsql lsp` | [Language server](https://execsql2.readthedocs.io/en/latest/guides/editors/): lint findings, completion, hover, navigation, quick fixes and formatting in your editor | No |
|
|
184
|
+
| [VS Code extension](extras/vscode-execsql) | Highlighting plus everything `execsql lsp` provides | No |
|
|
170
185
|
|
|
171
186
|
`format` and `lint` take files or directories.
|
|
172
187
|
|
|
@@ -451,7 +466,7 @@ execsql format --no-sql --in-place scripts/
|
|
|
451
466
|
```yaml
|
|
452
467
|
repos:
|
|
453
468
|
- repo: https://github.com/geocoug/execsql
|
|
454
|
-
rev: v2.
|
|
469
|
+
rev: v2.28.0
|
|
455
470
|
hooks:
|
|
456
471
|
- id: execsql-format
|
|
457
472
|
- id: execsql-lint
|
|
@@ -459,17 +474,18 @@ repos:
|
|
|
459
474
|
|
|
460
475
|
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.
|
|
461
476
|
|
|
462
|
-
## VS Code
|
|
477
|
+
## VS Code
|
|
463
478
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
To install, symlink the extension folder into your VS Code extensions directory:
|
|
479
|
+
The VS Code extension in [`extras/vscode-execsql`](extras/vscode-execsql) highlights execsql syntax in `.sql` files (metacommand markers, keywords, variable substitutions, export formats, config options) on top of standard SQL highlighting, and starts the execsql language server for lint findings as you type and completion. Each GitHub release has the extension attached as `execsql-syntax.vsix`:
|
|
467
480
|
|
|
468
481
|
```sh
|
|
469
|
-
|
|
482
|
+
uv tool install "execsql2[lsp]" # the language server
|
|
483
|
+
code --install-extension execsql-syntax.vsix # the extension, from the release
|
|
470
484
|
```
|
|
471
485
|
|
|
472
|
-
|
|
486
|
+
If execsql is already installed with other extras, name them too, e.g. `uv tool install "execsql2[postgres,lsp]"` or `pipx install --force "execsql2[postgres,lsp]"`: the new list replaces the old one (see [Adding an extra later](https://execsql2.readthedocs.io/en/latest/getting-started/installation/#adding-an-extra-later)).
|
|
487
|
+
|
|
488
|
+
Other editors use the language server directly: see [Editor Support](https://execsql2.readthedocs.io/en/latest/guides/editors/). The [extension README](extras/vscode-execsql/README.md) covers settings, installing from a clone, color customization, and troubleshooting.
|
|
473
489
|
|
|
474
490
|
## Templates
|
|
475
491
|
|
|
@@ -27,15 +27,16 @@
|
|
|
27
27
|
|
|
28
28
|
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.
|
|
29
29
|
|
|
30
|
-
| Command | What it does
|
|
31
|
-
| ------------------------------------------ |
|
|
32
|
-
| `execsql format` | Normalize keywords, indentation, and SQL layout
|
|
33
|
-
| `execsql lint` | Static analysis: structure, unknown metacommands, variables, targets
|
|
34
|
-
| `execsql run` | Run the script against PostgreSQL, MySQL, SQLite, DuckDB, …
|
|
35
|
-
| `execsql config` | Show every config option, its value, and the file that set it
|
|
36
|
-
| `execsql list` | Metacommands, encodings, plugins, or the keyword vocabulary
|
|
37
|
-
| `execsql init` | Set up a project: config file, a script with a header, pre-commit hooks
|
|
38
|
-
| [
|
|
30
|
+
| Command | What it does | Needs a database? |
|
|
31
|
+
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
|
|
32
|
+
| `execsql format` | Normalize keywords, indentation, and SQL layout | No |
|
|
33
|
+
| `execsql lint` | Static analysis: structure, unknown metacommands, variables, targets | No |
|
|
34
|
+
| `execsql run` | Run the script against PostgreSQL, MySQL, SQLite, DuckDB, … | Yes |
|
|
35
|
+
| `execsql config` | Show every config option, its value, and the file that set it | No |
|
|
36
|
+
| `execsql list` | Metacommands, encodings, plugins, or the keyword vocabulary | No |
|
|
37
|
+
| `execsql init` | Set up a project: config file, a script with a header, pre-commit hooks | No |
|
|
38
|
+
| `execsql lsp` | [Language server](https://execsql2.readthedocs.io/en/latest/guides/editors/): lint findings, completion, hover, navigation, quick fixes and formatting in your editor | No |
|
|
39
|
+
| [VS Code extension](extras/vscode-execsql) | Highlighting plus everything `execsql lsp` provides | No |
|
|
39
40
|
|
|
40
41
|
`format` and `lint` take files or directories.
|
|
41
42
|
|
|
@@ -320,7 +321,7 @@ execsql format --no-sql --in-place scripts/
|
|
|
320
321
|
```yaml
|
|
321
322
|
repos:
|
|
322
323
|
- repo: https://github.com/geocoug/execsql
|
|
323
|
-
rev: v2.
|
|
324
|
+
rev: v2.28.0
|
|
324
325
|
hooks:
|
|
325
326
|
- id: execsql-format
|
|
326
327
|
- id: execsql-lint
|
|
@@ -328,17 +329,18 @@ repos:
|
|
|
328
329
|
|
|
329
330
|
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.
|
|
330
331
|
|
|
331
|
-
## VS Code
|
|
332
|
+
## VS Code
|
|
332
333
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
To install, symlink the extension folder into your VS Code extensions directory:
|
|
334
|
+
The VS Code extension in [`extras/vscode-execsql`](extras/vscode-execsql) highlights execsql syntax in `.sql` files (metacommand markers, keywords, variable substitutions, export formats, config options) on top of standard SQL highlighting, and starts the execsql language server for lint findings as you type and completion. Each GitHub release has the extension attached as `execsql-syntax.vsix`:
|
|
336
335
|
|
|
337
336
|
```sh
|
|
338
|
-
|
|
337
|
+
uv tool install "execsql2[lsp]" # the language server
|
|
338
|
+
code --install-extension execsql-syntax.vsix # the extension, from the release
|
|
339
339
|
```
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
If execsql is already installed with other extras, name them too, e.g. `uv tool install "execsql2[postgres,lsp]"` or `pipx install --force "execsql2[postgres,lsp]"`: the new list replaces the old one (see [Adding an extra later](https://execsql2.readthedocs.io/en/latest/getting-started/installation/#adding-an-extra-later)).
|
|
342
|
+
|
|
343
|
+
Other editors use the language server directly: see [Editor Support](https://execsql2.readthedocs.io/en/latest/guides/editors/). The [extension README](extras/vscode-execsql/README.md) covers settings, installing from a clone, color customization, and troubleshooting.
|
|
342
344
|
|
|
343
345
|
## Templates
|
|
344
346
|
|
|
@@ -71,6 +71,7 @@ ______________________________________________________________________
|
|
|
71
71
|
| Fix | Description |
|
|
72
72
|
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
73
73
|
| Variable EXECUTE SCRIPT targets | `EXECUTE SCRIPT !!#var!!` now works — the parser accepts substitution variable patterns as script identifiers, and the executor resolves them at runtime. |
|
|
74
|
+
| `CONFIG MAX_INT` | The documented `CONFIG MAX_INT <n>` form is accepted. Upstream documented it but recognized only the bare `MAX_INT <n>`, which still works. |
|
|
74
75
|
| Quoted parameter defaults | `BEGIN SCRIPT proc(name="value")` previously stored the literal `"value"` (with surrounding quotes), causing substitutions like `WRITE "!!#name!!"` to expand to `WRITE ""value""` and fail. Defaults now strip surrounding quotes at parse time, matching the `wo_quotes` handling already applied to passed arguments. |
|
|
75
76
|
|
|
76
77
|
### Conditional Tests
|
|
@@ -134,8 +135,9 @@ today — a script named exactly like a command — is recorded under
|
|
|
134
135
|
| `execsql format` | The formatter, reached through the main command. It replaced the standalone `execsql-format` console script, which was removed. The published pre-commit hook **id** is still `execsql-format`, so downstream `.pre-commit-config.yaml` files need no change — only the hook's internal `entry` moved. Formatter for normalizing metacommand indentation and uppercasing SQL keywords. Supports `--check`, `--in-place`, `--indent N` (controls both metacommand and SQL indentation), `--leading-comma` (commas at start of lines), `--no-sql` (skip SQL reformatting), `--rewrite-sql` (accept sqlglot's rewrites of SQL text; off by default, so only layout changes), `-f`/`--script-encoding` (formerly `--encoding`, still accepted), and `--config`; `-` formats stdin to stdout. Also available as a [pre-commit hook](../guides/formatter.md) — the published hook defaults to `args: [--in-place]` so downstream consumers get formatting on commit without extra wiring. SQL reformatting (the optional sqlglot pass) requires the `[formatter]` extra as of 2.19.0; `--no-sql` works without it. |
|
|
135
136
|
| `execsql lint` | Static checks over files *and directories*, walking directories recursively for `*.sql`; `-` reads stdin. Scripts are read with `-f`/`--script-encoding` or `[encoding] script` from config, like `run`. Every issue carries a [rule code](../reference/lint.md#rules); `--select` / `--ignore` choose rules, `--output-format json` feeds tools, and `--statistics` counts issues per rule. It replaced the `--lint` flag, which checked only the one script it was given. |
|
|
136
137
|
| `execsql config` | List every config option with its current value, default, and the file that set it, resolved as a run would (pass a script to include its directory's `execsql.conf`). Passwords are masked. `--init` prints the template (replaces `--init-config`). `--validate` reports every problem in every config file a run reads, with file and line: invalid values and unparsable files as errors, unknown or misplaced sections and keys as warnings — upstream stopped at the first bad value and ignored unknown names silently. |
|
|
137
|
-
| `execsql list` | `metacommands`, `encodings`, `plugins` or `keywords`, as text or JSON. Replaces `-m`, `-y`, `--list-plugins` and `--dump-keywords`; `-m` and `-y` are upstream flags and keep working as hidden aliases, deprecated when used without a command.
|
|
138
|
+
| `execsql list` | `metacommands`, `encodings`, `plugins` or `keywords`, as text or JSON. Replaces `-m`, `-y`, `--list-plugins` and `--dump-keywords`; `-m` and `-y` are upstream flags and keep working as hidden aliases, deprecated when used without a command. `-m` / `list metacommands` prints each metacommand's category and one-line summary (and its syntax when given a keyword) instead of upstream's listing. |
|
|
138
139
|
| `execsql init` | Set up a project: `execsql.conf` from the template, a script with a header (from the upstream script template), and the `execsql-format` / `execsql-lint` pre-commit hooks. Never overwrites without `--force`, and never rewrites an existing `.pre-commit-config.yaml`. |
|
|
140
|
+
| `execsql lsp` | A language server for editors, started over stdio: `execsql lint` findings shown as you type, with the `[lint]` settings of the workspace's config, completion of metacommands (as templates of their documented syntax), conditional tests, variables and export formats, hover explanations, navigation (definition, references, outline, `INCLUDE` links), Rename Symbol for variables, folding, quick fixes for P003, P004, V001 and P002, and Format Document (`execsql format` with the workspace's `[format]` settings). Settings are read per workspace folder and again when `execsql.conf` or an included file changes. The VS Code extension in `extras/vscode-execsql` starts it only in a trusted workspace. Needs the `lsp` extra (pygls). See [Editor Support](../guides/editors.md#editors). |
|
|
139
141
|
|
|
140
142
|
Formatter correctness notes added in the 2.19.x line:
|
|
141
143
|
|
|
@@ -284,6 +286,7 @@ The legacy flat command-list engine (`_parse_script_lines` / `runscripts` / `Com
|
|
|
284
286
|
- **Exception hierarchy** — All custom exceptions inherit from `ExecSqlError`, enabling `except ExecSqlError` to catch any execsql-originated error.
|
|
285
287
|
- **Exception chaining** — All `raise` statements inside `except` blocks preserve the original traceback via `from`.
|
|
286
288
|
- **Database and driver error messages** — End with the error itself (`OperationalError: table t already exists`). Upstream appended "in <file> on line N of execsql", a line of its own source; in the package the file was often a driver's and the line number another file's. Where in execsql the error was raised goes to `execsql.log` as `Raised at: execsql/<module>.py:<line>`.
|
|
289
|
+
- **Missing optional package messages** — Name the execsql2 extra that installs the package and how to add it to a `uv tool` or `pipx` install without dropping the extras already there (`uv tool install "execsql2[...,postgres]"`). Upstream pointed at the package's web page.
|
|
287
290
|
- **Config file errors** — An invalid value in `execsql.conf` stops a run with `Configuration error: <file>: <problem>` (and the line, for an unreadable file) plus a pointer to `execsql config --validate`. Upstream printed `Configuration error on line N of execsql.py`, where N was a line of its own source. A duplicate key, a missing section header or a bare `%` is reported the same way; upstream failed with an uncaught exception. Errors raised by `ConfigData` for a file are `ConfigFileError`, a subclass of `ConfigError`.
|
|
288
291
|
- **ASSERT error type** — `ASSERT` failures now use a dedicated `"assert"` error type that produces `**** Assertion failed.` instead of `**** Error in metacommand.`. This distinguishes intentional script-level checks from actual metacommand errors. Upstream did not have `ASSERT`.
|
|
289
292
|
|
|
@@ -358,10 +361,11 @@ These are behavioral changes driven by security or correctness issues in the ups
|
|
|
358
361
|
| `DT_Timestamp` claims time-only values | `dateutil.parser.parse()` silently fills in today's date for bare time strings like `"13:15:45"`, so `DT_Timestamp` matched before `DT_Time` in the inference order. `parse_datetime()` now rejects time-only strings. |
|
|
359
362
|
| Partial dates inferred as timestamps | `dateutil` fills fields missing from a value with today's date, so `1-2`, `5/6`, `March 5`, `Jan` and `Monday` were inferred as timestamps and, on DuckDB, SQL Server, MySQL, Oracle, Firebird, Access and every ODS/XLSX/JSON/Parquet/Feather import, stored as dates in the current year. Inference now requires a four-digit year (or a month-first `m/d/yy` or `m-d-yy`) and a month and day, which restores upstream's behaviour for these values. `m-d-yy` is accepted in addition to upstream's `m/d/yy`. |
|
|
360
363
|
| Offset values stored as plain timestamps | With `dateutil`, a value with a UTC offset (`2024-01-01 10:00+05:00`) also counted as a plain timestamp, so a column mixing offset and plain values was created as `timestamp` and the driver converted the offset values with the client's time zone: the stored value depended on the machine that ran the import. A value with an offset is again not a plain timestamp, as with upstream's offset-free format list, so a mixed column is text and keeps each value as written. A column where every value has an offset is still `timestamptz`. |
|
|
364
|
+
| Binary columns in `COPY` | Every value a source cursor returned as bytes was decoded to text (undecodable bytes as `\xNN` escapes) before `COPY` wrote it, and `TO NEW` typed the column as text. Upstream did the same for SQLite BLOBs; with psycopg2 a PostgreSQL `bytea` arrived as a `memoryview` and escaped the decode, so for PostgreSQL this was an execsql2 regression. `COPY` now moves bytes unchanged and creates binary columns. Exports still write the decoded text. |
|
|
361
365
|
| Short data lines on import | A line with fewer values than the header was padded with NULLs only on PostgreSQL and MySQL. SQLite stopped with "Too few values", DuckDB and the other DBMSs with a driver parameter-count error. With `TO NEW` / `REPLACEMENT`, type inference skipped the missing values, so the column could be created `NOT NULL` and then reject the padded line, on PostgreSQL too. Missing trailing values are now NULL on every DBMS, and inference counts them as NULL. |
|
|
362
366
|
| `COPY` re-typed text values | Upstream described the destination table by re-reading the source's text values as if they came from a file, so a text column of `1`/`0` became `boolean` and one of dates became `timestamp` with `NEW` / `REPLACEMENT`, and values copied into an existing text column were converted on the way in (`1` stored as `true`). Text from the source database now stays text. Upstream also ran the source query twice, once to describe the table and once to copy it; execsql2 runs it once and holds the rows in a temporary file in between. |
|
|
363
367
|
| `REPLACEMENT` of a quoted or schema-qualified table | The SQLite, SQL Server, Oracle, Firebird and Access adapters quoted the table name a second time before dropping it, so `IMPORT` / `COPY ... TO REPLACEMENT "my tbl"` dropped a table named `"my tbl"` (quotes included) that did not exist and then failed to create the table, and on SQL Server, Oracle and Firebird `REPLACEMENT staging.t` tried to drop one table named `staging.t`. The name is now quoted once. |
|
|
364
|
-
| `TO NEW` onto an existing table | `COPY`'s checks that the source exists and that a `NEW` target does not were dead code: each raised its error inside a `try` that discarded it. `IMPORT ... TO NEW` had no check. Both now stop with `Table <name> already exists` before any DDL (when the database cannot say whether the table exists, the command goes ahead). A name without a schema counts only in the schema the table would be created in (MySQL: the current database). The source check was removed instead of revived: PostgreSQL reads an unquoted `COPY Orders` as `orders`, which the check would have reported missing.
|
|
368
|
+
| `TO NEW` onto an existing table | `COPY`'s checks that the source exists and that a `NEW` target does not were dead code: each raised its error inside a `try` that discarded it. `IMPORT ... TO NEW` had no check. Both now stop with `Table <name> already exists` before any DDL (when the database cannot say whether the table exists, the command goes ahead). A name without a schema counts only in the schema the table would be created in (MySQL: the current database), and on DuckDB only in the current database, not an `ATTACH`ed one. The source check was removed instead of revived: PostgreSQL reads an unquoted `COPY Orders` as `orders`, which the check would have reported missing. |
|
|
365
369
|
| No `exit` log record on error or halt | The log was closed before the `exit` record was written, so a run that ended with an error, a `HALT` or a cancelled prompt left no `exit` line, and Ctrl-C was recorded as `unknown`. Every run now writes exactly one `exit` record; Ctrl-C is `interrupted`. |
|
|
366
370
|
| SIGTERM lost the run's log | Python's default SIGTERM action ends the process without running exit handlers, so the buffered `execsql.log` (every record of the run) was never written, the transaction was not rolled back explicitly and a running `SYSTEM_CMD` kept going. The `execsql` command now turns SIGTERM into a normal exit with status 143 and an `exit` record of type `terminated`. `execsql.run()` does not install a handler. |
|
|
367
371
|
| `access_use_numeric` ignored | The config option was read but never applied, so MS-Access tables created by `IMPORT` / `COPY` always got `DOUBLE` for decimal data. With `Yes` they get `NUMERIC(precision,scale)` again, as upstream. The setting is read when each table is created, so it applies per run (upstream changed the shared type map once at startup). |
|
|
@@ -223,9 +223,32 @@ ______________________________________________________________________
|
|
|
223
223
|
- [ ] Handler function added to the appropriate `src/execsql/metacommands/*.py` module
|
|
224
224
|
- [ ] Handler imported in `src/execsql/metacommands/dispatch.py`
|
|
225
225
|
- [ ] `mcl.add(...)` call added in `build_dispatch_table()` with `description=` and `category=`
|
|
226
|
+
- [ ] Entry added to `src/execsql/metacommands/reference.py`: the syntax line(s) as the reference docs write them, a one-line summary and the docs anchor (see below)
|
|
227
|
+
- [ ] A line using it added to `tests/data/lint/every_metacommand.sql`
|
|
226
228
|
- [ ] Run `just install-vscode` to regenerate the VS Code grammar
|
|
227
229
|
- [ ] Integration test added to `tests/test_metacommands.py` (or relevant file)
|
|
228
|
-
- [ ] `pytest` passes locally (including `tests/test_registry.py`
|
|
230
|
+
- [ ] `pytest` passes locally (including `tests/test_registry.py` and `tests/test_reference.py`)
|
|
231
|
+
|
|
232
|
+
### The readable syntax entry
|
|
233
|
+
|
|
234
|
+
The dispatch table's regular expressions are not something to show a person.
|
|
235
|
+
`execsql.metacommands.reference` holds what editors (`execsql lsp`) and
|
|
236
|
+
`execsql list metacommands` show instead:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
Metacommand(
|
|
240
|
+
"MY_COMMAND", # the description= keyword
|
|
241
|
+
"action", # the category=
|
|
242
|
+
("MY_COMMAND <table> TO <file>",), # syntax lines, docs notation: <value>, [optional], A|B
|
|
243
|
+
"Does one thing to a table.", # one sentence, at most 120 characters
|
|
244
|
+
"my_command", # the heading's anchor in docs/reference/metacommands.md
|
|
245
|
+
),
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Editor completion turns each syntax line into a fill-in template (`<value>`
|
|
249
|
+
becomes a tab stop, `A|B` a choice). `tests/test_reference.py` fails until the
|
|
250
|
+
entry exists, its anchor is a real heading, and each syntax line, filled with
|
|
251
|
+
sample values, is accepted by the dispatch table.
|
|
229
252
|
|
|
230
253
|
______________________________________________________________________
|
|
231
254
|
|
|
@@ -251,3 +274,5 @@ mcl.add(
|
|
|
251
274
|
```
|
|
252
275
|
|
|
253
276
|
The result is exposed as `CONDITIONAL_TABLE` and consumed at runtime via `_state.conditionallist`.
|
|
277
|
+
|
|
278
|
+
Add a `Condition(...)` entry to `src/execsql/metacommands/reference.py` as well (name, syntax line such as `MY_TEST(<table>)`, one-line summary, docs anchor) and a use of it to `tests/data/lint/conditions_and_blocks.sql`; `tests/test_reference.py` checks that every conditional test has an entry.
|
|
@@ -53,15 +53,16 @@ fails. Stay on the command until it exits.
|
|
|
53
53
|
|
|
54
54
|
### What runs on a tag push
|
|
55
55
|
|
|
56
|
-
| Job | Gating?
|
|
57
|
-
| ---------------------- |
|
|
58
|
-
| `lint` | yes
|
|
59
|
-
| `tests` (matrix) | yes
|
|
60
|
-
| `integration-tests` | yes
|
|
61
|
-
| `access-tests-windows` | yes (when Access install succeeds)
|
|
62
|
-
| `build` | yes
|
|
63
|
-
| `publish` | yes (tag-gated)
|
|
64
|
-
| `
|
|
56
|
+
| Job | Gating? | Purpose |
|
|
57
|
+
| ---------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `lint` | yes | ruff check + ruff format check |
|
|
59
|
+
| `tests` (matrix) | yes | py3.10–3.14 × {ubuntu, macos, windows} |
|
|
60
|
+
| `integration-tests` | yes | PostgreSQL, MySQL, MSSQL service containers |
|
|
61
|
+
| `access-tests-windows` | yes (when Access install succeeds) | Real Access driver on `windows-latest` |
|
|
62
|
+
| `build` | yes | Checks the tag equals `project.version`; `python -m build` produces sdist + wheel |
|
|
63
|
+
| `publish` | yes (tag-gated) | OIDC trusted-publisher PyPI upload |
|
|
64
|
+
| `vscode-extension` | yes | Packages `extras/vscode-execsql` into `execsql-syntax.vsix` (on a tag, with the tag's X.Y.Z version) |
|
|
65
|
+
| `generate-release` | yes (tag-gated, after `publish` and `vscode-extension`) | Creates the GitHub release with auto-extracted CHANGELOG section; attaches the sdist, wheel and `.vsix` |
|
|
65
66
|
|
|
66
67
|
Publish / generate-release run only on tag refs
|
|
67
68
|
(`if: startsWith(github.ref, 'refs/tags/v')`), so a non-bump push to
|
|
@@ -129,6 +130,6 @@ After `gh run watch` exits green:
|
|
|
129
130
|
- `pip install execsql2==2.X.Y` in a throwaway venv — confirms the
|
|
130
131
|
wheel landed on PyPI.
|
|
131
132
|
- Browse the new GitHub release page; check the CHANGELOG section
|
|
132
|
-
matches what's on `main
|
|
133
|
+
matches what's on `main` and that `execsql-syntax.vsix` is attached.
|
|
133
134
|
- `git pull` locally to retrieve the bump commit (you already had it
|
|
134
135
|
locally if you bumped yourself, but other contributors will sync).
|