dirsql 0.4.60__tar.gz → 0.4.61__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.
- {dirsql-0.4.60 → dirsql-0.4.61}/Cargo.lock +2 -3
- {dirsql-0.4.60 → dirsql-0.4.61}/PKG-INFO +1 -1
- {dirsql-0.4.60/packages/rust → dirsql-0.4.61}/docs/reference/config.md +37 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/Cargo.toml +1 -1
- {dirsql-0.4.60 → dirsql-0.4.61/packages/python}/docs/reference/config.md +37 -0
- dirsql-0.4.61/packages/python/e2e-attestations/claude-1201-single-walk.json +7 -0
- dirsql-0.4.61/packages/python/e2e-attestations/claude-1204-embed-batch.json +7 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/Cargo.toml +2 -3
- {dirsql-0.4.60/packages/python → dirsql-0.4.61/packages/rust}/docs/reference/config.md +37 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/config.rs +58 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/db.rs +242 -10
- dirsql-0.4.61/packages/rust/src/functions.rs +1887 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/lib.rs +21 -137
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/parsed_vtab.rs +3 -3
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/scanner.rs +223 -98
- dirsql-0.4.61/packages/rust/src/vtab.rs +708 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/vtab_scaffold.rs +198 -12
- dirsql-0.4.60/packages/rust/src/functions.rs +0 -1040
- dirsql-0.4.60/packages/rust/src/vtab.rs +0 -498
- {dirsql-0.4.60 → dirsql-0.4.61}/Cargo.toml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/README.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/_async.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/py.typed +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/read_config.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/AGENTS.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/explanation.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/getting-started.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/embed.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/persist.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/index.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/package.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/plugins.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/cli.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/README.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/conftest.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/README.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/parsed_cache.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.60 → dirsql-0.4.61}/pyproject.toml +0 -0
|
@@ -552,7 +552,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
|
|
552
552
|
|
|
553
553
|
[[package]]
|
|
554
554
|
name = "dirsql"
|
|
555
|
-
version = "0.4.
|
|
555
|
+
version = "0.4.61"
|
|
556
556
|
dependencies = [
|
|
557
557
|
"assert_cmd",
|
|
558
558
|
"axum",
|
|
@@ -585,7 +585,6 @@ dependencies = [
|
|
|
585
585
|
"tokio-stream",
|
|
586
586
|
"toml",
|
|
587
587
|
"typed-path",
|
|
588
|
-
"walkdir",
|
|
589
588
|
]
|
|
590
589
|
|
|
591
590
|
[[package]]
|
|
@@ -601,7 +600,7 @@ dependencies = [
|
|
|
601
600
|
|
|
602
601
|
[[package]]
|
|
603
602
|
name = "dirsql-py-ext"
|
|
604
|
-
version = "0.4.
|
|
603
|
+
version = "0.4.61"
|
|
605
604
|
dependencies = [
|
|
606
605
|
"dirsql",
|
|
607
606
|
"pyo3",
|
|
@@ -111,6 +111,7 @@ its `embed()` function exactly this way.
|
|
|
111
111
|
| `command` | yes (non-empty) | The worker command. Argv-split with the same no-shell quoting rules as [command hooks](./hooks.md#argv-not-a-shell); runs in the config file's directory. |
|
|
112
112
|
| `deterministic` | no (default `false`) | When `true`, the function is registered with `SQLITE_DETERMINISTIC`, letting SQLite cache and reuse results for identical arguments within a query. Only set it when the worker really is a pure function of its arguments. |
|
|
113
113
|
| `timeout` | no | Per-**call** time bound: a positive integer is whole seconds (`timeout = 600`), a string is an integer suffixed `s` or `ms` (`"600s"`, `"250ms"`). When absent, the function mechanism's own 30-second default applies. |
|
|
114
|
+
| `batch` | no | A positive integer: the most calls one **batched request** carries. When set, a statement's values are gathered and sent to the worker in bulk (see [Batching](#batching)); the worker must then speak the batched protocol shape as well as the single-call one. When absent, the worker only ever sees single calls. |
|
|
114
115
|
|
|
115
116
|
```toml
|
|
116
117
|
[[dirsql.function]]
|
|
@@ -173,6 +174,42 @@ request line in, one response line out, per call:
|
|
|
173
174
|
- **stderr passes through** to `dirsql`'s stderr, so a worker's progress
|
|
174
175
|
bars and download logs reach the terminal.
|
|
175
176
|
|
|
177
|
+
### Batching
|
|
178
|
+
|
|
179
|
+
One round trip per row is the wrong shape for a worker whose cost is
|
|
180
|
+
per-request rather than per-value — an embedding model encodes a list of
|
|
181
|
+
texts in little more time than one. A function declaring `batch = N` is sent
|
|
182
|
+
values in bulk instead:
|
|
183
|
+
|
|
184
|
+
- **Request:** `{"calls": [[<arg>, ...], ...]}` — up to `N` calls, each
|
|
185
|
+
encoded exactly as a single call's argument list.
|
|
186
|
+
- **Response:** `{"results": [<response>, ...]}` — one single-call response
|
|
187
|
+
(`{"ok": ...}` with its optional `"meta"`, or `{"err": ...}`) per call, in
|
|
188
|
+
order. A per-call `{"err": ...}` fails the query the way it would on a
|
|
189
|
+
single call. A top-level `{"err": "message"}` instead fails every call in
|
|
190
|
+
the request.
|
|
191
|
+
- The round trip is bounded by the per-call `timeout` **times the number of
|
|
192
|
+
calls** in the request.
|
|
193
|
+
|
|
194
|
+
A batching worker must still answer `{"call": [...]}`: `dirsql` gathers a
|
|
195
|
+
statement's values by running it twice. The first run makes one ordinary
|
|
196
|
+
round trip for the function's first value, binds that reply in place of every
|
|
197
|
+
later distinct argument tuple, and queues those tuples into batched requests
|
|
198
|
+
of at most `N`; the second run is served from the replies. A statement that
|
|
199
|
+
never calls a batched function runs once, exactly as before. Values are
|
|
200
|
+
deduplicated along the way, so the [progress line](./cli.md#progress-reporting)
|
|
201
|
+
counts distinct calls, whichever request shape carried them.
|
|
202
|
+
|
|
203
|
+
```toml
|
|
204
|
+
[[dirsql.function]]
|
|
205
|
+
name = "embed"
|
|
206
|
+
args = [1, 2]
|
|
207
|
+
command = "dirsql-plugin-embeddings worker"
|
|
208
|
+
deterministic = true
|
|
209
|
+
timeout = "600s"
|
|
210
|
+
batch = 256
|
|
211
|
+
```
|
|
212
|
+
|
|
176
213
|
## `[[table]]`
|
|
177
214
|
|
|
178
215
|
Each entry maps a glob pattern to a SQL table. A table's columns are exactly
|
|
@@ -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.
|
|
7
|
+
version = "0.4.61"
|
|
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
|
|
@@ -111,6 +111,7 @@ its `embed()` function exactly this way.
|
|
|
111
111
|
| `command` | yes (non-empty) | The worker command. Argv-split with the same no-shell quoting rules as [command hooks](./hooks.md#argv-not-a-shell); runs in the config file's directory. |
|
|
112
112
|
| `deterministic` | no (default `false`) | When `true`, the function is registered with `SQLITE_DETERMINISTIC`, letting SQLite cache and reuse results for identical arguments within a query. Only set it when the worker really is a pure function of its arguments. |
|
|
113
113
|
| `timeout` | no | Per-**call** time bound: a positive integer is whole seconds (`timeout = 600`), a string is an integer suffixed `s` or `ms` (`"600s"`, `"250ms"`). When absent, the function mechanism's own 30-second default applies. |
|
|
114
|
+
| `batch` | no | A positive integer: the most calls one **batched request** carries. When set, a statement's values are gathered and sent to the worker in bulk (see [Batching](#batching)); the worker must then speak the batched protocol shape as well as the single-call one. When absent, the worker only ever sees single calls. |
|
|
114
115
|
|
|
115
116
|
```toml
|
|
116
117
|
[[dirsql.function]]
|
|
@@ -173,6 +174,42 @@ request line in, one response line out, per call:
|
|
|
173
174
|
- **stderr passes through** to `dirsql`'s stderr, so a worker's progress
|
|
174
175
|
bars and download logs reach the terminal.
|
|
175
176
|
|
|
177
|
+
### Batching
|
|
178
|
+
|
|
179
|
+
One round trip per row is the wrong shape for a worker whose cost is
|
|
180
|
+
per-request rather than per-value — an embedding model encodes a list of
|
|
181
|
+
texts in little more time than one. A function declaring `batch = N` is sent
|
|
182
|
+
values in bulk instead:
|
|
183
|
+
|
|
184
|
+
- **Request:** `{"calls": [[<arg>, ...], ...]}` — up to `N` calls, each
|
|
185
|
+
encoded exactly as a single call's argument list.
|
|
186
|
+
- **Response:** `{"results": [<response>, ...]}` — one single-call response
|
|
187
|
+
(`{"ok": ...}` with its optional `"meta"`, or `{"err": ...}`) per call, in
|
|
188
|
+
order. A per-call `{"err": ...}` fails the query the way it would on a
|
|
189
|
+
single call. A top-level `{"err": "message"}` instead fails every call in
|
|
190
|
+
the request.
|
|
191
|
+
- The round trip is bounded by the per-call `timeout` **times the number of
|
|
192
|
+
calls** in the request.
|
|
193
|
+
|
|
194
|
+
A batching worker must still answer `{"call": [...]}`: `dirsql` gathers a
|
|
195
|
+
statement's values by running it twice. The first run makes one ordinary
|
|
196
|
+
round trip for the function's first value, binds that reply in place of every
|
|
197
|
+
later distinct argument tuple, and queues those tuples into batched requests
|
|
198
|
+
of at most `N`; the second run is served from the replies. A statement that
|
|
199
|
+
never calls a batched function runs once, exactly as before. Values are
|
|
200
|
+
deduplicated along the way, so the [progress line](./cli.md#progress-reporting)
|
|
201
|
+
counts distinct calls, whichever request shape carried them.
|
|
202
|
+
|
|
203
|
+
```toml
|
|
204
|
+
[[dirsql.function]]
|
|
205
|
+
name = "embed"
|
|
206
|
+
args = [1, 2]
|
|
207
|
+
command = "dirsql-plugin-embeddings worker"
|
|
208
|
+
deterministic = true
|
|
209
|
+
timeout = "600s"
|
|
210
|
+
batch = 256
|
|
211
|
+
```
|
|
212
|
+
|
|
176
213
|
## `[[table]]`
|
|
177
214
|
|
|
178
215
|
Each entry maps a glob pattern to a SQL table. A table's columns are exactly
|
|
@@ -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.
|
|
9
|
+
version = "0.4.61"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -69,7 +69,7 @@ globset = "0.4"
|
|
|
69
69
|
# library consumer never pulls it.
|
|
70
70
|
hex = { version = "0.4", optional = true }
|
|
71
71
|
# Hierarchical `.gitignore` matching for path-table scans (the fd/ripgrep
|
|
72
|
-
# semantics), without adopting its walker: the scan
|
|
72
|
+
# semantics), without adopting its walker: the scan has its own.
|
|
73
73
|
ignore = "0.4"
|
|
74
74
|
indicatif = "0.18.6"
|
|
75
75
|
notify = "7"
|
|
@@ -87,7 +87,6 @@ tokio.workspace = true
|
|
|
87
87
|
tokio-stream = { version = "0.1", features = ["sync"], optional = true }
|
|
88
88
|
toml = "0.8"
|
|
89
89
|
typed-path = "0.12"
|
|
90
|
-
walkdir = "2"
|
|
91
90
|
|
|
92
91
|
[lints.rust]
|
|
93
92
|
# `deny`, not `forbid`: rusqlite's API imposes five unavoidable `unsafe`
|
|
@@ -111,6 +111,7 @@ its `embed()` function exactly this way.
|
|
|
111
111
|
| `command` | yes (non-empty) | The worker command. Argv-split with the same no-shell quoting rules as [command hooks](./hooks.md#argv-not-a-shell); runs in the config file's directory. |
|
|
112
112
|
| `deterministic` | no (default `false`) | When `true`, the function is registered with `SQLITE_DETERMINISTIC`, letting SQLite cache and reuse results for identical arguments within a query. Only set it when the worker really is a pure function of its arguments. |
|
|
113
113
|
| `timeout` | no | Per-**call** time bound: a positive integer is whole seconds (`timeout = 600`), a string is an integer suffixed `s` or `ms` (`"600s"`, `"250ms"`). When absent, the function mechanism's own 30-second default applies. |
|
|
114
|
+
| `batch` | no | A positive integer: the most calls one **batched request** carries. When set, a statement's values are gathered and sent to the worker in bulk (see [Batching](#batching)); the worker must then speak the batched protocol shape as well as the single-call one. When absent, the worker only ever sees single calls. |
|
|
114
115
|
|
|
115
116
|
```toml
|
|
116
117
|
[[dirsql.function]]
|
|
@@ -173,6 +174,42 @@ request line in, one response line out, per call:
|
|
|
173
174
|
- **stderr passes through** to `dirsql`'s stderr, so a worker's progress
|
|
174
175
|
bars and download logs reach the terminal.
|
|
175
176
|
|
|
177
|
+
### Batching
|
|
178
|
+
|
|
179
|
+
One round trip per row is the wrong shape for a worker whose cost is
|
|
180
|
+
per-request rather than per-value — an embedding model encodes a list of
|
|
181
|
+
texts in little more time than one. A function declaring `batch = N` is sent
|
|
182
|
+
values in bulk instead:
|
|
183
|
+
|
|
184
|
+
- **Request:** `{"calls": [[<arg>, ...], ...]}` — up to `N` calls, each
|
|
185
|
+
encoded exactly as a single call's argument list.
|
|
186
|
+
- **Response:** `{"results": [<response>, ...]}` — one single-call response
|
|
187
|
+
(`{"ok": ...}` with its optional `"meta"`, or `{"err": ...}`) per call, in
|
|
188
|
+
order. A per-call `{"err": ...}` fails the query the way it would on a
|
|
189
|
+
single call. A top-level `{"err": "message"}` instead fails every call in
|
|
190
|
+
the request.
|
|
191
|
+
- The round trip is bounded by the per-call `timeout` **times the number of
|
|
192
|
+
calls** in the request.
|
|
193
|
+
|
|
194
|
+
A batching worker must still answer `{"call": [...]}`: `dirsql` gathers a
|
|
195
|
+
statement's values by running it twice. The first run makes one ordinary
|
|
196
|
+
round trip for the function's first value, binds that reply in place of every
|
|
197
|
+
later distinct argument tuple, and queues those tuples into batched requests
|
|
198
|
+
of at most `N`; the second run is served from the replies. A statement that
|
|
199
|
+
never calls a batched function runs once, exactly as before. Values are
|
|
200
|
+
deduplicated along the way, so the [progress line](./cli.md#progress-reporting)
|
|
201
|
+
counts distinct calls, whichever request shape carried them.
|
|
202
|
+
|
|
203
|
+
```toml
|
|
204
|
+
[[dirsql.function]]
|
|
205
|
+
name = "embed"
|
|
206
|
+
args = [1, 2]
|
|
207
|
+
command = "dirsql-plugin-embeddings worker"
|
|
208
|
+
deterministic = true
|
|
209
|
+
timeout = "600s"
|
|
210
|
+
batch = 256
|
|
211
|
+
```
|
|
212
|
+
|
|
176
213
|
## `[[table]]`
|
|
177
214
|
|
|
178
215
|
Each entry maps a glob pattern to a SQL table. A table's columns are exactly
|
|
@@ -45,6 +45,9 @@ pub enum ConfigError {
|
|
|
45
45
|
)]
|
|
46
46
|
InvalidFunctionTimeout { name: String, value: String },
|
|
47
47
|
|
|
48
|
+
#[error("[[dirsql.function]] '{name}': 'batch' must be a positive integer, got {value}")]
|
|
49
|
+
InvalidFunctionBatch { name: String, value: String },
|
|
50
|
+
|
|
48
51
|
#[error("Field '{0}' must not be empty")]
|
|
49
52
|
EmptyField(&'static str),
|
|
50
53
|
|
|
@@ -212,6 +215,11 @@ pub struct FunctionSpec {
|
|
|
212
215
|
/// Optional per-round-trip-call timeout, overriding the function
|
|
213
216
|
/// mechanism's own 30-second default.
|
|
214
217
|
pub timeout: Option<Duration>,
|
|
218
|
+
/// Optional cap on the calls one batched request carries. When set, a
|
|
219
|
+
/// statement's values are sent to the worker in bulk (see
|
|
220
|
+
/// `dirsql::functions`); when absent the worker only ever sees single
|
|
221
|
+
/// calls.
|
|
222
|
+
pub batch: Option<usize>,
|
|
215
223
|
}
|
|
216
224
|
|
|
217
225
|
/// Configuration for a single table.
|
|
@@ -267,6 +275,9 @@ struct RawFunction {
|
|
|
267
275
|
command: Option<String>,
|
|
268
276
|
deterministic: Option<bool>,
|
|
269
277
|
timeout: Option<RawFunctionTimeout>,
|
|
278
|
+
// Any shape, so a non-integer hits the same actionable error as a
|
|
279
|
+
// non-positive one.
|
|
280
|
+
batch: Option<toml::Value>,
|
|
270
281
|
}
|
|
271
282
|
|
|
272
283
|
/// The `timeout` key accepts positive whole seconds (`timeout = 600`) or a
|
|
@@ -417,12 +428,27 @@ fn parse_function(raw: RawFunction) -> Result<FunctionSpec> {
|
|
|
417
428
|
Some(raw_timeout) => Some(parse_function_timeout(&name, &raw_timeout)?),
|
|
418
429
|
};
|
|
419
430
|
|
|
431
|
+
let batch = match raw.batch {
|
|
432
|
+
None => None,
|
|
433
|
+
Some(value) => Some(
|
|
434
|
+
value
|
|
435
|
+
.as_integer()
|
|
436
|
+
.and_then(|n| usize::try_from(n).ok())
|
|
437
|
+
.filter(|n| *n > 0)
|
|
438
|
+
.ok_or_else(|| ConfigError::InvalidFunctionBatch {
|
|
439
|
+
name: name.clone(),
|
|
440
|
+
value: value.to_string(),
|
|
441
|
+
})?,
|
|
442
|
+
),
|
|
443
|
+
};
|
|
444
|
+
|
|
420
445
|
Ok(FunctionSpec {
|
|
421
446
|
name,
|
|
422
447
|
args,
|
|
423
448
|
command,
|
|
424
449
|
deterministic: raw.deterministic.unwrap_or(false),
|
|
425
450
|
timeout,
|
|
451
|
+
batch,
|
|
426
452
|
})
|
|
427
453
|
}
|
|
428
454
|
|
|
@@ -1162,6 +1188,7 @@ args = [1, 2]
|
|
|
1162
1188
|
command = "dirsql-plugin-embeddings worker"
|
|
1163
1189
|
deterministic = true
|
|
1164
1190
|
timeout = "600s"
|
|
1191
|
+
batch = 64
|
|
1165
1192
|
"#;
|
|
1166
1193
|
let config = load_config_str(toml).unwrap();
|
|
1167
1194
|
assert_eq!(
|
|
@@ -1172,6 +1199,7 @@ timeout = "600s"
|
|
|
1172
1199
|
command: "dirsql-plugin-embeddings worker".to_string(),
|
|
1173
1200
|
deterministic: true,
|
|
1174
1201
|
timeout: Some(Duration::from_secs(600)),
|
|
1202
|
+
batch: Some(64),
|
|
1175
1203
|
}]
|
|
1176
1204
|
);
|
|
1177
1205
|
}
|
|
@@ -1187,6 +1215,36 @@ command = "worker"
|
|
|
1187
1215
|
let config = load_config_str(toml).unwrap();
|
|
1188
1216
|
assert!(!config.functions[0].deterministic);
|
|
1189
1217
|
assert!(config.functions[0].timeout.is_none());
|
|
1218
|
+
assert!(config.functions[0].batch.is_none());
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/// `batch = 0` would send empty requests, a negative cap means nothing,
|
|
1222
|
+
/// and a string is not a count; each is the one actionable error.
|
|
1223
|
+
#[test]
|
|
1224
|
+
fn function_batch_rejects_anything_but_a_positive_integer() {
|
|
1225
|
+
for value in ["0", "-4", "\"many\"", "2.5"] {
|
|
1226
|
+
let toml = format!(
|
|
1227
|
+
r#"
|
|
1228
|
+
[[dirsql.function]]
|
|
1229
|
+
name = "f"
|
|
1230
|
+
args = [1]
|
|
1231
|
+
command = "worker"
|
|
1232
|
+
batch = {value}
|
|
1233
|
+
"#
|
|
1234
|
+
);
|
|
1235
|
+
let err = load_config_str(&toml).unwrap_err();
|
|
1236
|
+
match &err {
|
|
1237
|
+
ConfigError::InvalidFunctionBatch { name, value: got } => {
|
|
1238
|
+
assert_eq!(name, "f");
|
|
1239
|
+
assert_eq!(got, value);
|
|
1240
|
+
}
|
|
1241
|
+
other => panic!("batch = {value}: expected InvalidFunctionBatch, got {other:?}"),
|
|
1242
|
+
}
|
|
1243
|
+
assert_eq!(
|
|
1244
|
+
err.to_string(),
|
|
1245
|
+
format!("[[dirsql.function]] 'f': 'batch' must be a positive integer, got {value}")
|
|
1246
|
+
);
|
|
1247
|
+
}
|
|
1190
1248
|
}
|
|
1191
1249
|
|
|
1192
1250
|
#[test]
|