Foreign-key relationships, rebuild-table, polish round
DSL:
- add 1:n relationship [as <name>] from <P>.<col> to <C>.<col>
[on delete <action>] [on update <action>] [--create-fk]
- drop relationship <name> | from <P>.<col> to <C>.<col>
- show table <name> for re-displaying a structure on demand
Database (ADR-0013):
- Rebuild-table primitive following SQLite's
ALTER-via-rebuild recipe (foreign_keys=OFF outside tx,
copy-by-name, foreign_key_check before commit). Reusable for
B2 (column drops/renames/type changes).
- ReferentialAction enum (no action / restrict / set null /
cascade); SET DEFAULT awaits column DEFAULTs.
- __rdbms_playground_relationships metadata table -- names,
auto-generated as <Parent>_<pcol>_to_<Child>_<ccol>.
- Type::fk_target_type() validation at declaration; friendly
errors for type mismatch, non-PK target, missing column,
duplicate name.
- describe_table populates symmetric outbound + inbound
relationship lists. drop_table refuses while inbound
references exist; outbound metadata cleaned up alongside drop.
App / UI:
- In-line cursor editing in the input field: Left, Right,
Home, End, Delete, Backspace honoring UTF-8 boundaries.
- PageUp / PageDown scrolls the output buffer; viewport row
count fed back from the renderer via App::note_output_viewport
so scroll is capped against the actual visible area
(regression-tested) and snaps to the bottom on new output.
- Failure messages quote the command portion ("verb target"
failed: ...) for visual clarity; RelationshipSelector has a
proper Display impl so "no such relationship" reads cleanly.
- Structure rendering shows References / Referenced by sections.
Docs:
- ADR-0013 covers naming, metadata table, symmetric view, and
the rebuild-table strategy.
- requirements.md updates: C3 (FK done), B2 (primitive in),
T3 (compound-PK FK still pending). New entries: I1a (cursor
editing -- landed), I1b (Ctrl-A/E and readline shortcuts --
pending), V4 partial scroll, V5 (show family), C3a (modify
relationship -- deferred).
Tests: 154 passing (140 lib + 14 integration), 0 skipped.
Clippy clean with nursery enabled.
This commit is contained in:
+34
-2
@@ -68,7 +68,7 @@ async fn run_loop(
|
||||
seed_initial_tables(&database, &event_tx).await;
|
||||
|
||||
terminal
|
||||
.draw(|f| ui::render(&app, &theme, f))
|
||||
.draw(|f| ui::render(&mut app, &theme, f))
|
||||
.context("initial draw")?;
|
||||
|
||||
info!("entering main event loop");
|
||||
@@ -87,7 +87,7 @@ async fn run_loop(
|
||||
}
|
||||
}
|
||||
terminal
|
||||
.draw(|f| ui::render(&app, &theme, f))
|
||||
.draw(|f| ui::render(&mut app, &theme, f))
|
||||
.context("redraw")?;
|
||||
if should_quit {
|
||||
break;
|
||||
@@ -170,6 +170,38 @@ async fn execute_command(
|
||||
.await
|
||||
.map(Some)
|
||||
.map_err(friendly),
|
||||
Command::AddRelationship {
|
||||
name,
|
||||
parent_table,
|
||||
parent_column,
|
||||
child_table,
|
||||
child_column,
|
||||
on_delete,
|
||||
on_update,
|
||||
create_fk,
|
||||
} => database
|
||||
.add_relationship(
|
||||
name,
|
||||
parent_table,
|
||||
parent_column,
|
||||
child_table,
|
||||
child_column,
|
||||
on_delete,
|
||||
on_update,
|
||||
create_fk,
|
||||
)
|
||||
.await
|
||||
.map(Some)
|
||||
.map_err(friendly),
|
||||
Command::DropRelationship { selector } => database
|
||||
.drop_relationship(selector)
|
||||
.await
|
||||
.map_err(friendly),
|
||||
Command::ShowTable { name } => database
|
||||
.describe_table(name)
|
||||
.await
|
||||
.map(Some)
|
||||
.map_err(friendly),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user