Skip to main content

gluesql_core/query_builder/
create_table.rs

1use {
2    super::Build,
3    crate::{ast::Statement, plan::StatementPlan, query_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    #[must_use]
23    pub fn add_column<T: Into<ColumnDefNode>>(mut self, column: T) -> Self {
24        match self.columns {
25            Some(ref mut columns) => {
26                columns.push(column.into());
27            }
28            None => {
29                self.columns = Some(vec![column.into()]);
30            }
31        }
32
33        self
34    }
35}
36
37impl Build for CreateTableNode {
38    fn build(self) -> Result<StatementPlan> {
39        let table_name = self.table_name;
40        let columns = match self.columns {
41            Some(columns) => Some(
42                columns
43                    .into_iter()
44                    .map(TryInto::try_into)
45                    .collect::<Result<Vec<_>>>()?,
46            ),
47            None => None,
48        };
49
50        Ok(Statement::CreateTable {
51            name: table_name,
52            if_not_exists: self.if_not_exists,
53            columns,
54            source: None,
55            engine: None,
56            foreign_keys: Vec::new(),
57            comment: None,
58        }
59        .into())
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use crate::query_builder::{Build, table, test};
66
67    #[test]
68    fn create_table() {
69        let actual = table("Foo")
70            .create_table()
71            .add_column("id INTEGER NULL")
72            .add_column("num INTEGER")
73            .add_column("name TEXT")
74            .build();
75        let expected = "CREATE TABLE Foo (id INTEGER NULL, num INTEGER, name TEXT)";
76        test(&actual, expected);
77
78        let actual = table("Foo")
79            .create_table_if_not_exists()
80            .add_column("id UUID UNIQUE")
81            .add_column("name TEXT")
82            .build();
83        let expected = "CREATE TABLE IF NOT EXISTS Foo (id UUID UNIQUE, name TEXT)";
84        test(&actual, expected);
85    }
86
87    #[test]
88    fn create_table_without_column() {
89        let actual = table("Foo").create_table().build();
90        let expected = "CREATE TABLE Foo";
91        test(&actual, expected);
92    }
93}