teo_runtime/model/
builder.rs

1use std::collections::{BTreeMap, BTreeSet};
2use std::sync::{Arc, Mutex};
3use std::sync::atomic::AtomicBool;
4use indexmap::IndexMap;
5use itertools::Itertools;
6use teo_parser::ast::model::ModelResolved;
7use teo_result::{Error, Result};
8use crate::action::Action;
9use crate::comment::Comment;
10use crate::model::{Field, Index, Migration, Model, Property, Relation};
11use crate::model::field::indexable::Indexable;
12use crate::model::relation::delete::Delete;
13use crate::pipeline::Pipeline;
14use crate::{model, Value};
15use crate::app::data::AppData;
16use crate::model::field::typed::Typed;
17use crate::model::index::Item;
18use crate::traits::named::Named;
19
20#[derive(Clone)]
21pub struct Builder {
22    inner: Arc<Inner>,
23}
24
25struct Inner {
26    pub path: Vec<String>,
27    pub namespace_path: Vec<String>,
28    pub parser_path: Vec<usize>,
29    pub comment: Option<Comment>,
30    pub table_name: Arc<Mutex<String>>,
31    pub actions: Arc<Mutex<Vec<Action>>>,
32    pub generate_client: AtomicBool,
33    pub generate_entity: AtomicBool,
34    pub show_in_studio: AtomicBool,
35    pub synthesize_shapes: AtomicBool,
36    pub fields: Arc<Mutex<IndexMap<String, Field>>>,
37    pub relations: Arc<Mutex<IndexMap<String, Relation>>>,
38    pub properties: Arc<Mutex<IndexMap<String, Property>>>,
39    pub indexes: Arc<Mutex<IndexMap<String, Index>>>,
40    pub primary_index: Arc<Mutex<String>>,
41    pub before_save: Arc<Mutex<Pipeline>>,
42    pub after_save: Arc<Mutex<Pipeline>>,
43    pub before_delete: Arc<Mutex<Pipeline>>,
44    pub after_delete: Arc<Mutex<Pipeline>>,
45    pub can_read: Arc<Mutex<Pipeline>>,
46    pub can_mutate: Arc<Mutex<Pipeline>>,
47    pub migration: Arc<Mutex<Migration>>,
48    pub data: Arc<Mutex<BTreeMap<String, Value>>>,
49    pub app_data: AppData,
50}
51
52impl Builder {
53    pub fn new(path: Vec<String>, parser_path: Vec<usize>, comment: Option<Comment>, app_data: AppData) -> Self {
54        let mut table_name_namespace_prefix = path.iter().take(path.len() - 1).join("_");
55        if !table_name_namespace_prefix.is_empty() {
56            table_name_namespace_prefix += "__";
57        }
58        let table_name = table_name_namespace_prefix + path.last().unwrap();
59        let namespace_path = path.iter().take(path.len() - 1).map(|s| s.to_string()).collect();
60        Self {
61            inner: Arc::new(Inner {
62                path,
63                namespace_path,
64                parser_path,
65                comment,
66                table_name: Arc::new(Mutex::new(table_name)),
67                actions: Arc::new(Mutex::new(vec![])),
68                generate_client: AtomicBool::new(true),
69                generate_entity: AtomicBool::new(true),
70                show_in_studio: AtomicBool::new(true),
71                synthesize_shapes: AtomicBool::new(true),
72                fields: Arc::new(Mutex::new(Default::default())),
73                relations: Arc::new(Mutex::new(Default::default())),
74                properties: Arc::new(Mutex::new(Default::default())),
75                indexes: Arc::new(Mutex::new(Default::default())),
76                primary_index: Arc::new(Mutex::new("".to_string())),
77                before_save: Arc::new(Mutex::new(Pipeline::new())),
78                after_save: Arc::new(Mutex::new(Pipeline::new())),
79                before_delete: Arc::new(Mutex::new(Pipeline::new())),
80                after_delete: Arc::new(Mutex::new(Pipeline::new())),
81                can_read: Arc::new(Mutex::new(Pipeline::new())),
82                can_mutate: Arc::new(Mutex::new(Pipeline::new())),
83                migration: Arc::new(Mutex::new(Default::default())),
84                data: Arc::new(Mutex::new(Default::default())),
85                app_data,
86            })
87        }
88    }
89
90    pub fn namespace_path(&self) -> &Vec<String> {
91        &self.inner.namespace_path
92    }
93
94    pub fn table_name(&self) -> String {
95        self.inner.table_name.lock().unwrap().clone()
96    }
97
98    pub fn set_table_name(&self, table_name: String) {
99        *self.inner.table_name.lock().unwrap() = table_name;
100    }
101
102    pub fn actions(&self) -> Vec<Action> {
103        self.inner.actions.lock().unwrap().clone()
104    }
105
106    pub fn set_actions(&self, actions: Vec<Action>) {
107        *self.inner.actions.lock().unwrap() = actions;
108    }
109
110    pub fn generate_client(&self) -> bool {
111        self.inner.generate_client.load(std::sync::atomic::Ordering::Relaxed)
112    }
113
114    pub fn set_generate_client(&self, generate_client: bool) {
115        self.inner.generate_client.store(generate_client, std::sync::atomic::Ordering::Relaxed);
116    }
117
118    pub fn generate_entity(&self) -> bool {
119        self.inner.generate_entity.load(std::sync::atomic::Ordering::Relaxed)
120    }
121
122    pub fn set_generate_entity(&self, generate_entity: bool) {
123        self.inner.generate_entity.store(generate_entity, std::sync::atomic::Ordering::Relaxed);
124    }
125
126    pub fn show_in_studio(&self) -> bool {
127        self.inner.show_in_studio.load(std::sync::atomic::Ordering::Relaxed)
128    }
129
130    pub fn set_show_in_studio(&self, show_in_studio: bool) {
131        self.inner.show_in_studio.store(show_in_studio, std::sync::atomic::Ordering::Relaxed);
132    }
133
134    pub fn synthesize_shapes(&self) -> bool {
135        self.inner.synthesize_shapes.load(std::sync::atomic::Ordering::Relaxed)
136    }
137
138    pub fn set_synthesize_shapes(&self, synthesize_shapes: bool) {
139        self.inner.synthesize_shapes.store(synthesize_shapes, std::sync::atomic::Ordering::Relaxed);
140    }
141
142    pub fn insert_field(&self, name: String, field: Field) {
143        self.inner.fields.lock().unwrap().insert(name, field);
144    }
145
146    pub fn fields(&self) -> IndexMap<String, Field> {
147        self.inner.fields.lock().unwrap().clone()
148    }
149
150    pub fn set_fields(&self, fields: IndexMap<String, Field>) {
151        *self.inner.fields.lock().unwrap() = fields;
152    }
153
154    pub fn insert_relation(&self, name: String, relation: Relation) {
155        self.inner.relations.lock().unwrap().insert(name, relation);
156    }
157
158    pub fn relations(&self) -> IndexMap<String, Relation> {
159        self.inner.relations.lock().unwrap().clone()
160    }
161
162    pub fn set_relations(&self, relations: IndexMap<String, Relation>) {
163        *self.inner.relations.lock().unwrap() = relations;
164    }
165
166    pub fn insert_property(&self, name: String, property: Property) {
167        self.inner.properties.lock().unwrap().insert(name, property);
168    }
169
170    pub fn properties(&self) -> IndexMap<String, Property> {
171        self.inner.properties.lock().unwrap().clone()
172    }
173
174    pub fn set_properties(&self, properties: IndexMap<String, Property>) {
175        *self.inner.properties.lock().unwrap() = properties;
176    }
177
178    pub fn insert_index(&self, name: String, index: Index) {
179        self.inner.indexes.lock().unwrap().insert(name, index);
180    }
181
182    pub fn indexes(&self) -> IndexMap<String, Index> {
183        self.inner.indexes.lock().unwrap().clone()
184    }
185
186    pub fn set_indexes(&self, indexes: IndexMap<String, Index>) {
187        *self.inner.indexes.lock().unwrap() = indexes;
188    }
189
190    pub fn primary_index(&self) -> String {
191        self.inner.primary_index.lock().unwrap().clone()
192    }
193
194    pub fn set_primary_index(&self, primary_index: String) {
195        *self.inner.primary_index.lock().unwrap() = primary_index;
196    }
197
198    pub fn before_save(&self) -> Pipeline {
199        self.inner.before_save.lock().unwrap().clone()
200    }
201
202    pub fn set_before_save(&self, before_save: Pipeline) {
203        *self.inner.before_save.lock().unwrap() = before_save;
204    }
205
206    pub fn after_save(&self) -> Pipeline {
207        self.inner.after_save.lock().unwrap().clone()
208    }
209
210    pub fn set_after_save(&self, after_save: Pipeline) {
211        *self.inner.after_save.lock().unwrap() = after_save;
212    }
213
214    pub fn before_delete(&self) -> Pipeline {
215        self.inner.before_delete.lock().unwrap().clone()
216    }
217
218    pub fn set_before_delete(&self, before_delete: Pipeline) {
219        *self.inner.before_delete.lock().unwrap() = before_delete;
220    }
221
222    pub fn after_delete(&self) -> Pipeline {
223        self.inner.after_delete.lock().unwrap().clone()
224    }
225
226    pub fn set_after_delete(&self, after_delete: Pipeline) {
227        *self.inner.after_delete.lock().unwrap() = after_delete;
228    }
229
230    pub fn can_read(&self) -> Pipeline {
231        self.inner.can_read.lock().unwrap().clone()
232    }
233
234    pub fn set_can_read(&self, can_read: Pipeline) {
235        *self.inner.can_read.lock().unwrap() = can_read;
236    }
237
238    pub fn can_mutate(&self) -> Pipeline {
239        self.inner.can_mutate.lock().unwrap().clone()
240    }
241
242    pub fn set_can_mutate(&self, can_mutate: Pipeline) {
243        *self.inner.can_mutate.lock().unwrap() = can_mutate;
244    }
245
246    pub fn migration(&self) -> Migration {
247        self.inner.migration.lock().unwrap().clone()
248    }
249
250    pub fn set_migration(&self, migration: Migration) {
251        *self.inner.migration.lock().unwrap() = migration;
252    }
253
254    pub fn data(&self) -> BTreeMap<String, Value> {
255        self.inner.data.lock().unwrap().clone()
256    }
257
258    pub fn set_data(&self, data: BTreeMap<String, Value>) {
259        *self.inner.data.lock().unwrap() = data;
260    }
261
262    pub fn insert_data_entry(&self, key: String, value: Value) {
263        self.inner.data.lock().unwrap().insert(key, value);
264    }
265
266    pub fn remove_data_entry(&self, key: &str) {
267        self.inner.data.lock().unwrap().remove(key);
268    }
269
270    pub fn data_entry(&self, key: &str) -> Option<Value> {
271        self.inner.data.lock().unwrap().get(key).cloned()
272    }
273
274    pub(crate) fn build(self, shape: ModelResolved) -> Result<Model> {
275        // set primary index if it is set through model decorator
276        let mut primary_index_name = "".to_owned();
277        for index in self.indexes().values() {
278            if index.r#type().is_primary() {
279                primary_index_name = index.name().to_string();
280            }
281        }
282        if !primary_index_name.is_empty() {
283            self.set_primary_index(primary_index_name);
284        }
285
286        // load index and set primary index
287        let mut indexes_from_fields = vec![];
288        for field in self.fields().values() {
289            if field.index().is_some() {
290                if let Some(index) = self.collect_field_index(field) {
291                    indexes_from_fields.push(index);
292                }
293            }
294        }
295        for property in self.properties().values() {
296            if property.index().is_some() {
297                if let Some(index) = self.collect_field_index(property) {
298                    indexes_from_fields.push(index);
299                }
300            }
301        }
302        for index in indexes_from_fields {
303            if index.r#type().is_primary() {
304                self.set_primary_index(index.name().to_owned());
305            }
306            self.insert_index(index.name().to_owned(), index);
307        }
308        if self.primary_index().is_empty() {
309            Err(Error::new("model must have a primary index"))?;
310        }
311
312        // load caches
313
314        let all_field_keys: Vec<String> = self.fields().values().map(|f| f.name().to_owned()).collect();
315        let all_relation_keys: Vec<String> = self.relations().values().map(|r| r.name().to_owned()).collect();
316        let all_property_keys: Vec<String> = self.properties().values().map(|p| p.name().to_owned()).collect();
317        let mut all_keys = vec![];
318        all_keys.extend(all_field_keys.clone());
319        all_keys.extend(all_relation_keys.clone());
320        all_keys.extend(all_property_keys.clone());
321        let input_field_keys: Vec<String> = self.fields().values().filter(|&f| !f.write().is_no_write()).map(|f| f.name().to_string()).collect();
322        let input_relation_keys = all_relation_keys.clone();
323        let input_property_keys: Vec<String> = self.properties().values().filter(|p| p.setter().is_some()).map(|p| p.name().to_string()).collect();
324        let mut input_keys = vec![];
325        input_keys.extend(input_field_keys);
326        input_keys.extend(input_relation_keys);
327        input_keys.extend(input_property_keys);
328        let field_save_keys: Vec<String> = self.fields().values().filter(|f| { !f.r#virtual() }).map(|f| f.name().to_string()).collect();
329        let property_save_keys: Vec<String> = self.properties().values().filter(|p| p.cached()).map(|p| p.name().to_string()).collect();
330        let mut save_keys = vec![];
331        save_keys.extend(field_save_keys.clone());
332        save_keys.extend(property_save_keys.clone());
333        let mut save_keys_and_virtual_keys = vec![];
334        save_keys_and_virtual_keys.extend(all_field_keys.clone());
335        save_keys_and_virtual_keys.extend(property_save_keys);
336        let output_field_keys: Vec<String> = self.fields().values().filter(|&f| { !f.read().is_no_read() }).map(|f| { f.name().to_string() }).collect();
337        let output_relation_keys = all_relation_keys.clone();
338        let output_property_keys: Vec<String> = self.properties().values().filter(|p| p.getter().is_some()).map(|p| p.name().to_string()).collect();
339        let mut output_keys = vec![];
340        output_keys.extend(output_field_keys.clone());
341        output_keys.extend(output_relation_keys.clone());
342        output_keys.extend(output_property_keys.clone());
343        let mut output_field_keys_and_property_keys = vec![];
344        output_field_keys_and_property_keys.extend(output_field_keys);
345        output_field_keys_and_property_keys.extend(output_property_keys);
346        let sort_keys: Vec<String> = self.fields().values().filter(|f| f.sortable()).map(|f| f.name().to_owned()).collect();
347        let query_keys: Vec<String> = {
348            let mut query_keys: Vec<String> = self.fields().values().filter(|f| f.queryable()).map(|f| f.name().to_owned()).collect();
349            query_keys.extend(all_relation_keys.clone());
350            query_keys
351        };
352        let unique_query_keys: Vec<BTreeSet<String>> = {
353            let mut result = vec![];
354            for index in self.indexes().values() {
355                let set = BTreeSet::from_iter(index.items().iter().map(|i| {
356                    i.field.clone()
357                }));
358                result.push(set);
359            }
360            result
361        };
362        let auto_keys: Vec<String> = self.fields()
363            .values()
364            .filter(|&f| { f.auto() || f.auto_increment() })
365            .map(|f| f.name().to_string())
366            .collect();
367        let deny_relation_keys: Vec<String> = self.relations()
368            .values()
369            .filter(|&r| { r.delete() == Delete::Deny })
370            .map(|r| r.name().to_string())
371            .collect();
372        let scalar_keys: Vec<String> = self.fields()
373            .values()
374            .map(|f| f.name().to_string())
375            .collect();
376        let scalar_number_keys: Vec<String> = self.fields()
377            .values()
378            .filter(|f| f.r#type().is_any_int_or_float() || f.r#type().is_decimal())
379            .map(|f| f.name().to_string())
380            .collect();
381        // assign
382        let mut cache = model::model::Cache::new();
383        cache.all_keys = all_keys.clone();
384        cache.input_keys = input_keys;
385        cache.save_keys = save_keys;
386        cache.save_keys_and_virtual_keys = save_keys_and_virtual_keys;
387        cache.output_keys = output_keys;
388        cache.query_keys = query_keys;
389        cache.sort_keys = sort_keys;
390        cache.unique_query_keys = unique_query_keys;
391        cache.auto_keys = auto_keys;
392        cache.deny_relation_keys = deny_relation_keys;
393        cache.scalar_keys = scalar_keys;
394        cache.scalar_number_keys = scalar_number_keys;
395        cache.local_output_keys = output_field_keys_and_property_keys;
396        cache.relation_output_keys = output_relation_keys;
397
398        // field property map
399        cache.field_property_map = {
400            let mut map = BTreeMap::new();
401            for property in self.properties().values() {
402                if property.cached() {
403                    for dependency in property.dependencies() {
404                        if map.get(dependency).is_none() {
405                            map.insert(dependency.clone(), vec![]);
406                        }
407                        map.get_mut(dependency).unwrap().push(property.name().to_string())
408                    }
409                }
410            }
411            map
412        };
413        cache.shape = shape;
414        Ok(Model {
415            inner: Arc::new(model::model::Inner {
416                path: self.inner.path.clone(),
417                parser_path: self.inner.parser_path.clone(),
418                namespace_path: self.inner.path.iter().take(self.inner.path.len() - 1).map(|s| s.to_string()).collect(),
419                comment: self.inner.comment.clone(),
420                table_name: self.inner.table_name.lock().unwrap().clone(),
421                actions: self.inner.actions.lock().unwrap().clone(),
422                generate_client: self.inner.generate_client.load(std::sync::atomic::Ordering::Relaxed),
423                generate_entity: self.inner.generate_entity.load(std::sync::atomic::Ordering::Relaxed),
424                show_in_studio: self.inner.show_in_studio.load(std::sync::atomic::Ordering::Relaxed),
425                synthesize_shapes: self.inner.synthesize_shapes.load(std::sync::atomic::Ordering::Relaxed),
426                fields: self.inner.fields.lock().unwrap().clone(),
427                relations: self.inner.relations.lock().unwrap().clone(),
428                properties: self.inner.properties.lock().unwrap().clone(),
429                indexes: self.inner.indexes.lock().unwrap().clone(),
430                primary_index: self.inner.primary_index.lock().unwrap().clone(),
431                before_save: self.inner.before_save.lock().unwrap().clone(),
432                after_save: self.inner.after_save.lock().unwrap().clone(),
433                before_delete: self.inner.before_delete.lock().unwrap().clone(),
434                after_delete: self.inner.after_delete.lock().unwrap().clone(),
435                can_read: self.inner.can_read.lock().unwrap().clone(),
436                can_mutate: self.inner.can_mutate.lock().unwrap().clone(),
437                migration: self.inner.migration.lock().unwrap().clone(),
438                data: self.inner.data.lock().unwrap().clone(),
439                cache,
440                builtin_handlers: self.figure_out_builtin_handlers()
441            }),
442        })
443    }
444
445    fn figure_out_builtin_handlers(&self) -> Vec<Action> {
446        let mut result = vec![];
447        for action in Action::builtin_handlers() {
448            result.push(*action);
449        }
450        result
451    }
452
453    pub fn collect_field_index<I>(&self, indexable: &I) -> Option<Index> where I: Indexable {
454        if let Some(field_index) = indexable.index() {
455            let name = indexable.name();
456            let index = model::Index::new(field_index.r#type(), name.to_owned(), vec![
457                Item::new(
458                    field_index.name().to_owned(),
459                    field_index.sort(),
460                    field_index.length(),
461                )
462            ]);
463            Some(index)
464        } else {
465            None
466        }
467    }
468
469    pub fn app_data(&self) -> &AppData {
470        &self.inner.app_data
471    }
472}