1- use sea_query:: { Alias , Table , TableAlterStatement } ;
1+ use sea_query:: { Alias , Expr , Query , Table , TableAlterStatement } ;
22
33use vespertide_core:: ColumnDef ;
44
5- use crate :: error:: QueryError ;
6- use super :: types:: { BuiltQuery , DatabaseBackend , RawSql } ;
75use super :: helpers:: build_sea_column_def;
6+ use super :: types:: { BuiltQuery , DatabaseBackend } ;
7+ use crate :: error:: QueryError ;
88
99fn build_add_column_alter_for_backend (
1010 backend : & DatabaseBackend ,
@@ -34,43 +34,32 @@ pub fn build_add_column(
3434 let mut temp_col = column. clone ( ) ;
3535 temp_col. nullable = true ;
3636
37- stmts. push ( BuiltQuery :: AlterTable (
38- Box :: new ( build_add_column_alter_for_backend ( backend, table, & temp_col) ) ,
39- ) ) ;
37+ stmts. push ( BuiltQuery :: AlterTable ( Box :: new (
38+ build_add_column_alter_for_backend ( backend, table, & temp_col) ,
39+ ) ) ) ;
4040
4141 // Backfill with provided value
4242 if let Some ( fill) = fill_with {
43- // PostgreSQL and SQLite use double quotes, MySQL uses backticks
44- let pg_sql = format ! ( "UPDATE \" {}\" SET \" {}\" = {}" , table, column. name, fill) ;
45- let mysql_sql = format ! ( "UPDATE `{}` SET `{}` = {}" , table, column. name, fill) ;
46- stmts. push ( BuiltQuery :: Raw ( RawSql :: per_backend (
47- pg_sql. clone ( ) ,
48- mysql_sql,
49- pg_sql,
50- ) ) ) ;
43+ // Build UPDATE query using sea_query
44+ let update_stmt = Query :: update ( )
45+ . table ( Alias :: new ( table) )
46+ . value ( Alias :: new ( & column. name ) , Expr :: cust ( fill) )
47+ . to_owned ( ) ;
48+ stmts. push ( BuiltQuery :: Update ( Box :: new ( update_stmt) ) ) ;
5149 }
5250
53- // Set NOT NULL - different syntax per backend
54- let pg_sql = format ! (
55- "ALTER TABLE \" {}\" ALTER COLUMN \" {}\" SET NOT NULL" ,
56- table, column. name
57- ) ;
58- let mysql_sql = format ! (
59- "ALTER TABLE `{}` MODIFY COLUMN `{}` NOT NULL" ,
60- table, column. name
61- ) ;
62- // SQLite doesn't support ALTER COLUMN, would need table recreation
63- let sqlite_sql = format ! (
64- "-- SQLite: ALTER TABLE \" {}\" requires table recreation to set NOT NULL on \" {}\" " ,
65- table, column. name
66- ) ;
67- stmts. push ( BuiltQuery :: Raw ( RawSql :: per_backend (
68- pg_sql, mysql_sql, sqlite_sql,
69- ) ) ) ;
51+ // Set NOT NULL using ALTER TABLE with modify_column
52+ // For SQLite, this will need table recreation, but we generate the SQL anyway
53+ let not_null_col = build_sea_column_def ( backend, column) ;
54+ let alter_not_null = Table :: alter ( )
55+ . table ( Alias :: new ( table) )
56+ . modify_column ( not_null_col)
57+ . to_owned ( ) ;
58+ stmts. push ( BuiltQuery :: AlterTable ( Box :: new ( alter_not_null) ) ) ;
7059 } else {
71- stmts. push ( BuiltQuery :: AlterTable (
72- Box :: new ( build_add_column_alter_for_backend ( backend, table, column) ) ,
73- ) ) ;
60+ stmts. push ( BuiltQuery :: AlterTable ( Box :: new (
61+ build_add_column_alter_for_backend ( backend, table, column) ,
62+ ) ) ) ;
7463 }
7564
7665 Ok ( stmts)
@@ -120,7 +109,12 @@ mod tests {
120109 #[ case] expected : & [ & str ] ,
121110 ) {
122111 let column = ColumnDef {
123- name : if title. contains ( "age" ) { "age" } else { "nickname" } . into ( ) ,
112+ name : if title. contains ( "age" ) {
113+ "age"
114+ } else {
115+ "nickname"
116+ }
117+ . into ( ) ,
124118 r#type : if title. contains ( "age" ) {
125119 ColumnType :: Simple ( SimpleColumnType :: Integer )
126120 } else {
@@ -134,7 +128,11 @@ mod tests {
134128 index : None ,
135129 foreign_key : None ,
136130 } ;
137- let fill_with = if title. contains ( "backfill" ) { Some ( "0" ) } else { None } ;
131+ let fill_with = if title. contains ( "backfill" ) {
132+ Some ( "0" )
133+ } else {
134+ None
135+ } ;
138136 let result = build_add_column ( & backend, "users" , & column, fill_with) . unwrap ( ) ;
139137 let sql = result[ 0 ] . build ( backend) ;
140138 for exp in expected {
0 commit comments