execsql2 2.4.4__tar.gz → 2.4.5__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.
Files changed (269) hide show
  1. {execsql2-2.4.4 → execsql2-2.4.5}/CHANGELOG.md +11 -0
  2. {execsql2-2.4.4 → execsql2-2.4.5}/CLAUDE.md +1 -0
  3. {execsql2-2.4.4 → execsql2-2.4.5}/PKG-INFO +30 -3
  4. {execsql2-2.4.4 → execsql2-2.4.5}/README.md +29 -2
  5. {execsql2-2.4.4 → execsql2-2.4.5}/pyproject.toml +2 -2
  6. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/dispatch.py +91 -2
  7. {execsql2-2.4.4 → execsql2-2.4.5}/uv.lock +1 -1
  8. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/dba.md +0 -0
  9. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/herald.md +0 -0
  10. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/inspector.md +0 -0
  11. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/oracle.md +0 -0
  12. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/patcher.md +0 -0
  13. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/qa.md +0 -0
  14. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/agents/scribe.md +0 -0
  15. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/code-oracle.md +0 -0
  16. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/migrate.md +0 -0
  17. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/review-changes.md +0 -0
  18. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/test-module.md +0 -0
  19. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/update-changelog.md +0 -0
  20. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/commands/where-is.md +0 -0
  21. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/project_context.md +0 -0
  22. {execsql2-2.4.4 → execsql2-2.4.5}/.claude/state/status.md +0 -0
  23. {execsql2-2.4.4 → execsql2-2.4.5}/.github/workflows/ci-cd.yml +0 -0
  24. {execsql2-2.4.4 → execsql2-2.4.5}/.gitignore +0 -0
  25. {execsql2-2.4.4 → execsql2-2.4.5}/.pre-commit-config.yaml +0 -0
  26. {execsql2-2.4.4 → execsql2-2.4.5}/.pre-commit-hooks.yaml +0 -0
  27. {execsql2-2.4.4 → execsql2-2.4.5}/.python-version +0 -0
  28. {execsql2-2.4.4 → execsql2-2.4.5}/.readthedocs.yaml +0 -0
  29. {execsql2-2.4.4 → execsql2-2.4.5}/CONTRIBUTING.md +0 -0
  30. {execsql2-2.4.4 → execsql2-2.4.5}/LICENSE.txt +0 -0
  31. {execsql2-2.4.4 → execsql2-2.4.5}/NOTICE +0 -0
  32. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/cli.md +0 -0
  33. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/db.md +0 -0
  34. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/exporters.md +0 -0
  35. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/importers.md +0 -0
  36. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/index.md +0 -0
  37. {execsql2-2.4.4 → execsql2-2.4.5}/docs/api/metacommands.md +0 -0
  38. {execsql2-2.4.4 → execsql2-2.4.5}/docs/change_log.md +0 -0
  39. {execsql2-2.4.4 → execsql2-2.4.5}/docs/configuration.md +0 -0
  40. {execsql2-2.4.4 → execsql2-2.4.5}/docs/contributors.md +0 -0
  41. {execsql2-2.4.4 → execsql2-2.4.5}/docs/copyright.md +0 -0
  42. {execsql2-2.4.4 → execsql2-2.4.5}/docs/debugging.md +0 -0
  43. {execsql2-2.4.4 → execsql2-2.4.5}/docs/dev/adding_db_adapters.md +0 -0
  44. {execsql2-2.4.4 → execsql2-2.4.5}/docs/dev/adding_exporters.md +0 -0
  45. {execsql2-2.4.4 → execsql2-2.4.5}/docs/dev/adding_importers.md +0 -0
  46. {execsql2-2.4.4 → execsql2-2.4.5}/docs/dev/adding_metacommands.md +0 -0
  47. {execsql2-2.4.4 → execsql2-2.4.5}/docs/documentation.md +0 -0
  48. {execsql2-2.4.4 → execsql2-2.4.5}/docs/encoding.md +0 -0
  49. {execsql2-2.4.4 → execsql2-2.4.5}/docs/examples.md +0 -0
  50. {execsql2-2.4.4 → execsql2-2.4.5}/docs/formatter.md +0 -0
  51. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/Compare_planets.png +0 -0
  52. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/actions.png +0 -0
  53. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/actions2.png +0 -0
  54. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/checkboxes.png +0 -0
  55. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/connect.b64 +0 -0
  56. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/connect.png +0 -0
  57. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/create_conf.png +0 -0
  58. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/data_error1_screenshot.jpg +0 -0
  59. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/entry_form.png +0 -0
  60. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/execsql_console.png +0 -0
  61. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/execsql_logo_01.png +0 -0
  62. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/fatals.png +0 -0
  63. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/logo_small.png +0 -0
  64. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/pause_terminal.png +0 -0
  65. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/pause_terminal_sm.b64 +0 -0
  66. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/pause_terminal_sm.png +0 -0
  67. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/prompt_compare.png +0 -0
  68. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/set_build_commands.jpg +0 -0
  69. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/unit_conversions.b64 +0 -0
  70. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/unit_conversions_029.png +0 -0
  71. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/unmatched.png +0 -0
  72. {execsql2-2.4.4 → execsql2-2.4.5}/docs/images/vim_execsql_highlight.png +0 -0
  73. {execsql2-2.4.4 → execsql2-2.4.5}/docs/index.md +0 -0
  74. {execsql2-2.4.4 → execsql2-2.4.5}/docs/installation.md +0 -0
  75. {execsql2-2.4.4 → execsql2-2.4.5}/docs/logging.md +0 -0
  76. {execsql2-2.4.4 → execsql2-2.4.5}/docs/metacommands.md +0 -0
  77. {execsql2-2.4.4 → execsql2-2.4.5}/docs/requirements.md +0 -0
  78. {execsql2-2.4.4 → execsql2-2.4.5}/docs/security.md +0 -0
  79. {execsql2-2.4.4 → execsql2-2.4.5}/docs/sql_syntax.md +0 -0
  80. {execsql2-2.4.4 → execsql2-2.4.5}/docs/substitution_vars.md +0 -0
  81. {execsql2-2.4.4 → execsql2-2.4.5}/docs/syntax.md +0 -0
  82. {execsql2-2.4.4 → execsql2-2.4.5}/docs/usage.md +0 -0
  83. {execsql2-2.4.4 → execsql2-2.4.5}/docs/using_scripts.md +0 -0
  84. {execsql2-2.4.4 → execsql2-2.4.5}/extras/vscode-execsql/README.md +0 -0
  85. {execsql2-2.4.4 → execsql2-2.4.5}/extras/vscode-execsql/package.json +0 -0
  86. {execsql2-2.4.4 → execsql2-2.4.5}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
  87. {execsql2-2.4.4 → execsql2-2.4.5}/justfile +0 -0
  88. {execsql2-2.4.4 → execsql2-2.4.5}/scripts/generate_vscode_grammar.py +0 -0
  89. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/__init__.py +0 -0
  90. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/__main__.py +0 -0
  91. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/cli/__init__.py +0 -0
  92. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/cli/dsn.py +0 -0
  93. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/cli/help.py +0 -0
  94. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/cli/run.py +0 -0
  95. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/config.py +0 -0
  96. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/constants.py +0 -0
  97. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/__init__.py +0 -0
  98. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/access.py +0 -0
  99. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/base.py +0 -0
  100. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/dsn.py +0 -0
  101. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/duckdb.py +0 -0
  102. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/factory.py +0 -0
  103. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/firebird.py +0 -0
  104. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/mysql.py +0 -0
  105. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/oracle.py +0 -0
  106. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/postgres.py +0 -0
  107. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/sqlite.py +0 -0
  108. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/db/sqlserver.py +0 -0
  109. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exceptions.py +0 -0
  110. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/__init__.py +0 -0
  111. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/base.py +0 -0
  112. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/delimited.py +0 -0
  113. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/duckdb.py +0 -0
  114. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/feather.py +0 -0
  115. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/html.py +0 -0
  116. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/json.py +0 -0
  117. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/latex.py +0 -0
  118. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/ods.py +0 -0
  119. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/parquet.py +0 -0
  120. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/pretty.py +0 -0
  121. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/raw.py +0 -0
  122. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/sqlite.py +0 -0
  123. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/templates.py +0 -0
  124. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/values.py +0 -0
  125. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/xls.py +0 -0
  126. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/xml.py +0 -0
  127. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/exporters/zip.py +0 -0
  128. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/format.py +0 -0
  129. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/gui/__init__.py +0 -0
  130. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/gui/base.py +0 -0
  131. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/gui/console.py +0 -0
  132. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/gui/desktop.py +0 -0
  133. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/gui/tui.py +0 -0
  134. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/__init__.py +0 -0
  135. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/base.py +0 -0
  136. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/csv.py +0 -0
  137. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/feather.py +0 -0
  138. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/ods.py +0 -0
  139. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/importers/xls.py +0 -0
  140. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/__init__.py +0 -0
  141. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/conditions.py +0 -0
  142. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/connect.py +0 -0
  143. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/control.py +0 -0
  144. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/data.py +0 -0
  145. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/debug.py +0 -0
  146. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/io.py +0 -0
  147. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/io_export.py +0 -0
  148. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/io_fileops.py +0 -0
  149. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/io_import.py +0 -0
  150. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/io_write.py +0 -0
  151. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/prompt.py +0 -0
  152. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/script_ext.py +0 -0
  153. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/metacommands/system.py +0 -0
  154. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/models.py +0 -0
  155. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/parser.py +0 -0
  156. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/py.typed +0 -0
  157. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/script/__init__.py +0 -0
  158. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/script/control.py +0 -0
  159. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/script/engine.py +0 -0
  160. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/script/variables.py +0 -0
  161. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/state.py +0 -0
  162. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/types.py +0 -0
  163. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/__init__.py +0 -0
  164. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/auth.py +0 -0
  165. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/crypto.py +0 -0
  166. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/datetime.py +0 -0
  167. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/errors.py +0 -0
  168. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/fileio.py +0 -0
  169. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/gui.py +0 -0
  170. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/mail.py +0 -0
  171. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/numeric.py +0 -0
  172. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/regex.py +0 -0
  173. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/strings.py +0 -0
  174. {execsql2-2.4.4 → execsql2-2.4.5}/src/execsql/utils/timer.py +0 -0
  175. {execsql2-2.4.4 → execsql2-2.4.5}/templates/README.md +0 -0
  176. {execsql2-2.4.4 → execsql2-2.4.5}/templates/config_settings.sqlite +0 -0
  177. {execsql2-2.4.4 → execsql2-2.4.5}/templates/example_config_prompt.sql +0 -0
  178. {execsql2-2.4.4 → execsql2-2.4.5}/templates/execsql.conf +0 -0
  179. {execsql2-2.4.4 → execsql2-2.4.5}/templates/make_config_db.sql +0 -0
  180. {execsql2-2.4.4 → execsql2-2.4.5}/templates/md_compare.sql +0 -0
  181. {execsql2-2.4.4 → execsql2-2.4.5}/templates/md_glossary.sql +0 -0
  182. {execsql2-2.4.4 → execsql2-2.4.5}/templates/md_upsert.sql +0 -0
  183. {execsql2-2.4.4 → execsql2-2.4.5}/templates/pg_compare.sql +0 -0
  184. {execsql2-2.4.4 → execsql2-2.4.5}/templates/pg_glossary.sql +0 -0
  185. {execsql2-2.4.4 → execsql2-2.4.5}/templates/pg_upsert.sql +0 -0
  186. {execsql2-2.4.4 → execsql2-2.4.5}/templates/script_template.sql +0 -0
  187. {execsql2-2.4.4 → execsql2-2.4.5}/templates/ss_compare.sql +0 -0
  188. {execsql2-2.4.4 → execsql2-2.4.5}/templates/ss_glossary.sql +0 -0
  189. {execsql2-2.4.4 → execsql2-2.4.5}/templates/ss_upsert.sql +0 -0
  190. {execsql2-2.4.4 → execsql2-2.4.5}/tests/__init__.py +0 -0
  191. {execsql2-2.4.4 → execsql2-2.4.5}/tests/conftest.py +0 -0
  192. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/__init__.py +0 -0
  193. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_base.py +0 -0
  194. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_duckdb.py +0 -0
  195. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_factory.py +0 -0
  196. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_postgres.py +0 -0
  197. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_sqlite.py +0 -0
  198. {execsql2-2.4.4 → execsql2-2.4.5}/tests/db/test_sqlite_extra.py +0 -0
  199. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/__init__.py +0 -0
  200. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_base.py +0 -0
  201. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_db.py +0 -0
  202. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_delimited.py +0 -0
  203. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_duckdb_exporter.py +0 -0
  204. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_exporters.py +0 -0
  205. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_feather.py +0 -0
  206. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_html_latex.py +0 -0
  207. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_json.py +0 -0
  208. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_ods.py +0 -0
  209. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_parquet.py +0 -0
  210. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_sqlite_exporter.py +0 -0
  211. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_templates.py +0 -0
  212. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_xls_xlsx.py +0 -0
  213. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_xml.py +0 -0
  214. {execsql2-2.4.4 → execsql2-2.4.5}/tests/exporters/test_zip.py +0 -0
  215. {execsql2-2.4.4 → execsql2-2.4.5}/tests/gui/__init__.py +0 -0
  216. {execsql2-2.4.4 → execsql2-2.4.5}/tests/gui/test_backends.py +0 -0
  217. {execsql2-2.4.4 → execsql2-2.4.5}/tests/importers/__init__.py +0 -0
  218. {execsql2-2.4.4 → execsql2-2.4.5}/tests/importers/test_csv_importer.py +0 -0
  219. {execsql2-2.4.4 → execsql2-2.4.5}/tests/importers/test_feather_importer.py +0 -0
  220. {execsql2-2.4.4 → execsql2-2.4.5}/tests/importers/test_ods_importer.py +0 -0
  221. {execsql2-2.4.4 → execsql2-2.4.5}/tests/importers/test_xls_importer.py +0 -0
  222. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/__init__.py +0 -0
  223. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/conftest.py +0 -0
  224. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/test_dsn.py +0 -0
  225. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/test_duckdb.py +0 -0
  226. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/test_mysql.py +0 -0
  227. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/test_postgres.py +0 -0
  228. {execsql2-2.4.4 → execsql2-2.4.5}/tests/integration/test_sqlite.py +0 -0
  229. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/__init__.py +0 -0
  230. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands.py +0 -0
  231. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_connect.py +0 -0
  232. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_data.py +0 -0
  233. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_extended.py +0 -0
  234. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_fileops_extra.py +0 -0
  235. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_io.py +0 -0
  236. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
  237. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_script_ext.py +0 -0
  238. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_system.py +0 -0
  239. {execsql2-2.4.4 → execsql2-2.4.5}/tests/metacommands/test_metacommands_system_extra.py +0 -0
  240. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_cli.py +0 -0
  241. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_cli_run.py +0 -0
  242. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_config.py +0 -0
  243. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_config_data.py +0 -0
  244. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_constants.py +0 -0
  245. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_exceptions.py +0 -0
  246. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_format.py +0 -0
  247. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_mail.py +0 -0
  248. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_models.py +0 -0
  249. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_package.py +0 -0
  250. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_parser.py +0 -0
  251. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_registry.py +0 -0
  252. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_script.py +0 -0
  253. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_state.py +0 -0
  254. {execsql2-2.4.4 → execsql2-2.4.5}/tests/test_types.py +0 -0
  255. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/__init__.py +0 -0
  256. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_auth.py +0 -0
  257. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_auth_extra.py +0 -0
  258. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_crypto.py +0 -0
  259. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_datetime.py +0 -0
  260. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_errors.py +0 -0
  261. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_errors_extra.py +0 -0
  262. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_fileio.py +0 -0
  263. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_fileio_extra.py +0 -0
  264. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_numeric.py +0 -0
  265. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_regex.py +0 -0
  266. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_strings.py +0 -0
  267. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_timer.py +0 -0
  268. {execsql2-2.4.4 → execsql2-2.4.5}/tests/utils/test_timer_extra.py +0 -0
  269. {execsql2-2.4.4 → execsql2-2.4.5}/zensical.toml +0 -0
