refactor(hive-c0re): shared additive-migration helper in db
db::apply_migrations runs ALTER lists and ignores duplicate-column errors (turn_stats' pattern); approvals, operator_questions, broker reminders, and scheduled_prompts drop their hand-rolled pragma_table_info guards. broker's acked_at migration stays bespoke — its backfill must only run when the column was just created
This commit is contained in:
parent
34b21b8038
commit
d190420946
7 changed files with 71 additions and 132 deletions
|
|
@ -24,66 +24,26 @@ CREATE INDEX IF NOT EXISTS idx_approvals_pending
|
|||
ON approvals (id) WHERE status = 'pending';
|
||||
";
|
||||
|
||||
/// Add the `description` column to pre-description databases. Manager-supplied
|
||||
/// note shown on the dashboard approval card at submission time (distinct from
|
||||
/// `note` which is set on denial/failure).
|
||||
fn ensure_description_column(conn: &Connection) -> Result<()> {
|
||||
let has: bool = conn
|
||||
.prepare("SELECT 1 FROM pragma_table_info('approvals') WHERE name = 'description'")?
|
||||
.exists([])?;
|
||||
if !has {
|
||||
conn.execute_batch("ALTER TABLE approvals ADD COLUMN description TEXT;")
|
||||
.context("add approvals.description column")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add the `kind` column to pre-Phase-8 databases. ALTER TABLE ADD COLUMN is
|
||||
/// idempotent here only via a column-existence check (sqlite doesn't support
|
||||
/// IF NOT EXISTS on ADD COLUMN). Defaults legacy rows to `apply_commit`,
|
||||
/// which matches their actual semantics.
|
||||
fn ensure_kind_column(conn: &Connection) -> Result<()> {
|
||||
let has_kind: bool = conn
|
||||
.prepare("SELECT 1 FROM pragma_table_info('approvals') WHERE name = 'kind'")?
|
||||
.exists([])?;
|
||||
if !has_kind {
|
||||
conn.execute_batch(
|
||||
"ALTER TABLE approvals ADD COLUMN kind TEXT NOT NULL DEFAULT 'apply_commit';",
|
||||
)
|
||||
.context("add approvals.kind column")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Same shape as `ensure_kind_column` but for `fetched_sha` — the
|
||||
/// canonical sha hive-c0re vouched for at `request_apply_commit` time.
|
||||
/// Distinct from `commit_ref` (manager-supplied, may not even resolve
|
||||
/// in proposed by the time we approve).
|
||||
fn ensure_fetched_sha_column(conn: &Connection) -> Result<()> {
|
||||
let has: bool = conn
|
||||
.prepare("SELECT 1 FROM pragma_table_info('approvals') WHERE name = 'fetched_sha'")?
|
||||
.exists([])?;
|
||||
if !has {
|
||||
conn.execute_batch("ALTER TABLE approvals ADD COLUMN fetched_sha TEXT;")
|
||||
.context("add approvals.fetched_sha column")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Same shape as `ensure_fetched_sha_column` but for `submitter` — the
|
||||
/// agent that submitted the approval (the authenticated socket caller).
|
||||
/// Approval-scoped helper events route to this agent. Legacy rows have
|
||||
/// NULL; callers fall back to the root agent for those.
|
||||
fn ensure_submitter_column(conn: &Connection) -> Result<()> {
|
||||
let has: bool = conn
|
||||
.prepare("SELECT 1 FROM pragma_table_info('approvals') WHERE name = 'submitter'")?
|
||||
.exists([])?;
|
||||
if !has {
|
||||
conn.execute_batch("ALTER TABLE approvals ADD COLUMN submitter TEXT;")
|
||||
.context("add approvals.submitter column")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Additive column migrations for pre-existing databases, applied via
|
||||
/// `db::apply_migrations` (try-and-ignore-duplicate-column).
|
||||
const MIGRATIONS: &[&str] = &[
|
||||
// `kind` (pre-Phase-8 dbs): legacy rows default to `apply_commit`,
|
||||
// which matches their actual semantics.
|
||||
"ALTER TABLE approvals ADD COLUMN kind TEXT NOT NULL DEFAULT 'apply_commit'",
|
||||
// `description`: manager-supplied note shown on the dashboard
|
||||
// approval card at submission time (distinct from `note`, set on
|
||||
// denial/failure).
|
||||
"ALTER TABLE approvals ADD COLUMN description TEXT",
|
||||
// `fetched_sha`: the canonical sha hive-c0re vouched for at
|
||||
// `request_apply_commit` time. Distinct from `commit_ref`
|
||||
// (manager-supplied, may not even resolve by approve time).
|
||||
"ALTER TABLE approvals ADD COLUMN fetched_sha TEXT",
|
||||
// `submitter`: the agent that submitted the approval (the
|
||||
// authenticated socket caller); approval-scoped helper events
|
||||
// route to it. Legacy rows are NULL → callers fall back to the
|
||||
// root agent.
|
||||
"ALTER TABLE approvals ADD COLUMN submitter TEXT",
|
||||
];
|
||||
|
||||
pub struct Approvals {
|
||||
conn: Mutex<Connection>,
|
||||
|
|
@ -94,10 +54,7 @@ impl Approvals {
|
|||
let conn = crate::db::open(path, "approvals")?;
|
||||
conn.execute_batch(SCHEMA)
|
||||
.context("apply approvals schema")?;
|
||||
ensure_kind_column(&conn).context("migrate approvals.kind")?;
|
||||
ensure_fetched_sha_column(&conn).context("migrate approvals.fetched_sha")?;
|
||||
ensure_description_column(&conn).context("migrate approvals.description")?;
|
||||
ensure_submitter_column(&conn).context("migrate approvals.submitter")?;
|
||||
crate::db::apply_migrations(&conn, "approvals", MIGRATIONS)?;
|
||||
Ok(Self {
|
||||
conn: Mutex::new(conn),
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue