dirsql 0.4.22__tar.gz → 0.4.24__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.22 → dirsql-0.4.24}/Cargo.lock +1 -1
- {dirsql-0.4.22 → dirsql-0.4.24}/PKG-INFO +1 -1
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/.vitepress/config.ts +1 -0
- {dirsql-0.4.22/packages/rust → dirsql-0.4.24}/docs/howto/extract-from-contents.md +3 -0
- dirsql-0.4.24/docs/howto/query-json.md +197 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/path-tables.md +11 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/Cargo.toml +1 -1
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/.vitepress/config.ts +1 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/extract-from-contents.md +3 -0
- dirsql-0.4.24/packages/python/docs/howto/query-json.md +197 -0
- {dirsql-0.4.22/packages/rust → dirsql-0.4.24/packages/python}/docs/reference/path-tables.md +11 -0
- dirsql-0.4.24/packages/python/e2e-attestations/claude-issue-951-0eease.json +7 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/Cargo.toml +6 -0
- {dirsql-0.4.22 → dirsql-0.4.24/packages/rust}/docs/howto/extract-from-contents.md +3 -0
- dirsql-0.4.24/packages/rust/docs/howto/query-json.md +197 -0
- {dirsql-0.4.22/packages/python → dirsql-0.4.24/packages/rust}/docs/reference/path-tables.md +11 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/db.rs +146 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-persist-wal.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +0 -10
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +0 -7
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -11
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +0 -11
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-20-schema-inference.md +0 -12
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-21-on-file-flag.md +0 -14
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-23-init-escalation-example.md +0 -10
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-23-query-default-cli.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-24-hookless-table-config-error.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-07-29-on-file-failures-accumulate.md +0 -8
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-02-drop-regex.md +0 -17
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-02-per-file-scan-failures.md +0 -35
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-02-release-profile.md +0 -7
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-03-gitignore-by-default.md +0 -9
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-03-nested-default-ignores.md +0 -11
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-04-cast-lints.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-04-cli-run-shim.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-04-configless-extension.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-10-dirsql-function.md +0 -1
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-10-remove-query-hooks.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-11-oneshot-query-no-timeout.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-11-persist-parsed-path-tables.md +0 -4
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-11-retire-hook-timeout.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/2026-08-12-unquote-inverts-quote-literal.md +0 -3
- dirsql-0.4.22/packages/rust/changelog.d/README.md +0 -17
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -52
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +0 -70
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-persist-wal.md +0 -38
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -54
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -46
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +0 -50
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -67
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +0 -57
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +0 -53
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-23-init-escalation-example.md +0 -64
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-23-query-default-cli.md +0 -55
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-24-hookless-table-config-error.md +0 -51
- dirsql-0.4.22/packages/rust/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -55
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-02-per-file-scan-failures.md +0 -100
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-03-gitignore-by-default.md +0 -52
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-03-nested-default-ignores.md +0 -46
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-10-remove-query-hooks.md +0 -47
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-11-oneshot-query-no-timeout.md +0 -46
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-11-persist-parsed-path-tables.md +0 -58
- dirsql-0.4.22/packages/rust/migrations.d/2026-08-11-retire-hook-timeout.md +0 -51
- dirsql-0.4.22/packages/rust/migrations.d/README.md +0 -19
- {dirsql-0.4.22 → dirsql-0.4.24}/Cargo.toml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/README.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/_async.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/py.typed +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/AGENTS.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/explanation.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/getting-started.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/embed.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/persist.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/index.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/package.json +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/plugins.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/cli.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/README.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/conftest.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/README.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/run.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/lib.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/parsed_cache.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.22 → dirsql-0.4.24}/pyproject.toml +0 -0
|
@@ -54,6 +54,7 @@ export default defineConfig({
|
|
|
54
54
|
{ text: 'Derive columns from file paths', link: '/howto/columns-from-paths' },
|
|
55
55
|
{ text: 'Extract rows from file contents', link: '/howto/extract-from-contents' },
|
|
56
56
|
{ text: 'Parse your files into columns', link: '/howto/parse-files-into-columns' },
|
|
57
|
+
{ text: 'Query JSON file contents', link: '/howto/query-json' },
|
|
57
58
|
{ text: 'Search documents by meaning', link: '/howto/search-by-meaning' },
|
|
58
59
|
{ text: "Skip files you don't want indexed", link: '/howto/skip-files' },
|
|
59
60
|
{ text: 'Load a SQLite extension', link: '/howto/load-extension' },
|
|
@@ -77,6 +77,9 @@ SQLite value mapping is under
|
|
|
77
77
|
|
|
78
78
|
## Going further
|
|
79
79
|
|
|
80
|
+
- Just want to read a field or two out of some JSON files? SQLite's JSON
|
|
81
|
+
operators work directly on a path-table's `content` column, with no config
|
|
82
|
+
and no command — [Query JSON file contents](./query-json.md).
|
|
80
83
|
- The command re-runs on every startup and on every change to a matched
|
|
81
84
|
file. If it is expensive, [keep the index across restarts](./persist.md).
|
|
82
85
|
- Embedding `dirsql` in a program instead? The SDK's `on_file` callback
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Query JSON file contents
|
|
2
|
+
|
|
3
|
+
A tree of JSON files is already a table — you just have to ask for it. The
|
|
4
|
+
hidden [`content`](../reference/path-tables.md#columns) column holds each
|
|
5
|
+
file's raw text, and SQLite's JSON operators read fields straight out of it.
|
|
6
|
+
No config, no parser, no schema.
|
|
7
|
+
|
|
8
|
+
## 1. Pull a field out of `content`
|
|
9
|
+
|
|
10
|
+
Suppose each plugin ships a `metadata.json`:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
plugins/alpha/metadata.json
|
|
14
|
+
plugins/beta/metadata.json
|
|
15
|
+
plugins/gamma/metadata.json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"name": "alpha",
|
|
21
|
+
"version": "1.4.0",
|
|
22
|
+
"disabled": false,
|
|
23
|
+
"runtime": { "engine": "wasm", "memory_mb": 64 },
|
|
24
|
+
"tags": ["search", "index"]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The `->>` operator extracts a field. **The key is a string literal, not a bare
|
|
29
|
+
identifier** — this is the one thing that trips everyone up:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dirsql query "SELECT content ->> disabled FROM './plugins/alpha/metadata.json'"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
dirsql query: SQLite error: no such column: disabled in SELECT content ->> disabled FROM './plugins/alpha/metadata.json' at offset 19
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Unquoted, `disabled` is a column name to SQLite's parser, and no such column
|
|
40
|
+
exists. Quote it and the field comes back:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
dirsql query "SELECT content ->> 'disabled' FROM './plugins/alpha/metadata.json'"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
[{"content ->> 'disabled'":0}]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The expression becomes the column name, so alias it:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
dirsql query "SELECT content ->> 'disabled' AS disabled FROM './plugins/alpha/metadata.json'"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
[{"disabled":0}]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 2. Query the whole tree
|
|
61
|
+
|
|
62
|
+
`content` is a [path-table](../reference/path-tables.md) column, so the same
|
|
63
|
+
expression works over a glob — one row per file:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
dirsql query "SELECT content ->> 'name' AS name, content ->> 'version' AS version
|
|
67
|
+
FROM './**/metadata.json' ORDER BY name"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
[{"name":"alpha","version":"1.4.0"},{"name":"beta","version":"0.9.2"},{"name":"gamma","version":"2.0.1"}]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`content` is read only when a query names it, so a glob over a large tree costs
|
|
75
|
+
nothing until you actually reach inside the files.
|
|
76
|
+
|
|
77
|
+
## 3. Reach nested keys
|
|
78
|
+
|
|
79
|
+
A key that starts with `$` is a **JSON path**: dotted for nested objects,
|
|
80
|
+
bracketed for array elements. It is still a string literal.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
dirsql query "SELECT content ->> 'name' AS name,
|
|
84
|
+
content ->> '$.runtime.engine' AS engine,
|
|
85
|
+
content ->> '$.runtime.memory_mb' AS memory_mb
|
|
86
|
+
FROM './**/metadata.json' ORDER BY name"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
[{"engine":"wasm","memory_mb":64,"name":"alpha"},{"engine":"native","memory_mb":256,"name":"beta"},{"engine":"wasm","memory_mb":128,"name":"gamma"}]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`content ->> 'name'` and `content ->> '$.name'` are the same lookup — the bare
|
|
94
|
+
form is shorthand for a top-level key. `json_extract(content, '$.name')` is the
|
|
95
|
+
function spelling of the same thing and takes the same paths.
|
|
96
|
+
|
|
97
|
+
## 4. Filter and aggregate
|
|
98
|
+
|
|
99
|
+
Extracted fields are ordinary SQL values, so they work in `WHERE`, `GROUP BY`,
|
|
100
|
+
and joins:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
dirsql query "SELECT path FROM './**/metadata.json'
|
|
104
|
+
WHERE content ->> 'disabled' = 0 ORDER BY path"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
[{"path":"plugins/alpha/metadata.json"},{"path":"plugins/gamma/metadata.json"}]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
To count across an array field, expand it with `json_each`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
dirsql query "SELECT t.value AS tag, COUNT(*) AS n
|
|
115
|
+
FROM './**/metadata.json' AS m, json_each(m.content, '$.tags') AS t
|
|
116
|
+
GROUP BY tag ORDER BY n DESC, tag"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
[{"n":2,"tag":"index"},{"n":2,"tag":"search"},{"n":1,"tag":"export"},{"n":1,"tag":"rerank"}]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## `->` and `->>`
|
|
124
|
+
|
|
125
|
+
Both take the same paths; they differ in what they hand back. `->>` returns the
|
|
126
|
+
**SQL value**; `->` returns the **JSON text** of that value, quotes and all:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
dirsql query "SELECT content -> 'name' AS arrow, content ->> 'name' AS arrow2
|
|
130
|
+
FROM './plugins/alpha/metadata.json'"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
[{"arrow":"\"alpha\"","arrow2":"alpha"}]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Reach for `->>` to get a value out, and `->` to keep drilling — its JSON result
|
|
138
|
+
is a valid left operand for another `->` or `->>`.
|
|
139
|
+
|
|
140
|
+
## How JSON types arrive
|
|
141
|
+
|
|
142
|
+
`->>` maps JSON types onto SQLite's, which has no boolean:
|
|
143
|
+
|
|
144
|
+
| In the file | In the row |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| `true` / `false` | `1` / `0` |
|
|
147
|
+
| `null` | `NULL` |
|
|
148
|
+
| number | INTEGER or REAL |
|
|
149
|
+
| string | TEXT, unquoted |
|
|
150
|
+
| object or array | its JSON text |
|
|
151
|
+
| key not present | `NULL` |
|
|
152
|
+
|
|
153
|
+
So `disabled: false` reads back as `0`, and `WHERE content ->> 'disabled' = 0`
|
|
154
|
+
is how you ask for the enabled ones — `= false` is not SQLite syntax.
|
|
155
|
+
|
|
156
|
+
A missing key and a `null` value both arrive as `NULL`. Use
|
|
157
|
+
`content -> 'key' IS NULL` to tell them apart: `->` yields the JSON text
|
|
158
|
+
`'null'` for a present null, and SQL `NULL` only when the key is absent.
|
|
159
|
+
|
|
160
|
+
## When a file isn't valid JSON
|
|
161
|
+
|
|
162
|
+
The JSON operators reject a non-JSON `content`, and that fails the **whole
|
|
163
|
+
query** — one stray file, no rows at all:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
dirsql query: SQLite error: malformed JSON
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
An empty file counts too: `content` is `''`, which is not valid JSON. Guard the
|
|
170
|
+
scan with `json_valid` when the glob might catch something it shouldn't:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
dirsql query "SELECT content ->> 'name' AS name FROM './**/metadata.json'
|
|
174
|
+
WHERE json_valid(content) ORDER BY name"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Files that fail the guard drop out and the rest still answer. A file that is
|
|
178
|
+
unreadable or not UTF-8 has `NULL` content, which is not an error —
|
|
179
|
+
`json_valid(NULL)` is `NULL`, so the guard excludes those too.
|
|
180
|
+
|
|
181
|
+
## Going further
|
|
182
|
+
|
|
183
|
+
- Only path-tables expose `content`. A named `[[table]]` has exactly the columns
|
|
184
|
+
its hook emits ([columns reference](../reference/columns.md)) — reading a
|
|
185
|
+
field with `->>` there means the hook already emitted it.
|
|
186
|
+
- Doing this on every query re-reads and re-parses every file. When the same
|
|
187
|
+
tree is queried repeatedly, move the extraction into a table:
|
|
188
|
+
[Extract rows from file contents](./extract-from-contents.md) declares the
|
|
189
|
+
columns in a config, and [Parse your files into columns](./parse-files-into-columns.md)
|
|
190
|
+
prototypes the same parser inline with `--on-file`. Either way the parsed rows
|
|
191
|
+
are indexed, watched, and [persistable](./persist.md).
|
|
192
|
+
- One JSON file holding *many* records is a parser's job, not an operator's —
|
|
193
|
+
`json_each` expands an array within a row, but one row per record needs
|
|
194
|
+
[`on-file`](../reference/hooks.md#on-file).
|
|
195
|
+
- The full operator and function set is SQLite's own:
|
|
196
|
+
[JSON functions](https://sqlite.org/json1.html). `dirsql` adds nothing to it
|
|
197
|
+
and takes nothing away.
|
|
@@ -61,6 +61,17 @@ SELECT * FROM '**/*.md';
|
|
|
61
61
|
-- no such table: **/*.md; did you mean './**/*.md'?
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
**The quotes are required too.** A path is not a bare SQL identifier — `./` is
|
|
65
|
+
punctuation to SQLite's parser, so an unquoted path fails at parse time, before
|
|
66
|
+
dirsql ever sees a table name to resolve. Single or double quotes both work;
|
|
67
|
+
the error names the quoted form:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
SELECT * FROM ./;
|
|
71
|
+
-- near ".": syntax error in SELECT * FROM ./ at offset 14
|
|
72
|
+
-- hint: paths used as table names must be quoted; did you mean "./"?
|
|
73
|
+
```
|
|
74
|
+
|
|
64
75
|
### Paths outside the index root
|
|
65
76
|
|
|
66
77
|
Three other prefixes resolve, with their usual shell meanings:
|
|
@@ -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.24"
|
|
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
|
|
@@ -54,6 +54,7 @@ export default defineConfig({
|
|
|
54
54
|
{ text: 'Derive columns from file paths', link: '/howto/columns-from-paths' },
|
|
55
55
|
{ text: 'Extract rows from file contents', link: '/howto/extract-from-contents' },
|
|
56
56
|
{ text: 'Parse your files into columns', link: '/howto/parse-files-into-columns' },
|
|
57
|
+
{ text: 'Query JSON file contents', link: '/howto/query-json' },
|
|
57
58
|
{ text: 'Search documents by meaning', link: '/howto/search-by-meaning' },
|
|
58
59
|
{ text: "Skip files you don't want indexed", link: '/howto/skip-files' },
|
|
59
60
|
{ text: 'Load a SQLite extension', link: '/howto/load-extension' },
|
|
@@ -77,6 +77,9 @@ SQLite value mapping is under
|
|
|
77
77
|
|
|
78
78
|
## Going further
|
|
79
79
|
|
|
80
|
+
- Just want to read a field or two out of some JSON files? SQLite's JSON
|
|
81
|
+
operators work directly on a path-table's `content` column, with no config
|
|
82
|
+
and no command — [Query JSON file contents](./query-json.md).
|
|
80
83
|
- The command re-runs on every startup and on every change to a matched
|
|
81
84
|
file. If it is expensive, [keep the index across restarts](./persist.md).
|
|
82
85
|
- Embedding `dirsql` in a program instead? The SDK's `on_file` callback
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Query JSON file contents
|
|
2
|
+
|
|
3
|
+
A tree of JSON files is already a table — you just have to ask for it. The
|
|
4
|
+
hidden [`content`](../reference/path-tables.md#columns) column holds each
|
|
5
|
+
file's raw text, and SQLite's JSON operators read fields straight out of it.
|
|
6
|
+
No config, no parser, no schema.
|
|
7
|
+
|
|
8
|
+
## 1. Pull a field out of `content`
|
|
9
|
+
|
|
10
|
+
Suppose each plugin ships a `metadata.json`:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
plugins/alpha/metadata.json
|
|
14
|
+
plugins/beta/metadata.json
|
|
15
|
+
plugins/gamma/metadata.json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"name": "alpha",
|
|
21
|
+
"version": "1.4.0",
|
|
22
|
+
"disabled": false,
|
|
23
|
+
"runtime": { "engine": "wasm", "memory_mb": 64 },
|
|
24
|
+
"tags": ["search", "index"]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The `->>` operator extracts a field. **The key is a string literal, not a bare
|
|
29
|
+
identifier** — this is the one thing that trips everyone up:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dirsql query "SELECT content ->> disabled FROM './plugins/alpha/metadata.json'"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
dirsql query: SQLite error: no such column: disabled in SELECT content ->> disabled FROM './plugins/alpha/metadata.json' at offset 19
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Unquoted, `disabled` is a column name to SQLite's parser, and no such column
|
|
40
|
+
exists. Quote it and the field comes back:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
dirsql query "SELECT content ->> 'disabled' FROM './plugins/alpha/metadata.json'"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
[{"content ->> 'disabled'":0}]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The expression becomes the column name, so alias it:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
dirsql query "SELECT content ->> 'disabled' AS disabled FROM './plugins/alpha/metadata.json'"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
[{"disabled":0}]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 2. Query the whole tree
|
|
61
|
+
|
|
62
|
+
`content` is a [path-table](../reference/path-tables.md) column, so the same
|
|
63
|
+
expression works over a glob — one row per file:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
dirsql query "SELECT content ->> 'name' AS name, content ->> 'version' AS version
|
|
67
|
+
FROM './**/metadata.json' ORDER BY name"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
[{"name":"alpha","version":"1.4.0"},{"name":"beta","version":"0.9.2"},{"name":"gamma","version":"2.0.1"}]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`content` is read only when a query names it, so a glob over a large tree costs
|
|
75
|
+
nothing until you actually reach inside the files.
|
|
76
|
+
|
|
77
|
+
## 3. Reach nested keys
|
|
78
|
+
|
|
79
|
+
A key that starts with `$` is a **JSON path**: dotted for nested objects,
|
|
80
|
+
bracketed for array elements. It is still a string literal.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
dirsql query "SELECT content ->> 'name' AS name,
|
|
84
|
+
content ->> '$.runtime.engine' AS engine,
|
|
85
|
+
content ->> '$.runtime.memory_mb' AS memory_mb
|
|
86
|
+
FROM './**/metadata.json' ORDER BY name"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
[{"engine":"wasm","memory_mb":64,"name":"alpha"},{"engine":"native","memory_mb":256,"name":"beta"},{"engine":"wasm","memory_mb":128,"name":"gamma"}]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`content ->> 'name'` and `content ->> '$.name'` are the same lookup — the bare
|
|
94
|
+
form is shorthand for a top-level key. `json_extract(content, '$.name')` is the
|
|
95
|
+
function spelling of the same thing and takes the same paths.
|
|
96
|
+
|
|
97
|
+
## 4. Filter and aggregate
|
|
98
|
+
|
|
99
|
+
Extracted fields are ordinary SQL values, so they work in `WHERE`, `GROUP BY`,
|
|
100
|
+
and joins:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
dirsql query "SELECT path FROM './**/metadata.json'
|
|
104
|
+
WHERE content ->> 'disabled' = 0 ORDER BY path"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
[{"path":"plugins/alpha/metadata.json"},{"path":"plugins/gamma/metadata.json"}]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
To count across an array field, expand it with `json_each`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
dirsql query "SELECT t.value AS tag, COUNT(*) AS n
|
|
115
|
+
FROM './**/metadata.json' AS m, json_each(m.content, '$.tags') AS t
|
|
116
|
+
GROUP BY tag ORDER BY n DESC, tag"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
[{"n":2,"tag":"index"},{"n":2,"tag":"search"},{"n":1,"tag":"export"},{"n":1,"tag":"rerank"}]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## `->` and `->>`
|
|
124
|
+
|
|
125
|
+
Both take the same paths; they differ in what they hand back. `->>` returns the
|
|
126
|
+
**SQL value**; `->` returns the **JSON text** of that value, quotes and all:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
dirsql query "SELECT content -> 'name' AS arrow, content ->> 'name' AS arrow2
|
|
130
|
+
FROM './plugins/alpha/metadata.json'"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
[{"arrow":"\"alpha\"","arrow2":"alpha"}]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Reach for `->>` to get a value out, and `->` to keep drilling — its JSON result
|
|
138
|
+
is a valid left operand for another `->` or `->>`.
|
|
139
|
+
|
|
140
|
+
## How JSON types arrive
|
|
141
|
+
|
|
142
|
+
`->>` maps JSON types onto SQLite's, which has no boolean:
|
|
143
|
+
|
|
144
|
+
| In the file | In the row |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| `true` / `false` | `1` / `0` |
|
|
147
|
+
| `null` | `NULL` |
|
|
148
|
+
| number | INTEGER or REAL |
|
|
149
|
+
| string | TEXT, unquoted |
|
|
150
|
+
| object or array | its JSON text |
|
|
151
|
+
| key not present | `NULL` |
|
|
152
|
+
|
|
153
|
+
So `disabled: false` reads back as `0`, and `WHERE content ->> 'disabled' = 0`
|
|
154
|
+
is how you ask for the enabled ones — `= false` is not SQLite syntax.
|
|
155
|
+
|
|
156
|
+
A missing key and a `null` value both arrive as `NULL`. Use
|
|
157
|
+
`content -> 'key' IS NULL` to tell them apart: `->` yields the JSON text
|
|
158
|
+
`'null'` for a present null, and SQL `NULL` only when the key is absent.
|
|
159
|
+
|
|
160
|
+
## When a file isn't valid JSON
|
|
161
|
+
|
|
162
|
+
The JSON operators reject a non-JSON `content`, and that fails the **whole
|
|
163
|
+
query** — one stray file, no rows at all:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
dirsql query: SQLite error: malformed JSON
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
An empty file counts too: `content` is `''`, which is not valid JSON. Guard the
|
|
170
|
+
scan with `json_valid` when the glob might catch something it shouldn't:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
dirsql query "SELECT content ->> 'name' AS name FROM './**/metadata.json'
|
|
174
|
+
WHERE json_valid(content) ORDER BY name"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Files that fail the guard drop out and the rest still answer. A file that is
|
|
178
|
+
unreadable or not UTF-8 has `NULL` content, which is not an error —
|
|
179
|
+
`json_valid(NULL)` is `NULL`, so the guard excludes those too.
|
|
180
|
+
|
|
181
|
+
## Going further
|
|
182
|
+
|
|
183
|
+
- Only path-tables expose `content`. A named `[[table]]` has exactly the columns
|
|
184
|
+
its hook emits ([columns reference](../reference/columns.md)) — reading a
|
|
185
|
+
field with `->>` there means the hook already emitted it.
|
|
186
|
+
- Doing this on every query re-reads and re-parses every file. When the same
|
|
187
|
+
tree is queried repeatedly, move the extraction into a table:
|
|
188
|
+
[Extract rows from file contents](./extract-from-contents.md) declares the
|
|
189
|
+
columns in a config, and [Parse your files into columns](./parse-files-into-columns.md)
|
|
190
|
+
prototypes the same parser inline with `--on-file`. Either way the parsed rows
|
|
191
|
+
are indexed, watched, and [persistable](./persist.md).
|
|
192
|
+
- One JSON file holding *many* records is a parser's job, not an operator's —
|
|
193
|
+
`json_each` expands an array within a row, but one row per record needs
|
|
194
|
+
[`on-file`](../reference/hooks.md#on-file).
|
|
195
|
+
- The full operator and function set is SQLite's own:
|
|
196
|
+
[JSON functions](https://sqlite.org/json1.html). `dirsql` adds nothing to it
|
|
197
|
+
and takes nothing away.
|
|
@@ -61,6 +61,17 @@ SELECT * FROM '**/*.md';
|
|
|
61
61
|
-- no such table: **/*.md; did you mean './**/*.md'?
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
**The quotes are required too.** A path is not a bare SQL identifier — `./` is
|
|
65
|
+
punctuation to SQLite's parser, so an unquoted path fails at parse time, before
|
|
66
|
+
dirsql ever sees a table name to resolve. Single or double quotes both work;
|
|
67
|
+
the error names the quoted form:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
SELECT * FROM ./;
|
|
71
|
+
-- near ".": syntax error in SELECT * FROM ./ at offset 14
|
|
72
|
+
-- hint: paths used as table names must be quoted; did you mean "./"?
|
|
73
|
+
```
|
|
74
|
+
|
|
64
75
|
### Paths outside the index root
|
|
65
76
|
|
|
66
77
|
Three other prefixes resolve, with their usual shell meanings:
|
|
@@ -19,8 +19,14 @@ repository.workspace = true
|
|
|
19
19
|
# `tests/` is the integration suite -- excluded so test files never ship in the
|
|
20
20
|
# published `.crate` (enforced by the `packaging` gate in CI). Inline unit tests
|
|
21
21
|
# stay (they are `#[cfg(test)]` modules inside `src/`, not separate files).
|
|
22
|
+
# The fragment dirs are repo inputs -- one file per change, assembled into
|
|
23
|
+
# nothing and read by no crate consumer. They need naming here because cargo
|
|
24
|
+
# ships whatever is not excluded; npm and maturin drop theirs structurally, via
|
|
25
|
+
# an allowlist and the wheel layout respectively.
|
|
22
26
|
exclude = [
|
|
23
27
|
"tests/",
|
|
28
|
+
"changelog.d/",
|
|
29
|
+
"migrations.d/",
|
|
24
30
|
"docs/.vitepress",
|
|
25
31
|
"docs/.claude",
|
|
26
32
|
"docs/tests",
|
|
@@ -77,6 +77,9 @@ SQLite value mapping is under
|
|
|
77
77
|
|
|
78
78
|
## Going further
|
|
79
79
|
|
|
80
|
+
- Just want to read a field or two out of some JSON files? SQLite's JSON
|
|
81
|
+
operators work directly on a path-table's `content` column, with no config
|
|
82
|
+
and no command — [Query JSON file contents](./query-json.md).
|
|
80
83
|
- The command re-runs on every startup and on every change to a matched
|
|
81
84
|
file. If it is expensive, [keep the index across restarts](./persist.md).
|
|
82
85
|
- Embedding `dirsql` in a program instead? The SDK's `on_file` callback
|