dirsql 0.4.114__tar.gz → 0.4.115__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.114 → dirsql-0.4.115}/Cargo.lock +2 -2
- {dirsql-0.4.114 → dirsql-0.4.115}/PKG-INFO +1 -1
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/context/usage.md +4 -0
- {dirsql-0.4.114/packages/rust → dirsql-0.4.115}/docs/reference/cli.md +11 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/Cargo.toml +1 -1
- {dirsql-0.4.114/packages/rust → dirsql-0.4.115/packages/python}/docs/context/usage.md +4 -0
- {dirsql-0.4.114 → dirsql-0.4.115/packages/python}/docs/reference/cli.md +11 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +7 -0
- dirsql-0.4.115/packages/python/e2e-attestations/bot-1526-main-red-1016.json +7 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/Cargo.toml +1 -1
- {dirsql-0.4.114/packages/python → dirsql-0.4.115/packages/rust}/docs/context/usage.md +4 -0
- {dirsql-0.4.114/packages/python → dirsql-0.4.115/packages/rust}/docs/reference/cli.md +11 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/db.rs +5 -5
- dirsql-0.4.115/packages/rust/src/gitignore_frame.rs +145 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/infer.rs +86 -30
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/lib.rs +174 -86
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/listing.rs +54 -4
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/matcher.rs +10 -6
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/parsed_vtab.rs +14 -2
- dirsql-0.4.115/packages/rust/src/per_thread.rs +111 -0
- dirsql-0.4.115/packages/rust/src/row_stream.rs +192 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/scanner.rs +211 -94
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/tree_walk.rs +86 -3
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/vtab.rs +155 -34
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/vtab_scaffold.rs +209 -104
- {dirsql-0.4.114 → dirsql-0.4.115}/Cargo.toml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/README.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/_async.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/py.typed +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/read_config.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/AGENTS.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/context/.gitattributes +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/context/recipes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/explanation.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/getting-started.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/embed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/persist.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/index.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/package.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/plugins.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/glob.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/docs/speed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/README.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/conftest.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/context/.gitattributes +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/context/recipes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/glob.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/docs/speed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/bench_report.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/bench_suite.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/README.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/context/.gitattributes +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/context/recipes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/glob.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/speed.json +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/docs/speed.md +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/brace.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/context.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/frontend.html +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/frontend.js +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/on_file.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/posix_class.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.114 → dirsql-0.4.115}/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.115"
|
|
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.115"
|
|
629
629
|
dependencies = [
|
|
630
630
|
"dirsql",
|
|
631
631
|
"pyo3",
|
|
@@ -46,6 +46,10 @@ Every row has `path`, `basename`, `dir`, `ext` (no dot, `NULL` when absent), `si
|
|
|
46
46
|
3. One row per record inside each file, inline: `--on-file <command>` attaches a parser to every path-table in the query. The parser prints one JSON object per line (NDJSON, never an array), and its output replaces the stat columns. See [hooks](https://dirsql.dev/reference/hooks).
|
|
47
47
|
4. Search by meaning: `uvx --with dirsql-plugin-embeddings dirsql "<sql>" --format json` adds `embed()` and `vec_distance_cosine()`. See [search by meaning](https://dirsql.dev/howto/search-by-meaning).
|
|
48
48
|
|
|
49
|
+
### Browser
|
|
50
|
+
|
|
51
|
+
When a person wants to explore the tree by hand, `uvx dirsql server --frontend` serves a SQL explorer and prints its URL (`Frontend at http://localhost:7117/`); add `-c .dirsql.toml` to list declared tables. The page runs nothing until **Run** is pressed; press it again to refresh. A config that fails to load shows its diagnostic in the page. It runs until Ctrl-C.
|
|
52
|
+
|
|
49
53
|
### Read-only
|
|
50
54
|
|
|
51
55
|
dirsql never writes to, moves or changes the files it scans, and it rejects mutating SQL. Do not pass `--persist`: it writes a cache database into the directory.
|
|
@@ -264,9 +264,20 @@ and declared tables reflect the server's index. The page does not use
|
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
266
|
dirsql server --frontend
|
|
267
|
+
# Frontend at http://localhost:7117/
|
|
268
|
+
# Running at localhost:7117
|
|
267
269
|
dirsql server --frontend -c .dirsql.toml
|
|
268
270
|
```
|
|
269
271
|
|
|
272
|
+
Every distribution embeds the same page and script in its binary, so
|
|
273
|
+
`npx dirsql server --frontend`, `uvx dirsql server --frontend`, and the
|
|
274
|
+
`cargo install`ed `dirsql server --frontend` serve the identical UI offline,
|
|
275
|
+
with no separate frontend runtime. In the page, a path-table query such as
|
|
276
|
+
`SELECT basename, size FROM './posts' ORDER BY basename` runs with or
|
|
277
|
+
without `-c`; a declared table such as `SELECT title, author FROM posts`
|
|
278
|
+
needs the config that declares it, passed with `-c`. The frontend stops like
|
|
279
|
+
the API-only server: `SIGINT` or `SIGTERM` exits `0`.
|
|
280
|
+
|
|
270
281
|
The shell reads `GET /frontend/state`. When the index is ready it returns
|
|
271
282
|
HTTP `200`:
|
|
272
283
|
|
|
@@ -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.115"
|
|
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
|
|
@@ -46,6 +46,10 @@ Every row has `path`, `basename`, `dir`, `ext` (no dot, `NULL` when absent), `si
|
|
|
46
46
|
3. One row per record inside each file, inline: `--on-file <command>` attaches a parser to every path-table in the query. The parser prints one JSON object per line (NDJSON, never an array), and its output replaces the stat columns. See [hooks](https://dirsql.dev/reference/hooks).
|
|
47
47
|
4. Search by meaning: `uvx --with dirsql-plugin-embeddings dirsql "<sql>" --format json` adds `embed()` and `vec_distance_cosine()`. See [search by meaning](https://dirsql.dev/howto/search-by-meaning).
|
|
48
48
|
|
|
49
|
+
### Browser
|
|
50
|
+
|
|
51
|
+
When a person wants to explore the tree by hand, `uvx dirsql server --frontend` serves a SQL explorer and prints its URL (`Frontend at http://localhost:7117/`); add `-c .dirsql.toml` to list declared tables. The page runs nothing until **Run** is pressed; press it again to refresh. A config that fails to load shows its diagnostic in the page. It runs until Ctrl-C.
|
|
52
|
+
|
|
49
53
|
### Read-only
|
|
50
54
|
|
|
51
55
|
dirsql never writes to, moves or changes the files it scans, and it rejects mutating SQL. Do not pass `--persist`: it writes a cache database into the directory.
|
|
@@ -264,9 +264,20 @@ and declared tables reflect the server's index. The page does not use
|
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
266
|
dirsql server --frontend
|
|
267
|
+
# Frontend at http://localhost:7117/
|
|
268
|
+
# Running at localhost:7117
|
|
267
269
|
dirsql server --frontend -c .dirsql.toml
|
|
268
270
|
```
|
|
269
271
|
|
|
272
|
+
Every distribution embeds the same page and script in its binary, so
|
|
273
|
+
`npx dirsql server --frontend`, `uvx dirsql server --frontend`, and the
|
|
274
|
+
`cargo install`ed `dirsql server --frontend` serve the identical UI offline,
|
|
275
|
+
with no separate frontend runtime. In the page, a path-table query such as
|
|
276
|
+
`SELECT basename, size FROM './posts' ORDER BY basename` runs with or
|
|
277
|
+
without `-c`; a declared table such as `SELECT title, author FROM posts`
|
|
278
|
+
needs the config that declares it, passed with `-c`. The frontend stops like
|
|
279
|
+
the API-only server: `SIGINT` or `SIGTERM` exits `0`.
|
|
280
|
+
|
|
270
281
|
The shell reads `GET /frontend/state`. When the index is ready it returns
|
|
271
282
|
HTTP `200`:
|
|
272
283
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_gitignore_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_node_modules_test.py tests/e2e/glob_speed_symlink_test.py tests/e2e/stat_speed_test.py tests/e2e/query_contract_test.py -q",
|
|
3
|
+
"ran_at": 1792077498,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "7c3d73c0397b24cb4a43a785b80223e5632a8dc5",
|
|
6
|
+
"branch": "bot/1461-wide-read-1015"
|
|
7
|
+
}
|
|
@@ -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",
|
|
3
|
+
"ran_at": 1792080077,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "c9a4e46dd7b2af9a444eacc52e308c6fba1cd0cb",
|
|
6
|
+
"branch": "bot/1477-onelevel-speed-1015"
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/glob_speed_gitignore_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/query_contract_test.py -x -q -s",
|
|
3
|
+
"ran_at": 1792078679,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "64a91dcf4851c02183542106f7230e7a237f482f",
|
|
6
|
+
"branch": "bot/1481-gitrepo-speed-1015"
|
|
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 -x -q -s",
|
|
3
|
+
"ran_at": 1792073709,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "fe211d95faa7bcae8234f897ce0d9c657072ecca",
|
|
6
|
+
"branch": "bot/1483-fm-speed-1015"
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"command": "uv run python -m pytest tests/e2e/jsonl_parse_speed_test.py tests/e2e/frontmatter_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_transcripts_test.py -x -q -s",
|
|
3
|
+
"ran_at": 1792074725,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "80a263f8596483f747e652b34ade1dca00bbd31e",
|
|
6
|
+
"branch": "bot/1484-jsonl-speed-1015"
|
|
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.115"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -46,6 +46,10 @@ Every row has `path`, `basename`, `dir`, `ext` (no dot, `NULL` when absent), `si
|
|
|
46
46
|
3. One row per record inside each file, inline: `--on-file <command>` attaches a parser to every path-table in the query. The parser prints one JSON object per line (NDJSON, never an array), and its output replaces the stat columns. See [hooks](https://dirsql.dev/reference/hooks).
|
|
47
47
|
4. Search by meaning: `uvx --with dirsql-plugin-embeddings dirsql "<sql>" --format json` adds `embed()` and `vec_distance_cosine()`. See [search by meaning](https://dirsql.dev/howto/search-by-meaning).
|
|
48
48
|
|
|
49
|
+
### Browser
|
|
50
|
+
|
|
51
|
+
When a person wants to explore the tree by hand, `uvx dirsql server --frontend` serves a SQL explorer and prints its URL (`Frontend at http://localhost:7117/`); add `-c .dirsql.toml` to list declared tables. The page runs nothing until **Run** is pressed; press it again to refresh. A config that fails to load shows its diagnostic in the page. It runs until Ctrl-C.
|
|
52
|
+
|
|
49
53
|
### Read-only
|
|
50
54
|
|
|
51
55
|
dirsql never writes to, moves or changes the files it scans, and it rejects mutating SQL. Do not pass `--persist`: it writes a cache database into the directory.
|
|
@@ -264,9 +264,20 @@ and declared tables reflect the server's index. The page does not use
|
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
266
|
dirsql server --frontend
|
|
267
|
+
# Frontend at http://localhost:7117/
|
|
268
|
+
# Running at localhost:7117
|
|
267
269
|
dirsql server --frontend -c .dirsql.toml
|
|
268
270
|
```
|
|
269
271
|
|
|
272
|
+
Every distribution embeds the same page and script in its binary, so
|
|
273
|
+
`npx dirsql server --frontend`, `uvx dirsql server --frontend`, and the
|
|
274
|
+
`cargo install`ed `dirsql server --frontend` serve the identical UI offline,
|
|
275
|
+
with no separate frontend runtime. In the page, a path-table query such as
|
|
276
|
+
`SELECT basename, size FROM './posts' ORDER BY basename` runs with or
|
|
277
|
+
without `-c`; a declared table such as `SELECT title, author FROM posts`
|
|
278
|
+
needs the config that declares it, passed with `-c`. The frontend stops like
|
|
279
|
+
the API-only server: `SIGINT` or `SIGTERM` exits `0`.
|
|
280
|
+
|
|
270
281
|
The shell reads `GET /frontend/state`. When the index is ready it returns
|
|
271
282
|
HTTP `200`:
|
|
272
283
|
|
|
@@ -724,7 +724,7 @@ impl Db {
|
|
|
724
724
|
let extra: Vec<&str> = row
|
|
725
725
|
.0
|
|
726
726
|
.iter()
|
|
727
|
-
.map(|(key, _)| key
|
|
727
|
+
.map(|(key, _)| &**key)
|
|
728
728
|
.filter(|key| !columns.iter().any(|c| c == key))
|
|
729
729
|
.collect();
|
|
730
730
|
if !extra.is_empty() {
|
|
@@ -737,7 +737,7 @@ impl Db {
|
|
|
737
737
|
let missing: Vec<&str> = columns
|
|
738
738
|
.iter()
|
|
739
739
|
.map(String::as_str)
|
|
740
|
-
.filter(|c| !row.0.iter().any(|(key, _)| key == c))
|
|
740
|
+
.filter(|c| !row.0.iter().any(|(key, _)| **key == **c))
|
|
741
741
|
.collect();
|
|
742
742
|
if !missing.is_empty() {
|
|
743
743
|
return Err(DbError::SchemaMismatch(format!(
|
|
@@ -748,14 +748,14 @@ impl Db {
|
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
750
|
let in_order = row.0.len() == columns.len()
|
|
751
|
-
&& row.0.iter().zip(&columns).all(|((key, _), c)| key == c);
|
|
751
|
+
&& row.0.iter().zip(&columns).all(|((key, _), c)| **key == **c);
|
|
752
752
|
if in_order {
|
|
753
753
|
cells.push(row.0.into_iter().map(|(_, v)| json_into_value(v)).collect());
|
|
754
754
|
continue;
|
|
755
755
|
}
|
|
756
756
|
let mut shaped = vec![Value::Null; columns.len()];
|
|
757
757
|
for (key, value) in row.0 {
|
|
758
|
-
if let Some(i) = columns.iter().position(|c|
|
|
758
|
+
if let Some(i) = columns.iter().position(|c| **c == *key) {
|
|
759
759
|
shaped[i] = json_into_value(value);
|
|
760
760
|
}
|
|
761
761
|
}
|
|
@@ -3211,7 +3211,7 @@ mod tests {
|
|
|
3211
3211
|
let serde_json::Value::Object(map) = row else {
|
|
3212
3212
|
panic!("row must be an object");
|
|
3213
3213
|
};
|
|
3214
|
-
JsonRow(map.into_iter().collect())
|
|
3214
|
+
JsonRow(map.into_iter().map(|(k, v)| (k.into(), v)).collect())
|
|
3215
3215
|
})
|
|
3216
3216
|
.collect()
|
|
3217
3217
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
use ignore::Match;
|
|
2
|
+
use ignore::gitignore::{Gitignore, GitignoreBuilder, Glob};
|
|
3
|
+
use std::path::Path;
|
|
4
|
+
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
5
|
+
use std::sync::{LazyLock, OnceLock};
|
|
6
|
+
|
|
7
|
+
/// One directory's `.gitignore` as the walk matches against it.
|
|
8
|
+
///
|
|
9
|
+
/// `Gitignore::matched` borrows a match buffer from a pool that only its
|
|
10
|
+
/// first caller's thread reaches without a lock; every other walk thread
|
|
11
|
+
/// contends on the rest. So each thread slot matches against a copy of its
|
|
12
|
+
/// own, compiled again on first use there.
|
|
13
|
+
pub(crate) struct Frame {
|
|
14
|
+
gitignore: Gitignore,
|
|
15
|
+
copies: Box<[OnceLock<Option<Gitignore>>]>,
|
|
16
|
+
compile: Box<dyn Fn() -> Option<Gitignore> + Send + Sync>,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static SLOTS: LazyLock<usize> =
|
|
20
|
+
LazyLock::new(|| std::thread::available_parallelism().map_or(1, usize::from));
|
|
21
|
+
|
|
22
|
+
static NEXT_SLOT: AtomicUsize = AtomicUsize::new(0);
|
|
23
|
+
|
|
24
|
+
thread_local! {
|
|
25
|
+
static SLOT: usize = NEXT_SLOT.fetch_add(1, Ordering::Relaxed);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
impl Frame {
|
|
29
|
+
/// The `.gitignore` in `dir`, if one exists. An unparsable file degrades
|
|
30
|
+
/// to no frame rather than failing the scan.
|
|
31
|
+
pub(crate) fn load(dir: &Path) -> Option<Frame> {
|
|
32
|
+
let dir = dir.to_path_buf();
|
|
33
|
+
Frame::compiled_by(move || {
|
|
34
|
+
let file = dir.join(".gitignore");
|
|
35
|
+
if !file.is_file() {
|
|
36
|
+
return None;
|
|
37
|
+
}
|
|
38
|
+
let mut builder = GitignoreBuilder::new(&dir);
|
|
39
|
+
builder.add(&file);
|
|
40
|
+
builder.build().ok()
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// A frame for `dir` holding `lines`, as though read from its `.gitignore`.
|
|
45
|
+
#[cfg(test)]
|
|
46
|
+
pub(crate) fn from_lines(dir: &Path, lines: &[&str]) -> Frame {
|
|
47
|
+
let dir = dir.to_path_buf();
|
|
48
|
+
let lines: Vec<String> = lines.iter().map(|line| line.to_string()).collect();
|
|
49
|
+
Frame::compiled_by(move || {
|
|
50
|
+
let mut builder = GitignoreBuilder::new(&dir);
|
|
51
|
+
for line in &lines {
|
|
52
|
+
builder.add_line(None, line).ok()?;
|
|
53
|
+
}
|
|
54
|
+
builder.build().ok()
|
|
55
|
+
})
|
|
56
|
+
.expect("in-memory gitignore lines compile")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fn compiled_by(
|
|
60
|
+
compile: impl Fn() -> Option<Gitignore> + Send + Sync + 'static,
|
|
61
|
+
) -> Option<Frame> {
|
|
62
|
+
Some(Frame {
|
|
63
|
+
gitignore: compile()?,
|
|
64
|
+
copies: (0..*SLOTS).map(|_| OnceLock::new()).collect(),
|
|
65
|
+
compile: Box::new(compile),
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
pub(crate) fn gitignore(&self) -> &Gitignore {
|
|
70
|
+
&self.gitignore
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// `Gitignore::matched`, on this thread's copy.
|
|
74
|
+
pub(crate) fn matched(&self, path: &Path, is_dir: bool) -> Match<&Glob> {
|
|
75
|
+
SLOT.with(|slot| self.copy(*slot)).matched(path, is_dir)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// The copy for thread `slot`, or the shared one when a copy no longer
|
|
79
|
+
/// compiles.
|
|
80
|
+
fn copy(&self, slot: usize) -> &Gitignore {
|
|
81
|
+
self.copies[slot % self.copies.len()]
|
|
82
|
+
.get_or_init(&*self.compile)
|
|
83
|
+
.as_ref()
|
|
84
|
+
.unwrap_or(&self.gitignore)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#[cfg(test)]
|
|
89
|
+
mod tests {
|
|
90
|
+
use super::*;
|
|
91
|
+
|
|
92
|
+
#[test]
|
|
93
|
+
fn a_frame_matches_as_its_gitignore_does() {
|
|
94
|
+
let frame = Frame::from_lines(Path::new("/r"), &["*.log", "!keep.log", "dist/"]);
|
|
95
|
+
assert!(frame.matched(Path::new("/r/a.log"), false).is_ignore());
|
|
96
|
+
assert!(
|
|
97
|
+
frame
|
|
98
|
+
.matched(Path::new("/r/keep.log"), false)
|
|
99
|
+
.is_whitelist()
|
|
100
|
+
);
|
|
101
|
+
assert!(frame.matched(Path::new("/r/dist"), true).is_ignore());
|
|
102
|
+
assert!(frame.matched(Path::new("/r/dist"), false).is_none());
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#[test]
|
|
106
|
+
fn each_thread_compiles_a_copy_of_its_own_once() {
|
|
107
|
+
let compiled = std::sync::Arc::new(AtomicUsize::new(0));
|
|
108
|
+
let count = std::sync::Arc::clone(&compiled);
|
|
109
|
+
let frame = Frame::compiled_by(move || {
|
|
110
|
+
count.fetch_add(1, Ordering::Relaxed);
|
|
111
|
+
Some(Gitignore::empty())
|
|
112
|
+
})
|
|
113
|
+
.unwrap();
|
|
114
|
+
frame.matched(Path::new("/r/a"), false);
|
|
115
|
+
frame.matched(Path::new("/r/b"), false);
|
|
116
|
+
assert_eq!(compiled.load(Ordering::Relaxed), 2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#[test]
|
|
120
|
+
fn a_thread_whose_copy_no_longer_compiles_matches_the_first() {
|
|
121
|
+
let first = std::sync::atomic::AtomicBool::new(true);
|
|
122
|
+
let frame = Frame::compiled_by(move || {
|
|
123
|
+
first.swap(false, Ordering::Relaxed).then(|| {
|
|
124
|
+
let mut builder = GitignoreBuilder::new("/r");
|
|
125
|
+
builder.add_line(None, "*.log").ok()?;
|
|
126
|
+
builder.build().ok()
|
|
127
|
+
})?
|
|
128
|
+
})
|
|
129
|
+
.unwrap();
|
|
130
|
+
assert!(frame.matched(Path::new("/r/a.log"), false).is_ignore());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#[test]
|
|
134
|
+
fn a_frame_serves_more_threads_than_it_has_copies() {
|
|
135
|
+
let frame = Frame::from_lines(Path::new("/r"), &["*.log"]);
|
|
136
|
+
let slot = frame.copies.len() * frame.copies.len();
|
|
137
|
+
assert!(frame.copy(slot).matched("/r/a.log", false).is_ignore());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#[test]
|
|
141
|
+
fn a_frame_reports_the_directory_of_its_gitignore() {
|
|
142
|
+
let frame = Frame::from_lines(Path::new("/r"), &["*.log"]);
|
|
143
|
+
assert_eq!(frame.gitignore().path(), Path::new("/r"));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
//! Everything here is pure. Reading files, running parsers, and declaring the
|
|
24
24
|
//! schema to SQLite belong to the caller (see [`crate::parsed_vtab`]).
|
|
25
25
|
|
|
26
|
-
use std::
|
|
26
|
+
use std::borrow::Cow;
|
|
27
|
+
use std::collections::{HashMap, HashSet};
|
|
27
28
|
use std::fmt;
|
|
29
|
+
use std::sync::Arc;
|
|
28
30
|
|
|
29
|
-
use serde::de::{Deserializer, MapAccess, Visitor};
|
|
31
|
+
use serde::de::{DeserializeSeed, Deserializer, MapAccess, Visitor};
|
|
30
32
|
|
|
31
33
|
use crate::Value;
|
|
32
34
|
use crate::json_to_value;
|
|
@@ -62,13 +64,17 @@ pub struct Column {
|
|
|
62
64
|
/// `serde_json::Map` sorts its keys, which would make column order
|
|
63
65
|
/// alphabetical; keeping the pairs in a `Vec` is what makes first-seen
|
|
64
66
|
/// ordering possible at all.
|
|
67
|
+
///
|
|
68
|
+
/// Keys are shared: every row parsed from one block of output holds the same
|
|
69
|
+
/// allocation for a key, so millions of rows cost no per-row key strings to
|
|
70
|
+
/// build or to free on the thread that stores them.
|
|
65
71
|
#[derive(Debug, Clone, Default, PartialEq)]
|
|
66
|
-
pub struct JsonRow(pub Vec<(
|
|
72
|
+
pub struct JsonRow(pub Vec<(Arc<str>, serde_json::Value)>);
|
|
67
73
|
|
|
68
74
|
impl JsonRow {
|
|
69
75
|
/// The raw JSON value for `key`, or `None` when the row omits it.
|
|
70
76
|
pub fn get(&self, key: &str) -> Option<&serde_json::Value> {
|
|
71
|
-
self.0.iter().find(|(k, _)| k == key).map(|(_, v)| v)
|
|
77
|
+
self.0.iter().find(|(k, _)| **k == *key).map(|(_, v)| v)
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
|
|
@@ -77,33 +83,55 @@ impl serde::Serialize for JsonRow {
|
|
|
77
83
|
use serde::ser::SerializeMap;
|
|
78
84
|
let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
|
79
85
|
for (key, value) in &self.0 {
|
|
80
|
-
map.serialize_entry(key, value)?;
|
|
86
|
+
map.serialize_entry(&**key, value)?;
|
|
81
87
|
}
|
|
82
88
|
map.end()
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
/// The keys one block of output has used, handed out shared.
|
|
93
|
+
#[derive(Default)]
|
|
94
|
+
struct Keys(HashSet<Arc<str>>);
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
impl Keys {
|
|
97
|
+
fn intern(&mut self, key: &str) -> Arc<str> {
|
|
98
|
+
if let Some(seen) = self.0.get(key) {
|
|
99
|
+
return Arc::clone(seen);
|
|
100
|
+
}
|
|
101
|
+
let key: Arc<str> = Arc::from(key);
|
|
102
|
+
self.0.insert(Arc::clone(&key));
|
|
103
|
+
key
|
|
104
|
+
}
|
|
105
|
+
}
|
|
92
106
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
107
|
+
/// A key as the line spells it, borrowed unless it carries an escape.
|
|
108
|
+
#[derive(serde::Deserialize)]
|
|
109
|
+
struct Key<'a>(#[serde(borrow)] Cow<'a, str>);
|
|
96
110
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
Ok(JsonRow(pairs))
|
|
103
|
-
}
|
|
104
|
-
}
|
|
111
|
+
/// Deserializes one row, drawing its keys from a block's [`Keys`].
|
|
112
|
+
struct RowSeed<'k>(&'k mut Keys);
|
|
113
|
+
|
|
114
|
+
impl<'de> DeserializeSeed<'de> for RowSeed<'_> {
|
|
115
|
+
type Value = JsonRow;
|
|
105
116
|
|
|
106
|
-
|
|
117
|
+
fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<JsonRow, D::Error> {
|
|
118
|
+
deserializer.deserialize_map(self)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
impl<'de> Visitor<'de> for RowSeed<'_> {
|
|
123
|
+
type Value = JsonRow;
|
|
124
|
+
|
|
125
|
+
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
126
|
+
f.write_str("a JSON row object")
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<JsonRow, A::Error> {
|
|
130
|
+
let mut pairs = Vec::new();
|
|
131
|
+
while let Some(Key(key)) = map.next_key::<Key<'de>>()? {
|
|
132
|
+
pairs.push((self.0.intern(&key), map.next_value::<serde_json::Value>()?));
|
|
133
|
+
}
|
|
134
|
+
Ok(JsonRow(pairs))
|
|
107
135
|
}
|
|
108
136
|
}
|
|
109
137
|
|
|
@@ -116,6 +144,7 @@ pub fn parse_rows(output: &str) -> Result<Vec<JsonRow>, String> {
|
|
|
116
144
|
/// [`parse_rows`] for a block that begins after `skipped` earlier lines of the
|
|
117
145
|
/// same output, so an error names its line in the whole output.
|
|
118
146
|
pub(crate) fn parse_rows_at(output: &str, skipped: usize) -> Result<Vec<JsonRow>, String> {
|
|
147
|
+
let mut keys = Keys::default();
|
|
119
148
|
let mut rows = Vec::new();
|
|
120
149
|
for (index, line) in output.lines().enumerate() {
|
|
121
150
|
let line = line.trim();
|
|
@@ -128,13 +157,22 @@ pub(crate) fn parse_rows_at(output: &str, skipped: usize) -> Result<Vec<JsonRow>
|
|
|
128
157
|
"line {number} is a JSON array; print one JSON object per line instead"
|
|
129
158
|
));
|
|
130
159
|
}
|
|
131
|
-
let row =
|
|
160
|
+
let row = parse_row(line, &mut keys)
|
|
132
161
|
.map_err(|e| format!("line {number} is not a JSON object: {e}"))?;
|
|
133
162
|
rows.push(row);
|
|
134
163
|
}
|
|
135
164
|
Ok(rows)
|
|
136
165
|
}
|
|
137
166
|
|
|
167
|
+
/// One line as a row, rejecting anything after the object as serde_json's
|
|
168
|
+
/// `from_str` does.
|
|
169
|
+
fn parse_row(line: &str, keys: &mut Keys) -> serde_json::Result<JsonRow> {
|
|
170
|
+
let mut deserializer = serde_json::Deserializer::from_str(line);
|
|
171
|
+
let row = RowSeed(keys).deserialize(&mut deserializer)?;
|
|
172
|
+
deserializer.end()?;
|
|
173
|
+
Ok(row)
|
|
174
|
+
}
|
|
175
|
+
|
|
138
176
|
/// What the rows have said about one key so far.
|
|
139
177
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
140
178
|
enum Observed {
|
|
@@ -194,8 +232,8 @@ pub fn infer_schema(rows: &[JsonRow]) -> Vec<Column> {
|
|
|
194
232
|
|
|
195
233
|
for row in rows {
|
|
196
234
|
for (key, value) in &row.0 {
|
|
197
|
-
let entry = observed.entry(key
|
|
198
|
-
order.push(key.
|
|
235
|
+
let entry = observed.entry(&**key).or_insert_with(|| {
|
|
236
|
+
order.push(key.to_string());
|
|
199
237
|
Observed::Untyped
|
|
200
238
|
});
|
|
201
239
|
*entry = entry.observe(value);
|
|
@@ -271,11 +309,7 @@ mod tests {
|
|
|
271
309
|
fn parse_rows_preserves_key_order_rather_than_sorting() {
|
|
272
310
|
let parsed = parse_rows(r#"{"zeta":1,"alpha":2}"#).unwrap();
|
|
273
311
|
assert_eq!(
|
|
274
|
-
parsed[0]
|
|
275
|
-
.0
|
|
276
|
-
.iter()
|
|
277
|
-
.map(|(k, _)| k.as_str())
|
|
278
|
-
.collect::<Vec<_>>(),
|
|
312
|
+
parsed[0].0.iter().map(|(k, _)| &**k).collect::<Vec<_>>(),
|
|
279
313
|
vec!["zeta", "alpha"]
|
|
280
314
|
);
|
|
281
315
|
}
|
|
@@ -303,6 +337,28 @@ mod tests {
|
|
|
303
337
|
fn parse_rows_rejects_a_line_that_is_not_an_object() {
|
|
304
338
|
let err = parse_rows("3").unwrap_err();
|
|
305
339
|
assert!(err.starts_with("line 1 is not a JSON object"), "got: {err}");
|
|
340
|
+
assert!(err.contains("expected a JSON row object"), "got: {err}");
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
#[test]
|
|
344
|
+
fn parse_rows_rejects_anything_after_the_object_on_its_line() {
|
|
345
|
+
let err = parse_rows(r#"{"a":1} {"b":2}"#).unwrap_err();
|
|
346
|
+
assert!(err.starts_with("line 1 is not a JSON object"), "got: {err}");
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
#[test]
|
|
350
|
+
fn parse_rows_reads_a_key_spelled_with_an_escape() {
|
|
351
|
+
let row = &rows(&[r#"{"a\u0062":1}"#])[0];
|
|
352
|
+
assert_eq!(row.get("ab"), Some(&serde_json::json!(1)));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
#[test]
|
|
356
|
+
fn parse_rows_shares_one_allocation_per_key_across_a_blocks_rows() {
|
|
357
|
+
let parsed = rows(&[r#"{"a":1,"b":2}"#, r#"{"b":3,"a":4}"#]);
|
|
358
|
+
let key = |row: usize, i: usize| parsed[row].0[i].0.as_ptr();
|
|
359
|
+
assert_eq!(key(0, 0), key(1, 1));
|
|
360
|
+
assert_eq!(key(0, 1), key(1, 0));
|
|
361
|
+
assert_ne!(key(0, 0), key(0, 1));
|
|
306
362
|
}
|
|
307
363
|
|
|
308
364
|
#[test]
|