dirsql 0.4.33__tar.gz → 0.4.34__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 (207) hide show
  1. {dirsql-0.4.33 → dirsql-0.4.34}/Cargo.lock +2 -2
  2. {dirsql-0.4.33 → dirsql-0.4.34}/PKG-INFO +1 -1
  3. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/cli.md +18 -0
  4. {dirsql-0.4.33/packages/rust → dirsql-0.4.34}/docs/reference/config.md +5 -0
  5. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/sdk.md +4 -0
  6. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/Cargo.toml +1 -1
  7. {dirsql-0.4.33/packages/rust → dirsql-0.4.34/packages/python}/docs/reference/cli.md +18 -0
  8. {dirsql-0.4.33 → dirsql-0.4.34/packages/python}/docs/reference/config.md +5 -0
  9. {dirsql-0.4.33/packages/rust → dirsql-0.4.34/packages/python}/docs/reference/sdk.md +4 -0
  10. dirsql-0.4.34/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +7 -0
  11. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/Cargo.toml +1 -1
  12. {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/cli.md +18 -0
  13. {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/config.md +5 -0
  14. {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/sdk.md +4 -0
  15. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/db.rs +20 -0
  16. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/functions.rs +191 -0
  17. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/lib.rs +2 -1
  18. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/progress.rs +153 -25
  19. {dirsql-0.4.33 → dirsql-0.4.34}/Cargo.toml +0 -0
  20. {dirsql-0.4.33 → dirsql-0.4.34}/README.md +0 -0
  21. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/__init__.py +0 -0
  22. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/_async.py +0 -0
  23. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/_dirsql.pyi +0 -0
  24. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/__init__.py +0 -0
  25. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/__init__.py +0 -0
  26. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  27. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  28. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  29. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  30. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  31. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/main.py +0 -0
  32. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/resolve_config_extensions.py +0 -0
  33. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/py.typed +0 -0
  34. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/resolve_config_extensions.py +0 -0
  35. {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/resolve_extension.py +0 -0
  36. {dirsql-0.4.33 → dirsql-0.4.34}/docs/.claude/CLAUDE.md +0 -0
  37. {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/config.ts +0 -0
  38. {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/theme/index.ts +0 -0
  39. {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/theme/lang.ts +0 -0
  40. {dirsql-0.4.33 → dirsql-0.4.34}/docs/AGENTS.md +0 -0
  41. {dirsql-0.4.33 → dirsql-0.4.34}/docs/explanation.md +0 -0
  42. {dirsql-0.4.33 → dirsql-0.4.34}/docs/getting-started.md +0 -0
  43. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/columns-from-paths.md +0 -0
  44. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/define-tables.md +0 -0
  45. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/embed.md +0 -0
  46. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/extract-from-contents.md +0 -0
  47. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/load-extension.md +0 -0
  48. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/parse-files-into-columns.md +0 -0
  49. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/persist.md +0 -0
  50. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/query-json.md +0 -0
  51. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/query-without-config.md +0 -0
  52. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/react-to-changes.md +0 -0
  53. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/search-by-meaning.md +0 -0
  54. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/search-indexes.md +0 -0
  55. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/skip-files.md +0 -0
  56. {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/write-a-plugin.md +0 -0
  57. {dirsql-0.4.33 → dirsql-0.4.34}/docs/index.md +0 -0
  58. {dirsql-0.4.33 → dirsql-0.4.34}/docs/package.json +0 -0
  59. {dirsql-0.4.33 → dirsql-0.4.34}/docs/plugins.md +0 -0
  60. {dirsql-0.4.33 → dirsql-0.4.34}/docs/pnpm-lock.yaml +0 -0
  61. {dirsql-0.4.33 → dirsql-0.4.34}/docs/pnpm-workspace.yaml +0 -0
  62. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/columns.md +0 -0
  63. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/hooks.md +0 -0
  64. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/http-api.md +0 -0
  65. {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/path-tables.md +0 -0
  66. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/CHANGELOG.md +0 -0
  67. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/MIGRATIONS.md +0 -0
  68. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/README.md +0 -0
  69. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  70. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  71. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  72. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  73. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  74. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  75. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  76. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  77. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  78. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  79. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  80. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  81. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  82. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  83. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  84. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  85. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  86. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  87. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  88. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/README.md +0 -0
  89. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/conftest.py +0 -0
  90. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.claude/CLAUDE.md +0 -0
  91. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/config.ts +0 -0
  92. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  93. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  94. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/AGENTS.md +0 -0
  95. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/explanation.md +0 -0
  96. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/getting-started.md +0 -0
  97. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/columns-from-paths.md +0 -0
  98. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/define-tables.md +0 -0
  99. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/embed.md +0 -0
  100. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/extract-from-contents.md +0 -0
  101. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/load-extension.md +0 -0
  102. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  103. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/persist.md +0 -0
  104. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/query-json.md +0 -0
  105. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/query-without-config.md +0 -0
  106. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/react-to-changes.md +0 -0
  107. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/search-by-meaning.md +0 -0
  108. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/search-indexes.md +0 -0
  109. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/skip-files.md +0 -0
  110. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/write-a-plugin.md +0 -0
  111. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/index.md +0 -0
  112. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/package.json +0 -0
  113. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/plugins.md +0 -0
  114. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/pnpm-lock.yaml +0 -0
  115. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/pnpm-workspace.yaml +0 -0
  116. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/columns.md +0 -0
  117. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/hooks.md +0 -0
  118. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/http-api.md +0 -0
  119. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/path-tables.md +0 -0
  120. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  121. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  122. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  123. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  124. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  125. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  126. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  127. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  128. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  129. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  130. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  131. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  132. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  133. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  134. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  135. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  136. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  137. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  138. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  139. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  140. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  141. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  142. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  143. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/README.md +0 -0
  144. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/src/lib.rs +0 -0
  145. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/testing-conventions.toml +0 -0
  146. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/__init__.py +0 -0
  147. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/conftest.py +0 -0
  148. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/__init__.py +0 -0
  149. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  150. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  151. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/__init__.py +0 -0
  152. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/binding/__init__.py +0 -0
  153. {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  154. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/CHANGELOG.md +0 -0
  155. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/MIGRATIONS.md +0 -0
  156. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/README.md +0 -0
  157. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/db_bench.rs +0 -0
  158. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/differ_bench.rs +0 -0
  159. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/matcher_bench.rs +0 -0
  160. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/scanner_bench.rs +0 -0
  161. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/explanation.md +0 -0
  162. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/getting-started.md +0 -0
  163. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  164. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/define-tables.md +0 -0
  165. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/embed.md +0 -0
  166. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  167. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/load-extension.md +0 -0
  168. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  169. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/persist.md +0 -0
  170. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/query-json.md +0 -0
  171. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/query-without-config.md +0 -0
  172. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/react-to-changes.md +0 -0
  173. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  174. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/search-indexes.md +0 -0
  175. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/skip-files.md +0 -0
  176. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  177. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/index.md +0 -0
  178. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/plugins.md +0 -0
  179. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/columns.md +0 -0
  180. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/hooks.md +0 -0
  181. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/http-api.md +0 -0
  182. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/path-tables.md +0 -0
  183. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/bin/dirsql.rs +0 -0
  184. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/execute.rs +0 -0
  185. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/init.rs +0 -0
  186. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/mod.rs +0 -0
  187. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/repl.rs +0 -0
  188. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/router.rs +0 -0
  189. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/run.rs +0 -0
  190. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/serialize.rs +0 -0
  191. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/server.rs +0 -0
  192. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/table.rs +0 -0
  193. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/command.rs +0 -0
  194. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/config.rs +0 -0
  195. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/default_config.toml +0 -0
  196. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/differ.rs +0 -0
  197. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/infer.rs +0 -0
  198. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/matcher.rs +0 -0
  199. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/parsed_cache.rs +0 -0
  200. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/parsed_vtab.rs +0 -0
  201. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/path_table.rs +0 -0
  202. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/persist.rs +0 -0
  203. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/scanner.rs +0 -0
  204. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/sql_literal.rs +0 -0
  205. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/vtab.rs +0 -0
  206. {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/watcher.rs +0 -0
  207. {dirsql-0.4.33 → dirsql-0.4.34}/pyproject.toml +0 -0
@@ -540,7 +540,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
540
540
 
541
541
  [[package]]
542
542
  name = "dirsql"
543
- version = "0.4.33"
543
+ version = "0.4.34"
544
544
  dependencies = [
545
545
  "assert_cmd",
546
546
  "axum",
@@ -583,7 +583,7 @@ dependencies = [
583
583
 
584
584
  [[package]]
585
585
  name = "dirsql-py-ext"
586
- version = "0.4.33"
586
+ version = "0.4.34"
587
587
  dependencies = [
588
588
  "dirsql",
589
589
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.33
3
+ Version: 0.4.34
4
4
  Requires-Dist: tomli>=2 ; python_full_version < '3.11'
5
5
  Requires-Dist: bin-shim>=0.1
6
6
  Summary: Ephemeral SQL index over a local directory
@@ -483,6 +483,24 @@ dirsql: indexed 41231 files in 3m12s
483
483
 
484
484
  stdout is untouched — it carries the query result and nothing else.
485
485
 
486
+ A query gets the same treatment when it calls a
487
+ [worker-backed function](./config.md#dirsql-function). Those cost one round
488
+ trip per row, so a query that calls one over a whole corpus is the slowest
489
+ thing dirsql does:
490
+
491
+ ```
492
+ dirsql: running 9204 worker calls
493
+ ```
494
+
495
+ and, when the query ends:
496
+
497
+ ```
498
+ dirsql: ran 41231 worker calls in 2m41s
499
+ ```
500
+
501
+ A query that calls no worker prints nothing, whatever the setting — the
502
+ reporting only ever speaks when there is something to report.
503
+
486
504
  By default this is **terminal-only, and only for work slow enough to wonder
487
505
  about**: a phase that finishes in under half a second prints nothing at all,
488
506
  and a run whose stderr is a pipe or a file prints nothing regardless of how
@@ -133,6 +133,11 @@ process alive for the rest of the invocation, sending it every subsequent
133
133
  call — one process total, never one per row or per file. The worker is torn
134
134
  down when the invocation ends.
135
135
 
136
+ A query paying per-row round trips reports them on stderr while it runs
137
+ (`dirsql: running 9204 worker calls`), on the same terms as every other
138
+ [progress line](./cli.md#progress-reporting): terminal-only by default, silent
139
+ on a pipe, and gone before the result is printed.
140
+
136
141
  The `timeout` bounds each **round-trip call**, not the query: a query that
137
142
  calls the function on 10 000 rows is 10 000 individually timed calls. A call
138
143
  that times out, or a worker that crashes or closes its pipes, fails the query
@@ -408,6 +408,10 @@ one summary of what each cost:
408
408
  dirsql: indexed 41231 files in 3m12s
409
409
  ```
410
410
 
411
+ A `query` that calls a worker-backed function is reported the same way, as a
412
+ running count of round trips (`dirsql: running 9204 worker calls`) — the shape
413
+ `dirsql-plugin-embeddings` produces when it embeds a corpus one row at a time.
414
+
411
415
  This is terminal-only by default, and only for a phase that runs longer than
412
416
  half a second — a program whose stderr is a pipe, a file, or a log collector
413
417
  sees nothing, whatever the scan costs. Set `DIRSQL_PROGRESS=never` to
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
4
4
  # pypi/maturin handler can rewrite it via `write-version` before
5
5
  # `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
6
6
  # and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
7
- version = "0.4.33"
7
+ version = "0.4.34"
8
8
  # abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
9
9
  # `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
10
10
  # (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
@@ -483,6 +483,24 @@ dirsql: indexed 41231 files in 3m12s
483
483
 
484
484
  stdout is untouched — it carries the query result and nothing else.
485
485
 
486
+ A query gets the same treatment when it calls a
487
+ [worker-backed function](./config.md#dirsql-function). Those cost one round
488
+ trip per row, so a query that calls one over a whole corpus is the slowest
489
+ thing dirsql does:
490
+
491
+ ```
492
+ dirsql: running 9204 worker calls
493
+ ```
494
+
495
+ and, when the query ends:
496
+
497
+ ```
498
+ dirsql: ran 41231 worker calls in 2m41s
499
+ ```
500
+
501
+ A query that calls no worker prints nothing, whatever the setting — the
502
+ reporting only ever speaks when there is something to report.
503
+
486
504
  By default this is **terminal-only, and only for work slow enough to wonder
487
505
  about**: a phase that finishes in under half a second prints nothing at all,
488
506
  and a run whose stderr is a pipe or a file prints nothing regardless of how
@@ -133,6 +133,11 @@ process alive for the rest of the invocation, sending it every subsequent
133
133
  call — one process total, never one per row or per file. The worker is torn
134
134
  down when the invocation ends.
135
135
 
136
+ A query paying per-row round trips reports them on stderr while it runs
137
+ (`dirsql: running 9204 worker calls`), on the same terms as every other
138
+ [progress line](./cli.md#progress-reporting): terminal-only by default, silent
139
+ on a pipe, and gone before the result is printed.
140
+
136
141
  The `timeout` bounds each **round-trip call**, not the query: a query that
137
142
  calls the function on 10 000 rows is 10 000 individually timed calls. A call
138
143
  that times out, or a worker that crashes or closes its pipes, fails the query
@@ -408,6 +408,10 @@ one summary of what each cost:
408
408
  dirsql: indexed 41231 files in 3m12s
409
409
  ```
410
410
 
411
+ A `query` that calls a worker-backed function is reported the same way, as a
412
+ running count of round trips (`dirsql: running 9204 worker calls`) — the shape
413
+ `dirsql-plugin-embeddings` produces when it embeds a corpus one row at a time.
414
+
411
415
  This is terminal-only by default, and only for a phase that runs longer than
412
416
  half a second — a program whose stderr is a pipe, a file, or a log collector
413
417
  sees nothing, whatever the scan costs. Set `DIRSQL_PROGRESS=never` to
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/ -x -q",
3
+ "ran_at": 1787263769,
4
+ "exit_code": 0,
5
+ "commit": "bced5b72c85b9c50073fd6326c1528326a1bd9d3",
6
+ "branch": "claude/tackle-957-lrm0z6-worker-calls"
7
+ }
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
6
6
  # version stays for the binding crates (publish = false). The literal
7
7
  # intentionally lags the published version: putitoutthere rewrites it to
8
8
  # the planned release version at build time and never commits it back.
9
- version = "0.4.33"
9
+ version = "0.4.34"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -483,6 +483,24 @@ dirsql: indexed 41231 files in 3m12s
483
483
 
484
484
  stdout is untouched — it carries the query result and nothing else.
485
485
 
486
+ A query gets the same treatment when it calls a
487
+ [worker-backed function](./config.md#dirsql-function). Those cost one round
488
+ trip per row, so a query that calls one over a whole corpus is the slowest
489
+ thing dirsql does:
490
+
491
+ ```
492
+ dirsql: running 9204 worker calls
493
+ ```
494
+
495
+ and, when the query ends:
496
+
497
+ ```
498
+ dirsql: ran 41231 worker calls in 2m41s
499
+ ```
500
+
501
+ A query that calls no worker prints nothing, whatever the setting — the
502
+ reporting only ever speaks when there is something to report.
503
+
486
504
  By default this is **terminal-only, and only for work slow enough to wonder
487
505
  about**: a phase that finishes in under half a second prints nothing at all,
488
506
  and a run whose stderr is a pipe or a file prints nothing regardless of how
@@ -133,6 +133,11 @@ process alive for the rest of the invocation, sending it every subsequent
133
133
  call — one process total, never one per row or per file. The worker is torn
134
134
  down when the invocation ends.
135
135
 
136
+ A query paying per-row round trips reports them on stderr while it runs
137
+ (`dirsql: running 9204 worker calls`), on the same terms as every other
138
+ [progress line](./cli.md#progress-reporting): terminal-only by default, silent
139
+ on a pipe, and gone before the result is printed.
140
+
136
141
  The `timeout` bounds each **round-trip call**, not the query: a query that
137
142
  calls the function on 10 000 rows is 10 000 individually timed calls. A call
138
143
  that times out, or a worker that crashes or closes its pipes, fails the query
@@ -408,6 +408,10 @@ one summary of what each cost:
408
408
  dirsql: indexed 41231 files in 3m12s
409
409
  ```
410
410
 
411
+ A `query` that calls a worker-backed function is reported the same way, as a
412
+ running count of round trips (`dirsql: running 9204 worker calls`) — the shape
413
+ `dirsql-plugin-embeddings` produces when it embeds a corpus one row at a time.
414
+
411
415
  This is terminal-only by default, and only for a phase that runs longer than
412
416
  half a second — a program whose stderr is a pipe, a file, or a log collector
413
417
  sees nothing, whatever the scan costs. Set `DIRSQL_PROGRESS=never` to
@@ -1,8 +1,10 @@
1
1
  use rusqlite::Connection;
2
2
  use std::collections::{HashMap, HashSet};
3
3
  use std::path::{Path, PathBuf};
4
+ use std::sync::Arc;
4
5
  use thiserror::Error;
5
6
 
7
+ use crate::functions::CallReporter;
6
8
  use crate::parsed_vtab;
7
9
  use crate::path_table::{self, PathTable, Resolution};
8
10
  use crate::scanner;
@@ -264,6 +266,10 @@ pub struct Db {
264
266
  /// The persistent cache a parsed path-table reuses across runs. `None` for
265
267
  /// an ephemeral index, which has nowhere to cache to.
266
268
  path_table_cache: Option<PathBuf>,
269
+ /// Counts the worker round trips a query pays for. Shared with every
270
+ /// declared function registered on `conn`; inert until a function is both
271
+ /// declared and called.
272
+ calls: Arc<CallReporter>,
267
273
  }
268
274
 
269
275
  /// The skip rules a fresh `Db` starts with.
@@ -299,6 +305,7 @@ impl Db {
299
305
  path_table_gitignore: true,
300
306
  path_table_parser: None,
301
307
  path_table_cache: None,
308
+ calls: CallReporter::new(),
302
309
  })
303
310
  }
304
311
 
@@ -321,6 +328,7 @@ impl Db {
321
328
  path_table_gitignore: true,
322
329
  path_table_parser: None,
323
330
  path_table_cache: None,
331
+ calls: CallReporter::new(),
324
332
  })
325
333
  }
326
334
 
@@ -365,6 +373,12 @@ impl Db {
365
373
  self.path_table_cache = Some(path);
366
374
  }
367
375
 
376
+ /// The reporter every declared function increments. Handed to
377
+ /// `functions::register_all` at build time.
378
+ pub(crate) fn call_reporter(&self) -> &Arc<CallReporter> {
379
+ &self.calls
380
+ }
381
+
368
382
  /// Borrow the underlying SQLite connection. Internal use only — exposed
369
383
  /// to the `persist` module so it can manage the sidecar tables.
370
384
  #[doc(hidden)]
@@ -687,6 +701,12 @@ impl Db {
687
701
  /// internal writes (`insert_row`, delete-by-file, persist), which never go
688
702
  /// through `query()`, are unaffected.
689
703
  pub fn query(&self, sql: &str) -> Result<Vec<HashMap<String, Value>>> {
704
+ // Bracket the whole statement, prepare included: a worker-backed
705
+ // function called on every row makes this the slowest thing dirsql
706
+ // does, and the guard is what erases the counter before the caller
707
+ // prints the rows.
708
+ let _calls = self.calls.phase();
709
+
690
710
  // Each iteration must register a table no earlier iteration did; a
691
711
  // repeat means the fallback is not making progress, so the SQLite
692
712
  // error stands. That is what bounds the loop.
@@ -37,6 +37,7 @@ use rusqlite::Connection;
37
37
  use rusqlite::functions::FunctionFlags;
38
38
 
39
39
  use crate::db::Value;
40
+ use crate::progress::{CallProgress, Progress};
40
41
 
41
42
  /// The per-call timeout when a `[[dirsql.function]]` entry declares no
42
43
  /// `timeout` of its own. A round-trip on a persistent worker cannot be
@@ -60,14 +61,20 @@ pub struct ResolvedFunction {
60
61
 
61
62
  /// Register every resolved function on `conn`, once per accepted arity.
62
63
  /// Purely registration — no worker is spawned here.
64
+ ///
65
+ /// Every function shares one `calls` reporter: what a user waiting on a query
66
+ /// wants to know is how many round trips it is paying for, not which function
67
+ /// made them.
63
68
  pub(crate) fn register_all(
64
69
  conn: &Connection,
65
70
  functions: &[ResolvedFunction],
71
+ calls: &Arc<CallReporter>,
66
72
  ) -> rusqlite::Result<()> {
67
73
  for function in functions {
68
74
  let worker = Arc::new(Worker::for_process(function));
69
75
  for &arity in &function.args {
70
76
  let worker = Arc::clone(&worker);
77
+ let calls = Arc::clone(calls);
71
78
  conn.create_scalar_function(
72
79
  &function.name,
73
80
  i32::from(arity),
@@ -77,6 +84,7 @@ pub(crate) fn register_all(
77
84
  for i in 0..ctx.len() {
78
85
  args.push(Value::from(rusqlite::types::Value::from(ctx.get_raw(i))));
79
86
  }
87
+ calls.record();
80
88
  worker
81
89
  .call(&args)
82
90
  .map_err(|message| rusqlite::Error::UserFunctionError(message.into()))
@@ -87,6 +95,78 @@ pub(crate) fn register_all(
87
95
  Ok(())
88
96
  }
89
97
 
98
+ /// Counts the worker round trips a query pays for, and reports them.
99
+ ///
100
+ /// A query that calls a declared function on every row spends one round trip
101
+ /// per row -- `dirsql-plugin-embeddings` runs `embed(content)` over the whole
102
+ /// corpus that way -- so the wall time of a single `query()` can be minutes
103
+ /// with nothing on the terminal (dirsql#957).
104
+ ///
105
+ /// The count has to be drawn *and erased* by the process that owns stdout, or
106
+ /// the query result lands on top of a leftover line. A worker cannot do that:
107
+ /// it is SIGKILLed on teardown, and teardown happens after the result is
108
+ /// printed anyway (dirsql#1001).
109
+ ///
110
+ /// Behind a mutex because SQLite invokes a scalar function on whatever thread
111
+ /// is running the query.
112
+ pub(crate) struct CallReporter {
113
+ state: Mutex<CallState>,
114
+ }
115
+
116
+ struct CallState {
117
+ count: u64,
118
+ progress: Box<dyn CallProgress>,
119
+ }
120
+
121
+ impl CallReporter {
122
+ pub(crate) fn new() -> Arc<Self> {
123
+ Arc::new(Self::with_progress(Box::new(Progress::worker_calls())))
124
+ }
125
+
126
+ fn with_progress(progress: Box<dyn CallProgress>) -> Self {
127
+ Self {
128
+ state: Mutex::new(CallState { count: 0, progress }),
129
+ }
130
+ }
131
+
132
+ /// Open a phase and return the guard that closes it. A guard rather than
133
+ /// a paired call so an error mid-query still ends the phase, and so the
134
+ /// live line is gone before the caller prints anything.
135
+ pub(crate) fn phase(&self) -> CallPhase<'_> {
136
+ if let Ok(mut state) = self.state.lock() {
137
+ state.count = 0;
138
+ state.progress.restart();
139
+ }
140
+ CallPhase(self)
141
+ }
142
+
143
+ /// Record one round trip. A poisoned mutex costs the counter, never the
144
+ /// call: reporting is not worth failing a query over.
145
+ fn record(&self) {
146
+ if let Ok(mut state) = self.state.lock() {
147
+ state.count += 1;
148
+ let count = state.count;
149
+ state.progress.update(count);
150
+ }
151
+ }
152
+
153
+ fn end(&self) {
154
+ if let Ok(mut state) = self.state.lock() {
155
+ let count = state.count;
156
+ state.progress.finish(count);
157
+ }
158
+ }
159
+ }
160
+
161
+ /// The open phase. Ends when it drops.
162
+ pub(crate) struct CallPhase<'a>(&'a CallReporter);
163
+
164
+ impl Drop for CallPhase<'_> {
165
+ fn drop(&mut self) {
166
+ self.0.end();
167
+ }
168
+ }
169
+
90
170
  /// The registration flags for a declared function: UTF-8 always, plus
91
171
  /// `SQLITE_DETERMINISTIC` when the entry opts in.
92
172
  fn function_flags(deterministic: bool) -> FunctionFlags {
@@ -438,6 +518,117 @@ mod tests {
438
518
  Value::Text(s.to_string())
439
519
  }
440
520
 
521
+ // --- call reporting ----------------------------------------------------
522
+
523
+ /// A [`CallProgress`] double recording what it was asked to do, so the
524
+ /// orchestration is assertable in-module. What the reporter *draws* is
525
+ /// `progress.rs`'s business and is unit-tested there.
526
+ #[derive(Clone, Default)]
527
+ struct Recorder(Arc<Mutex<Vec<String>>>);
528
+
529
+ impl Recorder {
530
+ fn events(&self) -> Vec<String> {
531
+ self.0.lock().unwrap().clone()
532
+ }
533
+
534
+ fn push(&self, event: String) {
535
+ self.0.lock().unwrap().push(event);
536
+ }
537
+ }
538
+
539
+ struct RecordingProgress(Recorder);
540
+
541
+ impl CallProgress for RecordingProgress {
542
+ fn update(&mut self, done: u64) {
543
+ self.0.push(format!("update {done}"));
544
+ }
545
+
546
+ fn finish(&mut self, done: u64) {
547
+ self.0.push(format!("finish {done}"));
548
+ }
549
+
550
+ fn restart(&mut self) {
551
+ self.0.push("restart".to_string());
552
+ }
553
+ }
554
+
555
+ fn reporter() -> (CallReporter, Recorder) {
556
+ let recorder = Recorder::default();
557
+ let reporter = CallReporter::with_progress(Box::new(RecordingProgress(recorder.clone())));
558
+ (reporter, recorder)
559
+ }
560
+
561
+ #[test]
562
+ fn a_recorded_round_trip_is_reported_as_a_running_count() {
563
+ let (reporter, recorder) = reporter();
564
+
565
+ reporter.record();
566
+ reporter.record();
567
+
568
+ assert_eq!(recorder.events(), ["update 1", "update 2"]);
569
+ }
570
+
571
+ /// The phase is what the count belongs to: a second query must not carry
572
+ /// the first one's total, and the reporter has to be told to start over.
573
+ #[test]
574
+ fn opening_a_phase_restarts_the_reporter_and_the_count() {
575
+ let (reporter, recorder) = reporter();
576
+ reporter.record();
577
+ reporter.record();
578
+
579
+ {
580
+ let _phase = reporter.phase();
581
+ reporter.record();
582
+ }
583
+
584
+ assert_eq!(
585
+ recorder.events(),
586
+ ["update 1", "update 2", "restart", "update 1", "finish 1"],
587
+ "the new phase counts from one, not from three"
588
+ );
589
+ }
590
+
591
+ /// Dropping the guard is what ends the phase — the whole reason it is a
592
+ /// guard, since a query can leave by an error path.
593
+ #[test]
594
+ fn the_phase_guard_finishes_when_it_drops() {
595
+ let (reporter, recorder) = reporter();
596
+
597
+ {
598
+ let _phase = reporter.phase();
599
+ reporter.record();
600
+ reporter.record();
601
+ assert_eq!(
602
+ recorder.events(),
603
+ ["restart", "update 1", "update 2"],
604
+ "nothing is finished while the phase is open"
605
+ );
606
+ }
607
+
608
+ assert_eq!(
609
+ recorder.events(),
610
+ ["restart", "update 1", "update 2", "finish 2"],
611
+ "the closed phase reports the count it accumulated"
612
+ );
613
+ }
614
+
615
+ /// The production constructor wires a real [`Progress`] through the same
616
+ /// trait, so a whole phase runs against it here — the double proves the
617
+ /// orchestration, this proves the wiring is connected to something real.
618
+ /// It draws nothing: the reporter is disabled unless stderr is a terminal.
619
+ #[test]
620
+ fn the_production_reporter_counts_round_trips() {
621
+ let reporter = CallReporter::new();
622
+
623
+ {
624
+ let _phase = reporter.phase();
625
+ reporter.record();
626
+ reporter.record();
627
+ }
628
+
629
+ assert_eq!(reporter.state.lock().unwrap().count, 2);
630
+ }
631
+
441
632
  // --- wire encoding -----------------------------------------------------
442
633
 
443
634
  #[test]
@@ -885,7 +885,8 @@ impl DirSQL {
885
885
  // Register declared functions after extensions so both are available
886
886
  // to queries. Registration is inert: no worker process exists until a
887
887
  // query's first call to the function.
888
- functions::register_all(db.conn(), &functions).map_err(DirSqlError::sqlite)?;
888
+ functions::register_all(db.conn(), &functions, db.call_reporter())
889
+ .map_err(DirSqlError::sqlite)?;
889
890
 
890
891
  // Sweep a cache the reconcile rejected. It happens *here*, after the
891
892
  // extensions and functions are on the connection, rather than where