@@ -13,6 +13,17 @@ ______________________________________________________________________
13
13
 
14
14
  ______________________________________________________________________
15
15
 
16
+ ## [2.4.5] - 2026-03-31
17
+
18
+ ### Fixed
19
+
20
+ - `ON ERROR_HALT EXECUTE SCRIPT` and `ON CANCEL_HALT EXECUTE SCRIPT` metacommands were not recognized — handler functions existed but dispatch patterns were missing.
21
+ - `EXTEND SCRIPT <X> WITH SCRIPT <Y>` metacommand was not recognized — only the `APPEND SCRIPT` synonym was ported from the upstream monolith.
22
+ - `PROMPT ASK` with single-quoted (`'...'`) or bracket-delimited (`[...]`) questions, and with unquoted `HELP` arguments, were not recognized — only the double-quoted question with double-quoted help variant was ported.
23
+ - `CONNECT TO SQLSERVER` with mixed quoting (e.g., quoted SERVER + unquoted DB) or quoted PASSWORD was not recognized — only the fully-unquoted and fully-quoted variants were ported.
24
+
25
+ ______________________________________________________________________
26
+
16
27
  ## [2.4.4] - 2026-03-30
17
28
 
18
29
  ______________________________________________________________________
@@ -50,3 +50,4 @@ A multi-agent system where specialized agents collaborate to improve, extend, de
50
50
  - The existing post-tool hooks (auto-changelog, auto-docs) continue working independently
