weldscli_lib/config/
table.rs

1use super::{Column, DbProvider, Relation};
2use serde::{Deserialize, Serialize};
3use welds::detect::{ColumnDef, DataType, TableDef};
4use welds::model_traits::TableIdent;
5
6#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)]
7pub struct Table {
8    pub schema: Option<String>,    // What schema this table belongs to
9    pub name: String,              // Table name
10    pub manual_update: bool,       // Tell welds to ignore this Def when scanning the database
11    model: Option<String>,         // value Default to singularized version of table name
12    pub r#type: String,            // This could be a table or view
13    pub columns: Vec<Column>,      // What are the columns on this table
14    pub belongs_to: Vec<Relation>, // list of objects this object belongs to
15    pub has_one: Vec<Relation>,    // which object this object has one of
16    pub has_many: Vec<Relation>,   // what objects this object has many of
17    pub database: DbProvider,      // what DB this object was scanned from.
18}
19
20fn type_str(ty: DataType) -> &'static str {
21    match ty {
22        DataType::View => "view",
23        DataType::Table => "table",
24    }
25}
26
27impl Table {
28    pub fn new(table_def: &TableDef, provider: DbProvider) -> Self {
29        let mut t = Table {
30            manual_update: false,
31            name: table_def.ident().name().to_string(),
32            schema: table_def.ident().schema().map(|s| s.to_string()),
33            model: None,
34            columns: vec![],
35            r#type: type_str(table_def.ty()).to_string(),
36            belongs_to: table_def.belongs_to().iter().map(|x| x.into()).collect(),
37            has_one: table_def.has_one().iter().map(|x| x.into()).collect(),
38            has_many: table_def.has_many().iter().map(|x| x.into()).collect(),
39            database: provider,
40        };
41        t.update_cols_from(table_def.columns());
42        t
43    }
44
45    pub fn update_from(&mut self, table_def: &TableDef, provider: DbProvider) {
46        if self.manual_update {
47            return;
48        }
49        self.name = table_def.ident().name().to_string();
50        self.schema = table_def.ident().schema().map(|s| s.to_string());
51        self.r#type = type_str(table_def.ty()).to_string();
52        self.belongs_to = table_def.belongs_to().iter().map(|x| x.into()).collect();
53        self.has_one = table_def.has_one().iter().map(|x| x.into()).collect();
54        self.has_many = table_def.has_many().iter().map(|x| x.into()).collect();
55        self.update_cols_from(table_def.columns());
56        self.database = provider;
57    }
58
59    fn update_cols_from(&mut self, cols: &[ColumnDef]) {
60        let col_names: Vec<&str> = cols.iter().map(|x| x.name()).collect();
61        // Remove Deleted tables
62        self.columns
63            .retain(|c| col_names.contains(&c.db_name.as_str()));
64        // Build a list of new columns to add.
65        let mut to_add = Vec::default();
66        // Add or update
67        for col in cols {
68            let existing = self.columns.iter_mut().find(|c| c.db_name == col.name());
69            match existing {
70                Some(existing) => existing.update_from(col),
71                None => to_add.push(Column::new(col)),
72            }
73        }
74        // append new tables
75        self.columns.append(&mut to_add);
76    }
77
78    /// Returns the name of the module this table will be placed in
79    pub fn module_name(&self) -> String {
80        use inflector::Inflector;
81        let start = match &self.model {
82            Some(s) => s.to_string(),
83            None => self.name.to_singular(),
84        };
85        start.to_snake_case()
86    }
87
88    /// Returns the name of the struct this table will generate
89    pub fn struct_name(&self) -> String {
90        use inflector::Inflector;
91        let start = match &self.model {
92            Some(s) => s.to_string(),
93            None => self.name.to_singular(),
94        };
95        start.to_class_case()
96    }
97
98    /// return how this table is identified by the database
99    pub(crate) fn ident(&self) -> TableIdent {
100        TableIdent::new(&self.name, self.schema.as_ref())
101    }
102}