Skip to main content

schema_sql_generator/common/
table_generator.rs

1use crate::common::column_constraint_generator::ColumnConstraintGenerator;
2use crate::common::column_generator::ColumnGenerator;
3use crate::common::generator_context::GeneratorContext;
4use crate::common::index_generator::IndexGenerator;
5use crate::common::key_generator::KeyGenerator;
6use crate::common::table_constraint_generator::TableConstraintGenerator;
7use crate::{sql_newline, sql_print, sql_println};
8use schema_model::model::table::Table;
9
10pub trait TableGenerator {
11    fn output_tables(&self);
12    fn output_table(&self, table: &Table);
13    fn output_table_header(&self, table: &Table);
14    fn output_table_definition(&self, table: &Table);
15    fn output_table_footer(&self, table: &Table);
16    fn output_indexes(&self, table: &Table);
17    fn output_initial_data(&self, table: &Table);
18}
19
20pub struct DefaultTableGenerator {
21    context: GeneratorContext,
22    column_generator: Box<dyn ColumnGenerator>,
23    key_generator: Box<dyn KeyGenerator>,
24    column_constraint_generator: Box<dyn ColumnConstraintGenerator>,
25    table_constraint_generator: Box<dyn TableConstraintGenerator>,
26    index_generator: Box<dyn IndexGenerator>,
27}
28
29impl DefaultTableGenerator {
30    pub fn new(
31        context: GeneratorContext,
32        column_generator: Box<dyn ColumnGenerator>,
33        key_generator: Box<dyn KeyGenerator>,
34        column_constraint_generator: Box<dyn ColumnConstraintGenerator>,
35        table_constraint_generator: Box<dyn TableConstraintGenerator>,
36        index_generator: Box<dyn IndexGenerator>,
37    ) -> Self {
38        Self {
39            column_generator,
40            key_generator,
41            column_constraint_generator,
42            table_constraint_generator,
43            index_generator,
44            context,
45        }
46    }
47}
48
49impl TableGenerator for DefaultTableGenerator {
50    fn output_tables(&self) {
51        for schema in self.context.settings().database_model().schemas() {
52            for table in schema.tables() {
53                self.output_table(table);
54            };
55        }
56    }
57
58
59    fn output_table(&self, table: &Table) {
60        self.output_table_header(table);
61        self.output_table_definition(table);
62        self.output_table_footer(table);
63        self.output_indexes(table);
64        self.output_initial_data(table);
65    }
66
67    fn output_table_header(&self, table: &Table) {
68        self.context.with_writer(|writer| {
69            let fully_qualified_table_name = table.fully_qualified_table_name();
70            sql_println!(writer, "/* {} */", fully_qualified_table_name);
71            sql_println!(writer, "create table {}", fully_qualified_table_name);
72            sql_println!(writer, "(");
73        });
74    }
75
76    fn output_table_definition(&self, table: &Table) {
77        let table_definitions: Vec<String> = self.column_generator.column_definitions(table)
78            .into_iter()
79            .chain(self.key_generator.key_constraints(table))
80            .chain(self.column_constraint_generator.column_check_constraints(table))
81            .chain(self.table_constraint_generator.table_check_constraints(table))
82            .collect();
83
84        self.context.with_writer(|writer| {
85            for (i, sql) in table_definitions.iter().enumerate() {
86                sql_print!(writer, "{}", sql);
87
88                if i < table_definitions.len() - 1 {
89                    sql_print!(writer, ",");
90                }
91
92                sql_newline!(writer);
93            }
94        });
95    }
96
97    fn output_table_footer(&self, _table: &Table) {
98        self.context.with_writer(|writer| {
99            sql_println!(writer, "){}", self.context.settings().statement_separator());
100            sql_newline!(writer);
101        });
102    }
103
104    fn output_indexes(&self, table: &Table) {
105        self.context.with_writer(|writer| {
106            self.index_generator.output_indexes_for_table(writer, table);
107        });
108    }
109
110    fn output_initial_data(&self, table: &Table) {
111        let initial_data = table.initial_data()
112            .iter()
113            .filter(|it| { it.database_type().is_none() || it.database_type().unwrap() == self.context.settings().database_type() })
114            .collect::<Vec<_>>();
115
116        if initial_data.len() > 0 {
117            self.context.with_writer(|writer| {
118                initial_data.iter().for_each(|it| {
119                    sql_println!(writer, "{}{}", it.sql(), self.context.settings().statement_separator());
120                });
121
122                writer.newline();
123            });
124        }
125    }
126}