51
51
  - All code must pass `ruff check` and target Python 3.10+
52
52
  - **Every user-visible change must be reflected in `CHANGELOG.md`** under the `[Unreleased]` section using [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) categories: Added, Changed, Fixed, Removed. Do not leave changelog updates for later — include them in the same commit or PR as the code change.
53
+ - **Every user-visible change must also update documentation** — review and revise `README.md`, `docs/`, and any other relevant documentation to stay consistent with the code. New CLI options, features, or behavior changes must be reflected in the README Options table, feature list, and the corresponding docs page. Do not leave doc updates for later.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: execsql2
3
- Version: 2.4.4
3
+ Version: 2.4.5
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: Repository, https://github.com/geocoug/execsql
6
6
  Project-URL: Issues, https://github.com/geocoug/execsql/issues
@@ -107,7 +107,7 @@ Description-Content-Type: text/markdown
107
107
 
108
108
  > [!NOTE]
109
109
  > **This is a maintained fork of [execsql](https://execsql.readthedocs.io/).**
110
- > The original monolith has been fully refactored into a modular package with 2,000+ tests.
110
+ > The original monolith has been fully refactored into a modular package.
111
111
  > The CLI and configuration are backwards-compatible with upstream v1.130.1.
112
112
  > Report issues at [github.com/geocoug/execsql/issues](https://github.com/geocoug/execsql/issues).
113
113
 
@@ -215,8 +215,12 @@ execsql script.sql # read connection from config file
215
215
  | `-m` | List metacommands and exit |
216
216
  | `-n` | Create a new SQLite or PostgreSQL database if it does not exist |
217
217
  | `-v {0,1,2,3}` | GUI level (0=none, 1=password, 2=selection, 3=full) |
218
- | `--gui-framework {tkinter,textual}` | GUI framework for interactive prompts |
219
218
  | `-w` | Skip password prompt when a username is supplied |
219
+ | `--dsn URL` | Connection string (e.g. `postgresql://user:pass@host/db`) |
220
+ | `--dry-run` | Parse the script and report commands without executing |
221
+ | `--progress` | Show a progress bar for long-running IMPORT operations |
222
+ | `--dump-keywords` | Print metacommand keywords as JSON and exit |
223
+ | `--gui-framework {tkinter,textual}` | GUI framework for interactive prompts |
220
224
 
221
225
  Run `execsql --help` for the full option list, or `execsql -m` to list all metacommands.
222
226
 
@@ -283,8 +287,31 @@ execsql-format --in-place scripts/
283
287
  execsql-format --check scripts/
284
288
  ```
285
289
 
290
+ `execsql-format` is also available as a [pre-commit](https://pre-commit.com/) hook:
291
+
292
+ ```yaml
293
+ repos:
294
+ - repo: https://github.com/geocoug/execsql
295
+ rev: v2.4.4
296
+ hooks:
297
+ - id: execsql-format
298
+ args: [--in-place]
299
+ ```
300
+
286
301
  See the [formatter documentation](https://execsql2.readthedocs.io/en/latest/formatter/) for all options.
287
302
 
303
+ # VS Code Syntax Highlighting
304
+
305
+ 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.
306
+
307
+ To install, symlink the extension folder into your VS Code extensions directory:
308
+
309
+ ```sh
310
+ ln -s /path/to/execsql/extras/vscode-execsql ~/.vscode/extensions/execsql-syntax
311
+ ```
312
+
313
+ See the [extension README](extras/vscode-execsql/README.md) for Windows instructions, color customization, and troubleshooting.
314
+
288
315
  # Templates
289
316
 
290
317
  The `templates/` directory in this repository includes ready-to-use execsql scripts:
@@ -1,6 +1,6 @@
1
1
  > [!NOTE]
2
2
  > **This is a maintained fork of [execsql](https://execsql.readthedocs.io/).**
3
- > The original monolith has been fully refactored into a modular package with 2,000+ tests.
3
+ > The original monolith has been fully refactored into a modular package.
4
4
  > The CLI and configuration are backwards-compatible with upstream v1.130.1.
5
5
  > Report issues at [github.com/geocoug/execsql/issues](https://github.com/geocoug/execsql/issues).
6
6
 
@@ -108,8 +108,12 @@ execsql script.sql # read connection from config file
108
108
  | `-m` | List metacommands and exit |
109
109
  | `-n` | Create a new SQLite or PostgreSQL database if it does not exist |
110
110
  | `-v {0,1,2,3}` | GUI level (0=none, 1=password, 2=selection, 3=full) |
111
- | `--gui-framework {tkinter,textual}` | GUI framework for interactive prompts |
112
111
  | `-w` | Skip password prompt when a username is supplied |
112
+ | `--dsn URL` | Connection string (e.g. `postgresql://user:pass@host/db`) |
113
+ | `--dry-run` | Parse the script and report commands without executing |
114
+ | `--progress` | Show a progress bar for long-running IMPORT operations |
115
+ | `--dump-keywords` | Print metacommand keywords as JSON and exit |
116
+ | `--gui-framework {tkinter,textual}` | GUI framework for interactive prompts |
113
117
 
114
118
  Run `execsql --help` for the full option list, or `execsql -m` to list all metacommands.
115
119
 
@@ -176,8 +180,31 @@ execsql-format --in-place scripts/
176
180
  execsql-format --check scripts/
177
181
  ```
178
182
 
183
+ `execsql-format` is also available as a [pre-commit](https://pre-commit.com/) hook:
184
+
185
+ ```yaml
186
+ repos:
187
+ - repo: https://github.com/geocoug/execsql
188
+ rev: v2.4.4
189
+ hooks:
190
+ - id: execsql-format
191
+ args: [--in-place]
192
+ ```
193
+
179
194
  See the [formatter documentation](https://execsql2.readthedocs.io/en/latest/formatter/) for all options.
180
195
 
196
+ # VS Code Syntax Highlighting
197
+
198
+ 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.
199
+
200
+ To install, symlink the extension folder into your VS Code extensions directory:
201
+
202
+ ```sh
203
+ ln -s /path/to/execsql/extras/vscode-execsql ~/.vscode/extensions/execsql-syntax
204
+ ```
205
+
206
+ See the [extension README](extras/vscode-execsql/README.md) for Windows instructions, color customization, and troubleshooting.
207
+
181
208
  # Templates
182
209
 
183
210
  The `templates/` directory in this repository includes ready-to-use execsql scripts:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execsql2"
7
- version = "2.4.4"
7
+ version = "2.4.5"
8
8
  description = "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."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  license = { file = "LICENSE.txt" }
@@ -155,7 +155,7 @@ skip-magic-trailing-comma = false
155
155
  line-ending = "auto"
156
156
 
157
157
  [tool.bumpversion]
158
- current_version = "2.4.4"
158
+ current_version = "2.4.5"
159
159
  commit = true
160
160
  commit_args = "--no-verify"
161
161
  tag = true
@@ -169,6 +169,7 @@ from execsql.metacommands.system import (
169
169
  x_cancel_halt,
170
170
  x_cancel_halt_email,
171
171
  x_cancel_halt_email_clear,
172
+ x_cancel_halt_exec,
172
173
  x_cancel_halt_exec_clear,
173
174
  x_cancel_halt_write,
174
175
  x_cancel_halt_write_clear,
@@ -185,6 +186,7 @@ from execsql.metacommands.system import (
185
186
  x_email,
186
187
  x_error_halt_email,
187
188
  x_error_halt_email_clear,
189
+ x_error_halt_exec,
188
190
  x_error_halt_exec_clear,
189
191
  x_error_halt_write,
190
192
  x_error_halt_write_clear,
@@ -1030,6 +1032,10 @@ def build_dispatch_table() -> MetaCommandList:
1030
1032
  x_error_halt_email,
1031
1033
  )
1032
1034
  mcl.add(r"^\s*ON\s+ERROR_HALT\s+EXEC\s+CLEAR\s*$", x_error_halt_exec_clear)
1035
+ mcl.add(
1036
+ r'^\s*ON\s+ERROR_HALT\s+EXEC(?:UTE)?\s+SCRIPT(?:\s+(?P<exists>IF\s+EXISTS))?\s+(?P<script_id>\w+)(?:(?:\s+WITH)?(?:\s+ARG(?:UMENT)?S?)?\s*\(\s*(?P<argexp>#?\w+\s*=\s*(?:(?:[^"\'\[][^,\)]*)|(?:"[^"]*")|(?:\'[^\']*\')|(?:\[[^\]]*\]))(?:\s*,\s*#?\w+\s*=\s*(?:(?:[^"\'\[][^,\)]*)|(?:"[^"]*")|(?:\'[^\']*\')|(?:\[[^\]]*\])))*)\s*\))?(?:\s+(?P<looptype>WHILE|UNTIL)\s*\(\s*(?P<loopcond>.+)\s*\))?\s*$',
1037
+ x_error_halt_exec,
1038
+ )
1033
1039
  mcl.add(
1034
1040
  r"^\s*ON\s+CANCEL_HALT\s+WRITE\s+CLEAR\s*$",
1035
1041
  x_cancel_halt_write_clear,
@@ -1077,6 +1083,10 @@ def build_dispatch_table() -> MetaCommandList:
1077
1083
  x_cancel_halt_email,
1078
1084
  )
1079
1085
  mcl.add(r"^\s*ON\s+CANCEL_HALT\s+EXEC\s+CLEAR\s*$", x_cancel_halt_exec_clear)
1086
+ mcl.add(
1087
+ r'^\s*ON\s+CANCEL_HALT\s+EXEC(?:UTE)?\s+SCRIPT(?:\s+(?P<exists>IF\s+EXISTS))?\s+(?P<script_id>\w+)(?:(?:\s+WITH)?(?:\s+ARG(?:UMENT)?S?)?\s*\(\s*(?P<argexp>#?\w+\s*=\s*(?:(?:[^"\'\[][^,\)]*)|(?:"[^"]*")|(?:\'[^\']*\')|(?:\[[^\]]*\]))(?:\s*,\s*#?\w+\s*=\s*(?:(?:[^"\'\[][^,\)]*)|(?:"[^"]*")|(?:\'[^\']*\')|(?:\[[^\]]*\])))*)\s*\))?(?:\s+(?P<looptype>WHILE|UNTIL)\s*\(\s*(?P<loopcond>.+)\s*\))?\s*$',
1088
+ x_cancel_halt_exec,
1089
+ )
1080
1090
 
1081
1091
  # ------------------------------------------------------------------
1082
1092
  # SUB_TEMPFILE
@@ -1680,16 +1690,54 @@ def build_dispatch_table() -> MetaCommandList:
1680
1690
  )
1681
1691
  mcl.add(
1682
1692
  (
1693
+ # SERVER unquoted, DB unquoted, PASSWORD unquoted
1683
1694
  r"^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*(?P<server>[A-Z0-9][A-Z0-9_\/\\\-\.]*)\s*,\s*"
1684
1695
  r"DB\s*=\s*(?P<db_name>[A-Z][A-Z0-9_\-]*)(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)"
1685
1696
  r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1686
1697
  r"(?:\s*,\s+PASSWORD\s*=\s*(?P<password>[^\s\)]+))?"
1687
1698
  r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1699
+ # SERVER quoted, DB quoted, PASSWORD unquoted
1688
1700
  r'^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*"(?P<server>[A-Z0-9][A-Z0-9_\/\\\s\-\.]*)"\s*,\s*'
1689
1701
  r'DB\s*=\s*"(?P<db_name>[A-Z][A-Z0-9_\-\s]*)"(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)'
1690
1702
  r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1691
1703
  r"(?:\s*,\s+PASSWORD\s*=\s*(?P<password>[^\s\)]+))?"
1692
1704
  r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1705
+ # SERVER quoted, DB unquoted, PASSWORD unquoted
1706
+ r'^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*"(?P<server>[A-Z0-9][A-Z0-9_\/\\\s\-\.]*)"\s*,\s*'
1707
+ r"DB\s*=\s*(?P<db_name>[A-Z][A-Z0-9_\-]*)(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)"
1708
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1709
+ r"(?:\s*,\s+PASSWORD\s*=\s*(?P<password>[^\s\)]+))?"
1710
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1711
+ # SERVER unquoted, DB quoted, PASSWORD unquoted
1712
+ r"^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*(?P<server>[A-Z0-9][A-Z0-9_\/\\\-\.]*)\s*,\s*"
1713
+ r'DB\s*=\s*"(?P<db_name>[A-Z][A-Z0-9_\- ]*)"(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)'
1714
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1715
+ r"(?:\s*,\s+PASSWORD\s*=\s*(?P<password>[^\s\)]+))?"
1716
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1717
+ # SERVER unquoted, DB unquoted, PASSWORD quoted
1718
+ r"^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*(?P<server>[A-Z0-9][A-Z0-9_\/\\\-\.]*)\s*,\s*"
1719
+ r"DB\s*=\s*(?P<db_name>[A-Z][A-Z0-9_\-]*)(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)"
1720
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1721
+ r'(?:\s*,\s+PASSWORD\s*=\s*(?P<password>"[^\s\)]+"))?'
1722
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1723
+ # SERVER quoted, DB quoted, PASSWORD quoted
1724
+ r'^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*"(?P<server>[A-Z0-9][A-Z0-9_\/\\\s\-\.]*)"\s*,\s*'
1725
+ r'DB\s*=\s*"(?P<db_name>[A-Z][A-Z0-9_\-\s]*)"(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)'
1726
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1727
+ r'(?:\s*,\s+PASSWORD\s*=\s*(?P<password>"[^\s\)]+"))?'
1728
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1729
+ # SERVER quoted, DB unquoted, PASSWORD quoted
1730
+ r'^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*"(?P<server>[A-Z0-9][A-Z0-9_\/\\\s\-\.]*)"\s*,\s*'
1731
+ r"DB\s*=\s*(?P<db_name>[A-Z][A-Z0-9_\-]*)(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)"
1732
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1733
+ r'(?:\s*,\s+PASSWORD\s*=\s*(?P<password>"[^\s\)]+"))?'
1734
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1735
+ # SERVER unquoted, DB quoted, PASSWORD quoted
1736
+ r"^CONNECT\s+TO\s+SQLSERVER\s*\(\s*SERVER\s*=\s*(?P<server>[A-Z0-9][A-Z0-9_\/\\\-\.]*)\s*,\s*"
1737
+ r'DB\s*=\s*"(?P<db_name>[A-Z][A-Z0-9_\- ]*)"(?:\s*,\s*USER\s*=\s*(?P<user>[A-Z][A-Z0-9_~`!@#$%^&\*\+=\/\?\.-]*)'
1738
+ r"\s*,\s*NEED_PWD\s*=\s*(?P<need_pwd>TRUE|FALSE))?(?:\s*,\s*PORT\s*=\s*(?P<port>\d+))?"
1739
+ r'(?:\s*,\s+PASSWORD\s*=\s*(?P<password>"[^\s\)]+"))?'
1740
+ r"(?:\s*,\s*ENCODING\s*=\s*(?P<encoding>[A-Z][A-Z0-9_-]+))?\s*\)\s+AS\s+(?P<db_alias>[A-Z][A-Z0-9_]*)\s*$",
1693
1741
  ),
1694
1742
  x_connect_ssvr,
1695
1743
  )
