Iteration 3: existence-only load + rebuild from text on missing .db
When the runtime opens a project whose playground.db is missing,
it now rebuilds the database from project.yaml + data/<table>.csv
per ADR-0015 §7. The rebuild path:
1. Parses project.yaml (serde_yml). Unknown versions / types /
actions surface as PersistenceFatal.
2. Recreates each user table with FK constraints inline
(PRAGMA foreign_keys=OFF), then populates the column-type,
relationship, and project metadata tables.
3. Loads each table's CSV via a hand-rolled reader that
preserves the NULL-vs-empty distinction (the csv crate
doesn't expose whether a field was quoted; ours does).
4. Runs PRAGMA foreign_key_check before commit; any violation
aborts.
5. Restores foreign_keys=ON regardless of success.
Row-level failures get DbError::RebuildRowFailed with row
number, file, table, and a friendly per-type detail. They land
in the runtime as a fatal stderr message ("unable to load row N
from `data/T.csv` into table `T`: ...") before the alternate
screen is entered.
created_at from project.yaml overwrites the configure-time
placeholder so timestamps round-trip stably.
Tests: 307 passing (267 lib + 9 + 5 new + 9 + 17), 0 failing,
0 skipped. Clippy clean with nursery lints.
This commit is contained in:
@@ -22,10 +22,15 @@ use crate::dsl::action::ReferentialAction;
|
||||
use crate::dsl::types::Type;
|
||||
use crate::project::{DATA_DIR, HISTORY_LOG, PROJECT_YAML};
|
||||
|
||||
// Submodules are private; the few items the db worker needs
|
||||
// during rebuild (ADR-0015 §7) are re-exported below.
|
||||
mod csv_io;
|
||||
mod history;
|
||||
mod yaml;
|
||||
|
||||
pub(crate) use csv_io::{decode_cell, parse_csv};
|
||||
pub(crate) use yaml::parse_schema;
|
||||
|
||||
/// Owns persistence to a single project on disk. Cheap to
|
||||
/// move; the db worker holds one instance for its lifetime.
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user