use crate::diff::change::ChangeEntry;
use crate::identifier::QualifiedName;
use crate::ir::constraint::Constraint;
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct OrderedChangeSet {
pub creates_and_adds: Vec<ChangeEntry>,
pub modifies: Vec<ChangeEntry>,
pub drops: Vec<ChangeEntry>,
pub deferred_fks: Vec<DeferredFkAdd>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeferredFkAdd {
pub table: QualifiedName,
pub constraint: Constraint,
}
impl OrderedChangeSet {
pub const fn is_empty(&self) -> bool {
self.creates_and_adds.is_empty()
&& self.modifies.is_empty()
&& self.drops.is_empty()
&& self.deferred_fks.is_empty()
}
pub const fn len(&self) -> usize {
self.creates_and_adds.len()
+ self.modifies.len()
+ self.drops.len()
+ self.deferred_fks.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::diff::change::Change;
use crate::diff::destructiveness::Destructiveness;
use crate::identifier::Identifier;
use crate::ir::constraint::{
ConstraintKind, Deferrable, FkMatchType, ForeignKey, ReferentialAction,
};
use crate::ir::schema::Schema;
fn id(s: &str) -> Identifier {
Identifier::from_unquoted(s).unwrap()
}
fn qn(schema: &str, name: &str) -> QualifiedName {
QualifiedName::new(id(schema), id(name))
}
fn fk_constraint() -> Constraint {
Constraint {
qname: qn("app", "fk1"),
kind: ConstraintKind::ForeignKey(ForeignKey {
columns: vec![id("ref_id")],
referenced_table: qn("app", "b"),
referenced_columns: vec![id("id")],
on_update: ReferentialAction::NoAction,
on_delete: ReferentialAction::NoAction,
match_type: FkMatchType::Simple,
}),
deferrable: Deferrable::NotDeferrable,
comment: None,
}
}
#[test]
fn default_is_empty() {
let o = OrderedChangeSet::default();
assert!(o.is_empty());
assert_eq!(o.len(), 0);
}
#[test]
fn len_sums_all_buckets() {
let o = OrderedChangeSet {
creates_and_adds: vec![ChangeEntry {
change: Change::CreateSchema(Schema::new(id("app"))),
destructiveness: Destructiveness::Safe,
}],
modifies: vec![],
drops: vec![ChangeEntry {
change: Change::DropSchema(id("old")),
destructiveness: Destructiveness::RequiresApproval {
reason: "drop".into(),
},
}],
deferred_fks: vec![DeferredFkAdd {
table: qn("app", "a"),
constraint: fk_constraint(),
}],
};
assert!(!o.is_empty());
assert_eq!(o.len(), 3);
}
#[test]
fn is_empty_iff_all_buckets_empty() {
let mut o = OrderedChangeSet::default();
assert!(o.is_empty());
o.deferred_fks.push(DeferredFkAdd {
table: qn("app", "a"),
constraint: fk_constraint(),
});
assert!(!o.is_empty());
}
}