This commit is contained in:
Kelorastus
2026-09-23 16:05:19 +02:00
parent 4a92cc0b63
commit 4d620fc5ad
27 changed files with 3571 additions and 104 deletions
+44 -1
View File
@@ -4,7 +4,7 @@
//! snapshot is restored in the order proven on the Data PC's dumps: pre-data,
//! every table's data (in parallel), sequences, post-data.
use std::collections::VecDeque;
use std::collections::{BTreeSet, VecDeque};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
@@ -420,6 +420,18 @@ const ADDING_MARKER: &str = "adding-tables.txt";
/// copy would make this PC's Engine API skip migrations its schema never had.
const OWN_DATABASE_ONLY: [&str; 1] = ["public.odian_schema_migrations"];
/// The files of a snapshot a database lacking only `missing` needs: the schema and sequence
/// dumps (small, and adding tables reads them) and the data of the missing tables. The rest
/// is data the database already holds. A data dump with no plain table name is kept, the
/// safe side of not knowing.
pub fn files_needed(files: &[DbFile], missing: &[String]) -> BTreeSet<String> {
files
.iter()
.filter(|f| f.section != "data" || table_of(f).is_none_or(|table| missing.contains(&table)))
.map(|f| f.path.clone())
.collect()
}
/// The snapshot's data tables an existing database may lack and be given.
fn candidate_tables(files: &[DbFile]) -> Vec<String> {
files
@@ -565,6 +577,37 @@ CREATE FUNCTION public.hospital_count() RETURNS bigint AS $$ SELECT count(*) FRO
("postgis_hospital", "TABLE", "public.postgis_hospital".to_string()));
}
#[test]
fn a_database_keeping_its_data_needs_only_the_schema_and_the_tables_it_lacks() {
let file = |section: &str, table: Option<&str>, path: &str| DbFile {
section: section.to_string(),
table: table.map(str::to_string),
path: path.to_string(),
size: 1,
};
let files = [
file("pre-data", None, "db/S/pre-data.dump"),
file("data", Some("public.odb_note"), "db/S/data/public.odb_note.dump"),
file("data", Some("public.postgis_hospital"), "db/S/data/public.postgis_hospital.dump"),
file("data", None, "db/S/data/Weird Name.dump"),
file("data", Some("public.odian_schema_migrations"), "db/S/data/public.odian_schema_migrations.dump"),
file("sequences", None, "db/S/sequences.dump"),
file("post-data", None, "db/S/post-data.dump"),
];
let needed = files_needed(&files, &["public.postgis_hospital".to_string()]);
assert_eq!(
needed.into_iter().collect::<Vec<_>>(),
[
"db/S/data/Weird Name.dump",
"db/S/data/public.postgis_hospital.dump",
"db/S/post-data.dump",
"db/S/pre-data.dump",
"db/S/sequences.dump",
]
);
assert_eq!(files_needed(&files, &[]).len(), 4, "nothing missing: the schema dumps and the unnamed one");
}
#[test]
fn a_table_is_referenced_whole_never_as_a_prefix() {
assert!(references("CREATE INDEX i ON public.postgis_hospital USING gist (geom);", "public.postgis_hospital"));