diff --git a/src/app.rs b/src/app.rs index d124b2e..98b4fc8 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5882,6 +5882,25 @@ mod tests { assert!(!output_contains(&app, "Remove a table")); } + // ── Phase C batch 3: DML hints render (incl. multi-form SHOW) ── + + #[test] + fn f1_on_update_renders_its_hint_block() { + let mut app = App::new(); + type_str(&mut app, "update Customers set email = 'x' "); + f1(&mut app); + assert!(output_contains(&app, "Change values in the rows")); + } + + #[test] + fn f1_disambiguates_show_forms() { + let mut app = App::new(); + type_str(&mut app, "show relationships"); + f1(&mut app); + assert!(output_contains(&app, "List all the relationships")); + assert!(!output_contains(&app, "rows stored in a table")); + } + #[test] fn messages_command_toggles_verbosity_and_reports() { let mut app = App::new(); diff --git a/src/dsl/grammar/data.rs b/src/dsl/grammar/data.rs index 752014d..665ba50 100644 --- a/src/dsl/grammar/data.rs +++ b/src/dsl/grammar/data.rs @@ -1790,7 +1790,13 @@ pub static SHOW: CommandNode = CommandNode { shape: SHOW_SHAPE, ast_builder: build_show, help_id: Some("data.show"), - hint_ids: &[], + hint_ids: &[ + "show_data", + "show_table", + "show_tables", + "show_relationships", + "show_indexes", + ], usage_ids: &[ "parse.usage.show_data", "parse.usage.show_table", @@ -1806,7 +1812,7 @@ pub static SEED: CommandNode = CommandNode { shape: SEED_SHAPE, ast_builder: build_seed, help_id: Some("data.seed"), - hint_ids: &[], + hint_ids: &["seed"], usage_ids: &["parse.usage.seed"], }; @@ -1824,7 +1830,7 @@ pub static UPDATE: CommandNode = CommandNode { shape: UPDATE_SHAPE, ast_builder: build_update, help_id: Some("data.update"), - hint_ids: &[], + hint_ids: &["update"], usage_ids: &["parse.usage.update"],}; pub static DELETE: CommandNode = CommandNode { @@ -1832,7 +1838,7 @@ pub static DELETE: CommandNode = CommandNode { shape: DELETE_SHAPE, ast_builder: build_delete, help_id: Some("data.delete"), - hint_ids: &[], + hint_ids: &["delete"], usage_ids: &["parse.usage.delete"],}; pub static REPLAY: CommandNode = CommandNode { @@ -1840,7 +1846,7 @@ pub static REPLAY: CommandNode = CommandNode { shape: REPLAY_PATH, ast_builder: build_replay, help_id: Some("data.replay"), - hint_ids: &[], + hint_ids: &["replay"], usage_ids: &["parse.usage.replay"],}; pub static EXPLAIN: CommandNode = CommandNode { @@ -1848,7 +1854,7 @@ pub static EXPLAIN: CommandNode = CommandNode { shape: EXPLAIN_SHAPE, ast_builder: build_explain, help_id: Some("data.explain"), - hint_ids: &[], + hint_ids: &["explain"], usage_ids: &["parse.usage.explain"],}; /// `explain` over advanced-mode SQL (ADR-0039). diff --git a/src/friendly/keys.rs b/src/friendly/keys.rs index c27c436..490e7eb 100644 --- a/src/friendly/keys.rs +++ b/src/friendly/keys.rs @@ -306,6 +306,36 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[ ("hint.cmd.change_column.what", &[]), ("hint.cmd.change_column.example", &[]), ("hint.cmd.change_column.concept", &[]), + // Phase C batch 3 — DML command hints. + ("hint.cmd.update.what", &[]), + ("hint.cmd.update.example", &[]), + ("hint.cmd.update.concept", &[]), + ("hint.cmd.delete.what", &[]), + ("hint.cmd.delete.example", &[]), + ("hint.cmd.delete.concept", &[]), + ("hint.cmd.show_data.what", &[]), + ("hint.cmd.show_data.example", &[]), + ("hint.cmd.show_data.concept", &[]), + ("hint.cmd.show_table.what", &[]), + ("hint.cmd.show_table.example", &[]), + ("hint.cmd.show_table.concept", &[]), + ("hint.cmd.show_tables.what", &[]), + ("hint.cmd.show_tables.example", &[]), + ("hint.cmd.show_relationships.what", &[]), + ("hint.cmd.show_relationships.example", &[]), + ("hint.cmd.show_relationships.concept", &[]), + ("hint.cmd.show_indexes.what", &[]), + ("hint.cmd.show_indexes.example", &[]), + ("hint.cmd.show_indexes.concept", &[]), + ("hint.cmd.seed.what", &[]), + ("hint.cmd.seed.example", &[]), + ("hint.cmd.seed.concept", &[]), + ("hint.cmd.explain.what", &[]), + ("hint.cmd.explain.example", &[]), + ("hint.cmd.explain.concept", &[]), + ("hint.cmd.replay.what", &[]), + ("hint.cmd.replay.example", &[]), + ("hint.cmd.replay.concept", &[]), ( "hint.ambient_invalid_ident", &["kind", "found"], diff --git a/src/friendly/strings/en-US.yaml b/src/friendly/strings/en-US.yaml index 9639ccb..5bf98ed 100644 --- a/src/friendly/strings/en-US.yaml +++ b/src/friendly/strings/en-US.yaml @@ -505,6 +505,46 @@ hint: what: "Change a column's type, converting the existing values." example: "change column Customers: status (int)" concept: "The database converts each stored value to the new type; if a value can't convert it refuses the change, so you don't silently lose data. Flags let you force or skip the conversion." + # DML — querying and changing data (Phase C batch 3). + update: + what: "Change values in the rows that match a condition." + example: "update Customers set email = 'new@example.io' where id = 1" + concept: "The `where` clause picks which rows change, and it's required — pass `--all-rows` to change the whole table on purpose — so you never update more than you meant to." + delete: + what: "Remove the rows that match a condition." + example: "delete from Orders where status = 'cancelled'" + concept: "A `where` is required (use `--all-rows` to clear the table on purpose). Rows a relationship points at may be blocked or cascade-deleted, per its `on delete` action." + show_data: + what: "Show the rows stored in a table." + example: "show data Customers" + concept: "This reads the data and never changes it. Add a `where` to show only matching rows." + show_table: + what: "Show a table's structure — its columns, types, keys, and relationships." + example: "show table Customers" + concept: "Structure, not data: the column definitions and how this table links to others. Use `show data` to see the rows themselves." + show_tables: + what: "List all the tables in the project." + example: "show tables" + show_relationships: + what: "List all the relationships between tables." + example: "show relationships" + concept: "Each relationship is a foreign-key link from a child column to a parent's key, with an `on delete` / `on update` rule." + show_indexes: + what: "List all the indexes in the project." + example: "show indexes" + concept: "Indexes speed up lookups; this shows which columns each one covers and whether it enforces uniqueness." + seed: + what: "Fill a table with generated sample rows, or fill one column on existing rows." + example: "seed Customers 50" + concept: "Seeding invents realistic-looking data so you have something to query. Pin a value with `set col = …`, choose a generator with `as`, or give a numeric range with `between`." + explain: + what: "Show how the database will run a query — without running it." + example: "explain show data Customers where email = 'a@example.io'" + concept: "The plan reveals whether the database scans the whole table or jumps straight to rows through an index — the payoff of `add index`. `explain` never executes, so it's safe even on a delete." + replay: + what: "Re-run the commands recorded in a history file." + example: "replay session.log" + concept: "Every successful command is journalled, so replaying re-applies them in order to reproduce a project's state — handy for scripting or redoing a sequence." err: foreign_key: child_side: