dirsql 0.3.125__tar.gz → 0.3.126__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.3.125 → dirsql-0.3.126}/Cargo.lock +1 -1
- {dirsql-0.3.125 → dirsql-0.3.126}/PKG-INFO +1 -1
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/Cargo.toml +1 -1
- dirsql-0.3.126/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +3 -0
- dirsql-0.3.126/packages/python/e2e-attestations/feat-634-slice4-hookless-error.json +7 -0
- dirsql-0.3.126/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +51 -0
- dirsql-0.3.126/packages/rust/changelog.d/2026-07-24-hookless-table-config-error.md +3 -0
- dirsql-0.3.126/packages/rust/migrations.d/2026-07-24-hookless-table-config-error.md +51 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/config.rs +78 -26
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/lib.rs +20 -25
- dirsql-0.3.125/packages/python/e2e-attestations/feat-634-core-remove-injection.json +0 -7
- {dirsql-0.3.125 → dirsql-0.3.126}/Cargo.toml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/_async.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/main.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/py.typed +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/AGENTS.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/explanation.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/getting-started.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/embed.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/persist.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/index.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/migrations.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/package.json +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/cli.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/hooks.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/http-api.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/path-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/docs/reference/sdk.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/conftest.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/index.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/package.json +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/Cargo.toml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-persist-wal.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-20-schema-inference.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-21-on-file-flag.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-23-init-escalation-example.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-23-query-default-cli.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/changelog.d/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/index.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-persist-wal.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-23-init-escalation-example.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-23-query-default-cli.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/migrations.d/README.md +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/command.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/db.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.125 → dirsql-0.3.126}/pyproject.toml +0 -0
|
@@ -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.3.
|
|
7
|
+
version = "0.3.126"
|
|
8
8
|
# abi3 note: the `abi3-py311` pyo3 feature (below) builds ONE stable-ABI
|
|
9
9
|
# `cp311-abi3` wheel per platform that loads on every CPython >= 3.11
|
|
10
10
|
# (matching `pyproject.toml`'s `requires-python = ">=3.11"`), instead of
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
**Changed**
|
|
2
|
+
|
|
3
|
+
- **A `[[table]]` with no `on-file` hook is now a config-load error.** After the stat-fact injection layer was removed, a hook-less named table emitted no columns of its own, so every row was all-NULL. Loading such a config (`DirSQL(config=…)` / `.ready()`) now raises, with a message pointing at the fix: add an `on-file` hook that emits the columns, or, for stat columns with no code, query the path directly with a path-table (`FROM './'`). This completes the fact-removal epic (#624). (#634)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
### Hook-less `[[table]]` is now a config error (#634)
|
|
2
|
+
|
|
3
|
+
#### Summary
|
|
4
|
+
|
|
5
|
+
A `[[table]]` with no `on-file` hook previously loaded fine and — after the
|
|
6
|
+
stat-fact injection layer was removed — produced rows that were all-NULL.
|
|
7
|
+
Loading such a config through the Python SDK (`DirSQL(config=…)`, awaited via
|
|
8
|
+
`.ready()`) now raises. No API signature changes — this is a load-time
|
|
9
|
+
validation change surfaced from the core.
|
|
10
|
+
|
|
11
|
+
#### Required changes
|
|
12
|
+
|
|
13
|
+
| Before (loaded, all-NULL rows) | After (raises) | Fix |
|
|
14
|
+
| ------------------------------ | -------------- | --- |
|
|
15
|
+
| `.dirsql.toml` `[[table]]` with `ddl` + `glob` but no `on-file` | `.ready()` raises `[[table]] '<glob>' has no on-file hook …` | Add an `on-file` hook that emits the declared columns. |
|
|
16
|
+
| You only wanted stat columns and wrote no hook code | `.ready()` raises | Drop the `[[table]]` and query the path directly: `SELECT path, size, mtime FROM './'` (globbable: `FROM './**/*.md'`). |
|
|
17
|
+
|
|
18
|
+
#### Deprecations removed
|
|
19
|
+
|
|
20
|
+
_None._
|
|
21
|
+
|
|
22
|
+
#### Behavior changes without code changes
|
|
23
|
+
|
|
24
|
+
- A `[[table]]` with no `on-file` hook, which used to load (and, after injection
|
|
25
|
+
removal, yield all-NULL rows), now raises at config load, with an error naming
|
|
26
|
+
the offending glob and pointing at the `FROM './'` path-table replacement.
|
|
27
|
+
|
|
28
|
+
#### Verification
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import asyncio
|
|
32
|
+
from dirsql import DirSQL
|
|
33
|
+
|
|
34
|
+
# .dirsql.toml with a hook-less table:
|
|
35
|
+
# [[table]]
|
|
36
|
+
# ddl = "CREATE TABLE files (path TEXT, size INTEGER)"
|
|
37
|
+
# glob = "**/*.md"
|
|
38
|
+
|
|
39
|
+
db = DirSQL(config=".dirsql.toml")
|
|
40
|
+
# Before this change: await db.ready() succeeded; SELECT * FROM files -> all-NULL rows.
|
|
41
|
+
# After this change:
|
|
42
|
+
try:
|
|
43
|
+
asyncio.run(db.ready())
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(e) # -> ... has no on-file hook ... query the path directly: `FROM './'`
|
|
46
|
+
|
|
47
|
+
# Replacement with no hook code — query the path directly (no config):
|
|
48
|
+
db2 = DirSQL(root=".")
|
|
49
|
+
asyncio.run(db2.ready())
|
|
50
|
+
print(asyncio.run(db2.query("SELECT path, size FROM './**/*.md'")))
|
|
51
|
+
```
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
**Changed**
|
|
2
|
+
|
|
3
|
+
- **A `[[table]]` with no `on-file` hook is now a load error.** After the stat-fact injection layer was removed, a hook-less named table emitted no columns of its own, so every row was all-NULL — useless and surprising. `load_config_str` (and every path that loads a config, including `DirSQL::from_config_path` and the CLI's `-c`) now rejects such a table with a message pointing at the fix: add an `on-file` hook that emits the columns, or, for stat columns with no code, query the path directly with a path-table (`FROM './'`). This completes the fact-removal epic (#624). (#634)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
### Hook-less `[[table]]` is now a config error (#634)
|
|
2
|
+
|
|
3
|
+
#### Summary
|
|
4
|
+
|
|
5
|
+
A `[[table]]` (or SDK-registered table) with no `on-file` hook previously
|
|
6
|
+
loaded fine and — after the stat-fact injection layer was removed — produced
|
|
7
|
+
rows that were all-NULL. dirsql now rejects a hook-less table at config load
|
|
8
|
+
(`ConfigError::HooklessTable`), so the failure is loud and actionable instead
|
|
9
|
+
of a silently useless table. No API signature changes — this is a
|
|
10
|
+
load-time validation change. `TableConfig.on_file` is now `String` (was
|
|
11
|
+
`Option<String>`) since a parsed table always carries a hook.
|
|
12
|
+
|
|
13
|
+
#### Required changes
|
|
14
|
+
|
|
15
|
+
| Before (loaded, all-NULL rows) | After (load error) | Fix |
|
|
16
|
+
| ------------------------------ | ------------------ | --- |
|
|
17
|
+
| `[[table]]` declares `ddl` + `glob` but no `on-file` | Load fails: `[[table]] '<glob>' has no on-file hook …` | Add an `on-file` hook that emits the declared columns, e.g. `on-file = 'rel=${1#"$2"/}; jq -n --arg path "$rel" '\''[{path:$path}]'\'''`. |
|
|
18
|
+
| You only wanted stat columns and wrote no hook code | Load fails | Drop the `[[table]]` and query the path directly with a path-table: `SELECT path, size, mtime FROM './'` (globbable: `FROM './**/*.md'`). |
|
|
19
|
+
|
|
20
|
+
#### Deprecations removed
|
|
21
|
+
|
|
22
|
+
_None._
|
|
23
|
+
|
|
24
|
+
#### Behavior changes without code changes
|
|
25
|
+
|
|
26
|
+
- A `[[table]]` with no `on-file` hook, which used to load (and, after injection
|
|
27
|
+
removal, yield all-NULL rows), now fails at config load with an error naming
|
|
28
|
+
the offending glob and pointing at the `FROM './'` path-table replacement.
|
|
29
|
+
|
|
30
|
+
#### Verification
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# .dirsql.toml with a hook-less table:
|
|
34
|
+
# [[table]]
|
|
35
|
+
# ddl = "CREATE TABLE files (path TEXT, size INTEGER)"
|
|
36
|
+
# glob = "**/*.md"
|
|
37
|
+
|
|
38
|
+
# Before this change:
|
|
39
|
+
dirsql query "SELECT * FROM files" -c ./.dirsql.toml
|
|
40
|
+
# -> [] or all-NULL rows (loaded, but useless)
|
|
41
|
+
|
|
42
|
+
# After this change:
|
|
43
|
+
dirsql query "SELECT * FROM files" -c ./.dirsql.toml
|
|
44
|
+
# -> error: [[table]] '**/*.md' has no on-file hook, so every row would be
|
|
45
|
+
# all-NULL. Add an `on-file` hook that emits the columns, or, for stat
|
|
46
|
+
# columns with no code, query the path directly: `FROM './'`
|
|
47
|
+
|
|
48
|
+
# Replacement with no hook code — query the path directly:
|
|
49
|
+
dirsql query "SELECT path, size FROM './**/*.md'"
|
|
50
|
+
# -> rows with real path/size, no config needed
|
|
51
|
+
```
|
|
@@ -21,6 +21,13 @@ pub enum ConfigError {
|
|
|
21
21
|
#[error("Field '{0}' must not be empty")]
|
|
22
22
|
EmptyField(&'static str),
|
|
23
23
|
|
|
24
|
+
#[error(
|
|
25
|
+
"[[table]] '{glob}' has no on-file hook, so every row would be all-NULL. \
|
|
26
|
+
Add an `on-file` hook that emits the columns, or, for stat columns with \
|
|
27
|
+
no code, query the path directly: `FROM './'`"
|
|
28
|
+
)]
|
|
29
|
+
HooklessTable { glob: String },
|
|
30
|
+
|
|
24
31
|
#[error("Field '{field}' must be a positive number of seconds, got {value}")]
|
|
25
32
|
InvalidTimeout { field: &'static str, value: i64 },
|
|
26
33
|
|
|
@@ -221,11 +228,12 @@ pub struct TableConfig {
|
|
|
221
228
|
pub ddl: String,
|
|
222
229
|
pub glob: String,
|
|
223
230
|
pub strict: Option<bool>,
|
|
224
|
-
///
|
|
225
|
-
///
|
|
226
|
-
///
|
|
227
|
-
/// row. See `dirsql::command`
|
|
228
|
-
|
|
231
|
+
/// The required per-file command (`on-file`). Each matched file's rows come
|
|
232
|
+
/// from running this command, which reads the file and prints a JSON array
|
|
233
|
+
/// of row objects. A table without it would emit no columns of its own —
|
|
234
|
+
/// every row all-NULL — so it is rejected at load. See `dirsql::command`
|
|
235
|
+
/// for the execution contract.
|
|
236
|
+
pub on_file: String,
|
|
229
237
|
}
|
|
230
238
|
|
|
231
239
|
#[derive(Deserialize)]
|
|
@@ -323,7 +331,8 @@ pub fn load_config_str(content: &str) -> Result<Config> {
|
|
|
323
331
|
Some(cmd) if cmd.trim().is_empty() => {
|
|
324
332
|
return Err(ConfigError::EmptyField("on-file"));
|
|
325
333
|
}
|
|
326
|
-
|
|
334
|
+
Some(cmd) => cmd,
|
|
335
|
+
None => return Err(ConfigError::HooklessTable { glob }),
|
|
327
336
|
};
|
|
328
337
|
|
|
329
338
|
tables.push(TableConfig {
|
|
@@ -367,10 +376,12 @@ ignore = ["node_modules/**", ".git/**"]
|
|
|
367
376
|
[[table]]
|
|
368
377
|
ddl = "CREATE TABLE comments (thread_id TEXT, path TEXT)"
|
|
369
378
|
glob = "_comments/{thread_id}/index.jsonl"
|
|
379
|
+
on-file = "cat {path}"
|
|
370
380
|
|
|
371
381
|
[[table]]
|
|
372
382
|
ddl = "CREATE TABLE items (path TEXT, size INTEGER)"
|
|
373
383
|
glob = "catalog/*.json"
|
|
384
|
+
on-file = "cat {path}"
|
|
374
385
|
strict = true
|
|
375
386
|
"#;
|
|
376
387
|
let config = load_config_str(toml).unwrap();
|
|
@@ -391,6 +402,7 @@ strict = true
|
|
|
391
402
|
let toml = r#"
|
|
392
403
|
[[table]]
|
|
393
404
|
glob = "*.json"
|
|
405
|
+
on-file = "cat {path}"
|
|
394
406
|
"#;
|
|
395
407
|
let err = load_config_str(toml).unwrap_err();
|
|
396
408
|
assert!(err.to_string().contains("ddl"));
|
|
@@ -438,6 +450,7 @@ ignore = ["*.tmp"]
|
|
|
438
450
|
[[table]]
|
|
439
451
|
ddl = "CREATE TABLE t (x TEXT)"
|
|
440
452
|
glob = "*.json"
|
|
453
|
+
on-file = "cat {path}"
|
|
441
454
|
"#;
|
|
442
455
|
let config = load_config_str(toml).unwrap();
|
|
443
456
|
assert!(config.ignore.is_empty());
|
|
@@ -478,14 +491,17 @@ persist_path = "/var/cache/dirsql.db"
|
|
|
478
491
|
[[table]]
|
|
479
492
|
ddl = "CREATE TABLE a (path TEXT)"
|
|
480
493
|
glob = "a/*.json"
|
|
494
|
+
on-file = "cat {path}"
|
|
481
495
|
|
|
482
496
|
[[table]]
|
|
483
497
|
ddl = "CREATE TABLE b (path TEXT)"
|
|
484
498
|
glob = "b/*.csv"
|
|
499
|
+
on-file = "cat {path}"
|
|
485
500
|
|
|
486
501
|
[[table]]
|
|
487
502
|
ddl = "CREATE TABLE c (path TEXT)"
|
|
488
503
|
glob = "c/*.yaml"
|
|
504
|
+
on-file = "cat {path}"
|
|
489
505
|
"#;
|
|
490
506
|
let config = load_config_str(toml).unwrap();
|
|
491
507
|
assert_eq!(config.tables.len(), 3);
|
|
@@ -502,6 +518,7 @@ glob = "c/*.yaml"
|
|
|
502
518
|
[[table]]
|
|
503
519
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
504
520
|
glob = "*.json"
|
|
521
|
+
on-file = "cat {path}"
|
|
505
522
|
format = "json"
|
|
506
523
|
"#;
|
|
507
524
|
let err = load_config_str(toml).unwrap_err();
|
|
@@ -568,6 +585,7 @@ entrypoint = "sqlite3_vec_init"
|
|
|
568
585
|
[[table]]
|
|
569
586
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
570
587
|
glob = "*.json"
|
|
588
|
+
on-file = "cat {path}"
|
|
571
589
|
"#;
|
|
572
590
|
let config = load_config_str(toml).unwrap();
|
|
573
591
|
assert_eq!(config.extensions.len(), 1);
|
|
@@ -608,6 +626,7 @@ entrypoint = "sqlite3_x_init"
|
|
|
608
626
|
[[table]]
|
|
609
627
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
610
628
|
glob = "*.json"
|
|
629
|
+
on-file = "cat {path}"
|
|
611
630
|
"#;
|
|
612
631
|
let config = load_config_str(toml).unwrap();
|
|
613
632
|
assert!(config.extensions.is_empty());
|
|
@@ -639,20 +658,26 @@ on-file = "uv run python extract_papers.py {path}"
|
|
|
639
658
|
let config = load_config_str(toml).unwrap();
|
|
640
659
|
assert_eq!(config.tables.len(), 1);
|
|
641
660
|
assert_eq!(
|
|
642
|
-
config.tables[0].on_file
|
|
643
|
-
|
|
661
|
+
config.tables[0].on_file,
|
|
662
|
+
"uv run python extract_papers.py {path}"
|
|
644
663
|
);
|
|
645
664
|
}
|
|
646
665
|
|
|
647
666
|
#[test]
|
|
648
|
-
fn
|
|
667
|
+
fn on_file_absent_is_a_hookless_load_error() {
|
|
649
668
|
let toml = r#"
|
|
650
669
|
[[table]]
|
|
651
670
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
652
671
|
glob = "*.json"
|
|
653
672
|
"#;
|
|
654
|
-
let
|
|
655
|
-
assert!(
|
|
673
|
+
let err = load_config_str(toml).unwrap_err();
|
|
674
|
+
assert!(
|
|
675
|
+
matches!(&err, ConfigError::HooklessTable { glob } if glob == "*.json"),
|
|
676
|
+
"got: {err:?}"
|
|
677
|
+
);
|
|
678
|
+
let msg = err.to_string();
|
|
679
|
+
assert!(msg.contains("on-file"), "got: {msg}");
|
|
680
|
+
assert!(msg.contains("FROM './'"), "got: {msg}");
|
|
656
681
|
}
|
|
657
682
|
|
|
658
683
|
#[test]
|
|
@@ -679,6 +704,7 @@ pre-query = "uv run python to_sql.py {args}"
|
|
|
679
704
|
[[table]]
|
|
680
705
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
681
706
|
glob = "*.json"
|
|
707
|
+
on-file = "cat {path}"
|
|
682
708
|
"#;
|
|
683
709
|
let config = load_config_str(toml).unwrap();
|
|
684
710
|
assert_eq!(
|
|
@@ -693,6 +719,7 @@ glob = "*.json"
|
|
|
693
719
|
[[table]]
|
|
694
720
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
695
721
|
glob = "*.json"
|
|
722
|
+
on-file = "cat {path}"
|
|
696
723
|
"#;
|
|
697
724
|
let config = load_config_str(toml).unwrap();
|
|
698
725
|
assert!(config.pre_query.is_none());
|
|
@@ -720,6 +747,7 @@ post-query = "jq '{results: .}'"
|
|
|
720
747
|
[[table]]
|
|
721
748
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
722
749
|
glob = "*.json"
|
|
750
|
+
on-file = "cat {path}"
|
|
723
751
|
"#;
|
|
724
752
|
let config = load_config_str(toml).unwrap();
|
|
725
753
|
assert_eq!(config.post_query.as_deref(), Some("jq '{results: .}'"));
|
|
@@ -731,6 +759,7 @@ glob = "*.json"
|
|
|
731
759
|
[[table]]
|
|
732
760
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
733
761
|
glob = "*.json"
|
|
762
|
+
on-file = "cat {path}"
|
|
734
763
|
"#;
|
|
735
764
|
let config = load_config_str(toml).unwrap();
|
|
736
765
|
assert!(config.post_query.is_none());
|
|
@@ -778,6 +807,7 @@ entrypoint = "sqlite3_vec_init"
|
|
|
778
807
|
[[table]]
|
|
779
808
|
ddl = "CREATE TABLE t (path TEXT)"
|
|
780
809
|
glob = "*.json"
|
|
810
|
+
on-file = "cat {path}"
|
|
781
811
|
"#);
|
|
782
812
|
let merged = combine_configs(&[(src("/proj/.dirsql.toml"), config.clone())]).unwrap();
|
|
783
813
|
assert_eq!(merged.ignore, config.ignore);
|
|
@@ -795,15 +825,18 @@ glob = "*.json"
|
|
|
795
825
|
[[table]]
|
|
796
826
|
ddl = "CREATE TABLE a (path TEXT)"
|
|
797
827
|
glob = "a/*.json"
|
|
828
|
+
on-file = "cat {path}"
|
|
798
829
|
|
|
799
830
|
[[table]]
|
|
800
831
|
ddl = "CREATE TABLE b (path TEXT)"
|
|
801
832
|
glob = "b/*.json"
|
|
833
|
+
on-file = "cat {path}"
|
|
802
834
|
"#);
|
|
803
835
|
let b = cfg(r#"
|
|
804
836
|
[[table]]
|
|
805
837
|
ddl = "CREATE TABLE c (path TEXT)"
|
|
806
838
|
glob = "c/*.json"
|
|
839
|
+
on-file = "cat {path}"
|
|
807
840
|
"#);
|
|
808
841
|
let merged = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap();
|
|
809
842
|
let ddls: Vec<&str> = merged.tables.iter().map(|t| t.ddl.as_str()).collect();
|
|
@@ -848,8 +881,12 @@ glob = "c/*.json"
|
|
|
848
881
|
|
|
849
882
|
#[test]
|
|
850
883
|
fn combine_duplicate_table_name_errors_naming_both_sources() {
|
|
851
|
-
let a = cfg(
|
|
852
|
-
|
|
884
|
+
let a = cfg(
|
|
885
|
+
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
886
|
+
);
|
|
887
|
+
let b = cfg(
|
|
888
|
+
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
889
|
+
);
|
|
853
890
|
let err = combine_configs(&[
|
|
854
891
|
(src("/proj/.dirsql.toml"), a),
|
|
855
892
|
(src("/plugin/frag.toml"), b),
|
|
@@ -878,8 +915,8 @@ glob = "c/*.json"
|
|
|
878
915
|
// The single-entry identity path runs no collision check, exactly like
|
|
879
916
|
// a plain single-config load.
|
|
880
917
|
let config = cfg(concat!(
|
|
881
|
-
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\n",
|
|
882
|
-
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\n",
|
|
918
|
+
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
919
|
+
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
883
920
|
));
|
|
884
921
|
let merged = combine_configs(&[(src("/a"), config)]).unwrap();
|
|
885
922
|
assert_eq!(merged.tables.len(), 2);
|
|
@@ -888,8 +925,8 @@ glob = "c/*.json"
|
|
|
888
925
|
#[test]
|
|
889
926
|
fn combine_intra_config_duplicate_in_multi_merge_errors() {
|
|
890
927
|
let a = cfg(concat!(
|
|
891
|
-
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\n",
|
|
892
|
-
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\n",
|
|
928
|
+
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
929
|
+
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
893
930
|
));
|
|
894
931
|
let b = cfg("[dirsql]\nignore = [\"c/**\"]\n");
|
|
895
932
|
let err = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap_err();
|
|
@@ -909,8 +946,12 @@ glob = "c/*.json"
|
|
|
909
946
|
|
|
910
947
|
#[test]
|
|
911
948
|
fn combine_duplicate_table_name_detected_through_quoting() {
|
|
912
|
-
let a = cfg(
|
|
913
|
-
|
|
949
|
+
let a = cfg(
|
|
950
|
+
"[[table]]\nddl = 'CREATE TABLE \"t\" (x TEXT)'\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
951
|
+
);
|
|
952
|
+
let b = cfg(
|
|
953
|
+
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
954
|
+
);
|
|
914
955
|
let err = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap_err();
|
|
915
956
|
assert!(
|
|
916
957
|
matches!(&err, ConfigError::DuplicateTable { name, .. } if name == "t"),
|
|
@@ -920,8 +961,12 @@ glob = "c/*.json"
|
|
|
920
961
|
|
|
921
962
|
#[test]
|
|
922
963
|
fn combine_unparseable_ddl_concatenates_without_collision_check() {
|
|
923
|
-
let a = cfg(
|
|
924
|
-
|
|
964
|
+
let a = cfg(
|
|
965
|
+
"[[table]]\nddl = \"not a create table\"\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
966
|
+
);
|
|
967
|
+
let b = cfg(
|
|
968
|
+
"[[table]]\nddl = \"also not a create table\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
969
|
+
);
|
|
925
970
|
let merged = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap();
|
|
926
971
|
assert_eq!(merged.tables.len(), 2);
|
|
927
972
|
}
|
|
@@ -967,8 +1012,12 @@ glob = "c/*.json"
|
|
|
967
1012
|
|
|
968
1013
|
#[test]
|
|
969
1014
|
fn combine_error_display_includes_package_source_verbatim() {
|
|
970
|
-
let a = cfg(
|
|
971
|
-
|
|
1015
|
+
let a = cfg(
|
|
1016
|
+
"[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\non-file = \"cat {path}\"\n",
|
|
1017
|
+
);
|
|
1018
|
+
let b = cfg(
|
|
1019
|
+
"[[table]]\nddl = \"CREATE TABLE t (y TEXT)\"\nglob = \"b/*.json\"\non-file = \"cat {path}\"\n",
|
|
1020
|
+
);
|
|
972
1021
|
let err = combine_configs(&[
|
|
973
1022
|
(src("/proj/.dirsql.toml"), a),
|
|
974
1023
|
(Source::Package("dirsql-plugin-notes".to_string()), b),
|
|
@@ -982,11 +1031,13 @@ glob = "c/*.json"
|
|
|
982
1031
|
#[test]
|
|
983
1032
|
fn combine_three_configs_concatenates_across_all() {
|
|
984
1033
|
let a = cfg(
|
|
985
|
-
"[dirsql]\nignore = [\"a/**\"]\n\n[[table]]\nddl = \"CREATE TABLE a (x TEXT)\"\nglob = \"a/*\"\n",
|
|
1034
|
+
"[dirsql]\nignore = [\"a/**\"]\n\n[[table]]\nddl = \"CREATE TABLE a (x TEXT)\"\nglob = \"a/*\"\non-file = \"cat {path}\"\n",
|
|
1035
|
+
);
|
|
1036
|
+
let b = cfg(
|
|
1037
|
+
"[[table]]\nddl = \"CREATE TABLE b (x TEXT)\"\nglob = \"b/*\"\non-file = \"cat {path}\"\n",
|
|
986
1038
|
);
|
|
987
|
-
let b = cfg("[[table]]\nddl = \"CREATE TABLE b (x TEXT)\"\nglob = \"b/*\"\n");
|
|
988
1039
|
let c = cfg(
|
|
989
|
-
"[dirsql]\nignore = [\"c/**\"]\n\n[[table]]\nddl = \"CREATE TABLE c (x TEXT)\"\nglob = \"c/*\"\n",
|
|
1040
|
+
"[dirsql]\nignore = [\"c/**\"]\n\n[[table]]\nddl = \"CREATE TABLE c (x TEXT)\"\nglob = \"c/*\"\non-file = \"cat {path}\"\n",
|
|
990
1041
|
);
|
|
991
1042
|
let merged = combine_configs(&[(src("/a"), a), (src("/b"), b), (src("/c"), c)]).unwrap();
|
|
992
1043
|
assert_eq!(merged.ignore, vec!["a/**", "c/**"]);
|
|
@@ -1026,6 +1077,7 @@ hook-timeout = 300
|
|
|
1026
1077
|
[[table]]
|
|
1027
1078
|
ddl = "CREATE TABLE t (x TEXT)"
|
|
1028
1079
|
glob = "*.json"
|
|
1080
|
+
on-file = "cat {path}"
|
|
1029
1081
|
"#;
|
|
1030
1082
|
let config = load_config_str(toml).unwrap();
|
|
1031
1083
|
assert!(config.hook_timeout.is_none());
|
|
@@ -1490,28 +1490,17 @@ fn build_tables_from_config(
|
|
|
1490
1490
|
let mut tables = Vec::with_capacity(cfg.tables.len());
|
|
1491
1491
|
|
|
1492
1492
|
for table_cfg in &cfg.tables {
|
|
1493
|
-
let
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
move |abs_path: &str| {
|
|
1505
|
-
run_on_file(&command, abs_path, &config_dir, &root, timeout)
|
|
1506
|
-
},
|
|
1507
|
-
)
|
|
1508
|
-
}
|
|
1509
|
-
None => Table::new(
|
|
1510
|
-
table_cfg.ddl.clone(),
|
|
1511
|
-
table_cfg.glob.clone(),
|
|
1512
|
-
|_path: &str| vec![Row::new()],
|
|
1513
|
-
),
|
|
1514
|
-
};
|
|
1493
|
+
let command = table_cfg.on_file.clone();
|
|
1494
|
+
let config_dir = config_dir.to_path_buf();
|
|
1495
|
+
let root = root.to_path_buf();
|
|
1496
|
+
// `Table::new` (infallible): `run_on_file` isolates its own errors to an
|
|
1497
|
+
// empty row set so one bad file never aborts the scan (the scan aborts
|
|
1498
|
+
// on an on_file `Err`).
|
|
1499
|
+
let mut table = Table::new(
|
|
1500
|
+
table_cfg.ddl.clone(),
|
|
1501
|
+
table_cfg.glob.clone(),
|
|
1502
|
+
move |abs_path: &str| run_on_file(&command, abs_path, &config_dir, &root, timeout),
|
|
1503
|
+
);
|
|
1515
1504
|
|
|
1516
1505
|
if table_cfg.strict == Some(true) {
|
|
1517
1506
|
table.strict = true;
|
|
@@ -3091,11 +3080,12 @@ mod internal_tests {
|
|
|
3091
3080
|
}
|
|
3092
3081
|
|
|
3093
3082
|
#[test]
|
|
3094
|
-
fn
|
|
3083
|
+
fn build_tables_from_config_creates_on_file_tables() {
|
|
3095
3084
|
let cfg = config::load_config_str(concat!(
|
|
3096
3085
|
"[[table]]\n",
|
|
3097
3086
|
"ddl = \"CREATE TABLE a (x TEXT)\"\n",
|
|
3098
|
-
"glob = \"*.a\"\n
|
|
3087
|
+
"glob = \"*.a\"\n",
|
|
3088
|
+
"on-file = \"printf '[{\\\"x\\\":1}]'\"\n\n",
|
|
3099
3089
|
"[[table]]\n",
|
|
3100
3090
|
"ddl = \"CREATE TABLE b (y TEXT)\"\n",
|
|
3101
3091
|
"glob = \"*.b\"\n",
|
|
@@ -3112,7 +3102,12 @@ mod internal_tests {
|
|
|
3112
3102
|
)
|
|
3113
3103
|
.unwrap();
|
|
3114
3104
|
assert_eq!(tables.len(), 2);
|
|
3115
|
-
assert_eq!(
|
|
3105
|
+
assert_eq!(
|
|
3106
|
+
(tables[0].on_file)(&dir.path().join("f.a").to_string_lossy())
|
|
3107
|
+
.unwrap()
|
|
3108
|
+
.len(),
|
|
3109
|
+
1
|
|
3110
|
+
);
|
|
3116
3111
|
assert!(tables[1].strict, "on-file table preserves strict flag");
|
|
3117
3112
|
}
|
|
3118
3113
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|