dirsql 0.4.116__tar.gz → 0.4.117__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.116 → dirsql-0.4.117}/Cargo.lock +2 -2
- {dirsql-0.4.116 → dirsql-0.4.117}/PKG-INFO +1 -1
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/Cargo.toml +1 -1
- dirsql-0.4.117/packages/python/e2e-attestations/bot-1477-onelevel-speed-1016.json +7 -0
- dirsql-0.4.117/packages/python/e2e-attestations/bot-1524-path-eq-1016.json +7 -0
- dirsql-0.4.117/packages/python/e2e-attestations/bot-1532-gitignore-fastest-bar-1016.json +7 -0
- dirsql-0.4.117/packages/python/e2e-attestations/bot-1534-fm-native-1016.json +7 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/Cargo.toml +1 -1
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/db.rs +71 -51
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/lib.rs +159 -49
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/scanner.rs +226 -141
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/tree_walk.rs +2 -84
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/vtab_scaffold.rs +96 -11
- {dirsql-0.4.116 → dirsql-0.4.117}/Cargo.toml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/README.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/_async.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/py.typed +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/read_config.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/AGENTS.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/context/.gitattributes +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/context/recipes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/context/usage.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/explanation.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/getting-started.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/embed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/persist.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/index.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/package.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/plugins.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/cli.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/glob.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/docs/speed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/README.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/conftest.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/context/.gitattributes +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/context/recipes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/context/usage.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/glob.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/docs/speed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1480-matcher-speed-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-1526-main-red-1016.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/bench_report.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/bench_suite.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/README.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/context/.gitattributes +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/context/recipes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/context/usage.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/glob.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/speed.json +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/docs/speed.md +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/brace.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/context.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/frontend.html +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/frontend.js +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/gitignore_frame.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/listing.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/on_file.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/per_thread.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/posix_class.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/row_stream.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.116 → dirsql-0.4.117}/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.117"
|
|
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.117"
|
|
629
629
|
dependencies = [
|
|
630
630
|
"dirsql",
|
|
631
631
|
"pyo3",
|
|
@@ -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.117"
|
|
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,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/glob_speed_gitignore_test.py tests/e2e/glob_speed_node_modules_test.py tests/e2e/glob_speed_symlink_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/use_case_join_test.py -q -s",
|
|
3
|
+
"ran_at": 1792409702,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "f500062c3a69da8d29e351d1a5580cff8f5af696",
|
|
6
|
+
"branch": "bot/1477-onelevel-speed-1016"
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/frontmatter_parse_speed_test.py tests/e2e/jsonl_parse_speed_test.py tests/e2e/on_file_query_test.py tests/e2e/fanout_test.py tests/e2e/declared_table_name_test.py tests/e2e/query_contract_test.py tests/e2e/use_case_notebook_test.py tests/e2e/use_case_transcripts_test.py tests/e2e/sigint_interrupt_test.py -q -s",
|
|
3
|
+
"ran_at": 1792158472,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "4eaa7f0c26fa324fdb9b161e90fdb3fe22b8774f",
|
|
6
|
+
"branch": "bot/1534-fm-native-1016"
|
|
7
|
+
}
|
|
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
|
|
|
6
6
|
# version stays for the binding crates (publish = false). The literal
|
|
7
7
|
# intentionally lags the published version: putitoutthere rewrites it to
|
|
8
8
|
# the planned release version at build time and never commits it back.
|
|
9
|
-
version = "0.4.
|
|
9
|
+
version = "0.4.117"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -312,6 +312,63 @@ impl ShapedRows {
|
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
+
/// [`Db::shape_rows`] against `columns`, the table's columns in DDL order,
|
|
316
|
+
/// so rows can be shaped off the connection's thread.
|
|
317
|
+
pub(crate) fn shape_json_rows(
|
|
318
|
+
table: &str,
|
|
319
|
+
columns: Vec<String>,
|
|
320
|
+
rows: Vec<JsonRow>,
|
|
321
|
+
strict: bool,
|
|
322
|
+
) -> Result<ShapedRows> {
|
|
323
|
+
let mut cells = Vec::with_capacity(rows.len());
|
|
324
|
+
for row in rows {
|
|
325
|
+
if strict {
|
|
326
|
+
for (key, _) in &row.0 {
|
|
327
|
+
validate_identifier(key)?;
|
|
328
|
+
}
|
|
329
|
+
let extra: Vec<&str> = row
|
|
330
|
+
.0
|
|
331
|
+
.iter()
|
|
332
|
+
.map(|(key, _)| &**key)
|
|
333
|
+
.filter(|key| !columns.iter().any(|c| c == key))
|
|
334
|
+
.collect();
|
|
335
|
+
if !extra.is_empty() {
|
|
336
|
+
return Err(DbError::SchemaMismatch(format!(
|
|
337
|
+
"extra columns not in table {}: {}",
|
|
338
|
+
table,
|
|
339
|
+
extra.join(", ")
|
|
340
|
+
)));
|
|
341
|
+
}
|
|
342
|
+
let missing: Vec<&str> = columns
|
|
343
|
+
.iter()
|
|
344
|
+
.map(String::as_str)
|
|
345
|
+
.filter(|c| !row.0.iter().any(|(key, _)| **key == **c))
|
|
346
|
+
.collect();
|
|
347
|
+
if !missing.is_empty() {
|
|
348
|
+
return Err(DbError::SchemaMismatch(format!(
|
|
349
|
+
"missing columns for table {}: {}",
|
|
350
|
+
table,
|
|
351
|
+
missing.join(", ")
|
|
352
|
+
)));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
let in_order = row.0.len() == columns.len()
|
|
356
|
+
&& row.0.iter().zip(&columns).all(|((key, _), c)| **key == **c);
|
|
357
|
+
if in_order {
|
|
358
|
+
cells.push(row.0.into_iter().map(|(_, v)| json_into_value(v)).collect());
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
let mut shaped = vec![Value::Null; columns.len()];
|
|
362
|
+
for (key, value) in row.0 {
|
|
363
|
+
if let Some(i) = columns.iter().position(|c| **c == *key) {
|
|
364
|
+
shaped[i] = json_into_value(value);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
cells.push(shaped);
|
|
368
|
+
}
|
|
369
|
+
Ok(ShapedRows { columns, cells })
|
|
370
|
+
}
|
|
371
|
+
|
|
315
372
|
fn json_into_value(value: serde_json::Value) -> Value {
|
|
316
373
|
match value {
|
|
317
374
|
serde_json::Value::String(s) => Value::Text(s),
|
|
@@ -566,9 +623,10 @@ impl Db {
|
|
|
566
623
|
/// Return the column names declared in `table`'s DDL.
|
|
567
624
|
pub fn get_table_columns(&self, table: &str) -> Result<Vec<String>> {
|
|
568
625
|
validate_identifier(table)?;
|
|
569
|
-
let mut stmt = self
|
|
570
|
-
|
|
571
|
-
|
|
626
|
+
let mut stmt = self.conn.prepare(&format!(
|
|
627
|
+
"PRAGMA table_info({})",
|
|
628
|
+
crate::sql_literal::quote_identifier(table)
|
|
629
|
+
))?;
|
|
572
630
|
let columns: Vec<String> = stmt
|
|
573
631
|
.query_map([], |row| row.get::<_, String>(1))?
|
|
574
632
|
.filter_map(|r| r.ok())
|
|
@@ -714,54 +772,7 @@ impl Db {
|
|
|
714
772
|
/// a less-actionable "extra columns" mismatch. Every row is shaped before
|
|
715
773
|
/// any is returned, so a hook that got one row wrong fails as a unit.
|
|
716
774
|
pub fn shape_rows(&self, table: &str, rows: Vec<JsonRow>, strict: bool) -> Result<ShapedRows> {
|
|
717
|
-
|
|
718
|
-
let mut cells = Vec::with_capacity(rows.len());
|
|
719
|
-
for row in rows {
|
|
720
|
-
if strict {
|
|
721
|
-
for (key, _) in &row.0 {
|
|
722
|
-
validate_identifier(key)?;
|
|
723
|
-
}
|
|
724
|
-
let extra: Vec<&str> = row
|
|
725
|
-
.0
|
|
726
|
-
.iter()
|
|
727
|
-
.map(|(key, _)| &**key)
|
|
728
|
-
.filter(|key| !columns.iter().any(|c| c == key))
|
|
729
|
-
.collect();
|
|
730
|
-
if !extra.is_empty() {
|
|
731
|
-
return Err(DbError::SchemaMismatch(format!(
|
|
732
|
-
"extra columns not in table {}: {}",
|
|
733
|
-
table,
|
|
734
|
-
extra.join(", ")
|
|
735
|
-
)));
|
|
736
|
-
}
|
|
737
|
-
let missing: Vec<&str> = columns
|
|
738
|
-
.iter()
|
|
739
|
-
.map(String::as_str)
|
|
740
|
-
.filter(|c| !row.0.iter().any(|(key, _)| **key == **c))
|
|
741
|
-
.collect();
|
|
742
|
-
if !missing.is_empty() {
|
|
743
|
-
return Err(DbError::SchemaMismatch(format!(
|
|
744
|
-
"missing columns for table {}: {}",
|
|
745
|
-
table,
|
|
746
|
-
missing.join(", ")
|
|
747
|
-
)));
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
let in_order = row.0.len() == columns.len()
|
|
751
|
-
&& row.0.iter().zip(&columns).all(|((key, _), c)| **key == **c);
|
|
752
|
-
if in_order {
|
|
753
|
-
cells.push(row.0.into_iter().map(|(_, v)| json_into_value(v)).collect());
|
|
754
|
-
continue;
|
|
755
|
-
}
|
|
756
|
-
let mut shaped = vec![Value::Null; columns.len()];
|
|
757
|
-
for (key, value) in row.0 {
|
|
758
|
-
if let Some(i) = columns.iter().position(|c| **c == *key) {
|
|
759
|
-
shaped[i] = json_into_value(value);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
cells.push(shaped);
|
|
763
|
-
}
|
|
764
|
-
Ok(ShapedRows { columns, cells })
|
|
775
|
+
shape_json_rows(table, self.get_table_columns(table)?, rows, strict)
|
|
765
776
|
}
|
|
766
777
|
|
|
767
778
|
/// Insert every row of `rows` under `file_path`, in order, through one
|
|
@@ -2476,6 +2487,15 @@ mod tests {
|
|
|
2476
2487
|
assert!(result.is_err());
|
|
2477
2488
|
}
|
|
2478
2489
|
|
|
2490
|
+
#[test]
|
|
2491
|
+
fn get_table_columns_reads_a_table_named_by_a_keyword() {
|
|
2492
|
+
let db = Db::new().unwrap();
|
|
2493
|
+
db.create_table("order", "CREATE TABLE \"order\" (name TEXT)")
|
|
2494
|
+
.unwrap();
|
|
2495
|
+
let cols = db.get_table_columns("order").unwrap();
|
|
2496
|
+
assert!(cols.contains(&"name".to_string()), "{cols:?}");
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2479
2499
|
#[test]
|
|
2480
2500
|
fn get_table_columns_nonexistent_table_returns_empty() {
|
|
2481
2501
|
let db = Db::new().unwrap();
|
|
@@ -1288,20 +1288,11 @@ impl DirSQL {
|
|
|
1288
1288
|
// (and that pass the racy-window check) are trusted instead of
|
|
1289
1289
|
// re-parsed.
|
|
1290
1290
|
let (scanned_files, deleted) = match &persist_ctx {
|
|
1291
|
-
None =>
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
abs_path: found.path,
|
|
1296
|
-
rel_path: found.rel_path,
|
|
1297
|
-
table_name: found.table_name,
|
|
1298
|
-
stat: None,
|
|
1299
|
-
trusted: false,
|
|
1300
|
-
})
|
|
1301
|
-
.collect();
|
|
1302
|
-
(files, Vec::new())
|
|
1291
|
+
None => (Scanned::Found(scanned), Vec::new()),
|
|
1292
|
+
Some(ctx) => {
|
|
1293
|
+
let (files, deleted) = reconcile_scan(scanned, ctx, &RealFs)?;
|
|
1294
|
+
(Scanned::Files(files), deleted)
|
|
1303
1295
|
}
|
|
1304
|
-
Some(ctx) => reconcile_scan(scanned, ctx, &RealFs)?,
|
|
1305
1296
|
};
|
|
1306
1297
|
|
|
1307
1298
|
Ok(PreparedBuild {
|
|
@@ -1482,17 +1473,22 @@ impl DirSQL {
|
|
|
1482
1473
|
let mut batch_files: HashMap<String, Vec<String>> = HashMap::new();
|
|
1483
1474
|
|
|
1484
1475
|
// Grouping walks every scanned file, so it runs beside the early
|
|
1485
|
-
// hooks' inserts instead of ahead of them
|
|
1476
|
+
// hooks' inserts instead of ahead of them, and settles the early
|
|
1477
|
+
// tables' file lists there too.
|
|
1478
|
+
let early_tables: HashSet<String> = early.keys().cloned().collect();
|
|
1486
1479
|
let (grouped, streamed) = std::thread::scope(|scope| {
|
|
1487
|
-
let grouping = scope.spawn(||
|
|
1480
|
+
let grouping = scope.spawn(|| {
|
|
1481
|
+
group_scanned(scanned_files.into_files(), &on_file_map)
|
|
1482
|
+
.map(|(per_file, batches)| (per_file, split_streamed(batches, &early_tables)))
|
|
1483
|
+
});
|
|
1488
1484
|
let streamed = stream_early(&db, early, &strict_map);
|
|
1489
1485
|
(
|
|
1490
1486
|
grouping.join().expect("grouping scanned files panicked"),
|
|
1491
1487
|
streamed,
|
|
1492
1488
|
)
|
|
1493
1489
|
});
|
|
1494
|
-
|
|
1495
|
-
let (per_file, batches) = grouped?;
|
|
1490
|
+
streamed?;
|
|
1491
|
+
let (per_file, (batches, streamed)) = grouped?;
|
|
1496
1492
|
|
|
1497
1493
|
// The phase a user actually waits on: one `on_file` round trip per
|
|
1498
1494
|
// file or per table, plus whatever the table's DDL triggers on insert.
|
|
@@ -1501,8 +1497,15 @@ impl DirSQL {
|
|
|
1501
1497
|
+ batches
|
|
1502
1498
|
.iter()
|
|
1503
1499
|
.map(|(_, _, files)| files.len())
|
|
1504
|
-
.sum::<usize>()
|
|
1500
|
+
.sum::<usize>()
|
|
1501
|
+
+ streamed.iter().map(|(_, rel)| rel.len()).sum::<usize>())
|
|
1502
|
+
as u64;
|
|
1505
1503
|
let mut done: u64 = 0;
|
|
1504
|
+
for (table_name, rel_paths) in streamed {
|
|
1505
|
+
progress.update(done, Some(total_files));
|
|
1506
|
+
done += rel_paths.len() as u64;
|
|
1507
|
+
batch_files.insert(table_name, rel_paths);
|
|
1508
|
+
}
|
|
1506
1509
|
for (
|
|
1507
1510
|
ScannedFile {
|
|
1508
1511
|
rel_path,
|
|
@@ -1580,7 +1583,7 @@ impl DirSQL {
|
|
|
1580
1583
|
let current = persist_ready.as_ref().is_some_and(|(deleted, _, _)| {
|
|
1581
1584
|
files.iter().all(|f| f.trusted) && !deleted.iter().any(|(_, t)| *t == table_name)
|
|
1582
1585
|
});
|
|
1583
|
-
if !current
|
|
1586
|
+
if !current {
|
|
1584
1587
|
let table_root = anchors.of(&table_name);
|
|
1585
1588
|
let production = start_hook(hook, abs_paths.into_iter());
|
|
1586
1589
|
let outcome = stream_table_rows(&db, &table_name, production, strict)
|
|
@@ -2004,6 +2007,33 @@ pub struct ScannedFile {
|
|
|
2004
2007
|
pub trusted: bool,
|
|
2005
2008
|
}
|
|
2006
2009
|
|
|
2010
|
+
/// The files the startup scan found: as the walk found them, or already
|
|
2011
|
+
/// reconciled against the persistent cache.
|
|
2012
|
+
enum Scanned {
|
|
2013
|
+
Found(Vec<Found>),
|
|
2014
|
+
Files(Vec<ScannedFile>),
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
impl Scanned {
|
|
2018
|
+
/// Every file as a [`ScannedFile`]. A fresh walk's are made here rather
|
|
2019
|
+
/// than in prepare, so the copy runs off the thread that inserts rows.
|
|
2020
|
+
fn into_files(self) -> Vec<ScannedFile> {
|
|
2021
|
+
match self {
|
|
2022
|
+
Self::Found(found) => found
|
|
2023
|
+
.into_iter()
|
|
2024
|
+
.map(|found| ScannedFile {
|
|
2025
|
+
abs_path: found.path,
|
|
2026
|
+
rel_path: found.rel_path,
|
|
2027
|
+
table_name: found.table_name,
|
|
2028
|
+
stat: None,
|
|
2029
|
+
trusted: false,
|
|
2030
|
+
})
|
|
2031
|
+
.collect(),
|
|
2032
|
+
Self::Files(files) => files,
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2007
2037
|
/// Intermediate state produced by [`DirSQL::prepare_resolved`] and consumed
|
|
2008
2038
|
/// by [`DirSQL::finish_build`]. Opaque on purpose; fields are only visible
|
|
2009
2039
|
/// to the in-workspace bindings.
|
|
@@ -2020,7 +2050,7 @@ pub struct PreparedBuild {
|
|
|
2020
2050
|
/// The configured skip rules, carried through so path-table scans apply
|
|
2021
2051
|
/// the same ones declared tables do.
|
|
2022
2052
|
ignore: Vec<String>,
|
|
2023
|
-
scanned_files:
|
|
2053
|
+
scanned_files: Scanned,
|
|
2024
2054
|
/// Per-table hooks already running over the paths the scan found, by table.
|
|
2025
2055
|
early: HashMap<String, Production>,
|
|
2026
2056
|
persist: Option<PreparedPersist>,
|
|
@@ -2437,9 +2467,10 @@ fn collect_table_rows(
|
|
|
2437
2467
|
|
|
2438
2468
|
/// Replace a per-table hook's rows under [`BATCH_OWNER`], storing each chunk
|
|
2439
2469
|
/// the hook emits while the hook, on its own thread, goes on producing the
|
|
2440
|
-
/// next.
|
|
2441
|
-
///
|
|
2442
|
-
///
|
|
2470
|
+
/// next. Chunks are shaped on a thread of their own, in order, so shaping one
|
|
2471
|
+
/// overlaps inserting the last. The caller's open transaction keeps a failure
|
|
2472
|
+
/// from being seen: the outer `Err` is SQLite's, the inner one the hook's or a
|
|
2473
|
+
/// row's. A hook failure outranks a row that failed to shape.
|
|
2443
2474
|
fn stream_table_rows(
|
|
2444
2475
|
db: &Db,
|
|
2445
2476
|
table: &str,
|
|
@@ -2447,17 +2478,32 @@ fn stream_table_rows(
|
|
|
2447
2478
|
strict: bool,
|
|
2448
2479
|
) -> db::Result<std::result::Result<(), String>> {
|
|
2449
2480
|
db.delete_rows_by_file(table, BATCH_OWNER)?;
|
|
2450
|
-
let
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2481
|
+
let columns = db.get_table_columns(table)?;
|
|
2482
|
+
let Production { chunks, handle } = production;
|
|
2483
|
+
let (shaped_tx, shaped_rx) = std::sync::mpsc::channel();
|
|
2484
|
+
let shaper = std::thread::spawn({
|
|
2485
|
+
let table = table.to_string();
|
|
2486
|
+
move || {
|
|
2487
|
+
for chunk in chunks {
|
|
2488
|
+
let shaped = db::shape_json_rows(&table, columns.clone(), chunk, strict);
|
|
2489
|
+
if shaped_tx.send(shaped).is_err() {
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2454
2493
|
}
|
|
2455
|
-
|
|
2494
|
+
});
|
|
2495
|
+
let mut shaped = Ok(());
|
|
2496
|
+
for rows in shaped_rx {
|
|
2497
|
+
match rows {
|
|
2456
2498
|
Ok(rows) => db.insert_rows(table, &rows, BATCH_OWNER)?,
|
|
2457
|
-
Err(e) =>
|
|
2499
|
+
Err(e) => {
|
|
2500
|
+
shaped = Err(e.to_string());
|
|
2501
|
+
break;
|
|
2502
|
+
}
|
|
2458
2503
|
}
|
|
2459
2504
|
}
|
|
2460
|
-
|
|
2505
|
+
shaper.join().expect("shaping a hook's rows panicked");
|
|
2506
|
+
let produced = handle.join().expect("per-table hook panicked");
|
|
2461
2507
|
Ok(produced.and(shaped))
|
|
2462
2508
|
}
|
|
2463
2509
|
|
|
@@ -2591,14 +2637,12 @@ fn group_scanned(
|
|
|
2591
2637
|
Ok((per_file, batches))
|
|
2592
2638
|
}
|
|
2593
2639
|
|
|
2594
|
-
/// Insert the rows of every hook started before the scan
|
|
2595
|
-
/// tables streamed.
|
|
2640
|
+
/// Insert the rows of every hook started before the scan.
|
|
2596
2641
|
fn stream_early(
|
|
2597
2642
|
db: &Db,
|
|
2598
2643
|
early: HashMap<String, Production>,
|
|
2599
2644
|
strict_map: &HashMap<String, bool>,
|
|
2600
|
-
) -> Result<
|
|
2601
|
-
let mut streamed = HashSet::new();
|
|
2645
|
+
) -> Result<()> {
|
|
2602
2646
|
for (table_name, production) in early {
|
|
2603
2647
|
let strict = *strict_map.get(&table_name).unwrap_or(&false);
|
|
2604
2648
|
if let Err(message) =
|
|
@@ -2609,9 +2653,30 @@ fn stream_early(
|
|
|
2609
2653
|
message,
|
|
2610
2654
|
});
|
|
2611
2655
|
}
|
|
2612
|
-
streamed.insert(table_name);
|
|
2613
2656
|
}
|
|
2614
|
-
Ok(
|
|
2657
|
+
Ok(())
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
/// Split off the batches of tables whose hooks already ran, keeping only
|
|
2661
|
+
/// each one's relative paths in scan order.
|
|
2662
|
+
#[allow(clippy::type_complexity)]
|
|
2663
|
+
fn split_streamed(
|
|
2664
|
+
batches: Vec<(String, Arc<OnFilesFn>, Vec<ScannedFile>)>,
|
|
2665
|
+
streamed: &HashSet<String>,
|
|
2666
|
+
) -> (
|
|
2667
|
+
Vec<(String, Arc<OnFilesFn>, Vec<ScannedFile>)>,
|
|
2668
|
+
Vec<(String, Vec<String>)>,
|
|
2669
|
+
) {
|
|
2670
|
+
let mut rest = Vec::new();
|
|
2671
|
+
let mut done = Vec::new();
|
|
2672
|
+
for (table_name, hook, mut files) in batches {
|
|
2673
|
+
if streamed.contains(&table_name) {
|
|
2674
|
+
done.push((table_name, batch_paths(&mut files, false).0));
|
|
2675
|
+
} else {
|
|
2676
|
+
rest.push((table_name, hook, files));
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
(rest, done)
|
|
2615
2680
|
}
|
|
2616
2681
|
|
|
2617
2682
|
fn batch_paths(files: &mut [ScannedFile], keep_rel: bool) -> (Vec<String>, Vec<PathBuf>) {
|
|
@@ -3154,7 +3219,7 @@ mod internal_tests {
|
|
|
3154
3219
|
0,
|
|
3155
3220
|
"zero tables can match nothing, so the startup walk is pure waste"
|
|
3156
3221
|
);
|
|
3157
|
-
assert!(prepared.scanned_files.is_empty());
|
|
3222
|
+
assert!(prepared.scanned_files.into_files().is_empty());
|
|
3158
3223
|
}
|
|
3159
3224
|
|
|
3160
3225
|
/// The skip is narrow: one declared table still walks, and prepare still
|
|
@@ -3175,10 +3240,11 @@ mod internal_tests {
|
|
|
3175
3240
|
.unwrap();
|
|
3176
3241
|
|
|
3177
3242
|
assert_eq!(scan.calls.get(), 1);
|
|
3178
|
-
let found: Vec
|
|
3243
|
+
let found: Vec<String> = prepared
|
|
3179
3244
|
.scanned_files
|
|
3180
|
-
.
|
|
3181
|
-
.
|
|
3245
|
+
.into_files()
|
|
3246
|
+
.into_iter()
|
|
3247
|
+
.map(|f| f.rel_path)
|
|
3182
3248
|
.collect();
|
|
3183
3249
|
assert_eq!(found, vec!["a.txt"]);
|
|
3184
3250
|
}
|
|
@@ -3295,13 +3361,13 @@ mod internal_tests {
|
|
|
3295
3361
|
functions: Vec::new(),
|
|
3296
3362
|
groups: Vec::new(),
|
|
3297
3363
|
anchors: TableAnchors::at_root(dir.path()),
|
|
3298
|
-
scanned_files: vec![ScannedFile {
|
|
3364
|
+
scanned_files: Scanned::Files(vec![ScannedFile {
|
|
3299
3365
|
abs_path: PathBuf::new(),
|
|
3300
3366
|
rel_path: "ghost.txt".into(),
|
|
3301
3367
|
table_name: "ghost".into(),
|
|
3302
3368
|
stat: None,
|
|
3303
3369
|
trusted: false,
|
|
3304
|
-
}],
|
|
3370
|
+
}]),
|
|
3305
3371
|
early: HashMap::new(),
|
|
3306
3372
|
poll_interval: DEFAULT_POLL_INTERVAL,
|
|
3307
3373
|
persist: None,
|
|
@@ -5367,13 +5433,15 @@ mod internal_tests {
|
|
|
5367
5433
|
scanned_files: Vec<ScannedFile>,
|
|
5368
5434
|
persist: Option<PreparedPersist>,
|
|
5369
5435
|
) -> PreparedBuild {
|
|
5370
|
-
let scanned_files =
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5436
|
+
let scanned_files = Scanned::Files(
|
|
5437
|
+
scanned_files
|
|
5438
|
+
.into_iter()
|
|
5439
|
+
.map(|mut file| {
|
|
5440
|
+
file.abs_path = root.join(&file.rel_path);
|
|
5441
|
+
file
|
|
5442
|
+
})
|
|
5443
|
+
.collect(),
|
|
5444
|
+
);
|
|
5377
5445
|
PreparedBuild {
|
|
5378
5446
|
ignore: Vec::new(),
|
|
5379
5447
|
root: root.to_path_buf(),
|
|
@@ -5710,6 +5778,48 @@ mod internal_tests {
|
|
|
5710
5778
|
}
|
|
5711
5779
|
}
|
|
5712
5780
|
|
|
5781
|
+
#[test]
|
|
5782
|
+
fn finish_build_counts_the_files_of_a_hook_started_before_the_scan_toward_the_ingest_total() {
|
|
5783
|
+
let dir = TempDir::new().unwrap();
|
|
5784
|
+
let out = Captured::default();
|
|
5785
|
+
let progress = Progress::new(
|
|
5786
|
+
"indexing",
|
|
5787
|
+
"indexed",
|
|
5788
|
+
"files",
|
|
5789
|
+
Box::new(out.clone()),
|
|
5790
|
+
Box::new(progress::SystemClock),
|
|
5791
|
+
progress::Mode::Always,
|
|
5792
|
+
false,
|
|
5793
|
+
);
|
|
5794
|
+
let notes = Table::new("notes", "CREATE TABLE notes (name TEXT)", "*.md", |_| {
|
|
5795
|
+
Vec::new()
|
|
5796
|
+
});
|
|
5797
|
+
let (items, _) = recording_per_table("items", "*.txt");
|
|
5798
|
+
let (feeds, early) = start_per_table_hooks(std::slice::from_ref(&items));
|
|
5799
|
+
for name in ["a.txt", "b.txt"] {
|
|
5800
|
+
feeds["items"].send(dir.path().join(name)).unwrap();
|
|
5801
|
+
}
|
|
5802
|
+
drop(feeds);
|
|
5803
|
+
let scanned = vec![
|
|
5804
|
+
scanned("a.txt", "items", false),
|
|
5805
|
+
scanned("b.txt", "items", false),
|
|
5806
|
+
scanned("n.md", "notes", false),
|
|
5807
|
+
];
|
|
5808
|
+
let mut prepared = prepared_build(dir.path(), vec![notes, items], scanned, None);
|
|
5809
|
+
prepared.early = early;
|
|
5810
|
+
|
|
5811
|
+
DirSQL::finish_build_with_fs(prepared, Arc::new(FakeFs::default()), progress).unwrap();
|
|
5812
|
+
|
|
5813
|
+
let text = out.text();
|
|
5814
|
+
for line in [
|
|
5815
|
+
"dirsql: indexing 0/3 files (0%)",
|
|
5816
|
+
"dirsql: indexing 2/3 files (66%)",
|
|
5817
|
+
"dirsql: indexed 3 files in",
|
|
5818
|
+
] {
|
|
5819
|
+
assert!(text.contains(line), "missing {line:?} in {text:?}");
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5713
5823
|
#[test]
|
|
5714
5824
|
fn finish_build_skips_a_per_file_hook_for_a_file_the_cache_holds() {
|
|
5715
5825
|
let dir = TempDir::new().unwrap();
|