vespertide_query/sql/
delete_column.rs1use sea_query::{Alias, Table};
2
3use vespertide_core::ColumnType;
4
5use super::helpers::build_drop_enum_type_sql;
6use super::types::BuiltQuery;
7
8pub fn build_delete_column(
10 table: &str,
11 column: &str,
12 column_type: Option<&ColumnType>,
13) -> Vec<BuiltQuery> {
14 let mut stmts = Vec::new();
15
16 let stmt = Table::alter()
18 .table(Alias::new(table))
19 .drop_column(Alias::new(column))
20 .to_owned();
21 stmts.push(BuiltQuery::AlterTable(Box::new(stmt)));
22
23 if let Some(col_type) = column_type
26 && let Some(drop_type_sql) = build_drop_enum_type_sql(table, col_type)
27 {
28 stmts.push(BuiltQuery::Raw(drop_type_sql));
29 }
30
31 stmts
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use crate::sql::types::DatabaseBackend;
38 use insta::{assert_snapshot, with_settings};
39 use rstest::rstest;
40 use vespertide_core::{ComplexColumnType, SimpleColumnType};
41
42 #[rstest]
43 #[case::delete_column_postgres(
44 "delete_column_postgres",
45 DatabaseBackend::Postgres,
46 &["ALTER TABLE \"users\" DROP COLUMN \"email\""]
47 )]
48 #[case::delete_column_mysql(
49 "delete_column_mysql",
50 DatabaseBackend::MySql,
51 &["ALTER TABLE `users` DROP COLUMN `email`"]
52 )]
53 #[case::delete_column_sqlite(
54 "delete_column_sqlite",
55 DatabaseBackend::Sqlite,
56 &["ALTER TABLE \"users\" DROP COLUMN \"email\""]
57 )]
58 fn test_delete_column(
59 #[case] title: &str,
60 #[case] backend: DatabaseBackend,
61 #[case] expected: &[&str],
62 ) {
63 let result = build_delete_column("users", "email", None);
64 let sql = result[0].build(backend);
65 for exp in expected {
66 assert!(
67 sql.contains(exp),
68 "Expected SQL to contain '{}', got: {}",
69 exp,
70 sql
71 );
72 }
73
74 with_settings!({ snapshot_suffix => format!("delete_column_{}", title) }, {
75 assert_snapshot!(sql);
76 });
77 }
78
79 #[test]
80 fn test_delete_enum_column_postgres() {
81 use vespertide_core::EnumValues;
82
83 let enum_type = ColumnType::Complex(ComplexColumnType::Enum {
84 name: "status".into(),
85 values: EnumValues::String(vec!["active".into(), "inactive".into()]),
86 });
87 let result = build_delete_column("users", "status", Some(&enum_type));
88
89 assert_eq!(result.len(), 2);
91
92 let alter_sql = result[0].build(DatabaseBackend::Postgres);
93 assert!(alter_sql.contains("DROP COLUMN"));
94
95 let drop_type_sql = result[1].build(DatabaseBackend::Postgres);
96 assert!(drop_type_sql.contains("DROP TYPE IF EXISTS \"users_status\""));
97
98 let drop_type_mysql = result[1].build(DatabaseBackend::MySql);
100 assert!(drop_type_mysql.is_empty());
101 }
102
103 #[test]
104 fn test_delete_non_enum_column_no_drop_type() {
105 let text_type = ColumnType::Simple(SimpleColumnType::Text);
106 let result = build_delete_column("users", "name", Some(&text_type));
107
108 assert_eq!(result.len(), 1);
110 }
111}