@@ -1722,6 +1770,12 @@ def build_dispatch_table() -> MetaCommandList:
1722
1770
  # ------------------------------------------------------------------
1723
1771
  # APPEND/EXTEND SCRIPT
1724
1772
  # ------------------------------------------------------------------
1773
+ mcl.add(
1774
+ r"\s*EXTEND\s+SCRIPT\s+(?P<script2>\w+)\s+WITH\s+SCRIPT\s+(?P<script1>\w+)\s*$",
1775
+ x_extendscript,
1776
+ description="EXTEND SCRIPT",
1777
+ category="action",
1778
+ )
1725
1779
  mcl.add(
1726
1780
  r"\s*APPEND\s+SCRIPT\s+(?P<script1>\w+)\s+TO\s+(?P<script2>\w+)\s*$",
1727
1781
  x_extendscript,
@@ -1897,13 +1951,48 @@ def build_dispatch_table() -> MetaCommandList:
1897
1951
  # ------------------------------------------------------------------
1898
1952
  mcl.add(
1899
1953
  ins_table_rxs(
1900
- r'^\s*PROMPT\s+ASK\s+"(?P<question>[^"]+)"\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+',
1901
- r')?(?:\s+HELP\s+"(?P<help>[^"]+)")?\s*$',
1954
+ r"^\s*PROMPT\s+ASK\s+'(?P<question>[^']+)'\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+",
1955
+ r")?(?:\s+HELP\s+(?P<help>[^\s]+))?\s*$",
1902
1956
  ),
1903
1957
  x_prompt_ask,
1904
1958
  description="PROMPT ASK",
1905
1959
  category="prompt",
1906
1960
  )
1961
+ mcl.add(
1962
+ ins_table_rxs(
1963
+ r"^\s*PROMPT\s+ASK\s+'(?P<question>[^']+)'\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+",
1964
+ r')?(?:\s+HELP\s+"(?P<help>[^"]+)")?\s*$',
1965
+ ),
1966
+ x_prompt_ask,
1967
+ )
1968
+ mcl.add(
1969
+ ins_table_rxs(
1970
+ r"^\s*PROMPT\s+ASK\s+\[(?P<question>[^\]]+)\]\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+",
1971
+ r")?(?:\s+HELP\s+(?P<help>[^\s]+))?\s*$",
1972
+ ),
1973
+ x_prompt_ask,
1974
+ )
1975
+ mcl.add(
1976
+ ins_table_rxs(
1977
+ r"^\s*PROMPT\s+ASK\s+\[(?P<question>[^\]]+)\]\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+",
1978
+ r')?(?:\s+HELP\s+"(?P<help>[^"]+)")?\s*$',
1979
+ ),
1980
+ x_prompt_ask,
1981
+ )
1982
+ mcl.add(
1983
+ ins_table_rxs(
1984
+ r'^\s*PROMPT\s+ASK\s+"(?P<question>[^"]+)"\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+',
1985
+ r")?(?:\s+HELP\s+(?P<help>[^\s]+))?\s*$",
1986
+ ),
1987
+ x_prompt_ask,
1988
+ )
1989
+ mcl.add(
1990
+ ins_table_rxs(
1991
+ r'^\s*PROMPT\s+ASK\s+"(?P<question>[^"]+)"\s+SUB\s+(?P<match>~?\w+)(?:\s+DISPLAY\s+',
1992
+ r')?(?:\s+HELP\s+"(?P<help>[^"]+)")?\s*$',
1993
+ ),
1994
+ x_prompt_ask,
1995
+ )
1907
1996
 
1908
1997
  # ------------------------------------------------------------------
1909
1998
  # PROMPT DISPLAY (table viewer)
@@ -657,7 +657,7 @@ wheels = [
657
657
 
658
658
  [[package]]
659
659
  name = "execsql2"
660
- version = "2.4.4"
660
+ version = "2.4.5"
661
661
  source = { editable = "." }
662
662
  dependencies = [
663
663
  { name = "rich" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes