gluesql_core/ast_builder/
create_table.rs1use {
2 super::Build,
3 crate::{ast::Statement, ast_builder::ColumnDefNode, result::Result},
4};
5
6#[derive(Clone, Debug)]
7pub struct CreateTableNode {
8 table_name: String,
9 if_not_exists: bool,
10 columns: Option<Vec<ColumnDefNode>>,
11}
12
13impl CreateTableNode {
14 pub fn new(table_name: String, not_exists: bool) -> Self {
15 Self {
16 table_name,
17 if_not_exists: not_exists,
18 columns: None,
19 }
20 }
21
22 pub fn add_column<T: Into<ColumnDefNode>>(mut self, column: T) -> Self {
23 match self.columns {
24 Some(ref mut columns) => {
25 columns.push(column.into());
26 }
27 None => {
28 self.columns = Some(vec![column.into()]);
29 }
30 }
31
32 self
33 }
34}
35
36impl Build for CreateTableNode {
37 fn build(self) -> Result<Statement> {
38 let table_name = self.table_name;
39 let columns = match self.columns {
40 Some(columns) => Some(
41 columns
42 .into_iter()
43 .map(TryInto::try_into)
44 .collect::<Result<Vec<_>>>()?,
45 ),
46 None => None,
47 };
48
49 Ok(Statement::CreateTable {
50 name: table_name,
51 if_not_exists: self.if_not_exists,
52 columns,
53 source: None,
54 engine: None,
55 foreign_keys: Vec::new(),
56 comment: None,
57 })
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use crate::ast_builder::{Build, table, test};
64
65 #[test]
66 fn create_table() {
67 let actual = table("Foo")
68 .create_table()
69 .add_column("id INTEGER NULL")
70 .add_column("num INTEGER")
71 .add_column("name TEXT")
72 .build();
73 let expected = "CREATE TABLE Foo (id INTEGER NULL, num INTEGER, name TEXT)";
74 test(actual, expected);
75
76 let actual = table("Foo")
77 .create_table_if_not_exists()
78 .add_column("id UUID UNIQUE")
79 .add_column("name TEXT")
80 .build();
81 let expected = "CREATE TABLE IF NOT EXISTS Foo (id UUID UNIQUE, name TEXT)";
82 test(actual, expected);
83 }
84
85 #[test]
86 fn create_table_without_column() {
87 let actual = table("Foo").create_table().build();
88 let expected = "CREATE TABLE Foo";
89 test(actual, expected);
90 }
91}