dirsql 0.4.126__tar.gz → 0.4.127__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.126 → dirsql-0.4.127}/Cargo.lock +2 -2
- {dirsql-0.4.126 → dirsql-0.4.127}/PKG-INFO +1 -1
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/Cargo.toml +1 -1
- dirsql-0.4.127/packages/python/e2e-attestations/bot-1562-hook-savepoint-1102.json +7 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/Cargo.toml +1 -1
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/command.rs +71 -21
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/foreign_key.rs +61 -10
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/lib.rs +152 -51
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/on_file.rs +59 -21
- {dirsql-0.4.126 → dirsql-0.4.127}/Cargo.toml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/README.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/_async.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/py.typed +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/read_config.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/AGENTS.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/context/.gitattributes +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/context/recipes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/context/usage.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/explanation.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/getting-started.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/embed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/persist.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/index.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/package.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/plugins.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/cli.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/glob.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/docs/speed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/README.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-11-02-watch-dirs-created-mid-registration.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/2026-11-02-watch-live-on-return.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/conftest.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/context/.gitattributes +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/context/recipes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/context/usage.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/glob.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/docs/speed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1461-chunked-read-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1461-step3-1020.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1475-rowpath-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1478-perdir-walk-1020.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1480-matcher-speed-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1524-path-eq-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1526-main-red-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1532-gitignore-fastest-bar-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1534-fm-native-1016.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1534-fm-native-1102.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1538-onfile-order-1019.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1540-update-in-place-1019.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1541-defer-fk-1019.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1544-perfile-update-1020.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1552-watch-gap-1102.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1557-watch-rename-1102.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-1562-watch-speed-1102.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-11-02-watch-dirs-created-mid-registration.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/2026-11-02-watch-live-on-return.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/bench_report.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/bench_suite.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/README.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/context/.gitattributes +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/context/recipes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/context/troubleshooting.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/context/usage.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/agent-skill.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/glob.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/speed.json +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/docs/speed.md +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/brace.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/context.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/frontend.html +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/frontend.js +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/db.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/gitignore_frame.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/listing.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/per_thread.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/posix_class.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/row_stream.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/tree_walk.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/vtab_scaffold.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.126 → dirsql-0.4.127}/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.127"
|
|
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.127"
|
|
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.127"
|
|
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/on_file_query_test.py tests/e2e/query_contract_test.py tests/e2e/declared_table_name_test.py tests/e2e/fanout_test.py tests/e2e/use_case_dossier_test.py tests/e2e/use_case_join_test.py tests/e2e/use_case_notebook_test.py tests/e2e/use_case_transcripts_test.py tests/e2e/watch_speed_test.py -q",
|
|
3
|
+
"ran_at": 1793671776,
|
|
4
|
+
"exit_code": 0,
|
|
5
|
+
"commit": "92277f18890c83a5a800db7c2dec4d6f0e4bb8fb",
|
|
6
|
+
"branch": "bot/1562-hook-savepoint-1102"
|
|
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.127"
|
|
10
10
|
edition.workspace = true
|
|
11
11
|
# Literal `license` (not `license.workspace = true`) because
|
|
12
12
|
# putitoutthere's preflight check reads `[package].license` directly
|
|
@@ -286,12 +286,14 @@ const READ_BYTES: usize = 262_144;
|
|
|
286
286
|
/// Run an already-built `argv` and hand its stdout to `on_block` as it
|
|
287
287
|
/// arrives, in blocks that each hold whole lines (the last block may lack its
|
|
288
288
|
/// trailing newline). The child runs with stdin closed. A non-zero exit is an
|
|
289
|
-
/// error after every block has been delivered.
|
|
289
|
+
/// error after every block has been delivered. `on_eof` runs once stdout has
|
|
290
|
+
/// closed, before the child's exit is known.
|
|
290
291
|
pub(crate) fn run_argv_blocks(
|
|
291
292
|
command: &str,
|
|
292
293
|
argv: &[String],
|
|
293
294
|
cwd: &Path,
|
|
294
295
|
on_block: &mut dyn FnMut(&str),
|
|
296
|
+
on_eof: &mut dyn FnMut(),
|
|
295
297
|
) -> Result<(), CommandError> {
|
|
296
298
|
let mut cmd = Command::new(&argv[0]);
|
|
297
299
|
push_args(&mut cmd, &argv[1..]);
|
|
@@ -310,10 +312,29 @@ pub(crate) fn run_argv_blocks(
|
|
|
310
312
|
buf
|
|
311
313
|
});
|
|
312
314
|
let mut stdout_pipe = child.stdout.take().expect("stdout piped");
|
|
315
|
+
let status =
|
|
316
|
+
drain_then_reap(&mut stdout_pipe, on_block, on_eof, || child.wait()).map_err(|source| {
|
|
317
|
+
CommandError::Io {
|
|
318
|
+
command: command.to_string(),
|
|
319
|
+
source,
|
|
320
|
+
}
|
|
321
|
+
})?;
|
|
322
|
+
let stderr = stderr_thread.join().unwrap_or_default();
|
|
323
|
+
check_exit(command, status, &stderr)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/// Hand `stdout` to `on_block` in blocks of whole lines until it closes, run
|
|
327
|
+
/// `on_eof`, then `reap` the child, so work on the output overlaps its exit.
|
|
328
|
+
fn drain_then_reap<T>(
|
|
329
|
+
stdout: &mut dyn Read,
|
|
330
|
+
on_block: &mut dyn FnMut(&str),
|
|
331
|
+
on_eof: &mut dyn FnMut(),
|
|
332
|
+
reap: impl FnOnce() -> T,
|
|
333
|
+
) -> T {
|
|
313
334
|
let mut pending: Vec<u8> = Vec::new();
|
|
314
335
|
let mut buf = vec![0u8; READ_BYTES];
|
|
315
336
|
loop {
|
|
316
|
-
let n = match
|
|
337
|
+
let n = match stdout.read(&mut buf) {
|
|
317
338
|
Ok(0) | Err(_) => break,
|
|
318
339
|
Ok(n) => n,
|
|
319
340
|
};
|
|
@@ -326,13 +347,8 @@ pub(crate) fn run_argv_blocks(
|
|
|
326
347
|
if !pending.is_empty() {
|
|
327
348
|
on_block(&String::from_utf8_lossy(&pending));
|
|
328
349
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
command: command.to_string(),
|
|
332
|
-
source,
|
|
333
|
-
})?;
|
|
334
|
-
let stderr = stderr_thread.join().unwrap_or_default();
|
|
335
|
-
check_exit(command, status, &stderr)
|
|
350
|
+
on_eof();
|
|
351
|
+
reap()
|
|
336
352
|
}
|
|
337
353
|
|
|
338
354
|
// One fn with cfg blocks rather than two cfg'd fns: cargo-mutants mutates
|
|
@@ -809,10 +825,16 @@ mod tests {
|
|
|
809
825
|
];
|
|
810
826
|
let mut seen = String::new();
|
|
811
827
|
let mut blocks = 0;
|
|
812
|
-
run_argv_blocks(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
828
|
+
run_argv_blocks(
|
|
829
|
+
"t",
|
|
830
|
+
&argv,
|
|
831
|
+
&cwd(),
|
|
832
|
+
&mut |block| {
|
|
833
|
+
seen.push_str(block);
|
|
834
|
+
blocks += 1;
|
|
835
|
+
},
|
|
836
|
+
&mut || {},
|
|
837
|
+
)
|
|
816
838
|
.unwrap();
|
|
817
839
|
assert_eq!(seen, "a\nb\nc");
|
|
818
840
|
assert!(blocks >= 1);
|
|
@@ -827,11 +849,17 @@ mod tests {
|
|
|
827
849
|
];
|
|
828
850
|
let mut lines = 0;
|
|
829
851
|
let mut blocks = 0;
|
|
830
|
-
run_argv_blocks(
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
852
|
+
run_argv_blocks(
|
|
853
|
+
"t",
|
|
854
|
+
&argv,
|
|
855
|
+
&cwd(),
|
|
856
|
+
&mut |block| {
|
|
857
|
+
blocks += 1;
|
|
858
|
+
assert!(block.ends_with('\n'), "block cut mid-line");
|
|
859
|
+
lines += block.lines().count();
|
|
860
|
+
},
|
|
861
|
+
&mut || {},
|
|
862
|
+
)
|
|
835
863
|
.unwrap();
|
|
836
864
|
assert_eq!(lines, 100_000);
|
|
837
865
|
assert!(blocks > 1, "2.7 MB arrives in more than one read");
|
|
@@ -845,8 +873,14 @@ mod tests {
|
|
|
845
873
|
"echo partial; echo oops >&2; exit 3".to_string(),
|
|
846
874
|
];
|
|
847
875
|
let mut seen = String::new();
|
|
848
|
-
let err =
|
|
849
|
-
|
|
876
|
+
let err = run_argv_blocks(
|
|
877
|
+
"t",
|
|
878
|
+
&argv,
|
|
879
|
+
&cwd(),
|
|
880
|
+
&mut |block| seen.push_str(block),
|
|
881
|
+
&mut || {},
|
|
882
|
+
)
|
|
883
|
+
.unwrap_err();
|
|
850
884
|
assert_eq!(seen, "partial\n");
|
|
851
885
|
match err {
|
|
852
886
|
CommandError::NonZeroExit {
|
|
@@ -859,10 +893,26 @@ mod tests {
|
|
|
859
893
|
}
|
|
860
894
|
}
|
|
861
895
|
|
|
896
|
+
#[test]
|
|
897
|
+
fn drain_then_reap_ends_the_output_before_reaping_the_child() {
|
|
898
|
+
let order = std::cell::RefCell::new(Vec::new());
|
|
899
|
+
let reaped = drain_then_reap(
|
|
900
|
+
&mut &b"a\nb"[..],
|
|
901
|
+
&mut |block| order.borrow_mut().push(block.to_string()),
|
|
902
|
+
&mut || order.borrow_mut().push("eof".to_string()),
|
|
903
|
+
|| {
|
|
904
|
+
order.borrow_mut().push("reap".to_string());
|
|
905
|
+
7
|
|
906
|
+
},
|
|
907
|
+
);
|
|
908
|
+
assert_eq!(reaped, 7);
|
|
909
|
+
assert_eq!(*order.borrow(), vec!["a\n", "b", "eof", "reap"]);
|
|
910
|
+
}
|
|
911
|
+
|
|
862
912
|
#[test]
|
|
863
913
|
fn run_argv_blocks_names_a_missing_program() {
|
|
864
914
|
let argv = vec!["definitely-not-a-real-binary-xyzzy".to_string()];
|
|
865
|
-
let err = run_argv_blocks("t", &argv, &cwd(), &mut |_| {}).unwrap_err();
|
|
915
|
+
let err = run_argv_blocks("t", &argv, &cwd(), &mut |_| {}, &mut || {}).unwrap_err();
|
|
866
916
|
assert!(
|
|
867
917
|
matches!(err, CommandError::NotOnPath { .. }),
|
|
868
918
|
"got: {err:?}"
|
|
@@ -54,18 +54,32 @@ pub(crate) fn commit(conn: &Connection) -> Result<(), DbError> {
|
|
|
54
54
|
pub(crate) fn atomically<T, E: From<rusqlite::Error>>(
|
|
55
55
|
conn: &Connection,
|
|
56
56
|
unit: impl FnOnce() -> Result<T, E>,
|
|
57
|
+
) -> Result<T, E> {
|
|
58
|
+
let value = stage(conn, unit)?;
|
|
59
|
+
keep(conn)?;
|
|
60
|
+
Ok(value)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// Apply `unit` but hold it open, for [`keep`] or [`discard`] to settle. A
|
|
64
|
+
/// unit that fails is discarded here and leaves nothing open.
|
|
65
|
+
pub(crate) fn stage<T, E: From<rusqlite::Error>>(
|
|
66
|
+
conn: &Connection,
|
|
67
|
+
unit: impl FnOnce() -> Result<T, E>,
|
|
57
68
|
) -> Result<T, E> {
|
|
58
69
|
conn.execute_batch("SAVEPOINT dirsql_unit")?;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
unit().inspect_err(|_| {
|
|
71
|
+
let _ = discard(conn);
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/// Keep the unit [`stage`] left open.
|
|
76
|
+
pub(crate) fn keep(conn: &Connection) -> rusqlite::Result<()> {
|
|
77
|
+
conn.execute_batch("RELEASE dirsql_unit")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// Drop the unit [`stage`] left open, as if it had never run.
|
|
81
|
+
pub(crate) fn discard(conn: &Connection) -> rusqlite::Result<()> {
|
|
82
|
+
conn.execute_batch("ROLLBACK TO dirsql_unit; RELEASE dirsql_unit")
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
/// The rows violating a foreign key right now, or `None` when there are none.
|
|
@@ -402,4 +416,41 @@ mod tests {
|
|
|
402
416
|
commit(&conn).unwrap();
|
|
403
417
|
assert_eq!(count(&conn, "parent"), 1);
|
|
404
418
|
}
|
|
419
|
+
#[test]
|
|
420
|
+
fn a_staged_unit_is_visible_until_discarded() {
|
|
421
|
+
let conn = family(CHILD);
|
|
422
|
+
let out: rusqlite::Result<i32> = stage(&conn, || {
|
|
423
|
+
conn.execute_batch("INSERT INTO parent VALUES (1, 'a')")?;
|
|
424
|
+
Ok(7)
|
|
425
|
+
});
|
|
426
|
+
assert_eq!(out.unwrap(), 7);
|
|
427
|
+
assert_eq!(count(&conn, "parent"), 1);
|
|
428
|
+
discard(&conn).unwrap();
|
|
429
|
+
assert_eq!(count(&conn, "parent"), 0);
|
|
430
|
+
assert!(conn.is_autocommit());
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
#[test]
|
|
434
|
+
fn a_staged_unit_kept_stays() {
|
|
435
|
+
let conn = family(CHILD);
|
|
436
|
+
let out: rusqlite::Result<()> = stage(&conn, || {
|
|
437
|
+
conn.execute_batch("INSERT INTO parent VALUES (1, 'a')")
|
|
438
|
+
});
|
|
439
|
+
out.unwrap();
|
|
440
|
+
keep(&conn).unwrap();
|
|
441
|
+
assert!(conn.is_autocommit());
|
|
442
|
+
assert_eq!(count(&conn, "parent"), 1);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
#[test]
|
|
446
|
+
fn a_staged_unit_that_fails_leaves_nothing_open() {
|
|
447
|
+
let conn = family(CHILD);
|
|
448
|
+
let out: rusqlite::Result<()> = stage(&conn, || {
|
|
449
|
+
conn.execute_batch("INSERT INTO parent VALUES (1, 'a')")?;
|
|
450
|
+
conn.execute_batch("INSERT INTO nowhere VALUES (1)")
|
|
451
|
+
});
|
|
452
|
+
assert!(out.is_err());
|
|
453
|
+
assert!(conn.is_autocommit());
|
|
454
|
+
assert_eq!(count(&conn, "parent"), 0);
|
|
455
|
+
}
|
|
405
456
|
}
|
|
@@ -108,7 +108,10 @@ type OnFileFn = dyn Fn(&str) -> std::result::Result<Vec<Row>, BoxError> + Send +
|
|
|
108
108
|
type RowSink<'a> = dyn FnMut(Vec<infer::JsonRow>) + Send + 'a;
|
|
109
109
|
/// The paths a per-table hook runs over, yielded as the scan finds them.
|
|
110
110
|
type PathFeed<'a> = dyn Iterator<Item = PathBuf> + Send + 'a;
|
|
111
|
-
|
|
111
|
+
/// What a per-table hook may call once its last chunk is out, before it knows
|
|
112
|
+
/// whether it succeeded, so its rows can be staged while it finishes.
|
|
113
|
+
type OutputEnd<'a> = dyn FnMut() + 'a;
|
|
114
|
+
type OnFilesFn = dyn Fn(&mut PathFeed<'_>, &mut RowSink<'_>, &mut OutputEnd<'_>) -> std::result::Result<(), BoxError>
|
|
112
115
|
+ Send
|
|
113
116
|
+ Sync
|
|
114
117
|
+ 'static;
|
|
@@ -378,11 +381,16 @@ impl Table {
|
|
|
378
381
|
+ Sync
|
|
379
382
|
+ 'static,
|
|
380
383
|
{
|
|
381
|
-
Self::per_table_streaming(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
Self::per_table_streaming(
|
|
385
|
+
name,
|
|
386
|
+
ddl,
|
|
387
|
+
glob,
|
|
388
|
+
move |feed, sink: &mut RowSink<'_>, _: &mut OutputEnd<'_>| {
|
|
389
|
+
let paths: Vec<PathBuf> = feed.collect();
|
|
390
|
+
sink(on_files(&paths)?);
|
|
391
|
+
Ok(())
|
|
392
|
+
},
|
|
393
|
+
)
|
|
386
394
|
}
|
|
387
395
|
|
|
388
396
|
/// [`per_table`](Self::per_table) for a hook that hands its rows over in
|
|
@@ -394,7 +402,11 @@ impl Table {
|
|
|
394
402
|
on_files: F,
|
|
395
403
|
) -> Self
|
|
396
404
|
where
|
|
397
|
-
F: Fn(
|
|
405
|
+
F: Fn(
|
|
406
|
+
&mut PathFeed<'_>,
|
|
407
|
+
&mut RowSink<'_>,
|
|
408
|
+
&mut OutputEnd<'_>,
|
|
409
|
+
) -> std::result::Result<(), BoxError>
|
|
398
410
|
+ Send
|
|
399
411
|
+ Sync
|
|
400
412
|
+ 'static,
|
|
@@ -1031,27 +1043,31 @@ impl DirSQL {
|
|
|
1031
1043
|
.unwrap_or_default(),
|
|
1032
1044
|
Err(e) => return vec![error_event(Some(table), trigger, e.to_string())],
|
|
1033
1045
|
};
|
|
1034
|
-
let raw_rows = match collect_table_rows(hook.as_ref(), &abs_paths) {
|
|
1035
|
-
Ok(rows) => rows,
|
|
1036
|
-
Err(e) => return vec![error_event(Some(table), trigger, e.to_string())],
|
|
1037
|
-
};
|
|
1038
1046
|
let strict = *self.inner.strict_map.get(table).unwrap_or(&false);
|
|
1039
|
-
|
|
1040
|
-
let
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
Err(e) => return vec![error_event(Some(table), trigger, e.to_string())],
|
|
1047
|
+
let rows = Mutex::new(Vec::new());
|
|
1048
|
+
let take_rows = || std::mem::take(&mut *rows.lock().expect("hook rows lock"));
|
|
1049
|
+
let mut staged = None;
|
|
1050
|
+
let produced = hook(
|
|
1051
|
+
&mut abs_paths.into_iter(),
|
|
1052
|
+
&mut |chunk| rows.lock().expect("hook rows lock").extend(chunk),
|
|
1053
|
+
&mut || staged = Some(self.stage_table_rows(table, take_rows(), strict)),
|
|
1054
|
+
);
|
|
1055
|
+
let staged = match (produced, staged) {
|
|
1056
|
+
(Err(e), staged) => {
|
|
1057
|
+
if let Some(Ok(staged)) = staged {
|
|
1058
|
+
let _ = foreign_key::discard(staged.db.conn());
|
|
1059
|
+
}
|
|
1060
|
+
return vec![error_event(Some(table), trigger, e.to_string())];
|
|
1054
1061
|
}
|
|
1062
|
+
(Ok(()), Some(staged)) => staged,
|
|
1063
|
+
(Ok(()), None) => self.stage_table_rows(table, take_rows(), strict),
|
|
1064
|
+
};
|
|
1065
|
+
let changes = match staged {
|
|
1066
|
+
Ok(Staged { db, changes }) => match foreign_key::keep(db.conn()) {
|
|
1067
|
+
Ok(()) => changes,
|
|
1068
|
+
Err(e) => return vec![error_event(Some(table), trigger, e.to_string())],
|
|
1069
|
+
},
|
|
1070
|
+
Err(message) => return vec![error_event(Some(table), trigger, message)],
|
|
1055
1071
|
};
|
|
1056
1072
|
|
|
1057
1073
|
if changes.keyed {
|
|
@@ -1067,6 +1083,23 @@ impl DirSQL {
|
|
|
1067
1083
|
}
|
|
1068
1084
|
}
|
|
1069
1085
|
|
|
1086
|
+
/// Shape a per-table hook's rows and write them as `table`'s, held open
|
|
1087
|
+
/// under the database lock until the hook's exit keeps or discards them.
|
|
1088
|
+
fn stage_table_rows(
|
|
1089
|
+
&self,
|
|
1090
|
+
table: &str,
|
|
1091
|
+
raw_rows: Vec<infer::JsonRow>,
|
|
1092
|
+
strict: bool,
|
|
1093
|
+
) -> std::result::Result<Staged<'_>, String> {
|
|
1094
|
+
let db = self.inner.db.lock().map_err(|e| e.to_string())?;
|
|
1095
|
+
let rows = shape_rows(&db, table, raw_rows, strict)?;
|
|
1096
|
+
let changes = foreign_key::stage(db.conn(), || {
|
|
1097
|
+
db.reconcile_batch_rows(table, BATCH_OWNER, &rows)
|
|
1098
|
+
})
|
|
1099
|
+
.map_err(|e| e.to_string())?;
|
|
1100
|
+
Ok(Staged { db, changes })
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1070
1103
|
/// Record in the table's file set whether `abs_path` is, now, one of the
|
|
1071
1104
|
/// files its per-table hook runs over. The set stays in walk order
|
|
1072
1105
|
/// (component-wise byte order), so the hook sees the same argument list a
|
|
@@ -2567,16 +2600,6 @@ fn shape_rows(
|
|
|
2567
2600
|
.map_err(|e| e.to_string())
|
|
2568
2601
|
}
|
|
2569
2602
|
|
|
2570
|
-
/// Every row a per-table hook produces over `paths`, gathered into one list.
|
|
2571
|
-
fn collect_table_rows(
|
|
2572
|
-
hook: &OnFilesFn,
|
|
2573
|
-
paths: &[PathBuf],
|
|
2574
|
-
) -> std::result::Result<Vec<infer::JsonRow>, BoxError> {
|
|
2575
|
-
let mut rows = Vec::new();
|
|
2576
|
-
hook(&mut paths.iter().cloned(), &mut |chunk| rows.extend(chunk))?;
|
|
2577
|
-
Ok(rows)
|
|
2578
|
-
}
|
|
2579
|
-
|
|
2580
2603
|
/// Replace a per-table hook's rows under [`BATCH_OWNER`], storing each chunk
|
|
2581
2604
|
/// the hook emits while the hook, on its own thread, goes on producing the
|
|
2582
2605
|
/// next. Chunks are shaped on a thread of their own, in order, so shaping one
|
|
@@ -2660,6 +2683,12 @@ fn refill_table_rows(
|
|
|
2660
2683
|
Ok(outcome)
|
|
2661
2684
|
}
|
|
2662
2685
|
|
|
2686
|
+
/// A per-table hook's rows written but not yet kept.
|
|
2687
|
+
struct Staged<'a> {
|
|
2688
|
+
db: std::sync::MutexGuard<'a, Db>,
|
|
2689
|
+
changes: db::RowChanges,
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2663
2692
|
/// A per-table hook running on its own thread, its rows arriving as chunks.
|
|
2664
2693
|
struct Production {
|
|
2665
2694
|
chunks: std::sync::mpsc::Receiver<Vec<infer::JsonRow>>,
|
|
@@ -2689,9 +2718,13 @@ fn start_hook(
|
|
|
2689
2718
|
if paths.peek().is_none() {
|
|
2690
2719
|
return Ok(());
|
|
2691
2720
|
}
|
|
2692
|
-
hook(
|
|
2693
|
-
|
|
2694
|
-
|
|
2721
|
+
hook(
|
|
2722
|
+
&mut paths,
|
|
2723
|
+
&mut |chunk| {
|
|
2724
|
+
let _ = sender.send(chunk);
|
|
2725
|
+
},
|
|
2726
|
+
&mut || {},
|
|
2727
|
+
)
|
|
2695
2728
|
.map_err(|e| e.to_string())
|
|
2696
2729
|
});
|
|
2697
2730
|
Production { chunks, handle }
|
|
@@ -2964,8 +2997,8 @@ fn build_tables_from_config(cfg: &config::Config, config_dir: &Path) -> Result<V
|
|
|
2964
2997
|
table_cfg.name.clone(),
|
|
2965
2998
|
table_cfg.ddl.clone(),
|
|
2966
2999
|
glob,
|
|
2967
|
-
move |paths: &mut PathFeed<'_>, sink: &mut RowSink<'_>| {
|
|
2968
|
-
run_on_files(&command, paths, &hook_cwd, &hook_root, sink)
|
|
3000
|
+
move |paths: &mut PathFeed<'_>, sink: &mut RowSink<'_>, end: &mut OutputEnd<'_>| {
|
|
3001
|
+
run_on_files(&command, paths, &hook_cwd, &hook_root, sink, end)
|
|
2969
3002
|
},
|
|
2970
3003
|
)
|
|
2971
3004
|
.anchored(anchor)
|
|
@@ -2992,9 +3025,10 @@ fn run_on_files(
|
|
|
2992
3025
|
config_dir: &Path,
|
|
2993
3026
|
root: &Path,
|
|
2994
3027
|
sink: &mut RowSink<'_>,
|
|
3028
|
+
end: &mut OutputEnd<'_>,
|
|
2995
3029
|
) -> std::result::Result<(), BoxError> {
|
|
2996
3030
|
Ok(on_file::run_streaming(
|
|
2997
|
-
command, config_dir, root, paths, sink,
|
|
3031
|
+
command, config_dir, root, paths, sink, end,
|
|
2998
3032
|
)?)
|
|
2999
3033
|
}
|
|
3000
3034
|
|
|
@@ -3478,7 +3512,7 @@ mod internal_tests {
|
|
|
3478
3512
|
"items",
|
|
3479
3513
|
"CREATE TABLE items (name TEXT)",
|
|
3480
3514
|
"**/*.txt",
|
|
3481
|
-
move |paths: &mut PathFeed<'_>, _: &mut RowSink<'_>| {
|
|
3515
|
+
move |paths: &mut PathFeed<'_>, _: &mut RowSink<'_>, _: &mut OutputEnd<'_>| {
|
|
3482
3516
|
for path in paths {
|
|
3483
3517
|
let _ = got.lock().unwrap().send(path);
|
|
3484
3518
|
}
|
|
@@ -4794,7 +4828,7 @@ mod internal_tests {
|
|
|
4794
4828
|
chunks: Vec<Vec<infer::JsonRow>>,
|
|
4795
4829
|
outcome: std::result::Result<(), String>,
|
|
4796
4830
|
) -> Production {
|
|
4797
|
-
let hook: Arc<OnFilesFn> = Arc::new(move |_paths, sink| {
|
|
4831
|
+
let hook: Arc<OnFilesFn> = Arc::new(move |_paths, sink, _end| {
|
|
4798
4832
|
for chunk in chunks.clone() {
|
|
4799
4833
|
sink(chunk);
|
|
4800
4834
|
}
|
|
@@ -5399,12 +5433,14 @@ mod internal_tests {
|
|
|
5399
5433
|
let Hook::PerTable(on_files) = &tables[0].hook else {
|
|
5400
5434
|
panic!("a configured on-file command runs once per table");
|
|
5401
5435
|
};
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
)
|
|
5436
|
+
let mut rows = Vec::new();
|
|
5437
|
+
on_files(
|
|
5438
|
+
&mut std::iter::once(dir.path().join("f.a")),
|
|
5439
|
+
&mut |chunk| rows.extend(chunk),
|
|
5440
|
+
&mut || {},
|
|
5441
|
+
)
|
|
5442
|
+
.unwrap();
|
|
5443
|
+
assert_eq!(rows.len(), 1);
|
|
5408
5444
|
assert!(tables[1].strict, "on-file table preserves strict flag");
|
|
5409
5445
|
}
|
|
5410
5446
|
|
|
@@ -5574,6 +5610,7 @@ mod internal_tests {
|
|
|
5574
5610
|
config_dir,
|
|
5575
5611
|
root,
|
|
5576
5612
|
&mut |chunk| rows.extend(chunk),
|
|
5613
|
+
&mut || {},
|
|
5577
5614
|
)?;
|
|
5578
5615
|
Ok(rows)
|
|
5579
5616
|
}
|
|
@@ -5605,6 +5642,7 @@ mod internal_tests {
|
|
|
5605
5642
|
dir.path(),
|
|
5606
5643
|
dir.path(),
|
|
5607
5644
|
&mut |chunk| chunks.push(chunk),
|
|
5645
|
+
&mut || {},
|
|
5608
5646
|
)
|
|
5609
5647
|
.expect("a well-formed payload parses");
|
|
5610
5648
|
assert!(chunks.len() > 1, "{} invocation(s)", chunks.len());
|
|
@@ -5991,7 +6029,7 @@ mod internal_tests {
|
|
|
5991
6029
|
"items",
|
|
5992
6030
|
"CREATE TABLE items (name TEXT)",
|
|
5993
6031
|
"*.txt",
|
|
5994
|
-
move |_: &mut PathFeed<'_>, sink: &mut RowSink<'_>| hook(sink),
|
|
6032
|
+
move |_: &mut PathFeed<'_>, sink: &mut RowSink<'_>, _: &mut OutputEnd<'_>| hook(sink),
|
|
5995
6033
|
)
|
|
5996
6034
|
}
|
|
5997
6035
|
|
|
@@ -6421,6 +6459,69 @@ mod internal_tests {
|
|
|
6421
6459
|
);
|
|
6422
6460
|
}
|
|
6423
6461
|
|
|
6462
|
+
/// A per-table hook that answers `answer`'s name, ends its output, and
|
|
6463
|
+
/// then fails when `answer` says so.
|
|
6464
|
+
fn ending_per_table(answer: Arc<Mutex<(String, bool)>>) -> Table {
|
|
6465
|
+
Table::per_table_streaming(
|
|
6466
|
+
"items",
|
|
6467
|
+
"CREATE TABLE items (name TEXT)",
|
|
6468
|
+
"**/*.txt",
|
|
6469
|
+
move |_: &mut PathFeed<'_>, sink: &mut RowSink<'_>, end: &mut OutputEnd<'_>| {
|
|
6470
|
+
let (name, fails) = answer.lock().unwrap().clone();
|
|
6471
|
+
sink(vec![name_json_row(&name)]);
|
|
6472
|
+
end();
|
|
6473
|
+
if fails {
|
|
6474
|
+
return Err("exited 1".into());
|
|
6475
|
+
}
|
|
6476
|
+
Ok(())
|
|
6477
|
+
},
|
|
6478
|
+
)
|
|
6479
|
+
}
|
|
6480
|
+
|
|
6481
|
+
fn ending_hook_db(answer: &Arc<Mutex<(String, bool)>>) -> (TempDir, DirSQL, PathBuf) {
|
|
6482
|
+
let dir = TempDir::new().unwrap();
|
|
6483
|
+
let root = dir.path().to_path_buf();
|
|
6484
|
+
let a = root.join("a.txt");
|
|
6485
|
+
let fake = Arc::new(
|
|
6486
|
+
FakeFs::default().with_subtree(root.clone(), vec![(a.clone(), "items".into())]),
|
|
6487
|
+
);
|
|
6488
|
+
let items = ending_per_table(Arc::clone(answer));
|
|
6489
|
+
let db =
|
|
6490
|
+
DirSQL::with_ignore_and_fs(&root, vec![items], Vec::<String>::new(), fake).unwrap();
|
|
6491
|
+
db.apply_file_events(vec![FileEvent::Created(a.clone())]);
|
|
6492
|
+
(dir, db, a)
|
|
6493
|
+
}
|
|
6494
|
+
|
|
6495
|
+
#[test]
|
|
6496
|
+
fn a_per_table_hook_that_fails_after_ending_its_output_writes_nothing() {
|
|
6497
|
+
let answer = Arc::new(Mutex::new(("old".to_string(), false)));
|
|
6498
|
+
let (_dir, db, a) = ending_hook_db(&answer);
|
|
6499
|
+
*answer.lock().unwrap() = ("new".to_string(), true);
|
|
6500
|
+
|
|
6501
|
+
let events = db.apply_file_events(vec![FileEvent::Modified(a)]);
|
|
6502
|
+
|
|
6503
|
+
assert!(
|
|
6504
|
+
matches!(&events[..], [RowEvent::Error { error, .. }] if error.contains("exited 1")),
|
|
6505
|
+
"{events:?}"
|
|
6506
|
+
);
|
|
6507
|
+
assert_eq!(row_names(&db), vec!["old"]);
|
|
6508
|
+
}
|
|
6509
|
+
|
|
6510
|
+
#[test]
|
|
6511
|
+
fn a_per_table_hook_that_succeeds_after_ending_its_output_keeps_its_rows() {
|
|
6512
|
+
let answer = Arc::new(Mutex::new(("old".to_string(), false)));
|
|
6513
|
+
let (_dir, db, a) = ending_hook_db(&answer);
|
|
6514
|
+
*answer.lock().unwrap() = ("new".to_string(), false);
|
|
6515
|
+
|
|
6516
|
+
let events = db.apply_file_events(vec![FileEvent::Modified(a)]);
|
|
6517
|
+
|
|
6518
|
+
assert!(
|
|
6519
|
+
matches!(&events[..], [RowEvent::Update { .. }]),
|
|
6520
|
+
"{events:?}"
|
|
6521
|
+
);
|
|
6522
|
+
assert_eq!(row_names(&db), vec!["new"]);
|
|
6523
|
+
}
|
|
6524
|
+
|
|
6424
6525
|
#[test]
|
|
6425
6526
|
fn apply_file_events_writes_only_the_rows_a_per_table_refresh_changed() {
|
|
6426
6527
|
let dir = TempDir::new().unwrap();
|