use super::schema::{Column, ForeignKey, Index, Table};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TableChange {
CreateTable(Table),
DropTable {
table_name: String,
},
AlterTable {
table_name: String,
column_changes: Vec<ColumnChange>,
added_columns: Vec<Column>,
removed_columns: Vec<String>,
added_indexes: Vec<Index>,
removed_indexes: Vec<String>,
added_foreign_keys: Vec<ForeignKey>,
removed_foreign_keys: Vec<String>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ColumnChange {
AddColumn(Column),
RemoveColumn {
column_name: String,
},
ModifyColumn {
column_name: String,
new_column: Column,
},
RenameColumn {
old_name: String,
new_name: String,
},
TypeChanged {
column_name: String,
old_type: super::schema::ColumnType,
new_type: super::schema::ColumnType,
},
NullabilityChanged {
column_name: String,
old_nullable: bool,
new_nullable: bool,
},
DefaultChanged {
column_name: String,
old_default: Option<String>,
new_default: Option<String>,
},
}
#[cfg(test)]
mod tests {
use super::*;
use crate::domain::migration::schema::{Column, ColumnType, Table};
fn sample_column() -> Column {
Column {
name: "id".into(),
column_type: ColumnType::Integer,
is_primary_key: true,
is_nullable: false,
has_default: false,
default_value: None,
is_auto_increment: true,
comment: None,
}
}
fn sample_table() -> Table {
Table {
name: "users".into(),
columns: vec![sample_column()],
primary_key_columns: vec!["id".into()],
indexes: vec![],
foreign_keys: vec![],
comment: None,
}
}
#[test]
fn table_change_create_table() {
let c = TableChange::CreateTable(sample_table());
assert!(matches!(c, TableChange::CreateTable(_)));
}
#[test]
fn table_change_drop_table() {
let c = TableChange::DropTable {
table_name: "old".into(),
};
assert_eq!(
match c {
TableChange::DropTable { ref table_name } => table_name,
_ => "",
},
"old"
);
}
#[test]
fn table_change_alter_table() {
let c = TableChange::AlterTable {
table_name: "users".into(),
column_changes: vec![ColumnChange::AddColumn(sample_column())],
added_columns: vec![],
removed_columns: vec![],
added_indexes: vec![],
removed_indexes: vec![],
added_foreign_keys: vec![],
removed_foreign_keys: vec![],
};
match c {
TableChange::AlterTable {
ref table_name,
ref column_changes,
..
} => {
assert_eq!(table_name, "users");
assert_eq!(column_changes.len(), 1);
}
_ => panic!("expected AlterTable"),
}
}
#[test]
fn column_change_add_column() {
let c = ColumnChange::AddColumn(sample_column());
assert!(matches!(c, ColumnChange::AddColumn(_)));
}
#[test]
fn column_change_remove_column() {
let c = ColumnChange::RemoveColumn {
column_name: "age".into(),
};
assert_eq!(
match c {
ColumnChange::RemoveColumn { ref column_name } => column_name,
_ => "",
},
"age"
);
}
#[test]
fn column_change_modify_column() {
let c = ColumnChange::ModifyColumn {
column_name: "name".into(),
new_column: sample_column(),
};
match c {
ColumnChange::ModifyColumn { ref column_name, .. } => assert_eq!(column_name, "name"),
_ => panic!("expected ModifyColumn"),
}
}
#[test]
fn column_change_rename_column() {
let c = ColumnChange::RenameColumn {
old_name: "old".into(),
new_name: "new".into(),
};
match c {
ColumnChange::RenameColumn {
ref old_name,
ref new_name,
} => {
assert_eq!(old_name, "old");
assert_eq!(new_name, "new");
}
_ => panic!("expected RenameColumn"),
}
}
#[test]
fn column_change_type_changed() {
let c = ColumnChange::TypeChanged {
column_name: "col".into(),
old_type: ColumnType::Integer,
new_type: ColumnType::Text,
};
match c {
ColumnChange::TypeChanged {
ref column_name,
ref old_type,
ref new_type,
} => {
assert_eq!(column_name, "col");
assert_eq!(*old_type, ColumnType::Integer);
assert_eq!(*new_type, ColumnType::Text);
}
_ => panic!("expected TypeChanged"),
}
}
#[test]
fn column_change_nullability_changed() {
let c = ColumnChange::NullabilityChanged {
column_name: "col".into(),
old_nullable: true,
new_nullable: false,
};
match c {
ColumnChange::NullabilityChanged {
ref column_name,
old_nullable,
new_nullable,
} => {
assert_eq!(column_name, "col");
assert!(old_nullable);
assert!(!new_nullable);
}
_ => panic!("expected NullabilityChanged"),
}
}
#[test]
fn column_change_default_changed() {
let c = ColumnChange::DefaultChanged {
column_name: "col".into(),
old_default: Some("0".into()),
new_default: None,
};
match c {
ColumnChange::DefaultChanged {
ref column_name,
ref old_default,
ref new_default,
} => {
assert_eq!(column_name, "col");
assert_eq!(old_default.as_deref(), Some("0"));
assert!(new_default.is_none());
}
_ => panic!("expected DefaultChanged"),
}
}
}