Commit 8699ee0
committed
feat(ogar-adapter-surrealql): AST -> Class walk (closes ADR-017)
The `parse_surrealql_ddl` function now actually walks the SurrealDB
AST and lifts the supported DDL subset into `Vec<Class>`. PR #24
wired the parser for syntax validation only; this PR completes the
walk for the v1 subset.
# Supported in this walk
- DEFINE TABLE <name> -> Class
- DEFINE FIELD <field> ON <table> TYPE
string | int | bool | datetime | float | decimal |
uuid | bytes | object | duration | any -> Attribute
- DEFINE FIELD <field> ON <table> TYPE record<X> -> Association(BelongsTo)
- DEFINE FIELD <field> ON <table> TYPE option<record<X>>
-> Association(BelongsTo, optional=true)
- DEFINE FIELD <field> ON <table> TYPE option<<primitive>>
-> Attribute(type=option<primitive>)
- Implicit-table-from-field (no preceding DEFINE TABLE) — the
walker creates the class lazily on first field encounter.
- Multi-table definition order preserved.
# Not yet supported (intentional next-sprint shape)
- DEFINE FIELD … ASSERT $value IN [...] (EnumDecl::Static lift)
- VALUE / DEFAULT / COMPUTED clauses
- PERMISSIONS / FLEXIBLE / READONLY
- DEFINE EVENT (lifecycle -> ActionDef)
- DEFINE INDEX (not part of OGAR IR; ignored)
- Comment-marker recovery for non-owning sides
(`-- {table} HasMany {name}` is a SurrealQL comment, invisible
to the parser; the non-owning side is recoverable from the
owning side's record<X> in a separate post-pass over the full
Vec<Class>).
# AST walker architecture
New private `walk` module under `#[cfg(feature = "surrealdb-parser")]`:
- `walk_query(&Ast, Query) -> Vec<Class>` — entry point.
- `visit_define(&Ast, NodeId<Expr>, &mut by_name, &mut order)`
matches on Expr::DefineTable / Expr::DefineField.
- `expr_to_simple_name(&Ast, NodeId<Expr>) -> Option<String>`
extracts identifier names from `Expr::Path { start: Ident,
parts: None }`.
- `lift_field_type(&Ast, Option<NodeId<Type>>) -> FieldShape`
classifies the Type AST into Primitive | Record | Untyped |
Other. Handles the `option<X>` encoding (NodeList<PrimeType>
prefixed with PrimeType::None — per surrealdb/parser/src/
parse/kind.rs at T![OPTION]).
- `iter_node_list<T>(&Ast, NodeListId<T>)` — closure-based
iterator over the AST's linked-list structure.
# Round-trip tests
8 new tests on top of the 14 pre-existing. The shape:
walk_minimal_table_produces_class
walk_table_with_string_attribute
walk_table_with_belongs_to_record_field
walk_table_with_optional_belongs_to
walk_multi_table_preserves_definition_order
walk_round_trip_simple_class <- emit then parse, structural eq
walk_round_trip_belongs_to_association
walk_implicit_table_from_field_alone
walk_returns_parse_error_on_invalid_ddl
# Producer of `schema_ddl_hint` (the loop closure)
PR #25 introduced `KnowableFromStore::register(class_identity,
schema_ddl_hint: Option<&str>)` — the registry's "self-describing"
clause. Today every caller passes `None`. This PR makes
`emit_surrealql_ddl(&[class.clone()])` the canonical producer of the
hint, closing the loop that PR #25's docstring named ("Future PRs
can render via ogar-adapter-surrealql::emit_surrealql_ddl"). A
follow-up can wire that call into `register_class_knowable_from`'s
body.
# CI floor extended
`.github/workflows/ci.yml` adds:
cargo test -p ogar-adapter-surrealql --features surrealdb-parser
The default `cargo test --workspace` step doesn't enable the feature
(the parser dep is heavy and not needed by other workspace members);
this extra step makes the walker tests part of the CI floor. ~30-60s
added to CI; bounded scope (one crate).
# Verification
Local:
- `cargo test -p ogar-adapter-surrealql --features surrealdb-parser`
-> 22 passed (14 prior + 8 walker tests).
- `cargo test --workspace` (default, no feature) -> clean (the
walker code is behind cfg; the existing parser-off test still
runs).
- `cargo check --workspace --all-targets` -> clean.
Closes ADR-017 (the surrealql-AST-to-Class walk) for the v1 subset.
https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY1 parent abadc02 commit 8699ee0
2 files changed
Lines changed: 404 additions & 42 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
0 commit comments