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.
- {dirsql-0.4.33 → dirsql-0.4.34}/Cargo.lock +2 -2
- {dirsql-0.4.33 → dirsql-0.4.34}/PKG-INFO +1 -1
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/cli.md +18 -0
- {dirsql-0.4.33/packages/rust → dirsql-0.4.34}/docs/reference/config.md +5 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/sdk.md +4 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/Cargo.toml +1 -1
- {dirsql-0.4.33/packages/rust → dirsql-0.4.34/packages/python}/docs/reference/cli.md +18 -0
- {dirsql-0.4.33 → dirsql-0.4.34/packages/python}/docs/reference/config.md +5 -0
- {dirsql-0.4.33/packages/rust → dirsql-0.4.34/packages/python}/docs/reference/sdk.md +4 -0
- dirsql-0.4.34/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +7 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/Cargo.toml +1 -1
- {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/cli.md +18 -0
- {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/config.md +5 -0
- {dirsql-0.4.33/packages/python → dirsql-0.4.34/packages/rust}/docs/reference/sdk.md +4 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/db.rs +20 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/functions.rs +191 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/lib.rs +2 -1
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/progress.rs +153 -25
- {dirsql-0.4.33 → dirsql-0.4.34}/Cargo.toml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/README.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/_async.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/py.typed +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/AGENTS.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/explanation.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/getting-started.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/embed.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/persist.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/index.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/package.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/plugins.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/README.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/conftest.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/README.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/parsed_cache.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.33 → dirsql-0.4.34}/packages/rust/src/watcher.rs +0 -0
- {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.
|
|
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.
|
|
586
|
+
version = "0.4.34"
|
|
587
587
|
dependencies = [
|
|
588
588
|
"dirsql",
|
|
589
589
|
"pyo3",
|
|
@@ -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.
|
|
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
|
|
@@ -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.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
|
|
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
|