dirsql 0.3.37__tar.gz → 0.3.38__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.37 → dirsql-0.3.38}/Cargo.lock +1 -1
- {dirsql-0.3.37 → dirsql-0.3.38}/PKG-INFO +1 -1
- {dirsql-0.3.37/packages/rust → dirsql-0.3.38}/docs/guide/tables.md +1 -1
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/Cargo.toml +1 -1
- {dirsql-0.3.37 → dirsql-0.3.38/packages/python}/docs/guide/tables.md +1 -1
- dirsql-0.3.38/packages/python/e2e-attestation.json +6 -0
- {dirsql-0.3.37/packages/python → dirsql-0.3.38/packages/rust}/docs/guide/tables.md +1 -1
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/db.rs +164 -15
- dirsql-0.3.37/packages/python/e2e-attestation.json +0 -6
- {dirsql-0.3.37 → dirsql-0.3.38}/Cargo.toml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/README.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/_async.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/interpret/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/interpret/dispatch_extract.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/interpret/load_app.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/interpret/run.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/interpret/write_message.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/cli/main.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/py.typed +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/dirsql/resolve_config.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/AGENTS.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/api/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/cli/config.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/cli/http-api.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/cli/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/cli/init.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/cli/server.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/getting-started.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/guide/async.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/guide/crdt.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/guide/persistence.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/guide/querying.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/guide/watching.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/migrations.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/package.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/playwright.config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/docs/vitest.config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/README.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/conftest.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/api/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/cli/config.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/cli/http-api.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/cli/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/cli/init.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/cli/server.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/guide/async.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/guide/crdt.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/guide/persistence.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/guide/querying.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/guide/watching.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/package.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/playwright.config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/vitest.config.ts +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/data/a/meta.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/data/b/meta.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/dirsql.config.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/data/a/meta.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/data/b/meta.json +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/dirsql.config.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/dirsql.config_no_app.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/dirsql.config_raises.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/interpret_subprocess.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/Cargo.toml +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/README.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/api/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/cli/config.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/cli/http-api.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/cli/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/cli/init.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/cli/server.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/guide/async.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/guide/crdt.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/guide/persistence.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/guide/querying.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/guide/watching.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/index.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/native_config.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/config.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/lib.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.37 → dirsql-0.3.38}/pyproject.toml +0 -0
|
@@ -72,7 +72,7 @@ ddl="CREATE TABLE metrics (name TEXT, value REAL, count INTEGER)"
|
|
|
72
72
|
ddl="CREATE TABLE items (id TEXT PRIMARY KEY, name TEXT NOT NULL)"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
The table name is parsed from the DDL
|
|
75
|
+
The table name is parsed from the DDL and must resolve to a valid SQLite identifier.
|
|
76
76
|
|
|
77
77
|
### `glob`
|
|
78
78
|
|
|
@@ -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.
|
|
7
|
+
version = "0.3.38"
|
|
8
8
|
edition.workspace = true
|
|
9
9
|
publish = false
|
|
10
10
|
readme = "README.md"
|
|
@@ -72,7 +72,7 @@ ddl="CREATE TABLE metrics (name TEXT, value REAL, count INTEGER)"
|
|
|
72
72
|
ddl="CREATE TABLE items (id TEXT PRIMARY KEY, name TEXT NOT NULL)"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
The table name is parsed from the DDL
|
|
75
|
+
The table name is parsed from the DDL and must resolve to a valid SQLite identifier.
|
|
76
76
|
|
|
77
77
|
### `glob`
|
|
78
78
|
|
|
@@ -72,7 +72,7 @@ ddl="CREATE TABLE metrics (name TEXT, value REAL, count INTEGER)"
|
|
|
72
72
|
ddl="CREATE TABLE items (id TEXT PRIMARY KEY, name TEXT NOT NULL)"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
The table name is parsed from the DDL
|
|
75
|
+
The table name is parsed from the DDL and must resolve to a valid SQLite identifier.
|
|
76
76
|
|
|
77
77
|
### `glob`
|
|
78
78
|
|
|
@@ -402,27 +402,89 @@ impl rusqlite::types::ToSql for Value {
|
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
-
/// Extract the table name from a CREATE TABLE DDL statement.
|
|
406
|
-
///
|
|
405
|
+
/// Extract the table name from a `CREATE TABLE` DDL statement.
|
|
406
|
+
///
|
|
407
|
+
/// The name token in `CREATE TABLE [IF NOT EXISTS] <name> (...)` may be:
|
|
408
|
+
/// - a bare identifier: `comments`
|
|
409
|
+
/// - a quoted identifier: `"comments"`, `` `comments` ``, `[comments]`
|
|
410
|
+
/// - schema-qualified: `main.comments`, `"main"."comments"`
|
|
411
|
+
///
|
|
412
|
+
/// Surrounding quotes are SQL *delimiters*, not part of the name, so they are
|
|
413
|
+
/// stripped: a tool that emits `CREATE TABLE "comments" (...)` (as ORMs and
|
|
414
|
+
/// schema generators routinely do) names the table `comments`. Schema-qualified
|
|
415
|
+
/// names resolve to the table segment. Returns `None` when the input isn't a
|
|
416
|
+
/// `CREATE TABLE` or carries no name token.
|
|
417
|
+
///
|
|
418
|
+
/// This is deliberately a small, pure tokenizer rather than a full SQL parser
|
|
419
|
+
/// (or a round-trip through SQLite): dirsql constrains table names to safe
|
|
420
|
+
/// unquoted identifiers via [`validate_identifier`], so the handful of forms
|
|
421
|
+
/// above are the only ones that can actually resolve to a usable table.
|
|
407
422
|
pub fn parse_table_name(ddl: &str) -> Option<String> {
|
|
408
423
|
let upper = ddl.to_uppercase();
|
|
409
424
|
let idx = upper.find("CREATE TABLE")?;
|
|
410
|
-
let rest =
|
|
425
|
+
let mut rest = ddl[idx + "CREATE TABLE".len()..].trim_start();
|
|
411
426
|
|
|
412
|
-
// Skip optional "IF NOT EXISTS"
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
427
|
+
// Skip optional "IF NOT EXISTS". `.get()` avoids slicing on a non-char
|
|
428
|
+
// boundary when the name itself begins with a multi-byte character.
|
|
429
|
+
const IF_NOT_EXISTS: &str = "IF NOT EXISTS";
|
|
430
|
+
if rest
|
|
431
|
+
.get(..IF_NOT_EXISTS.len())
|
|
432
|
+
.is_some_and(|p| p.eq_ignore_ascii_case(IF_NOT_EXISTS))
|
|
433
|
+
{
|
|
434
|
+
rest = rest[IF_NOT_EXISTS.len()..].trim_start();
|
|
435
|
+
}
|
|
418
436
|
|
|
419
|
-
//
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
437
|
+
// Parse dot-separated identifier segments (`schema.table`) and keep the
|
|
438
|
+
// last one: the table name. Each segment may be quoted independently.
|
|
439
|
+
let mut chars = rest.chars().peekable();
|
|
440
|
+
let mut table = parse_identifier(&mut chars)?;
|
|
441
|
+
while chars.peek() == Some(&'.') {
|
|
442
|
+
chars.next();
|
|
443
|
+
table = parse_identifier(&mut chars)?;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if table.is_empty() { None } else { Some(table) }
|
|
447
|
+
}
|
|
424
448
|
|
|
425
|
-
|
|
449
|
+
/// Read one identifier segment from `chars`: a quoted identifier
|
|
450
|
+
/// (`"..."`, `` `...` ``, or `[...]`, with the doubled-delimiter escape for the
|
|
451
|
+
/// matching close on the SQL-standard quote forms) or a bare run up to the
|
|
452
|
+
/// first whitespace, `(`, or `.`. Returns the *unquoted* text. Returns `None`
|
|
453
|
+
/// only when the cursor is already exhausted.
|
|
454
|
+
fn parse_identifier(chars: &mut std::iter::Peekable<std::str::Chars<'_>>) -> Option<String> {
|
|
455
|
+
let (open, close) = match *chars.peek()? {
|
|
456
|
+
'"' => ('"', '"'),
|
|
457
|
+
'`' => ('`', '`'),
|
|
458
|
+
'[' => ('[', ']'),
|
|
459
|
+
_ => {
|
|
460
|
+
let mut bare = String::new();
|
|
461
|
+
while let Some(&c) = chars.peek() {
|
|
462
|
+
if c.is_whitespace() || c == '(' || c == '.' {
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
bare.push(c);
|
|
466
|
+
chars.next();
|
|
467
|
+
}
|
|
468
|
+
return Some(bare);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
chars.next(); // consume the opening delimiter
|
|
473
|
+
let mut name = String::new();
|
|
474
|
+
while let Some(c) = chars.next() {
|
|
475
|
+
if c == close {
|
|
476
|
+
// On `"` / `` ` ``, a doubled close delimiter is an escaped literal
|
|
477
|
+
// (`""` -> `"`); SQLite's `[...]` form has no such escape.
|
|
478
|
+
if open != '[' && chars.peek() == Some(&close) {
|
|
479
|
+
chars.next();
|
|
480
|
+
name.push(close);
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
name.push(c);
|
|
486
|
+
}
|
|
487
|
+
Some(name)
|
|
426
488
|
}
|
|
427
489
|
|
|
428
490
|
/// True if `ddl` is a `CREATE VIRTUAL TABLE` statement. dirsql tables are
|
|
@@ -630,6 +692,93 @@ mod tests {
|
|
|
630
692
|
assert_eq!(parse_table_name("CREATE TABLE "), None);
|
|
631
693
|
}
|
|
632
694
|
|
|
695
|
+
#[test]
|
|
696
|
+
fn parse_table_name_double_quoted() {
|
|
697
|
+
// The canonical ORM / schema-generator shape: the quotes are SQL
|
|
698
|
+
// delimiters and must be stripped to the bare `comments`.
|
|
699
|
+
assert_eq!(
|
|
700
|
+
parse_table_name(r#"CREATE TABLE "comments" (id TEXT)"#),
|
|
701
|
+
Some("comments".to_string())
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
#[test]
|
|
706
|
+
fn parse_table_name_double_quoted_no_space_before_paren() {
|
|
707
|
+
assert_eq!(
|
|
708
|
+
parse_table_name(r#"CREATE TABLE "comments"(id TEXT)"#),
|
|
709
|
+
Some("comments".to_string())
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
#[test]
|
|
714
|
+
fn parse_table_name_backtick_quoted() {
|
|
715
|
+
assert_eq!(
|
|
716
|
+
parse_table_name("CREATE TABLE `comments` (id TEXT)"),
|
|
717
|
+
Some("comments".to_string())
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
#[test]
|
|
722
|
+
fn parse_table_name_bracket_quoted() {
|
|
723
|
+
// SQLite's `[ident]` form ends at the first `]` -- no doubling escape.
|
|
724
|
+
assert_eq!(
|
|
725
|
+
parse_table_name("CREATE TABLE [comments] (id TEXT)"),
|
|
726
|
+
Some("comments".to_string())
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
#[test]
|
|
731
|
+
fn parse_table_name_double_quote_escape() {
|
|
732
|
+
// `""` inside a double-quoted identifier is one literal `"`. The
|
|
733
|
+
// extracted name is later rejected by `validate_identifier`; here we
|
|
734
|
+
// only assert the tokenizer unescapes correctly.
|
|
735
|
+
assert_eq!(
|
|
736
|
+
parse_table_name(r#"CREATE TABLE "we""ird" (id TEXT)"#),
|
|
737
|
+
Some("we\"ird".to_string())
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
#[test]
|
|
742
|
+
fn parse_table_name_if_not_exists_quoted_mixed_case() {
|
|
743
|
+
assert_eq!(
|
|
744
|
+
parse_table_name(r#"CREATE TABLE if not exists "comments" (id TEXT)"#),
|
|
745
|
+
Some("comments".to_string())
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
#[test]
|
|
750
|
+
fn parse_table_name_schema_qualified() {
|
|
751
|
+
// `schema.table` resolves to the table segment (the name SQLite stores
|
|
752
|
+
// in `sqlite_master`).
|
|
753
|
+
assert_eq!(
|
|
754
|
+
parse_table_name("CREATE TABLE main.comments (id TEXT)"),
|
|
755
|
+
Some("comments".to_string())
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
#[test]
|
|
760
|
+
fn parse_table_name_schema_qualified_quoted() {
|
|
761
|
+
assert_eq!(
|
|
762
|
+
parse_table_name(r#"CREATE TABLE "main"."comments" (id TEXT)"#),
|
|
763
|
+
Some("comments".to_string())
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
#[test]
|
|
768
|
+
fn parse_table_name_runs_to_end_of_input() {
|
|
769
|
+
// Bare identifier terminated by EOF rather than whitespace/paren.
|
|
770
|
+
assert_eq!(
|
|
771
|
+
parse_table_name("CREATE TABLE comments"),
|
|
772
|
+
Some("comments".to_string())
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
#[test]
|
|
777
|
+
fn parse_table_name_missing_name_is_none() {
|
|
778
|
+
// A `(` where the name should be yields an empty token -> None.
|
|
779
|
+
assert_eq!(parse_table_name("CREATE TABLE (id TEXT)"), None);
|
|
780
|
+
}
|
|
781
|
+
|
|
633
782
|
#[test]
|
|
634
783
|
fn get_table_columns_returns_user_columns_only() {
|
|
635
784
|
let db = Db::new().unwrap();
|
|
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
|
|
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
|
|
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
|
{dirsql-0.3.37 → dirsql-0.3.38}/packages/python/docs/tests/integration/language-flag.spec.ts
RENAMED
|
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
|
{dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/data/a/meta.json
RENAMED
|
File without changes
|
{dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/data/b/meta.json
RENAMED
|
File without changes
|
{dirsql-0.3.37 → dirsql-0.3.38}/packages/python/tests/e2e/__fixtures__/interpret/dirsql.config.py
RENAMED
|
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
|
|
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
|