style: format the whole tree with cargo fmt (stock defaults, #35)
One-time, mechanical reformat — no functional changes. The tree was not rustfmt-clean (~1800 hunks across ~100 files); this brings it to stock `cargo fmt` defaults so a `cargo fmt --check` CI gate can follow. Behaviour-preserving: 2509 pass / 0 fail / 1 ignored (unchanged baseline), clippy clean. A .git-blame-ignore-revs entry follows so `git blame` skips this commit.
This commit is contained in:
+165
-45
@@ -8,7 +8,7 @@
|
||||
|
||||
use rdbms_playground::db::Database;
|
||||
use rdbms_playground::dsl::command::RowFilter;
|
||||
use rdbms_playground::dsl::{parse_command, ColumnSpec, Command, Type, Value};
|
||||
use rdbms_playground::dsl::{ColumnSpec, Command, Type, Value, parse_command};
|
||||
use rdbms_playground::persistence::Persistence;
|
||||
use rdbms_playground::project::{self, PLAYGROUND_DB};
|
||||
|
||||
@@ -22,8 +22,11 @@ fn rt() -> tokio::runtime::Runtime {
|
||||
fn open() -> (project::Project, Database, tempfile::TempDir) {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let project = project::open_or_create(None, Some(dir.path())).expect("project");
|
||||
let db = Database::open_with_persistence(project.db_path(), Persistence::new(project.path().to_path_buf()))
|
||||
.expect("db");
|
||||
let db = Database::open_with_persistence(
|
||||
project.db_path(),
|
||||
Persistence::new(project.path().to_path_buf()),
|
||||
)
|
||||
.expect("db");
|
||||
(project, db, dir)
|
||||
}
|
||||
|
||||
@@ -45,7 +48,10 @@ fn open_with_undo() -> (project::Project, Database, tempfile::TempDir) {
|
||||
async fn serial_pk_table(db: &Database, name: &str) {
|
||||
db.create_table(
|
||||
name.to_string(),
|
||||
vec![ColumnSpec::new("id", Type::Serial), ColumnSpec::new("label", Type::Text)],
|
||||
vec![
|
||||
ColumnSpec::new("id", Type::Serial),
|
||||
ColumnSpec::new("label", Type::Text),
|
||||
],
|
||||
vec!["id".to_string()],
|
||||
None,
|
||||
)
|
||||
@@ -84,7 +90,9 @@ fn parses_with_as_name() {
|
||||
match parse_command("create m:n relationship from Students to Courses as Enrollments")
|
||||
.expect("parses")
|
||||
{
|
||||
Command::CreateM2nRelationship { name, .. } => assert_eq!(name.as_deref(), Some("Enrollments")),
|
||||
Command::CreateM2nRelationship { name, .. } => {
|
||||
assert_eq!(name.as_deref(), Some("Enrollments"))
|
||||
}
|
||||
other => panic!("expected CreateM2nRelationship, got {other:?}"),
|
||||
}
|
||||
}
|
||||
@@ -104,12 +112,21 @@ fn generates_junction_with_compound_pk_and_two_enforced_fks() {
|
||||
|
||||
// Auto-named `Students_Courses` exists.
|
||||
let tables = db.list_tables().await.unwrap();
|
||||
assert!(tables.contains(&"Students_Courses".to_string()), "tables: {tables:?}");
|
||||
assert!(
|
||||
tables.contains(&"Students_Courses".to_string()),
|
||||
"tables: {tables:?}"
|
||||
);
|
||||
|
||||
// Two FK columns, both part of the compound PK.
|
||||
let desc = db.describe_table("Students_Courses".to_string()).await.unwrap();
|
||||
let cols: Vec<(&str, bool)> =
|
||||
desc.columns.iter().map(|c| (c.name.as_str(), c.primary_key)).collect();
|
||||
let desc = db
|
||||
.describe_table("Students_Courses".to_string())
|
||||
.await
|
||||
.unwrap();
|
||||
let cols: Vec<(&str, bool)> = desc
|
||||
.columns
|
||||
.iter()
|
||||
.map(|c| (c.name.as_str(), c.primary_key))
|
||||
.collect();
|
||||
assert_eq!(
|
||||
cols,
|
||||
vec![("Students_id", true), ("Courses_id", true)],
|
||||
@@ -124,7 +141,10 @@ fn generates_junction_with_compound_pk_and_two_enforced_fks() {
|
||||
db.insert(
|
||||
"Students_Courses".to_string(),
|
||||
Some(vec!["Students_id".to_string(), "Courses_id".to_string()]),
|
||||
vec![Value::Number("1".to_string()), Value::Number("1".to_string())],
|
||||
vec![
|
||||
Value::Number("1".to_string()),
|
||||
Value::Number("1".to_string()),
|
||||
],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
@@ -134,21 +154,33 @@ fn generates_junction_with_compound_pk_and_two_enforced_fks() {
|
||||
.insert(
|
||||
"Students_Courses".to_string(),
|
||||
Some(vec!["Students_id".to_string(), "Courses_id".to_string()]),
|
||||
vec![Value::Number("1".to_string()), Value::Number("1".to_string())],
|
||||
vec![
|
||||
Value::Number("1".to_string()),
|
||||
Value::Number("1".to_string()),
|
||||
],
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert!(dup.is_err(), "duplicate (Students_id, Courses_id) must be refused");
|
||||
assert!(
|
||||
dup.is_err(),
|
||||
"duplicate (Students_id, Courses_id) must be refused"
|
||||
);
|
||||
// A link to a non-existent parent is refused by the FK.
|
||||
let orphan = db
|
||||
.insert(
|
||||
"Students_Courses".to_string(),
|
||||
Some(vec!["Students_id".to_string(), "Courses_id".to_string()]),
|
||||
vec![Value::Number("1".to_string()), Value::Number("99".to_string())],
|
||||
vec![
|
||||
Value::Number("1".to_string()),
|
||||
Value::Number("99".to_string()),
|
||||
],
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert!(orphan.is_err(), "link to a non-existent Course must be refused");
|
||||
assert!(
|
||||
orphan.is_err(),
|
||||
"link to a non-existent Course must be refused"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -167,7 +199,10 @@ fn as_name_overrides_the_junction_table_name() {
|
||||
.await
|
||||
.expect("create m:n as Enrollments");
|
||||
let tables = db.list_tables().await.unwrap();
|
||||
assert!(tables.contains(&"Enrollments".to_string()), "tables: {tables:?}");
|
||||
assert!(
|
||||
tables.contains(&"Enrollments".to_string()),
|
||||
"tables: {tables:?}"
|
||||
);
|
||||
assert!(!tables.contains(&"Students_Courses".to_string()));
|
||||
});
|
||||
}
|
||||
@@ -179,7 +214,10 @@ fn compound_parent_pk_contributes_one_fk_column_each() {
|
||||
// Sections has a 2-column PK (course_id, term).
|
||||
db.create_table(
|
||||
"Sections".to_string(),
|
||||
vec![ColumnSpec::new("course_id", Type::Int), ColumnSpec::new("term", Type::Int)],
|
||||
vec![
|
||||
ColumnSpec::new("course_id", Type::Int),
|
||||
ColumnSpec::new("term", Type::Int),
|
||||
],
|
||||
vec!["course_id".to_string(), "term".to_string()],
|
||||
None,
|
||||
)
|
||||
@@ -191,11 +229,20 @@ fn compound_parent_pk_contributes_one_fk_column_each() {
|
||||
.await
|
||||
.expect("create m:n");
|
||||
|
||||
let desc = db.describe_table("Students_Sections".to_string()).await.unwrap();
|
||||
let desc = db
|
||||
.describe_table("Students_Sections".to_string())
|
||||
.await
|
||||
.unwrap();
|
||||
let names: Vec<&str> = desc.columns.iter().map(|c| c.name.as_str()).collect();
|
||||
assert_eq!(names, vec!["Students_id", "Sections_course_id", "Sections_term"]);
|
||||
assert_eq!(
|
||||
names,
|
||||
vec!["Students_id", "Sections_course_id", "Sections_term"]
|
||||
);
|
||||
// All three form the compound PK.
|
||||
assert!(desc.columns.iter().all(|c| c.primary_key), "all columns are PK: {names:?}");
|
||||
assert!(
|
||||
desc.columns.iter().all(|c| c.primary_key),
|
||||
"all columns are PK: {names:?}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -213,16 +260,28 @@ fn deleting_a_parent_cascades_to_the_junction() {
|
||||
db.insert(
|
||||
"Students_Courses".to_string(),
|
||||
Some(vec!["Students_id".to_string(), "Courses_id".to_string()]),
|
||||
vec![Value::Number("1".to_string()), Value::Number("1".to_string())],
|
||||
vec![
|
||||
Value::Number("1".to_string()),
|
||||
Value::Number("1".to_string()),
|
||||
],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Deleting the student cascades to the junction (ON DELETE CASCADE).
|
||||
db.delete("Students".to_string(), RowFilter::AllRows, None).await.unwrap();
|
||||
let rows = db.query_data("Students_Courses".to_string(), None, None).await.unwrap();
|
||||
assert!(rows.rows.is_empty(), "junction rows should cascade-delete, got {:?}", rows.rows);
|
||||
db.delete("Students".to_string(), RowFilter::AllRows, None)
|
||||
.await
|
||||
.unwrap();
|
||||
let rows = db
|
||||
.query_data("Students_Courses".to_string(), None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
rows.rows.is_empty(),
|
||||
"junction rows should cascade-delete, got {:?}",
|
||||
rows.rows
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -242,15 +301,26 @@ fn create_m2n_is_one_undo_step() {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(db.list_tables().await.unwrap().contains(&"Students_Courses".to_string()));
|
||||
assert!(
|
||||
db.list_tables()
|
||||
.await
|
||||
.unwrap()
|
||||
.contains(&"Students_Courses".to_string())
|
||||
);
|
||||
|
||||
// One undo removes the junction table AND both relationships.
|
||||
db.undo().await.unwrap();
|
||||
let tables = db.list_tables().await.unwrap();
|
||||
assert!(!tables.contains(&"Students_Courses".to_string()), "undo should remove the junction: {tables:?}");
|
||||
assert!(
|
||||
!tables.contains(&"Students_Courses".to_string()),
|
||||
"undo should remove the junction: {tables:?}"
|
||||
);
|
||||
// The parents' relationships are gone too (the junction held them).
|
||||
let students = db.describe_table("Students".to_string()).await.unwrap();
|
||||
assert!(students.inbound_relationships.is_empty(), "no leftover relationship after undo");
|
||||
assert!(
|
||||
students.inbound_relationships.is_empty(),
|
||||
"no leftover relationship after undo"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -265,7 +335,10 @@ fn self_referential_m2n_is_refused() {
|
||||
.create_m2n_relationship("Users".to_string(), "Users".to_string(), None, None)
|
||||
.await
|
||||
.expect_err("self m:n must be refused");
|
||||
assert!(format!("{err}").contains("two different tables"), "got: {err}");
|
||||
assert!(
|
||||
format!("{err}").contains("two different tables"),
|
||||
"got: {err}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -275,11 +348,19 @@ fn missing_parent_table_is_refused() {
|
||||
rt().block_on(async {
|
||||
serial_pk_table(&db, "Students").await;
|
||||
let err = db
|
||||
.create_m2n_relationship("Students".to_string(), "Nonexistent".to_string(), None, None)
|
||||
.create_m2n_relationship(
|
||||
"Students".to_string(),
|
||||
"Nonexistent".to_string(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect_err("a missing parent table must be refused");
|
||||
// The standard "no such table" guard (require_canonical_table).
|
||||
assert!(format!("{err}").to_lowercase().contains("no such table"), "got: {err}");
|
||||
assert!(
|
||||
format!("{err}").to_lowercase().contains("no such table"),
|
||||
"got: {err}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -297,7 +378,10 @@ fn junction_name_collision_is_refused() {
|
||||
.create_m2n_relationship("Students".to_string(), "Courses".to_string(), None, None)
|
||||
.await
|
||||
.expect_err("a junction-name collision must be refused");
|
||||
assert!(format!("{err}").to_lowercase().contains("exist"), "got: {err}");
|
||||
assert!(
|
||||
format!("{err}").to_lowercase().contains("exist"),
|
||||
"got: {err}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -314,15 +398,26 @@ fn the_junction_can_be_renamed() {
|
||||
db.create_m2n_relationship("Students".to_string(), "Courses".to_string(), None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
db.rename_table("Students_Courses".to_string(), "Enrollments".to_string(), None)
|
||||
.await
|
||||
.expect("rename the junction");
|
||||
db.rename_table(
|
||||
"Students_Courses".to_string(),
|
||||
"Enrollments".to_string(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("rename the junction");
|
||||
let tables = db.list_tables().await.unwrap();
|
||||
assert!(tables.contains(&"Enrollments".to_string()), "tables: {tables:?}");
|
||||
assert!(
|
||||
tables.contains(&"Enrollments".to_string()),
|
||||
"tables: {tables:?}"
|
||||
);
|
||||
assert!(!tables.contains(&"Students_Courses".to_string()));
|
||||
// Both relationships survive the rename (rebuild-preserving).
|
||||
let desc = db.describe_table("Enrollments".to_string()).await.unwrap();
|
||||
assert_eq!(desc.outbound_relationships.len(), 2, "FKs preserved across rename");
|
||||
assert_eq!(
|
||||
desc.outbound_relationships.len(),
|
||||
2,
|
||||
"FKs preserved across rename"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -355,16 +450,33 @@ fn junction_survives_save_and_rebuild() {
|
||||
// Discard the derived .db so the next open rebuilds from text.
|
||||
std::fs::remove_file(project_path.join(PLAYGROUND_DB)).unwrap();
|
||||
let project = project::Project::open(&project_path).unwrap();
|
||||
let db =
|
||||
Database::open_with_persistence(project.db_path(), Persistence::new(project.path().to_path_buf()))
|
||||
.unwrap();
|
||||
let db = Database::open_with_persistence(
|
||||
project.db_path(),
|
||||
Persistence::new(project.path().to_path_buf()),
|
||||
)
|
||||
.unwrap();
|
||||
rt().block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None).await.expect("rebuild");
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None)
|
||||
.await
|
||||
.expect("rebuild");
|
||||
let tables = db.list_tables().await.unwrap();
|
||||
assert!(tables.contains(&"Students_Courses".to_string()), "junction survived: {tables:?}");
|
||||
let desc = db.describe_table("Students_Courses".to_string()).await.unwrap();
|
||||
assert_eq!(desc.outbound_relationships.len(), 2, "both FKs reconstructed");
|
||||
assert!(desc.columns.iter().all(|c| c.primary_key), "compound PK reconstructed");
|
||||
assert!(
|
||||
tables.contains(&"Students_Courses".to_string()),
|
||||
"junction survived: {tables:?}"
|
||||
);
|
||||
let desc = db
|
||||
.describe_table("Students_Courses".to_string())
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
desc.outbound_relationships.len(),
|
||||
2,
|
||||
"both FKs reconstructed"
|
||||
);
|
||||
assert!(
|
||||
desc.columns.iter().all(|c| c.primary_key),
|
||||
"compound PK reconstructed"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -387,7 +499,12 @@ fn as_an_internal_name_is_refused() {
|
||||
.await
|
||||
.expect_err("an internal junction name must be refused");
|
||||
assert!(format!("{err}").contains("no such table"), "got: {err}");
|
||||
assert!(!db.list_tables().await.unwrap().contains(&"__rdbms_evil".to_string()));
|
||||
assert!(
|
||||
!db.list_tables()
|
||||
.await
|
||||
.unwrap()
|
||||
.contains(&"__rdbms_evil".to_string())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -442,7 +559,10 @@ fn read_all_relationships_returns_the_junction_relationships() {
|
||||
);
|
||||
// Both have the junction (Students_Courses) as their child.
|
||||
for r in &rels {
|
||||
assert_eq!(r.child_table, "Students_Courses", "child is the junction: {r:?}");
|
||||
assert_eq!(
|
||||
r.child_table, "Students_Courses",
|
||||
"child is the junction: {r:?}"
|
||||
);
|
||||
}
|
||||
// One points back to each parent.
|
||||
let parents: std::collections::BTreeSet<&str> =
|
||||
|
||||
Reference in New Issue
Block a user