dirsql 0.3.66__tar.gz → 0.3.67__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.
Files changed (135) hide show
  1. {dirsql-0.3.66 → dirsql-0.3.67}/Cargo.lock +1 -1
  2. {dirsql-0.3.66 → dirsql-0.3.67}/PKG-INFO +1 -1
  3. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/Cargo.toml +1 -1
  4. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/cli/init.rs +42 -0
  5. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/cli/mod.rs +22 -0
  6. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/cli/router.rs +34 -0
  7. {dirsql-0.3.66 → dirsql-0.3.67}/Cargo.toml +0 -0
  8. {dirsql-0.3.66 → dirsql-0.3.67}/README.md +0 -0
  9. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/__init__.py +0 -0
  10. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/_async.py +0 -0
  11. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/_dirsql.pyi +0 -0
  12. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/cli/__init__.py +0 -0
  13. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/cli/binary_path.py +0 -0
  14. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/cli/is_windows.py +0 -0
  15. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/cli/main.py +0 -0
  16. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/cli/resolve_config_extensions.py +0 -0
  17. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/py.typed +0 -0
  18. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/resolve_config_extensions.py +0 -0
  19. {dirsql-0.3.66 → dirsql-0.3.67}/dirsql/resolve_extension.py +0 -0
  20. {dirsql-0.3.66 → dirsql-0.3.67}/docs/.claude/CLAUDE.md +0 -0
  21. {dirsql-0.3.66 → dirsql-0.3.67}/docs/.vitepress/config.ts +0 -0
  22. {dirsql-0.3.66 → dirsql-0.3.67}/docs/.vitepress/theme/index.ts +0 -0
  23. {dirsql-0.3.66 → dirsql-0.3.67}/docs/.vitepress/theme/lang.ts +0 -0
  24. {dirsql-0.3.66 → dirsql-0.3.67}/docs/AGENTS.md +0 -0
  25. {dirsql-0.3.66 → dirsql-0.3.67}/docs/explanation.md +0 -0
  26. {dirsql-0.3.66 → dirsql-0.3.67}/docs/getting-started.md +0 -0
  27. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/columns-from-paths.md +0 -0
  28. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/define-tables.md +0 -0
  29. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/embed.md +0 -0
  30. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/extract-from-contents.md +0 -0
  31. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/load-extension.md +0 -0
  32. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/persist.md +0 -0
  33. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/react-to-changes.md +0 -0
  34. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/search-by-meaning.md +0 -0
  35. {dirsql-0.3.66 → dirsql-0.3.67}/docs/howto/skip-files.md +0 -0
  36. {dirsql-0.3.66 → dirsql-0.3.67}/docs/index.md +0 -0
  37. {dirsql-0.3.66 → dirsql-0.3.67}/docs/migrations.md +0 -0
  38. {dirsql-0.3.66 → dirsql-0.3.67}/docs/package.json +0 -0
  39. {dirsql-0.3.66 → dirsql-0.3.67}/docs/playwright.config.ts +0 -0
  40. {dirsql-0.3.66 → dirsql-0.3.67}/docs/pnpm-lock.yaml +0 -0
  41. {dirsql-0.3.66 → dirsql-0.3.67}/docs/pnpm-workspace.yaml +0 -0
  42. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/cli.md +0 -0
  43. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/columns.md +0 -0
  44. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/config.md +0 -0
  45. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/hooks.md +0 -0
  46. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/http-api.md +0 -0
  47. {dirsql-0.3.66 → dirsql-0.3.67}/docs/reference/sdk.md +0 -0
  48. {dirsql-0.3.66 → dirsql-0.3.67}/docs/tests/integration/home.spec.ts +0 -0
  49. {dirsql-0.3.66 → dirsql-0.3.67}/docs/tests/integration/language-flag.spec.ts +0 -0
  50. {dirsql-0.3.66 → dirsql-0.3.67}/docs/tests/integration/sidebar.spec.ts +0 -0
  51. {dirsql-0.3.66 → dirsql-0.3.67}/docs/tests/unit/config.test.ts +0 -0
  52. {dirsql-0.3.66 → dirsql-0.3.67}/docs/tests/unit/lang.test.ts +0 -0
  53. {dirsql-0.3.66 → dirsql-0.3.67}/docs/vitest.config.ts +0 -0
  54. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/README.md +0 -0
  55. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/conftest.py +0 -0
  56. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/.claude/CLAUDE.md +0 -0
  57. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/.vitepress/config.ts +0 -0
  58. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  59. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  60. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/AGENTS.md +0 -0
  61. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/explanation.md +0 -0
  62. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/getting-started.md +0 -0
  63. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/columns-from-paths.md +0 -0
  64. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/define-tables.md +0 -0
  65. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/embed.md +0 -0
  66. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/extract-from-contents.md +0 -0
  67. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/load-extension.md +0 -0
  68. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/persist.md +0 -0
  69. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/react-to-changes.md +0 -0
  70. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/search-by-meaning.md +0 -0
  71. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/howto/skip-files.md +0 -0
  72. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/index.md +0 -0
  73. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/migrations.md +0 -0
  74. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/package.json +0 -0
  75. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/playwright.config.ts +0 -0
  76. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/pnpm-lock.yaml +0 -0
  77. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/pnpm-workspace.yaml +0 -0
  78. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/cli.md +0 -0
  79. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/columns.md +0 -0
  80. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/config.md +0 -0
  81. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/hooks.md +0 -0
  82. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/http-api.md +0 -0
  83. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/reference/sdk.md +0 -0
  84. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/tests/integration/home.spec.ts +0 -0
  85. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/tests/integration/language-flag.spec.ts +0 -0
  86. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/tests/integration/sidebar.spec.ts +0 -0
  87. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/tests/unit/config.test.ts +0 -0
  88. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/tests/unit/lang.test.ts +0 -0
  89. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/docs/vitest.config.ts +0 -0
  90. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/e2e-attestation.json +0 -0
  91. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/src/lib.rs +0 -0
  92. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/__init__.py +0 -0
  93. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/binding/__init__.py +0 -0
  94. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/conftest.py +0 -0
  95. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/e2e/__init__.py +0 -0
  96. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/integration/__init__.py +0 -0
  97. {dirsql-0.3.66 → dirsql-0.3.67}/packages/python/tests/smoke/__init__.py +0 -0
  98. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/Cargo.toml +0 -0
  99. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/README.md +0 -0
  100. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/benches/db_bench.rs +0 -0
  101. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/benches/differ_bench.rs +0 -0
  102. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/benches/matcher_bench.rs +0 -0
  103. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/benches/scanner_bench.rs +0 -0
  104. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/explanation.md +0 -0
  105. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/getting-started.md +0 -0
  106. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  107. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/define-tables.md +0 -0
  108. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/embed.md +0 -0
  109. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  110. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/load-extension.md +0 -0
  111. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/persist.md +0 -0
  112. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/react-to-changes.md +0 -0
  113. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  114. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/howto/skip-files.md +0 -0
  115. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/index.md +0 -0
  116. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/migrations.md +0 -0
  117. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/cli.md +0 -0
  118. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/columns.md +0 -0
  119. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/config.md +0 -0
  120. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/hooks.md +0 -0
  121. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/http-api.md +0 -0
  122. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/docs/reference/sdk.md +0 -0
  123. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/bin/dirsql.rs +0 -0
  124. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/cli/serialize.rs +0 -0
  125. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/cli/server.rs +0 -0
  126. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/command.rs +0 -0
  127. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/config.rs +0 -0
  128. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/db.rs +0 -0
  129. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/differ.rs +0 -0
  130. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/lib.rs +0 -0
  131. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/matcher.rs +0 -0
  132. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/persist.rs +0 -0
  133. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/scanner.rs +0 -0
  134. {dirsql-0.3.66 → dirsql-0.3.67}/packages/rust/src/watcher.rs +0 -0
  135. {dirsql-0.3.66 → dirsql-0.3.67}/pyproject.toml +0 -0
