database_reflection/reflection/
table.rs

1use crate::metadata::consts::{METADATA_CHARSET, METADATA_COLLATION, METADATA_FLAG_PRIMARY};
2use crate::metadata::WithMetadata;
3use crate::reflection::column::Column;
4use crate::reflection::index::Index;
5use indexmap::IndexMap;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::slice::Iter;
9use std::sync::Arc;
10
11#[derive(Clone, Default, Debug, Serialize, Deserialize)]
12pub struct Table {
13    name: Arc<String>,
14    primary_key: Vec<Arc<String>>,
15    columns: IndexMap<Arc<String>, Arc<Column>>,
16    indexes: IndexMap<Arc<String>, Index>,
17    metadata: HashMap<String, String>,
18}
19
20impl WithMetadata for Table {
21    /// Borrow metadata container for reading
22    fn get_metadata(&self) -> &HashMap<String, String> {
23        &self.metadata
24    }
25
26    /// Borrow metadata container for writing
27    fn get_metadata_mut(&mut self) -> &mut HashMap<String, String> {
28        &mut self.metadata
29    }
30}
31
32impl Table {
33    /// Create a new empty table
34    pub fn new(name: impl ToString) -> Table {
35        Table {
36            name: Arc::new(name.to_string()),
37            ..Default::default()
38        }
39    }
40
41    /// Get table name
42    pub fn name(&self) -> Arc<String> {
43        self.name.clone()
44    }
45
46    /// Add a new column to the table
47    pub fn set_column(&mut self, mut column: Column) -> &mut Table {
48        if column.datatype().is_text()
49            && column.meta(METADATA_CHARSET).is_none()
50            && column.meta(METADATA_COLLATION).is_none()
51            && self.meta(METADATA_CHARSET).is_some()
52            && self.meta(METADATA_COLLATION).is_some()
53        {
54            column
55                .set_meta(
56                    METADATA_CHARSET,
57                    self.meta(METADATA_CHARSET).unwrap_or_default(),
58                )
59                .set_meta(
60                    METADATA_COLLATION,
61                    self.meta(METADATA_COLLATION).unwrap_or_default(),
62                );
63        }
64
65        if column.meta_flag(METADATA_FLAG_PRIMARY) && !self.primary_key.contains(&column.name()) {
66            self.primary_key.push(column.name());
67        }
68
69        self.columns.insert(column.name(), Arc::new(column));
70
71        self
72    }
73
74    /// Find a column by name
75    pub fn column(&self, key: &str) -> Option<Arc<Column>> {
76        self.columns.get(&key.to_string()).cloned()
77    }
78
79    /// Get columns iterator
80    pub fn columns(&self) -> indexmap::map::Iter<'_, Arc<String>, Arc<Column>> {
81        self.columns.iter()
82    }
83
84    /// Add a new index
85    pub fn set_index(&mut self, index: Index) -> &mut Table {
86        if index.primary() && !self.primary_key.contains(&index.column().name()) {
87            self.primary_key.push(index.column().name());
88        }
89
90        self.indexes.insert(index.name(), index);
91
92        self
93    }
94
95    /// Find an index by name
96    pub fn index(&self, key: &str) -> Option<&Index> {
97        self.indexes.get(&key.to_string())
98    }
99
100    /// Find an index by column name
101    pub fn index_by_column_name(&self, column_name: Arc<String>) -> Option<Index> {
102        self.indexes
103            .iter()
104            .find(|(_, c)| c.column().name() == column_name)
105            .map(|(_, c)| c.clone())
106    }
107
108    /// Find an index by column
109    pub fn index_by_column(&self, column: &Column) -> Option<Index> {
110        self.indexes
111            .iter()
112            .find(|(_, c)| c.column() == column)
113            .map(|(_, c)| c.clone())
114    }
115
116    /// Get indexes iterator
117    pub fn indexes(&self) -> indexmap::map::Iter<'_, Arc<String>, Index> {
118        self.indexes.iter()
119    }
120
121    /// Get number of primary keys
122    pub fn primary_key_count(&self) -> usize {
123        self.primary_key.len()
124    }
125
126    /// Get primary key, or first primary key column name
127    pub fn primary_key(&self) -> Option<Arc<String>> {
128        self.primary_key.first().cloned()
129    }
130
131    /// Get primary key column or first primary key column
132    pub fn primary_key_column(&self) -> Option<Arc<Column>> {
133        self.primary_key
134            .first()
135            .map(|k| self.columns.get(k).cloned())
136            .unwrap()
137    }
138
139    /// Get primary keys iterator
140    pub fn primary_keys(&self) -> Iter<'_, Arc<String>> {
141        self.primary_key.iter()
142    }
143
144    /// Get primary key columns
145    pub fn primary_key_columns(&self) -> Vec<Arc<Column>> {
146        self.columns
147            .iter()
148            .filter(|kv| self.primary_key.contains(kv.0))
149            .map(|kv| kv.1.clone())
150            .collect::<Vec<Arc<Column>>>()
151    }
152}