dirsql 0.4.101__tar.gz → 0.4.103__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.101 → dirsql-0.4.103}/Cargo.lock +2 -2
- {dirsql-0.4.101 → dirsql-0.4.103}/PKG-INFO +1 -1
- {dirsql-0.4.101/packages/rust → dirsql-0.4.103}/docs/reference/hooks.md +3 -1
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/Cargo.toml +1 -1
- dirsql-0.4.103/packages/python/changelog.d/2026-10-07-parallel-hooks.md +1 -0
- dirsql-0.4.103/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +1 -0
- {dirsql-0.4.101 → dirsql-0.4.103/packages/python}/docs/reference/hooks.md +3 -1
- dirsql-0.4.103/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +7 -0
- dirsql-0.4.103/packages/python/e2e-attestations/bot-1454-split-few-files.json +7 -0
- dirsql-0.4.103/packages/python/migrations.d/2026-10-07-parallel-hooks.md +41 -0
- dirsql-0.4.103/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +39 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/Cargo.toml +1 -1
- {dirsql-0.4.101/packages/python → dirsql-0.4.103/packages/rust}/docs/reference/hooks.md +3 -1
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/command.rs +144 -11
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/db.rs +14 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/infer.rs +13 -1
- dirsql-0.4.103/packages/rust/src/on_file.rs +505 -0
- dirsql-0.4.101/packages/rust/src/on_file.rs +0 -269
- {dirsql-0.4.101 → dirsql-0.4.103}/Cargo.toml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/README.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/_async.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/py.typed +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/read_config.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/AGENTS.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/context/.gitattributes +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/context/recipes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/context/usage.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/explanation.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/getting-started.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/embed.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/persist.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/index.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/package.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/plugins.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/cli.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/glob.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/README.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/conftest.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/context/.gitattributes +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/context/recipes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/context/usage.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/glob.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/README.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/context/.gitattributes +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/context/recipes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/context/usage.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/glob.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/brace.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/context.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/lib.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/listing.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/posix_class.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/tree_walk.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/vtab_scaffold.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.101 → dirsql-0.4.103}/pyproject.toml +0 -0
|
@@ -573,7 +573,7 @@ dependencies = [
|
|
|
573
573
|
|
|
574
574
|
[[package]]
|
|
575
575
|
name = "dirsql"
|
|
576
|
-
version = "0.4.
|
|
576
|
+
version = "0.4.103"
|
|
577
577
|
dependencies = [
|
|
578
578
|
"assert_cmd",
|
|
579
579
|
"axum",
|
|
@@ -625,7 +625,7 @@ dependencies = [
|
|
|
625
625
|
|
|
626
626
|
[[package]]
|
|
627
627
|
name = "dirsql-py-ext"
|
|
628
|
-
version = "0.4.
|
|
628
|
+
version = "0.4.103"
|
|
629
629
|
dependencies = [
|
|
630
630
|
"dirsql",
|
|
631
631
|
"pyo3",
|
|
@@ -161,7 +161,9 @@ on-file command `python3 extract.py {path}` uses `{path}`, but an on-file comman
|
|
|
161
161
|
Every platform caps the bytes one process may receive as arguments. When a
|
|
162
162
|
table's paths outgrow that cap, dirsql splits them into the fewest
|
|
163
163
|
consecutive runs that fit, runs the command once per run, and concatenates
|
|
164
|
-
the rows it prints
|
|
164
|
+
the rows it prints. Runs execute concurrently, one per CPU at most, like
|
|
165
|
+
`xargs -P`, so rows keep their order within a run but not across runs; SQL
|
|
166
|
+
never promised row order, so `ORDER BY` what you need. A table whose paths fit one run is also split, by file size, into up to one run per CPU once it holds at least 4 MiB of file data per run, so a few large files do not serialize behind one process. The command cannot tell: each run is an
|
|
165
167
|
ordinary invocation with a subset of the paths. A command must therefore not
|
|
166
168
|
assume one invocation sees every path — a count, a cross-file join, or a
|
|
167
169
|
dedupe over `sys.argv[1:]` is per run, not per table. Do that work in SQL.
|
|
@@ -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.103"
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
**Changed** An `on-file` command's runs now execute concurrently, one per CPU at most, when a table's paths outgrow one argument list, and each run's output is parsed as it is written instead of after it exits. Rows keep their order within a run but not across runs. A 2M-row JSONL ingest through `jq` runs within 5% of the equivalent `jq | awk` pipeline, and a frontmatter parse over thousands of files runs in a quarter of the time of `find -exec awk +`. The scratch database no longer syncs to disk.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
**Changed** An `on-file` table with a few large files now runs its command over up to one run per CPU, split by file size at 4 MiB of data per run, instead of one run over all of them. Small tables still use one run.
|
|
@@ -161,7 +161,9 @@ on-file command `python3 extract.py {path}` uses `{path}`, but an on-file comman
|
|
|
161
161
|
Every platform caps the bytes one process may receive as arguments. When a
|
|
162
162
|
table's paths outgrow that cap, dirsql splits them into the fewest
|
|
163
163
|
consecutive runs that fit, runs the command once per run, and concatenates
|
|
164
|
-
the rows it prints
|
|
164
|
+
the rows it prints. Runs execute concurrently, one per CPU at most, like
|
|
165
|
+
`xargs -P`, so rows keep their order within a run but not across runs; SQL
|
|
166
|
+
never promised row order, so `ORDER BY` what you need. A table whose paths fit one run is also split, by file size, into up to one run per CPU once it holds at least 4 MiB of file data per run, so a few large files do not serialize behind one process. The command cannot tell: each run is an
|
|
165
167
|
ordinary invocation with a subset of the paths. A command must therefore not
|
|
166
168
|
assume one invocation sees every path — a count, a cross-file join, or a
|
|
167
169
|
dedupe over `sys.argv[1:]` is per run, not per table. Do that work in SQL.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/declared_table_name_test.py tests/e2e/fanout_test.py tests/e2e/extension_package_test.py tests/e2e/frontmatter_parse_speed_test.py tests/e2e/jsonl_parse_speed_test.py tests/e2e/plugin_extension_discovery_test.py tests/e2e/on_file_query_test.py tests/e2e/sigint_interrupt_test.py tests/e2e/use_case_notebook_test.py tests/e2e/server_speed_test.py tests/e2e/query_contract_test.py tests/e2e/plugin_discovery_test.py tests/e2e/use_case_transcripts_test.py -q",
|
|
3
|
+
"ran_at": 1791407652,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "8d6801314e86177dc46926aedb94bf63e47e87bb",
|
|
6
|
+
"branch": "bot/1429-parallel-hooks"
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/declared_table_name_test.py tests/e2e/fanout_test.py tests/e2e/extension_package_test.py tests/e2e/frontmatter_parse_speed_test.py tests/e2e/jsonl_parse_speed_test.py tests/e2e/plugin_extension_discovery_test.py tests/e2e/on_file_query_test.py tests/e2e/sigint_interrupt_test.py tests/e2e/use_case_notebook_test.py tests/e2e/server_speed_test.py tests/e2e/query_contract_test.py tests/e2e/plugin_discovery_test.py tests/e2e/use_case_transcripts_test.py -q",
|
|
3
|
+
"ran_at": 1791411055,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "7a93d0b97fe085a269b90d2b75c2a0aa22511c18",
|
|
6
|
+
"branch": "bot/1454-split-few-files"
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
### `on-file` runs execute concurrently
|
|
2
|
+
|
|
3
|
+
#### Summary
|
|
4
|
+
|
|
5
|
+
When a table's matched paths outgrow one argument list, dirsql splits them
|
|
6
|
+
into runs and now executes the runs concurrently, one per CPU at most. Rows
|
|
7
|
+
keep their order within a run, but not across runs.
|
|
8
|
+
|
|
9
|
+
#### Required changes
|
|
10
|
+
|
|
11
|
+
_None._
|
|
12
|
+
|
|
13
|
+
#### Deprecations removed
|
|
14
|
+
|
|
15
|
+
_None._
|
|
16
|
+
|
|
17
|
+
#### Behavior changes without code changes
|
|
18
|
+
|
|
19
|
+
- A query that relied on rows coming back in path order across runs must add
|
|
20
|
+
an `ORDER BY`. A table small enough for one run is unchanged.
|
|
21
|
+
- A hook that holds memory or a GPU may now have several copies running at
|
|
22
|
+
once on a very large table.
|
|
23
|
+
|
|
24
|
+
#### Verification
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd "$(mktemp -d)"
|
|
28
|
+
for i in $(seq 1 5000); do : > "a-long-file-name-to-fill-the-argument-list-$i.txt"; done
|
|
29
|
+
cat > count.sh <<'SH'
|
|
30
|
+
echo "{\"n\":$#}"
|
|
31
|
+
SH
|
|
32
|
+
cat > .dirsql.toml <<'TOML'
|
|
33
|
+
[[table]]
|
|
34
|
+
name = "t"
|
|
35
|
+
ddl = "CREATE TABLE t (n INTEGER)"
|
|
36
|
+
glob = "*.txt"
|
|
37
|
+
on-file = "sh count.sh"
|
|
38
|
+
TOML
|
|
39
|
+
dirsql query "SELECT count(*) AS runs, sum(n) AS paths FROM t" -c .dirsql.toml
|
|
40
|
+
# expected: one row whose paths is 5000 and whose runs is greater than 1
|
|
41
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
### `on-file` splits large tables by file size
|
|
2
|
+
|
|
3
|
+
#### Summary
|
|
4
|
+
|
|
5
|
+
A table whose paths fit one argument list is now also split into several
|
|
6
|
+
concurrent runs when its files hold at least 4 MiB in total per run, up
|
|
7
|
+
to one run per CPU. Small tables are unchanged.
|
|
8
|
+
|
|
9
|
+
#### Required changes
|
|
10
|
+
|
|
11
|
+
_None._
|
|
12
|
+
|
|
13
|
+
#### Deprecations removed
|
|
14
|
+
|
|
15
|
+
_None._
|
|
16
|
+
|
|
17
|
+
#### Behavior changes without code changes
|
|
18
|
+
|
|
19
|
+
- A hook may now see a subset of the table's paths even when the table is
|
|
20
|
+
small in path count. A hook must already not assume it sees every path;
|
|
21
|
+
do cross-file work in SQL.
|
|
22
|
+
- Rows from different runs have no defined order; add an `ORDER BY`.
|
|
23
|
+
|
|
24
|
+
#### Verification
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd "$(mktemp -d)"
|
|
28
|
+
for i in 1 2 3 4; do head -c 5000000 /dev/zero | tr '\0' x > "f$i.txt"; done
|
|
29
|
+
printf 'echo "{\\"n\\":$#}"\n' > count.sh
|
|
30
|
+
cat > .dirsql.toml <<'TOML'
|
|
31
|
+
[[table]]
|
|
32
|
+
name = "t"
|
|
33
|
+
ddl = "CREATE TABLE t (n INTEGER)"
|
|
34
|
+
glob = "*.txt"
|
|
35
|
+
on-file = "sh count.sh"
|
|
36
|
+
TOML
|
|
37
|
+
dirsql query "SELECT count(*) AS runs, sum(n) AS paths FROM t" -c .dirsql.toml
|
|
38
|
+
# expected: paths is 4; runs is the smaller of 4 and the CPU count
|
|
39
|
+
```
|
|
@@ -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.103"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -161,7 +161,9 @@ on-file command `python3 extract.py {path}` uses `{path}`, but an on-file comman
|
|
|
161
161
|
Every platform caps the bytes one process may receive as arguments. When a
|
|
162
162
|
table's paths outgrow that cap, dirsql splits them into the fewest
|
|
163
163
|
consecutive runs that fit, runs the command once per run, and concatenates
|
|
164
|
-
the rows it prints
|
|
164
|
+
the rows it prints. Runs execute concurrently, one per CPU at most, like
|
|
165
|
+
`xargs -P`, so rows keep their order within a run but not across runs; SQL
|
|
166
|
+
never promised row order, so `ORDER BY` what you need. A table whose paths fit one run is also split, by file size, into up to one run per CPU once it holds at least 4 MiB of file data per run, so a few large files do not serialize behind one process. The command cannot tell: each run is an
|
|
165
167
|
ordinary invocation with a subset of the paths. A command must therefore not
|
|
166
168
|
assume one invocation sees every path — a count, a cross-file join, or a
|
|
167
169
|
dedupe over `sys.argv[1:]` is per run, not per table. Do that work in SQL.
|
|
@@ -256,21 +256,85 @@ pub(crate) fn run_argv_stdout(
|
|
|
256
256
|
let stdout = stdout_thread.join().unwrap_or_default();
|
|
257
257
|
let stderr = stderr_thread.join().unwrap_or_default();
|
|
258
258
|
|
|
259
|
-
|
|
260
|
-
let code = status
|
|
261
|
-
.code()
|
|
262
|
-
.map(|c| c.to_string())
|
|
263
|
-
.unwrap_or_else(|| "signal".to_string());
|
|
264
|
-
return Err(CommandError::NonZeroExit {
|
|
265
|
-
command: command.to_string(),
|
|
266
|
-
code,
|
|
267
|
-
stderr_tail: stderr_tail(&stderr),
|
|
268
|
-
});
|
|
269
|
-
}
|
|
259
|
+
check_exit(command, status, &stderr)?;
|
|
270
260
|
|
|
271
261
|
Ok(String::from_utf8_lossy(&stdout).into_owned())
|
|
272
262
|
}
|
|
273
263
|
|
|
264
|
+
fn check_exit(
|
|
265
|
+
command: &str,
|
|
266
|
+
status: std::process::ExitStatus,
|
|
267
|
+
stderr: &[u8],
|
|
268
|
+
) -> Result<(), CommandError> {
|
|
269
|
+
if status.success() {
|
|
270
|
+
return Ok(());
|
|
271
|
+
}
|
|
272
|
+
let code = status
|
|
273
|
+
.code()
|
|
274
|
+
.map(|c| c.to_string())
|
|
275
|
+
.unwrap_or_else(|| "signal".to_string());
|
|
276
|
+
Err(CommandError::NonZeroExit {
|
|
277
|
+
command: command.to_string(),
|
|
278
|
+
code,
|
|
279
|
+
stderr_tail: stderr_tail(stderr),
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/// Bytes read from a child's stdout per `read` call.
|
|
284
|
+
const READ_BYTES: usize = 262_144;
|
|
285
|
+
|
|
286
|
+
/// Run an already-built `argv` and hand its stdout to `on_block` as it
|
|
287
|
+
/// arrives, in blocks that each hold whole lines (the last block may lack its
|
|
288
|
+
/// trailing newline). The child runs with stdin closed. A non-zero exit is an
|
|
289
|
+
/// error after every block has been delivered.
|
|
290
|
+
pub(crate) fn run_argv_blocks(
|
|
291
|
+
command: &str,
|
|
292
|
+
argv: &[String],
|
|
293
|
+
cwd: &Path,
|
|
294
|
+
on_block: &mut dyn FnMut(&str),
|
|
295
|
+
) -> Result<(), CommandError> {
|
|
296
|
+
let mut cmd = Command::new(&argv[0]);
|
|
297
|
+
push_args(&mut cmd, &argv[1..]);
|
|
298
|
+
cmd.current_dir(cwd)
|
|
299
|
+
.stdout(Stdio::piped())
|
|
300
|
+
.stderr(Stdio::piped())
|
|
301
|
+
.stdin(Stdio::null());
|
|
302
|
+
let mut child = cmd
|
|
303
|
+
.spawn()
|
|
304
|
+
.map_err(|source| spawn_error(&argv[0], source, cwd))?;
|
|
305
|
+
|
|
306
|
+
let mut stderr_pipe = child.stderr.take().expect("stderr piped");
|
|
307
|
+
let stderr_thread = std::thread::spawn(move || {
|
|
308
|
+
let mut buf = Vec::new();
|
|
309
|
+
let _ = stderr_pipe.read_to_end(&mut buf);
|
|
310
|
+
buf
|
|
311
|
+
});
|
|
312
|
+
let mut stdout_pipe = child.stdout.take().expect("stdout piped");
|
|
313
|
+
let mut pending: Vec<u8> = Vec::new();
|
|
314
|
+
let mut buf = vec![0u8; READ_BYTES];
|
|
315
|
+
loop {
|
|
316
|
+
let n = match stdout_pipe.read(&mut buf) {
|
|
317
|
+
Ok(0) | Err(_) => break,
|
|
318
|
+
Ok(n) => n,
|
|
319
|
+
};
|
|
320
|
+
pending.extend_from_slice(&buf[..n]);
|
|
321
|
+
if let Some(end) = pending.iter().rposition(|&b| b == b'\n') {
|
|
322
|
+
on_block(&String::from_utf8_lossy(&pending[..=end]));
|
|
323
|
+
pending.drain(..=end);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if !pending.is_empty() {
|
|
327
|
+
on_block(&String::from_utf8_lossy(&pending));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
let status = child.wait().map_err(|source| CommandError::Io {
|
|
331
|
+
command: command.to_string(),
|
|
332
|
+
source,
|
|
333
|
+
})?;
|
|
334
|
+
let stderr = stderr_thread.join().unwrap_or_default();
|
|
335
|
+
check_exit(command, status, &stderr)
|
|
336
|
+
}
|
|
337
|
+
|
|
274
338
|
// One fn with cfg blocks rather than two cfg'd fns: cargo-mutants mutates
|
|
275
339
|
// the uncompiled twin too, and no test on a Linux gate can kill that mutant.
|
|
276
340
|
fn push_args(cmd: &mut Command, args: &[String]) {
|
|
@@ -736,6 +800,75 @@ mod tests {
|
|
|
736
800
|
);
|
|
737
801
|
}
|
|
738
802
|
|
|
803
|
+
#[test]
|
|
804
|
+
fn run_argv_blocks_delivers_whole_lines_and_the_unterminated_tail() {
|
|
805
|
+
let argv = vec![
|
|
806
|
+
"sh".to_string(),
|
|
807
|
+
"-c".to_string(),
|
|
808
|
+
"printf 'a\\nb\\nc'".to_string(),
|
|
809
|
+
];
|
|
810
|
+
let mut seen = String::new();
|
|
811
|
+
let mut blocks = 0;
|
|
812
|
+
run_argv_blocks("t", &argv, &cwd(), &mut |block| {
|
|
813
|
+
seen.push_str(block);
|
|
814
|
+
blocks += 1;
|
|
815
|
+
})
|
|
816
|
+
.unwrap();
|
|
817
|
+
assert_eq!(seen, "a\nb\nc");
|
|
818
|
+
assert!(blocks >= 1);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
#[test]
|
|
822
|
+
fn run_argv_blocks_cuts_every_block_at_a_line_boundary() {
|
|
823
|
+
let argv = vec![
|
|
824
|
+
"sh".to_string(),
|
|
825
|
+
"-c".to_string(),
|
|
826
|
+
"yes abcdefghijklmnopqrstuvwxyz | head -n 100000".to_string(),
|
|
827
|
+
];
|
|
828
|
+
let mut lines = 0;
|
|
829
|
+
let mut blocks = 0;
|
|
830
|
+
run_argv_blocks("t", &argv, &cwd(), &mut |block| {
|
|
831
|
+
blocks += 1;
|
|
832
|
+
assert!(block.ends_with('\n'), "block cut mid-line");
|
|
833
|
+
lines += block.lines().count();
|
|
834
|
+
})
|
|
835
|
+
.unwrap();
|
|
836
|
+
assert_eq!(lines, 100_000);
|
|
837
|
+
assert!(blocks > 1, "2.7 MB arrives in more than one read");
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
#[test]
|
|
841
|
+
fn run_argv_blocks_reports_a_non_zero_exit_after_delivering_output() {
|
|
842
|
+
let argv = vec![
|
|
843
|
+
"sh".to_string(),
|
|
844
|
+
"-c".to_string(),
|
|
845
|
+
"echo partial; echo oops >&2; exit 3".to_string(),
|
|
846
|
+
];
|
|
847
|
+
let mut seen = String::new();
|
|
848
|
+
let err =
|
|
849
|
+
run_argv_blocks("t", &argv, &cwd(), &mut |block| seen.push_str(block)).unwrap_err();
|
|
850
|
+
assert_eq!(seen, "partial\n");
|
|
851
|
+
match err {
|
|
852
|
+
CommandError::NonZeroExit {
|
|
853
|
+
code, stderr_tail, ..
|
|
854
|
+
} => {
|
|
855
|
+
assert_eq!(code, "3");
|
|
856
|
+
assert!(stderr_tail.contains("oops"));
|
|
857
|
+
}
|
|
858
|
+
other => panic!("expected NonZeroExit, got {other:?}"),
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
#[test]
|
|
863
|
+
fn run_argv_blocks_names_a_missing_program() {
|
|
864
|
+
let argv = vec!["definitely-not-a-real-binary-xyzzy".to_string()];
|
|
865
|
+
let err = run_argv_blocks("t", &argv, &cwd(), &mut |_| {}).unwrap_err();
|
|
866
|
+
assert!(
|
|
867
|
+
matches!(err, CommandError::NotOnPath { .. }),
|
|
868
|
+
"got: {err:?}"
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
|
|
739
872
|
#[test]
|
|
740
873
|
fn run_command_writes_stdin_payload_to_the_child() {
|
|
741
874
|
let out = run_command("cat", &[], &cwd(), Some(b"hello-stdin")).unwrap();
|
|
@@ -368,6 +368,9 @@ impl Db {
|
|
|
368
368
|
/// tmpfs mount.
|
|
369
369
|
pub fn new() -> Result<Self> {
|
|
370
370
|
let conn = Connection::open("")?;
|
|
371
|
+
// The database is a private temp file that dies with the process, so
|
|
372
|
+
// durability buys nothing.
|
|
373
|
+
conn.pragma_update(None, "synchronous", "OFF")?;
|
|
371
374
|
ensure_internal_rows_table(&conn)?;
|
|
372
375
|
let scope = StatementScope::new();
|
|
373
376
|
vtab::load_module(&conn, Arc::clone(&scope))?;
|
|
@@ -2066,6 +2069,17 @@ mod tests {
|
|
|
2066
2069
|
assert_eq!(mode, "delete");
|
|
2067
2070
|
}
|
|
2068
2071
|
|
|
2072
|
+
#[test]
|
|
2073
|
+
fn new_skips_fsync() {
|
|
2074
|
+
let db = Db::new().unwrap();
|
|
2075
|
+
let pragma = |name: &str| -> i64 {
|
|
2076
|
+
db.conn()
|
|
2077
|
+
.query_row(&format!("PRAGMA {name}"), [], |row| row.get(0))
|
|
2078
|
+
.unwrap()
|
|
2079
|
+
};
|
|
2080
|
+
assert_eq!(pragma("synchronous"), 0);
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2069
2083
|
#[test]
|
|
2070
2084
|
fn get_rows_by_file_returns_rows_in_row_index_order() {
|
|
2071
2085
|
let db = Db::new().unwrap();
|
|
@@ -110,13 +110,19 @@ impl<'de> serde::Deserialize<'de> for JsonRow {
|
|
|
110
110
|
/// Parse a parser command's output — one JSON object per line (NDJSON), blank
|
|
111
111
|
/// lines skipped — into rows that remember their key order.
|
|
112
112
|
pub fn parse_rows(output: &str) -> Result<Vec<JsonRow>, String> {
|
|
113
|
+
parse_rows_at(output, 0)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// [`parse_rows`] for a block that begins after `skipped` earlier lines of the
|
|
117
|
+
/// same output, so an error names its line in the whole output.
|
|
118
|
+
pub(crate) fn parse_rows_at(output: &str, skipped: usize) -> Result<Vec<JsonRow>, String> {
|
|
113
119
|
let mut rows = Vec::new();
|
|
114
120
|
for (index, line) in output.lines().enumerate() {
|
|
115
121
|
let line = line.trim();
|
|
116
122
|
if line.is_empty() {
|
|
117
123
|
continue;
|
|
118
124
|
}
|
|
119
|
-
let number = index + 1;
|
|
125
|
+
let number = skipped + index + 1;
|
|
120
126
|
if line.starts_with('[') {
|
|
121
127
|
return Err(format!(
|
|
122
128
|
"line {number} is a JSON array; print one JSON object per line instead"
|
|
@@ -255,6 +261,12 @@ mod tests {
|
|
|
255
261
|
assert_eq!(SqlType::Real.as_str(), "REAL");
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
#[test]
|
|
265
|
+
fn parse_rows_at_numbers_lines_after_the_skipped_ones() {
|
|
266
|
+
let err = parse_rows_at("{\"a\":1}\nnope", 40).unwrap_err();
|
|
267
|
+
assert!(err.starts_with("line 42 "), "got: {err}");
|
|
268
|
+
}
|
|
269
|
+
|
|
258
270
|
#[test]
|
|
259
271
|
fn parse_rows_preserves_key_order_rather_than_sorting() {
|
|
260
272
|
let parsed = parse_rows(r#"{"zeta":1,"alpha":2}"#).unwrap();
|