@@ -500,7 +500,7 @@ dependencies = [
500
500
 
501
501
  [[package]]
502
502
  name = "dirsql-py-ext"
503
- version = "0.3.66"
503
+ version = "0.3.67"
504
504
  dependencies = [
505
505
  "dirsql",
506
506
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.3.66
3
+ Version: 0.3.67
4
4
  Requires-Dist: pytest>=8 ; extra == 'dev'
5
5
  Requires-Dist: pytest-describe>=2 ; extra == 'dev'
6
6
  Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
@@ -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.3.66"
7
+ version = "0.3.67"
8
8
  edition.workspace = true
9
9
  publish = false
10
10
  readme = "README.md"
@@ -166,4 +166,46 @@ mod tests {
166
166
  "got: {err:?}"
167
167
  );
168
168
  }
169
+
170
+ // The spawn / non-zero-exit / write failure arms of `run` require actually
171
+ // invoking `claude` and touching the filesystem, so they are exercised at
172
+ // the e2e tier. Their `Display` renderings, however, are pure and covered
173
+ // here (the values are constructed inline, no process or fs I/O).
174
+
175
+ #[test]
176
+ fn spawn_error_display_mentions_spawn() {
177
+ let err = InitError::Spawn(std::io::Error::new(
178
+ std::io::ErrorKind::PermissionDenied,
179
+ "denied",
180
+ ));
181
+ let msg = format!("{err}");
182
+ assert!(msg.contains("failed to spawn"), "got: {msg}");
183
+ assert!(msg.contains("denied"), "got: {msg}");
184
+ }
185
+
186
+ #[test]
187
+ fn write_error_display_names_the_path_and_source() {
188
+ let err = InitError::Write {
189
+ path: PathBuf::from("/tmp/out.toml"),
190
+ source: std::io::Error::other("disk full"),
191
+ };
192
+ let msg = format!("{err}");
193
+ assert!(msg.contains("/tmp/out.toml"), "got: {msg}");
194
+ assert!(msg.contains("disk full"), "got: {msg}");
195
+ }
196
+
197
+ #[test]
198
+ fn invalid_utf8_error_display_mentions_utf8() {
199
+ // A non-UTF8 byte sequence yields the `FromUtf8Error` that `#[from]`
200
+ // converts into `InitError::InvalidUtf8`.
201
+ let utf8_err = String::from_utf8(vec![0xff, 0xfe]).unwrap_err();
202
+ let err: InitError = utf8_err.into();
203
+ let msg = format!("{err}");
204
+ assert!(msg.contains("non-UTF8"), "got: {msg}");
205
+ }
206
+
207
+ // NOTE: `InitError::ClaudeFailed`'s `Display` is not unit-tested -- building
208
+ // it needs an `ExitStatus`, and `std::process::ExitStatus::from_raw` is
209
+ // effectful std the unit-isolation lint (`no-out-of-module-call`) forbids.
210
+ // Its rendering is covered end-to-end at the e2e tier instead.
169
211
  }
