Skip to main content

datasources_sqlite/
statement_renderer.rs

1use crate::alter_table_statement_renderer::SqliteAlterTableStatementRenderer;
2use crate::create_table_statement_renderer::SqliteCreateTableStatementRenderer;
3use crate::create_trigger_statement_renderer::SqliteCreateTriggerStatementRenderer;
4use crate::select_inserted_id_statement_text_renderer::SqliteSelectInsertedIdStatementTextRenderer;
5use datasources::{
6    AlterTableStatement, CreateTableStatement,
7    CreateTableStatementTextRenderer, CreateTriggerStatement, SelectInsertedIdStatement,
8    StatementTextRenderer, StatementVisitor,
9};
10
11pub struct SqliteStatementRenderer;
12
13impl StatementVisitor for SqliteStatementRenderer {
14    fn visit_create_table(
15        &self,
16        statement: &CreateTableStatement,
17        _text: &StatementTextRenderer,
18    ) -> String {
19        SqliteCreateTableStatementRenderer.render(statement)
20    }
21
22    fn visit_alter_table(
23        &self,
24        statement: &AlterTableStatement,
25        _text: &StatementTextRenderer,
26    ) -> String {
27        SqliteAlterTableStatementRenderer.render(statement)
28    }
29
30    fn visit_create_trigger(
31        &self,
32        statement: &CreateTriggerStatement,
33        _text: &StatementTextRenderer,
34    ) -> String {
35        SqliteCreateTriggerStatementRenderer.render(statement)
36    }
37
38    fn visit_select_inserted_id(
39        &self,
40        statement: &SelectInsertedIdStatement,
41        _text: &StatementTextRenderer,
42    ) -> String {
43        SqliteSelectInsertedIdStatementTextRenderer.render(statement)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::SqliteStatementRenderer;
50    use crate::create_table_statement_renderer::SqliteCreateTableStatementRenderer;
51    use datasources::{
52        Column, ColumnDefault, CreateTableStatement, CreateTableStatementTextRenderer,
53        DefaultStatementTextRenderer, ForeignKey, NotNull, PrimaryKey, ReferentialAction,
54        SelectInsertedIdStatement, SelectStatement, SelectStatementOptions, StatementTextRenderer,
55    };
56
57    fn renderer() -> StatementTextRenderer {
58        StatementTextRenderer::new(Some(Box::new(SqliteStatementRenderer)), None)
59    }
60
61    #[test]
62    fn renders_inserted_id_and_create_table() {
63        let statements = renderer();
64        assert_eq!(
65            statements.render(&SelectInsertedIdStatement::new("users", "id")),
66            "SELECT last_insert_rowid() AS id"
67        );
68
69        let columns = [
70            Column::new("id", "INTEGER")
71                .default(ColumnDefault::new("0", Some("df_id")))
72                .not_null(NotNull::new(Some("nn_id"))),
73            Column::new("user_id", "INTEGER"),
74        ];
75        let constraints = [
76            PrimaryKey::new("pk_orders", &["id"]),
77            ForeignKey::new(
78                "fk_orders_user",
79                &["user_id"],
80                "users",
81                &["id"],
82                Some(ReferentialAction::Cascade),
83                None,
84            ),
85        ];
86        let create = CreateTableStatement::new("orders", &columns, &constraints);
87        assert_eq!(
88            statements.render(&create),
89            SqliteCreateTableStatementRenderer.render(&create)
90        );
91        assert_eq!(
92            statements.render(&SelectStatement::new(SelectStatementOptions::new(
93                "users",
94                &["id"]
95            ))),
96            "SELECT id FROM users"
97        );
98    }
99
100    #[test]
101    fn renders_canonical_types() {
102        let columns = [Column::new("id", "int")
103            .identity()
104            .default(ColumnDefault::new("0", None))
105            .not_null(NotNull::new(None))];
106        let create = CreateTableStatement::new("users", &columns, &[]);
107        assert_eq!(
108            renderer().render(&create),
109            "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT 0 NOT NULL)"
110        );
111        assert_eq!(
112            DefaultStatementTextRenderer::instance().render(&create),
113            "CREATE TABLE users (id int DEFAULT 0 NOT NULL)"
114        );
115
116        let keyed = CreateTableStatement::new(
117            "users",
118            &[Column::new("id", "int").identity()],
119            &[PrimaryKey::new("pk_users", &["id"])],
120        );
121        assert_eq!(
122            renderer().render(&keyed),
123            "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT)"
124        );
125    }
126
127    #[test]
128    fn renders_alter_add_column() {
129        use datasources::{AlterAction, AlterTableStatement, NotNull};
130        let alter = AlterTableStatement::new(
131            "users",
132            AlterAction::AddColumn(Column::new("email", "TEXT").not_null(NotNull::new(None))),
133        );
134        assert_eq!(
135            renderer().render(&alter),
136            "ALTER TABLE users ADD COLUMN email TEXT NOT NULL"
137        );
138    }
139
140    #[test]
141    #[should_panic(expected = "SQLite cannot ALTER COLUMN")]
142    fn throws_on_alter_column() {
143        use datasources::{AlterAction, AlterTableStatement};
144        let alter = AlterTableStatement::new("users", AlterAction::AlterColumn(Column::new("age", "INTEGER")));
145        renderer().render(&alter);
146    }
147}