use crate::catalog::view::View;
use crate::diff::operations::{MigrationStep, ViewOperation, ViewOption};
pub fn diff(old: Option<&View>, new: Option<&View>) -> Vec<MigrationStep> {
match (old, new) {
(None, Some(n)) => vec![MigrationStep::View(ViewOperation::Create {
schema: n.schema.clone(),
name: n.name.clone(),
definition: n.definition.clone(),
security_invoker: n.security_invoker,
security_barrier: n.security_barrier,
})],
(Some(o), None) => vec![MigrationStep::View(ViewOperation::Drop {
schema: o.schema.clone(),
name: o.name.clone(),
})],
(Some(o), Some(n)) => {
let structural_columns_changed = o.columns.len() != n.columns.len()
|| o.columns
.iter()
.zip(n.columns.iter())
.any(|(a, b)| a.name != b.name || a.type_ != b.type_);
if structural_columns_changed {
vec![
MigrationStep::View(ViewOperation::Drop {
schema: o.schema.clone(),
name: o.name.clone(),
}),
MigrationStep::View(ViewOperation::Create {
schema: n.schema.clone(),
name: n.name.clone(),
definition: n.definition.clone(),
security_invoker: n.security_invoker,
security_barrier: n.security_barrier,
}),
]
} else if o.definition != n.definition {
vec![MigrationStep::View(ViewOperation::Replace {
schema: n.schema.clone(),
name: n.name.clone(),
definition: n.definition.clone(),
security_invoker: n.security_invoker,
security_barrier: n.security_barrier,
})]
} else {
let mut steps = Vec::new();
if o.security_invoker != n.security_invoker {
steps.push(MigrationStep::View(ViewOperation::SetOption {
schema: n.schema.clone(),
name: n.name.clone(),
option: ViewOption::SecurityInvoker,
enabled: n.security_invoker,
}));
}
if o.security_barrier != n.security_barrier {
steps.push(MigrationStep::View(ViewOperation::SetOption {
schema: n.schema.clone(),
name: n.name.clone(),
option: ViewOption::SecurityBarrier,
enabled: n.security_barrier,
}));
}
steps
}
}
(None, None) => Vec::new(),
}
}