@@ -330,4 +330,26 @@ mod tests {
330
330
  assert_eq!(pq.command, "reshape {args}");
331
331
  assert_eq!(pq.config_dir, PathBuf::from("/proj"));
332
332
  }
333
+
334
+ #[test]
335
+ fn with_query_timeout_overrides_the_default() {
336
+ // The builder replaces the 30s default with the supplied timeout and
337
+ // leaves the rest of the config untouched.
338
+ let cfg = ServerConfig::bind("127.0.0.1", 8080).with_query_timeout(Duration::from_secs(5));
339
+ assert_eq!(cfg.query_timeout, Duration::from_secs(5));
340
+ assert_eq!(cfg.host, "127.0.0.1");
341
+ assert_eq!(cfg.port, 8080);
342
+ }
343
+
344
+ #[test]
345
+ fn app_state_from_string_builds_the_unavailable_arm() {
346
+ // `String -> AppState` yields the degraded arm carrying the diagnostic
347
+ // verbatim (the `/query`/`/events` 503 body). `AppState` isn't `Debug`,
348
+ // so match rather than assert on a rendering.
349
+ let state: AppState = "config failed to load".to_string().into();
350
+ match state {
351
+ AppState::Unavailable(reason) => assert_eq!(reason, "config failed to load"),
352
+ AppState::Ready(_) => panic!("String must map to the Unavailable arm"),
353
+ }
354
+ }
333
355
  }
@@ -356,4 +356,38 @@ mod tests {
356
356
  "application/json"
357
357
  );
358
358
  }
359
+
360
+ // `parse_sql_body` is the no-`pre-query` request path: it is pure (serde
361
+ // only), so it is unit-tested here directly rather than through the async
362
+ // `handle_query` handler (which needs a live server and is covered at the
363
+ // integration tier).
364
+
365
+ #[test]
366
+ fn parse_sql_body_returns_trimmed_sql() {
367
+ // Surrounding whitespace is stripped; the inner SQL is returned as-is.
368
+ let sql = parse_sql_body(r#"{"sql": " SELECT 1 "}"#).expect("valid body");
369
+ assert_eq!(sql, "SELECT 1");
370
+ }
371
+
372
+ #[test]
373
+ fn parse_sql_body_rejects_malformed_json() {
374
+ // A body that isn't JSON fails at the serde step -> 400.
375
+ let resp = parse_sql_body("not json").expect_err("malformed JSON must be rejected");
376
+ assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
377
+ }
378
+
379
+ #[test]
380
+ fn parse_sql_body_rejects_whitespace_only_sql() {
381
+ // A present-but-blank `sql` trims to empty -> 400 (the `Some(_)` arm,
382
+ // and the `false` side of the `!s.is_empty()` guard).
383
+ let resp = parse_sql_body(r#"{"sql": " "}"#).expect_err("empty sql must be rejected");
384
+ assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
385
+ }
386
+
387
+ #[test]
388
+ fn parse_sql_body_rejects_missing_sql_field() {
389
+ // Valid JSON object with no `sql` key -> the `None` arm -> 400.
390
+ let resp = parse_sql_body("{}").expect_err("missing sql must be rejected");
391
+ assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
392
+ }
359
393
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes