use crate::catalog::schema::Schema;
use crate::diff::comment_utils;
use crate::diff::operations::{MigrationStep, SchemaOperation, SchemaTarget};
const PG_DEFAULT_PUBLIC_COMMENT: &str = "standard public schema";
fn normalize_public_comment(schema_name: &str, comment: &Option<String>) -> Option<String> {
if schema_name == "public"
&& comment.as_ref().map(|c| c.as_str()) == Some(PG_DEFAULT_PUBLIC_COMMENT)
{
None
} else {
comment.clone()
}
}
pub fn diff(old: Option<&Schema>, new: Option<&Schema>) -> Vec<MigrationStep> {
match (old, new) {
(None, Some(n)) => {
if n.name == "public" {
return Vec::new();
}
let mut steps = vec![MigrationStep::Schema(SchemaOperation::Create {
name: n.name.clone(),
})];
if let Some(comment_op) = comment_utils::handle_comment_creation(
&n.comment,
SchemaTarget {
name: n.name.clone(),
},
) {
steps.push(MigrationStep::Schema(SchemaOperation::Comment(comment_op)));
}
steps
}
(Some(o), None) => {
if o.name == "public" {
return Vec::new();
}
vec![MigrationStep::Schema(SchemaOperation::Drop {
name: o.name.clone(),
})]
}
(Some(o), Some(n)) => {
let mut steps = Vec::new();
let old_normalized_comment = normalize_public_comment(&n.name, &o.comment);
let new_normalized_comment = normalize_public_comment(&n.name, &n.comment);
if old_normalized_comment != new_normalized_comment {
let old_normalized = Schema {
name: o.name.clone(),
comment: old_normalized_comment,
};
let new_normalized = Schema {
name: n.name.clone(),
comment: new_normalized_comment,
};
let comment_ops = comment_utils::handle_comment_diff(
Some(&old_normalized),
Some(&new_normalized),
|| SchemaTarget {
name: n.name.clone(),
},
);
for comment_op in comment_ops {
steps.push(MigrationStep::Schema(SchemaOperation::Comment(comment_op)));
}
}
steps
}
(None, None) => Vec::new(),
}
}