dirsql 0.3.101__tar.gz → 0.3.119__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.3.101 → dirsql-0.3.119}/Cargo.lock +1 -1
- {dirsql-0.3.101 → dirsql-0.3.119}/PKG-INFO +1 -1
- dirsql-0.3.119/dirsql/cli/discover_plugins/discovered_fragments.py +18 -0
- dirsql-0.3.119/dirsql/cli/discover_plugins/discovery_disabled.py +14 -0
- dirsql-0.3.119/dirsql/cli/discover_plugins/fragment_path.py +25 -0
- dirsql-0.3.119/dirsql/cli/discover_plugins/user_passed_config.py +15 -0
- dirsql-0.3.119/dirsql/cli/discover_plugins/with_discovered_plugins.py +48 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/cli/main.py +6 -2
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/.vitepress/config.ts +3 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/getting-started.md +22 -23
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/columns-from-paths.md +5 -2
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/howto/define-tables.md +7 -6
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/extract-from-contents.md +5 -2
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/load-extension.md +4 -3
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/persist.md +10 -1
- dirsql-0.3.119/docs/howto/query-without-config.md +69 -0
- {dirsql-0.3.101/packages/python → dirsql-0.3.119}/docs/howto/react-to-changes.md +13 -2
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/search-by-meaning.md +12 -3
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/howto/skip-files.md +5 -2
- dirsql-0.3.119/docs/howto/write-a-plugin.md +238 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/index.md +2 -0
- dirsql-0.3.119/docs/package.json +13 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/pnpm-lock.yaml +1 -332
- dirsql-0.3.119/docs/reference/cli.md +243 -0
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/reference/config.md +11 -9
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/reference/http-api.md +5 -1
- dirsql-0.3.119/docs/reference/path-tables.md +207 -0
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119}/docs/reference/sdk.md +17 -3
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/Cargo.toml +1 -1
- dirsql-0.3.119/packages/python/MIGRATIONS.md +11 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +3 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-13-plugin-discovery.md +1 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +3 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-13-repeatable-config.md +3 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +3 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +11 -0
- dirsql-0.3.119/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +3 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/.vitepress/config.ts +3 -0
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119/packages/python}/docs/getting-started.md +22 -23
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/howto/columns-from-paths.md +5 -2
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119/packages/python}/docs/howto/define-tables.md +7 -6
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/howto/extract-from-contents.md +5 -2
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/howto/load-extension.md +4 -3
- {dirsql-0.3.101 → dirsql-0.3.119/packages/python}/docs/howto/persist.md +10 -1
- dirsql-0.3.119/packages/python/docs/howto/query-without-config.md +69 -0
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119/packages/python}/docs/howto/react-to-changes.md +13 -2
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/howto/search-by-meaning.md +12 -3
- {dirsql-0.3.101 → dirsql-0.3.119/packages/python}/docs/howto/skip-files.md +5 -2
- dirsql-0.3.119/packages/python/docs/howto/write-a-plugin.md +238 -0
- {dirsql-0.3.101/packages/rust → dirsql-0.3.119/packages/python}/docs/index.md +2 -0
- dirsql-0.3.119/packages/python/docs/package.json +13 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/pnpm-lock.yaml +1 -332
- dirsql-0.3.119/packages/python/docs/reference/cli.md +243 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/reference/config.md +11 -9
- {dirsql-0.3.101 → dirsql-0.3.119/packages/python}/docs/reference/http-api.md +5 -1
- dirsql-0.3.119/packages/python/docs/reference/path-tables.md +207 -0
- {dirsql-0.3.101 → dirsql-0.3.119/packages/python}/docs/reference/sdk.md +17 -3
- dirsql-0.3.119/packages/python/e2e-attestations/feat-631-on-file-flag.json +7 -0
- dirsql-0.3.119/packages/python/e2e-attestations/feat-655-drop-glob-captures.json +7 -0
- dirsql-0.3.119/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +37 -0
- dirsql-0.3.119/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +54 -0
- dirsql-0.3.119/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +36 -0
- dirsql-0.3.119/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +67 -0
- dirsql-0.3.119/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +52 -0
- dirsql-0.3.119/packages/python/migrations.d/README.md +19 -0
- dirsql-0.3.119/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- dirsql-0.3.119/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +7 -0
- dirsql-0.3.119/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/Cargo.toml +1 -1
- dirsql-0.3.119/packages/rust/MIGRATIONS.md +11 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +1 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-persist-wal.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +3 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +1 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +10 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +7 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +11 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +11 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-20-schema-inference.md +12 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-21-on-file-flag.md +14 -0
- dirsql-0.3.119/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +3 -0
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/getting-started.md +22 -23
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/howto/columns-from-paths.md +5 -2
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/howto/define-tables.md +7 -6
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/howto/extract-from-contents.md +5 -2
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/howto/load-extension.md +4 -3
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/howto/persist.md +10 -1
- dirsql-0.3.119/packages/rust/docs/howto/query-without-config.md +69 -0
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/howto/react-to-changes.md +13 -2
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/howto/search-by-meaning.md +12 -3
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/howto/skip-files.md +5 -2
- dirsql-0.3.119/packages/rust/docs/howto/write-a-plugin.md +238 -0
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/index.md +2 -0
- dirsql-0.3.119/packages/rust/docs/reference/cli.md +243 -0
- {dirsql-0.3.101 → dirsql-0.3.119/packages/rust}/docs/reference/config.md +11 -9
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/reference/http-api.md +5 -1
- dirsql-0.3.119/packages/rust/docs/reference/path-tables.md +207 -0
- {dirsql-0.3.101/packages/python → dirsql-0.3.119/packages/rust}/docs/reference/sdk.md +17 -3
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +52 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +70 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-persist-wal.md +38 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +54 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +46 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +50 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +67 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +57 -0
- dirsql-0.3.119/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +53 -0
- dirsql-0.3.119/packages/rust/migrations.d/README.md +19 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/bin/dirsql.rs +325 -98
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/mod.rs +5 -5
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/db.rs +701 -51
- dirsql-0.3.119/packages/rust/src/infer.rs +511 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/lib.rs +353 -98
- dirsql-0.3.119/packages/rust/src/matcher.rs +252 -0
- dirsql-0.3.119/packages/rust/src/parsed_vtab.rs +597 -0
- dirsql-0.3.119/packages/rust/src/path_table.rs +415 -0
- dirsql-0.3.119/packages/rust/src/scanner.rs +220 -0
- dirsql-0.3.119/packages/rust/src/vtab.rs +649 -0
- dirsql-0.3.101/docs/package.json +0 -18
- dirsql-0.3.101/docs/playwright.config.ts +0 -40
- dirsql-0.3.101/docs/reference/cli.md +0 -172
- dirsql-0.3.101/docs/tests/integration/home.spec.ts +0 -6
- dirsql-0.3.101/docs/tests/integration/language-flag.spec.ts +0 -69
- dirsql-0.3.101/docs/tests/integration/sidebar.spec.ts +0 -97
- dirsql-0.3.101/docs/tests/unit/config.test.ts +0 -102
- dirsql-0.3.101/docs/tests/unit/lang.test.ts +0 -35
- dirsql-0.3.101/docs/vitest.config.ts +0 -8
- dirsql-0.3.101/packages/python/docs/package.json +0 -18
- dirsql-0.3.101/packages/python/docs/playwright.config.ts +0 -40
- dirsql-0.3.101/packages/python/docs/reference/cli.md +0 -172
- dirsql-0.3.101/packages/python/docs/tests/integration/home.spec.ts +0 -6
- dirsql-0.3.101/packages/python/docs/tests/integration/language-flag.spec.ts +0 -69
- dirsql-0.3.101/packages/python/docs/tests/integration/sidebar.spec.ts +0 -97
- dirsql-0.3.101/packages/python/docs/tests/unit/config.test.ts +0 -102
- dirsql-0.3.101/packages/python/docs/tests/unit/lang.test.ts +0 -35
- dirsql-0.3.101/packages/python/docs/vitest.config.ts +0 -8
- dirsql-0.3.101/packages/python/e2e-attestations/claude-open-issues-review-le8hm5-588.json +0 -7
- dirsql-0.3.101/packages/rust/docs/reference/cli.md +0 -172
- dirsql-0.3.101/packages/rust/src/matcher.rs +0 -409
- dirsql-0.3.101/packages/rust/src/scanner.rs +0 -75
- {dirsql-0.3.101 → dirsql-0.3.119}/Cargo.toml +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/README.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/_async.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.101/packages/python/tests/e2e → dirsql-0.3.119/dirsql/cli/discover_plugins}/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/py.typed +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/AGENTS.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/explanation.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/howto/embed.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/migrations.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/reference/columns.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/docs/reference/hooks.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/README.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/conftest.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.101/packages/python/tests/integration/binding → dirsql-0.3.119/packages/python/tests/e2e}/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/README.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/changelog.d/README.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/command.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/config.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.101 → dirsql-0.3.119}/pyproject.toml +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Discover installed plugins' fragment paths, ordered by entry-point name."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import metadata
|
|
6
|
+
|
|
7
|
+
from .fragment_path import fragment_path
|
|
8
|
+
|
|
9
|
+
ENTRY_POINT_GROUP = "dirsql"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def discovered_fragments() -> list[str]:
|
|
13
|
+
"""Fragment paths for every installed plugin, ordered by entry-point name
|
|
14
|
+
(deterministic, so a running server's ``-c`` list is reproducible)."""
|
|
15
|
+
entry_points = sorted(
|
|
16
|
+
metadata.entry_points(group=ENTRY_POINT_GROUP), key=lambda ep: ep.name
|
|
17
|
+
)
|
|
18
|
+
return [fragment_path(ep.value) for ep in entry_points]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Whether plugin discovery is opted out (flag or env var)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
NO_PLUGIN_FLAG = "--no-plugin"
|
|
8
|
+
NO_PLUGIN_ENV = "DIRSQL_NO_PLUGIN"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def discovery_disabled(argv: list[str]) -> bool:
|
|
12
|
+
"""True when discovery is opted out via ``--no-plugin`` or
|
|
13
|
+
``DIRSQL_NO_PLUGIN``."""
|
|
14
|
+
return NO_PLUGIN_FLAG in argv or bool(os.environ.get(NO_PLUGIN_ENV))
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Resolve a plugin module's shipped ``dirsql.toml`` fragment path."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import resources
|
|
6
|
+
|
|
7
|
+
FRAGMENT_NAME = "dirsql.toml"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def fragment_path(module_name: str) -> str:
|
|
11
|
+
"""Absolute path to a plugin module's shipped ``dirsql.toml``. Raises a
|
|
12
|
+
clear error naming the plugin when the module or the fragment is missing --
|
|
13
|
+
never a silent skip."""
|
|
14
|
+
try:
|
|
15
|
+
fragment = resources.files(module_name).joinpath(FRAGMENT_NAME)
|
|
16
|
+
except ModuleNotFoundError as exc:
|
|
17
|
+
raise ValueError(
|
|
18
|
+
f"dirsql plugin module {module_name!r} is not importable: {exc}"
|
|
19
|
+
) from exc
|
|
20
|
+
if not fragment.is_file():
|
|
21
|
+
raise ValueError(
|
|
22
|
+
f"dirsql plugin {module_name!r} ships no {FRAGMENT_NAME} fragment "
|
|
23
|
+
f"(expected at {fragment})"
|
|
24
|
+
)
|
|
25
|
+
return str(fragment)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Whether the user's argv already names a config file."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def user_passed_config(argv: list[str]) -> bool:
|
|
7
|
+
"""True when argv already names a ``-c`` / ``--config`` file -- the user's
|
|
8
|
+
own config is the base, so the baked-in default is not re-added."""
|
|
9
|
+
for arg in argv:
|
|
10
|
+
# `--config` naturally fails `startswith("-c")` (it starts with `--`),
|
|
11
|
+
# so the three clauses are disjoint: bare/attached short `-c`, long
|
|
12
|
+
# `--config`, and the `--config=<value>` form.
|
|
13
|
+
if arg == "--config" or arg.startswith("--config=") or arg.startswith("-c"):
|
|
14
|
+
return True
|
|
15
|
+
return False
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Rewrite argv to activate installed plugins (the discovery orchestrator).
|
|
2
|
+
|
|
3
|
+
This is the public entry point of the ``discover_plugins`` package (installed =
|
|
4
|
+
active, CLI only; #363/#529). A plugin is an ordinary Python package that
|
|
5
|
+
declares ``[project.entry-points.dirsql]`` naming its top-level module and ships
|
|
6
|
+
a ``dirsql.toml`` fragment there; when installed alongside ``dirsql``, the
|
|
7
|
+
``pip``/``uvx`` launcher discovers it and injects the fragment as a ``-c`` flag
|
|
8
|
+
plus the hidden ``--include-default`` (#604) when the user gave no ``-c``.
|
|
9
|
+
Opt out via ``--no-plugin`` / ``DIRSQL_NO_PLUGIN=1``. The compiled binary knows
|
|
10
|
+
nothing about plugins, and the SDK never discovers -- only this CLI launcher.
|
|
11
|
+
The helpers each live in their own module (``user_passed_config``,
|
|
12
|
+
``discovery_disabled``, ``fragment_path``, ``discovered_fragments``).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from .discovered_fragments import discovered_fragments
|
|
18
|
+
from .discovery_disabled import NO_PLUGIN_FLAG, discovery_disabled
|
|
19
|
+
from .user_passed_config import user_passed_config
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def with_discovered_plugins(argv: list[str]) -> list[str]:
|
|
23
|
+
"""Return ``argv`` with each installed plugin's fragment appended as ``-c``
|
|
24
|
+
(plus ``--include-default`` when the user passed no ``-c``). ``--no-plugin``
|
|
25
|
+
/ ``DIRSQL_NO_PLUGIN`` skip discovery, consuming the flag. ``init`` takes no
|
|
26
|
+
config, so it is left untouched. Raises if a declared plugin is missing its
|
|
27
|
+
module or fragment (the launcher surfaces a clean error).
|
|
28
|
+
|
|
29
|
+
Appending is safe because config flags are subcommand-local (#609): the
|
|
30
|
+
user's own ``-c`` sits after the ``query`` subcommand (or at top level in
|
|
31
|
+
server mode), so the injected flags land in the same clap context and
|
|
32
|
+
accumulate with it -- plugins merge after the user's config, preserving
|
|
33
|
+
user-first order.
|
|
34
|
+
"""
|
|
35
|
+
if discovery_disabled(argv):
|
|
36
|
+
return [a for a in argv if a != NO_PLUGIN_FLAG]
|
|
37
|
+
if argv and argv[0] == "init":
|
|
38
|
+
return argv
|
|
39
|
+
fragments = discovered_fragments()
|
|
40
|
+
if not fragments:
|
|
41
|
+
return argv
|
|
42
|
+
injected: list[str] = []
|
|
43
|
+
if not user_passed_config(argv):
|
|
44
|
+
injected.append("--include-default")
|
|
45
|
+
for fragment in fragments:
|
|
46
|
+
injected.append("-c")
|
|
47
|
+
injected.append(fragment)
|
|
48
|
+
return [*argv, *injected]
|
|
@@ -9,6 +9,7 @@ import subprocess
|
|
|
9
9
|
import sys
|
|
10
10
|
|
|
11
11
|
from .binary_path import binary_path
|
|
12
|
+
from .discover_plugins.with_discovered_plugins import with_discovered_plugins
|
|
12
13
|
from .is_windows import is_windows
|
|
13
14
|
from .resolve_config_extensions import with_resolved_extensions
|
|
14
15
|
|
|
@@ -23,9 +24,12 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
23
24
|
print(f"dirsql: {exc}", file=sys.stderr)
|
|
24
25
|
return 1
|
|
25
26
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
27
|
+
# Discover installed plugins (CLI only) and inject their config fragments as
|
|
28
|
+
# `-c` flags before resolving extensions; then resolve any package-name
|
|
29
|
+
# extensions in a TOML config here (the binary can't) as `--extension`
|
|
30
|
+
# flags. Both are no-ops when nothing applies.
|
|
28
31
|
try:
|
|
32
|
+
argv = with_discovered_plugins(argv)
|
|
29
33
|
argv = with_resolved_extensions(argv)
|
|
30
34
|
except Exception as exc:
|
|
31
35
|
print(f"dirsql: {exc}", file=sys.stderr)
|
|
@@ -37,6 +37,7 @@ export default defineConfig({
|
|
|
37
37
|
{
|
|
38
38
|
text: 'How-to Guides',
|
|
39
39
|
items: [
|
|
40
|
+
{ text: 'Query files without a config', link: '/howto/query-without-config' },
|
|
40
41
|
{ text: 'Define tables for your files', link: '/howto/define-tables' },
|
|
41
42
|
{ text: 'Derive columns from file paths', link: '/howto/columns-from-paths' },
|
|
42
43
|
{ text: 'Extract rows from file contents', link: '/howto/extract-from-contents' },
|
|
@@ -45,6 +46,7 @@ export default defineConfig({
|
|
|
45
46
|
{ text: 'Load a SQLite extension', link: '/howto/load-extension' },
|
|
46
47
|
{ text: 'Keep the index across restarts', link: '/howto/persist' },
|
|
47
48
|
{ text: 'React to file changes', link: '/howto/react-to-changes' },
|
|
49
|
+
{ text: 'Write a plugin', link: '/howto/write-a-plugin' },
|
|
48
50
|
{ text: 'Embed dirsql in your application', link: '/howto/embed' }
|
|
49
51
|
]
|
|
50
52
|
},
|
|
@@ -55,6 +57,7 @@ export default defineConfig({
|
|
|
55
57
|
{ text: 'Configuration File', link: '/reference/config' },
|
|
56
58
|
{ text: 'Command Hooks', link: '/reference/hooks' },
|
|
57
59
|
{ text: 'Virtual Columns & Glob Captures', link: '/reference/columns' },
|
|
60
|
+
{ text: 'Path-tables', link: '/reference/path-tables' },
|
|
58
61
|
{ text: 'HTTP API', link: '/reference/http-api' },
|
|
59
62
|
{ text: 'SDK', link: '/reference/sdk' },
|
|
60
63
|
{ text: 'Migrations', link: '/migrations' }
|
|
@@ -9,6 +9,10 @@ a SQL database you can query over HTTP — without writing any code. You will:
|
|
|
9
9
|
|
|
10
10
|
It takes about five minutes.
|
|
11
11
|
|
|
12
|
+
`dirsql` only ever reads your files — it never writes, moves, or changes
|
|
13
|
+
them — so it is safe to point at a real directory of your own once you are
|
|
14
|
+
done here. See [Read-only by design](./explanation#read-only-by-design).
|
|
15
|
+
|
|
12
16
|
**You need:** a terminal with `curl` and [`jq`](https://jqlang.org/), and
|
|
13
17
|
Node ≥ 20.11 (for `npx`). Every `npx dirsql` step below also has a `uvx`
|
|
14
18
|
tab that behaves identically, if you prefer Python tooling
|
|
@@ -16,33 +20,23 @@ tab that behaves identically, if you prefer Python tooling
|
|
|
16
20
|
|
|
17
21
|
## 1. Create three files
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
Paste this whole block into your terminal. It makes a working directory
|
|
24
|
+
with a subfolder per note author and writes three tiny markdown notes:
|
|
20
25
|
|
|
21
26
|
```bash
|
|
22
27
|
mkdir -p my-notes/notes/alice my-notes/notes/bob
|
|
23
28
|
cd my-notes
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Create the three notes by pasting each block exactly as shown:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
29
|
cat > notes/alice/welcome.md <<'EOF'
|
|
30
30
|
# Welcome
|
|
31
31
|
|
|
32
32
|
Start here. This folder is about to become a database.
|
|
33
33
|
EOF
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
34
|
cat > notes/alice/ideas.md <<'EOF'
|
|
38
35
|
# Ideas
|
|
39
36
|
|
|
40
37
|
- query files with SQL
|
|
41
38
|
- watch for changes
|
|
42
39
|
EOF
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
40
|
cat > notes/bob/reading-list.md <<'EOF'
|
|
47
41
|
# Reading list
|
|
48
42
|
|
|
@@ -50,6 +44,9 @@ cat > notes/bob/reading-list.md <<'EOF'
|
|
|
50
44
|
EOF
|
|
51
45
|
```
|
|
52
46
|
|
|
47
|
+
(Any directory of files works with `dirsql` — the rest of this tutorial
|
|
48
|
+
assumes exactly these three so your output matches ours.)
|
|
49
|
+
|
|
53
50
|
Check that all three files are in place:
|
|
54
51
|
|
|
55
52
|
```bash
|
|
@@ -91,14 +88,15 @@ open a **second terminal** for the next step.
|
|
|
91
88
|
|
|
92
89
|
## 3. Query your files
|
|
93
90
|
|
|
94
|
-
You gave `dirsql` no configuration, so
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
You gave `dirsql` no configuration, so no named tables exist. Query the
|
|
92
|
+
filesystem directly with a [path-table](./reference/path-tables.md) — a
|
|
93
|
+
quoted path where a table name goes. `'./'` means everything under the
|
|
94
|
+
index root. Ask it how many files there are:
|
|
97
95
|
|
|
98
96
|
```bash
|
|
99
97
|
curl -s http://localhost:7117/query \
|
|
100
98
|
-H 'content-type: application/json' \
|
|
101
|
-
-d '{"sql":"SELECT COUNT(*) AS files FROM
|
|
99
|
+
-d '{"sql":"SELECT COUNT(*) AS files FROM \'./\'"}'
|
|
102
100
|
```
|
|
103
101
|
|
|
104
102
|
```
|
|
@@ -112,7 +110,7 @@ through `jq` to pretty-print. Now select some columns:
|
|
|
112
110
|
```bash
|
|
113
111
|
curl -s http://localhost:7117/query \
|
|
114
112
|
-H 'content-type: application/json' \
|
|
115
|
-
-d '{"sql":"SELECT path, size FROM
|
|
113
|
+
-d '{"sql":"SELECT path, size FROM \'./\' ORDER BY path"}' \
|
|
116
114
|
| jq
|
|
117
115
|
```
|
|
118
116
|
|
|
@@ -167,16 +165,18 @@ Two keys define the table:
|
|
|
167
165
|
## 5. Restart and query the new shape
|
|
168
166
|
|
|
169
167
|
Config is read at startup, so go back to the **first terminal**, stop the
|
|
170
|
-
server with `Ctrl-C`, and start it again
|
|
168
|
+
server with `Ctrl-C`, and start it again — this time pointing `dirsql` at
|
|
169
|
+
your config with `-c` (`dirsql` does not auto-load a `.dirsql.toml` from the
|
|
170
|
+
current directory; you always pass it explicitly):
|
|
171
171
|
|
|
172
172
|
::: code-group
|
|
173
173
|
|
|
174
174
|
```bash [npm]
|
|
175
|
-
npx dirsql
|
|
175
|
+
npx dirsql -c .dirsql.toml
|
|
176
176
|
```
|
|
177
177
|
|
|
178
178
|
```bash [PyPI]
|
|
179
|
-
uvx dirsql
|
|
179
|
+
uvx dirsql -c .dirsql.toml
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
:::
|
|
@@ -185,9 +185,8 @@ uvx dirsql
|
|
|
185
185
|
Running at localhost:7117
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
This time `dirsql`
|
|
189
|
-
you defined
|
|
190
|
-
terminal:
|
|
188
|
+
This time `dirsql` loaded your `.dirsql.toml` and served the `notes` table
|
|
189
|
+
you defined. Query it from the second terminal:
|
|
191
190
|
|
|
192
191
|
```bash
|
|
193
192
|
curl -s http://localhost:7117/query \
|
|
@@ -29,8 +29,11 @@ within one path segment) are in
|
|
|
29
29
|
|
|
30
30
|
## 2. Query the captured columns
|
|
31
31
|
|
|
32
|
+
Pass the config with [`-c`](../reference/cli.md#flags) (`dirsql` does not
|
|
33
|
+
auto-load a `.dirsql.toml` from the current directory):
|
|
34
|
+
|
|
32
35
|
```bash
|
|
33
|
-
dirsql query "SELECT year, month, basename FROM photos ORDER BY year, month"
|
|
36
|
+
dirsql query "SELECT year, month, basename FROM photos ORDER BY year, month" -c ./.dirsql.toml
|
|
34
37
|
```
|
|
35
38
|
|
|
36
39
|
```json
|
|
@@ -40,7 +43,7 @@ dirsql query "SELECT year, month, basename FROM photos ORDER BY year, month"
|
|
|
40
43
|
Captures are real SQL columns, so aggregation works:
|
|
41
44
|
|
|
42
45
|
```bash
|
|
43
|
-
dirsql query "SELECT year, COUNT(*) AS photos FROM photos GROUP BY year"
|
|
46
|
+
dirsql query "SELECT year, COUNT(*) AS photos FROM photos GROUP BY year" -c ./.dirsql.toml
|
|
44
47
|
```
|
|
45
48
|
|
|
46
49
|
```json
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Map a glob of files to a named SQL table so you query exactly the files you
|
|
4
4
|
care about, with exactly the columns you care about — instead of the
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
ad-hoc [path-tables](../reference/path-tables.md)
|
|
6
|
+
[configless mode](../reference/cli.md#configless-mode) leaves you with.
|
|
7
7
|
|
|
8
8
|
## 1. Create a config next to your files
|
|
9
9
|
|
|
@@ -26,10 +26,12 @@ glob = "posts/**/*.md"
|
|
|
26
26
|
|
|
27
27
|
## 2. Query the table
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Pass the config with [`-c`](../reference/cli.md#flags) — `dirsql` does not
|
|
30
|
+
auto-load a `.dirsql.toml` from the current directory. Each matched file is
|
|
31
|
+
one row:
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
|
-
dirsql query "SELECT path, size FROM posts ORDER BY path"
|
|
34
|
+
dirsql query "SELECT path, size FROM posts ORDER BY path" -c ./.dirsql.toml
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
```json
|
|
@@ -37,8 +39,7 @@ dirsql query "SELECT path, size FROM posts ORDER BY path"
|
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
Files that don't match the glob (a `README.txt` next to `posts/`, say) are
|
|
40
|
-
simply not in the table.
|
|
41
|
-
zero-config default — only the tables you define are served.
|
|
42
|
+
simply not in the table. Only the tables you define are served.
|
|
42
43
|
|
|
43
44
|
## Multiple tables
|
|
44
45
|
|
|
@@ -31,8 +31,11 @@ by every hook.
|
|
|
31
31
|
|
|
32
32
|
## 2. Query the extracted columns
|
|
33
33
|
|
|
34
|
+
Pass the config with [`-c`](../reference/cli.md#flags) (`dirsql` does not
|
|
35
|
+
auto-load a `.dirsql.toml` from the current directory):
|
|
36
|
+
|
|
34
37
|
```bash
|
|
35
|
-
dirsql query "SELECT title, author, year, path FROM books ORDER BY year"
|
|
38
|
+
dirsql query "SELECT title, author, year, path FROM books ORDER BY year" -c ./.dirsql.toml
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
```json
|
|
@@ -57,7 +60,7 @@ on-file = "jq -c -s '.' {path}"
|
|
|
57
60
|
```
|
|
58
61
|
|
|
59
62
|
```bash
|
|
60
|
-
dirsql query "SELECT event, user FROM events"
|
|
63
|
+
dirsql query "SELECT event, user FROM events" -c ./.dirsql.toml
|
|
61
64
|
```
|
|
62
65
|
|
|
63
66
|
```json
|
|
@@ -23,10 +23,11 @@ overrides the init symbol when it doesn't match the filename-derived
|
|
|
23
23
|
default — `sqlite-vec` is exactly such a case
|
|
24
24
|
([reference](../reference/config.md#dirsql-extension)).
|
|
25
25
|
|
|
26
|
-
The extension's functions are callable
|
|
26
|
+
The extension's functions are callable (pass the config with
|
|
27
|
+
[`-c`](../reference/cli.md#flags) so its `[[dirsql.extension]]` entry loads):
|
|
27
28
|
|
|
28
29
|
```bash
|
|
29
|
-
dirsql query "SELECT vec_version() AS vec_version"
|
|
30
|
+
dirsql query "SELECT vec_version() AS vec_version" -c ./.dirsql.toml
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
```json
|
|
@@ -52,7 +53,7 @@ entrypoint = "sqlite3_vec_init"
|
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
```bash
|
|
55
|
-
uvx --with sqlite-vec dirsql
|
|
56
|
+
uvx --with sqlite-vec dirsql -c ./.dirsql.toml
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
**Node (`npx dirsql`, TypeScript SDK).** Use the *npm package name* — but
|
|
@@ -41,7 +41,9 @@ large. Add it to `.gitignore`:
|
|
|
41
41
|
|
|
42
42
|
The top-level `.dirsql/` directory is reserved for `dirsql`'s metadata and
|
|
43
43
|
is never scanned as data, so the cache can't index itself
|
|
44
|
-
([config reference](../reference/config.md#dirsql-keys)).
|
|
44
|
+
([config reference](../reference/config.md#dirsql-keys)). While running,
|
|
45
|
+
`dirsql` also creates transient `cache.db-wal` and `cache.db-shm` sidecar
|
|
46
|
+
files next to the cache; the `.dirsql/` ignore already covers all three.
|
|
45
47
|
|
|
46
48
|
## What survives, what rebuilds
|
|
47
49
|
|
|
@@ -57,6 +59,13 @@ Persistence is a startup-time optimization, not a change in meaning: the
|
|
|
57
59
|
database remains a derived view of your files, and queries return the same
|
|
58
60
|
rows either way ([how `dirsql` thinks](../explanation.md)).
|
|
59
61
|
|
|
62
|
+
### Durability
|
|
63
|
+
|
|
64
|
+
The cache favors throughput over durability: it opens in WAL journal mode
|
|
65
|
+
with `synchronous=NORMAL`. On power loss the most recent cache updates may
|
|
66
|
+
be lost, but the file cannot corrupt — the next startup reconciles and
|
|
67
|
+
re-parses anything missing.
|
|
68
|
+
|
|
60
69
|
## Embedding `dirsql`?
|
|
61
70
|
|
|
62
71
|
The SDK constructors expose the same switch as `persist` / `persistPath`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Query files without a config
|
|
2
|
+
|
|
3
|
+
You have a directory and a question about the files in it. You want an answer
|
|
4
|
+
now — not a `.dirsql.toml`, not a schema, not a setup step. Point `dirsql` at
|
|
5
|
+
the directory and write a path where a table name goes.
|
|
6
|
+
|
|
7
|
+
## 1. Run a query against the directory
|
|
8
|
+
|
|
9
|
+
No config, no install ceremony — `uvx` (or `npx`) fetches and runs `dirsql`,
|
|
10
|
+
rooted at the directory you run it from:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uvx dirsql query "SELECT basename, size FROM './' ORDER BY size DESC LIMIT 5"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
[
|
|
18
|
+
{"basename":"video.mp4","size":84213770},
|
|
19
|
+
{"basename":"archive.zip","size":9123400},
|
|
20
|
+
{"basename":"notes.md","size":40213},
|
|
21
|
+
{"basename":"todo.md","size":1200},
|
|
22
|
+
{"basename":"README.md","size":840}
|
|
23
|
+
]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`'./'` stands in for a table you never declared. `dirsql` scans the directory
|
|
27
|
+
live and hands SQLite one row per file — this is a
|
|
28
|
+
[path-table](../reference/path-tables.md). Because there is no `-c`, there are
|
|
29
|
+
**no named tables** at all; the path *is* the query
|
|
30
|
+
([configless mode](../reference/cli.md#configless-mode)).
|
|
31
|
+
|
|
32
|
+
## 2. Ask about content, not just names
|
|
33
|
+
|
|
34
|
+
Every file exposes the seven [stat columns](../reference/columns.md) (`path`,
|
|
35
|
+
`basename`, `dir`, `ext`, `size`, `mtime`, `ctime`) plus a hidden `content`
|
|
36
|
+
column. `content` is read only when you name it, so filtering on it is cheap
|
|
37
|
+
until you actually ask:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
uvx dirsql query "SELECT path FROM './docs/**/*.md' WHERE content LIKE '%deprecated%'"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The `./` prefix is required. A bare glob is rejected with a hint rather than
|
|
44
|
+
silently guessed:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
uvx dirsql query "SELECT * FROM '**/*.md'"
|
|
48
|
+
-- no such table: **/*.md; did you mean './**/*.md'?
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 3. Graduate to a named table when it pays off
|
|
52
|
+
|
|
53
|
+
A path-table re-scans the filesystem on every query — perfect for a one-off
|
|
54
|
+
question over a few hundred files, wasteful for a large tree you query
|
|
55
|
+
repeatedly. When that day comes, [declare a table](./define-tables.md): it is
|
|
56
|
+
indexed once, kept fresh by the watcher, and can persist across restarts. The
|
|
57
|
+
zero-config query is the floor; a named table is the escalation path — nothing
|
|
58
|
+
you write here has to be thrown away to get there.
|
|
59
|
+
|
|
60
|
+
## Notes
|
|
61
|
+
|
|
62
|
+
- The same query works from the SDK: construct `DirSQL` with neither a
|
|
63
|
+
`config` nor `tables` and call `query("SELECT * FROM './'")`
|
|
64
|
+
([SDK reference](../reference/sdk.md)).
|
|
65
|
+
- Paths outside the root resolve too — `'/var/log/*.log'`, `'../notes'`,
|
|
66
|
+
`'~/notes/*.md'` — reporting absolute paths
|
|
67
|
+
([path-tables reference](../reference/path-tables.md#paths-outside-the-index-root)).
|
|
68
|
+
- `node_modules/` and `.git/` are skipped by default so a bare `'./'` does not
|
|
69
|
+
drown in machinery ([skip rules](../reference/path-tables.md#skip-rules)).
|
|
@@ -5,10 +5,21 @@ change — and [`GET /events`](../reference/http-api.md#get-events) pushes
|
|
|
5
5
|
every row-level change to you as it happens. No polling, no diffing on your
|
|
6
6
|
side.
|
|
7
7
|
|
|
8
|
+
Row events are emitted for **named tables**, so this flow needs a config —
|
|
9
|
+
[path-tables](../reference/path-tables.md) are scanned per query and are not
|
|
10
|
+
watched. Define one next to your files:
|
|
11
|
+
|
|
12
|
+
```toml
|
|
13
|
+
# .dirsql.toml
|
|
14
|
+
[[table]]
|
|
15
|
+
ddl = "CREATE TABLE files (path TEXT, basename TEXT, dir TEXT, ext TEXT, size INTEGER, mtime INTEGER, ctime INTEGER)"
|
|
16
|
+
glob = "**/*"
|
|
17
|
+
```
|
|
18
|
+
|
|
8
19
|
## 1. Open the stream
|
|
9
20
|
|
|
10
|
-
With the server running (`npx dirsql
|
|
11
|
-
another terminal:
|
|
21
|
+
With the server running (`npx dirsql -c ./.dirsql.toml` /
|
|
22
|
+
`uvx dirsql -c ./.dirsql.toml`), subscribe from another terminal:
|
|
12
23
|
|
|
13
24
|
```bash
|
|
14
25
|
curl -N http://localhost:7117/events
|
|
@@ -7,6 +7,13 @@ into semantic search: a SQLite vector extension for the distance math, an
|
|
|
7
7
|
index time, and a [`pre-query`](../reference/hooks.md#pre-query) command to
|
|
8
8
|
embed each question at query time.
|
|
9
9
|
|
|
10
|
+
::: tip Just want it working?
|
|
11
|
+
[`dirsql-plugin-embeddings`](https://pypi.org/project/dirsql-plugin-embeddings/)
|
|
12
|
+
packages exactly what this guide builds, ready to install:
|
|
13
|
+
`uvx --with dirsql-plugin-embeddings dirsql`. Keep reading to see how it's
|
|
14
|
+
built — the same three pieces, from scratch.
|
|
15
|
+
:::
|
|
16
|
+
|
|
10
17
|
## How the pieces fit
|
|
11
18
|
|
|
12
19
|
1. **[`[[dirsql.extension]]`](../reference/config.md#dirsql-extension)**
|
|
@@ -103,10 +110,12 @@ runtime — and the literal-path alternative that works everywhere — are in
|
|
|
103
110
|
|
|
104
111
|
Run with `sqlite-vec` available to the launcher's environment. The initial
|
|
105
112
|
scan runs `embed.py` once per note, then the query argument goes straight to
|
|
106
|
-
`pre-query`, exactly as a `POST /query` body would
|
|
113
|
+
`pre-query`, exactly as a `POST /query` body would. Pass the config with
|
|
114
|
+
[`-c`](../reference/cli.md#flags) — `dirsql` does not auto-load a
|
|
115
|
+
`.dirsql.toml` from the current directory:
|
|
107
116
|
|
|
108
117
|
```bash
|
|
109
|
-
uvx --with sqlite-vec dirsql query '{"q": "how do I cook pasta?"}'
|
|
118
|
+
uvx --with sqlite-vec dirsql query '{"q": "how do I cook pasta?"}' -c ./.dirsql.toml
|
|
110
119
|
```
|
|
111
120
|
|
|
112
121
|
```json
|
|
@@ -114,7 +123,7 @@ uvx --with sqlite-vec dirsql query '{"q": "how do I cook pasta?"}'
|
|
|
114
123
|
```
|
|
115
124
|
|
|
116
125
|
```bash
|
|
117
|
-
uvx --with sqlite-vec dirsql query '{"q": "reviewing code on github"}'
|
|
126
|
+
uvx --with sqlite-vec dirsql query '{"q": "reviewing code on github"}' -c ./.dirsql.toml
|
|
118
127
|
```
|
|
119
128
|
|
|
120
129
|
```json
|
|
@@ -31,8 +31,11 @@ ignored file never reaches any table — even one whose glob would match it.
|
|
|
31
31
|
|
|
32
32
|
## 2. Confirm what made it in
|
|
33
33
|
|
|
34
|
+
Pass the config with [`-c`](../reference/cli.md#flags) (`dirsql` does not
|
|
35
|
+
auto-load a `.dirsql.toml` from the current directory):
|
|
36
|
+
|
|
34
37
|
```bash
|
|
35
|
-
dirsql query "SELECT path FROM notes ORDER BY path"
|
|
38
|
+
dirsql query "SELECT path FROM notes ORDER BY path" -c ./.dirsql.toml
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
```json
|
|
@@ -42,7 +45,7 @@ dirsql query "SELECT path FROM notes ORDER BY path"
|
|
|
42
45
|
## Notes
|
|
43
46
|
|
|
44
47
|
- `ignore` lives in a config file, so it needs one:
|
|
45
|
-
[
|
|
48
|
+
[configless mode](../reference/cli.md#configless-mode) indexes
|
|
46
49
|
everything with no ignores.
|
|
47
50
|
- The top-level `.dirsql/` directory is always excluded, ignore list or
|
|
48
51
|
not — it is reserved for `dirsql`'s own metadata
|