gluesql_core/ast_builder/
alter_table.rs

1use {
2    super::Build,
3    crate::{
4        ast::{AlterTableOperation, Statement},
5        ast_builder::ColumnDefNode,
6        result::Result,
7    },
8};
9
10#[derive(Clone, Debug)]
11pub struct AlterTableNode {
12    table_name: String,
13}
14
15impl AlterTableNode {
16    pub fn new(table_name: String) -> Self {
17        Self { table_name }
18    }
19
20    pub fn add_column<T: Into<ColumnDefNode>>(self, column: T) -> AddColumnNode {
21        AddColumnNode {
22            table_node: self,
23            column_def: column.into(),
24        }
25    }
26
27    pub fn drop_column(self, column_name: &str) -> DropColumnNode {
28        DropColumnNode {
29            table_node: self,
30            column_name: column_name.to_owned(),
31            if_exists: false,
32        }
33    }
34
35    pub fn drop_column_if_exists(self, column_name: &str) -> DropColumnNode {
36        DropColumnNode {
37            table_node: self,
38            column_name: column_name.to_owned(),
39            if_exists: true,
40        }
41    }
42
43    pub fn rename_column(self, old_name: &str, new_name: &str) -> RenameColumnNode {
44        RenameColumnNode {
45            table_node: self,
46            old_column_name: old_name.to_owned(),
47            new_column_name: new_name.to_owned(),
48        }
49    }
50
51    pub fn rename_table(self, new_table_name: &str) -> RenameTableNode {
52        RenameTableNode {
53            table_node: self,
54            new_table_name: new_table_name.to_owned(),
55        }
56    }
57}
58
59pub struct AddColumnNode {
60    table_node: AlterTableNode,
61    column_def: ColumnDefNode,
62}
63
64impl Build for AddColumnNode {
65    fn build(self) -> Result<Statement> {
66        let table_name = self.table_node.table_name;
67        let operation = AlterTableOperation::AddColumn {
68            column_def: self.column_def.try_into()?,
69        };
70        Ok(Statement::AlterTable {
71            name: table_name,
72            operation,
73        })
74    }
75}
76
77pub struct DropColumnNode {
78    table_node: AlterTableNode,
79    column_name: String,
80    if_exists: bool,
81}
82
83impl Build for DropColumnNode {
84    fn build(self) -> Result<Statement> {
85        let table_name = self.table_node.table_name;
86        let operation = AlterTableOperation::DropColumn {
87            column_name: self.column_name,
88            if_exists: self.if_exists,
89        };
90        Ok(Statement::AlterTable {
91            name: table_name,
92            operation,
93        })
94    }
95}
96
97pub struct RenameColumnNode {
98    table_node: AlterTableNode,
99    old_column_name: String,
100    new_column_name: String,
101}
102
103impl Build for RenameColumnNode {
104    fn build(self) -> Result<Statement> {
105        let table_name = self.table_node.table_name;
106        let operation = AlterTableOperation::RenameColumn {
107            old_column_name: self.old_column_name,
108            new_column_name: self.new_column_name,
109        };
110        Ok(Statement::AlterTable {
111            name: table_name,
112            operation,
113        })
114    }
115}
116
117pub struct RenameTableNode {
118    table_node: AlterTableNode,
119    new_table_name: String,
120}
121
122impl Build for RenameTableNode {
123    fn build(self) -> Result<Statement> {
124        let old_table_name = self.table_node.table_name;
125        let operation = AlterTableOperation::RenameTable {
126            table_name: self.new_table_name,
127        };
128        Ok(Statement::AlterTable {
129            name: old_table_name,
130            operation,
131        })
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use crate::ast_builder::{Build, table, test};
138
139    #[test]
140    fn alter_table() {
141        let actual = table("Foo")
142            .alter_table()
143            .add_column("opt BOOLEAN NULL")
144            .build();
145        let expected = "ALTER TABLE Foo ADD COLUMN opt BOOLEAN NULL";
146        test(actual, expected);
147
148        let actual = table("Foo").alter_table().drop_column("col_name").build();
149        let expected = "ALTER TABLE Foo DROP COLUMN col_name";
150        test(actual, expected);
151
152        let actual = table("Foo")
153            .alter_table()
154            .drop_column_if_exists("col_name")
155            .build();
156        let expected = "ALTER TABLE Foo DROP COLUMN IF EXISTS col_name";
157        test(actual, expected);
158
159        let actual = table("Foo")
160            .alter_table()
161            .rename_column("old", "new")
162            .build();
163        let expected = "ALTER TABLE Foo RENAME COLUMN old TO new";
164        test(actual, expected);
165
166        let actual = table("Foo")
167            .alter_table()
168            .rename_table("new_table_name")
169            .build();
170        let expected = "ALTER TABLE Foo RENAME TO new_table_name";
171        test(actual, expected);
172    }
173}