teo_runtime/model/property/
builder.rs

1use std::collections::BTreeMap;
2use std::sync::{Arc, Mutex};
3use std::sync::atomic::AtomicBool;
4use teo_parser::ast::schema::Schema;
5use teo_parser::r#type::Type;
6use teo_result::Result;
7use crate::app::data::AppData;
8use crate::comment::Comment;
9use crate::database::database::Database;
10use crate::database::r#type::DatabaseType;
11use crate::model::field::Index;
12use crate::model::field::indexable::SetIndex;
13use crate::model::field::set_optional::SetOptional;
14use crate::model::Property;
15use crate::model::property::property;
16use crate::optionality::Optionality;
17use crate::pipeline::Pipeline;
18use crate::traits::named::Named;
19use crate::Value;
20
21#[derive(Clone)]
22pub struct Builder {
23    inner: Arc<Inner>
24}
25
26pub struct Inner {
27    name: String,
28    comment: Option<Comment>,
29    r#type: Type,
30    column_name: Arc<Mutex<String>>,
31    optionality: Arc<Mutex<Optionality>>,
32    database_type: Arc<Mutex<DatabaseType>>,
33    dependencies: Arc<Mutex<Vec<String>>>,
34    setter: Arc<Mutex<Option<Pipeline>>>,
35    getter: Arc<Mutex<Option<Pipeline>>>,
36    input_omissible: AtomicBool,
37    output_omissible: AtomicBool,
38    cached: AtomicBool,
39    index: Arc<Mutex<Option<Index>>>,
40    data: Arc<Mutex<BTreeMap<String, Value>>>,
41    app_data: AppData,
42}
43
44impl Builder {
45
46    pub fn new(name: String, comment: Option<Comment>, r#type: Type, app_data: AppData) -> Self {
47        Self {
48            inner: Arc::new(Inner {
49                name: name.clone(),
50                comment,
51                r#type,
52                column_name: Arc::new(Mutex::new(name)),
53                optionality: Arc::new(Mutex::new(Optionality::Optional)),
54                database_type: Arc::new(Mutex::new(DatabaseType::Undetermined)),
55                dependencies: Arc::new(Mutex::new(vec![])),
56                setter: Arc::new(Mutex::new(None)),
57                getter: Arc::new(Mutex::new(None)),
58                input_omissible: AtomicBool::new(false),
59                output_omissible: AtomicBool::new(false),
60                cached: AtomicBool::new(false),
61                index: Arc::new(Mutex::new(None)),
62                data: Arc::new(Mutex::new(BTreeMap::new())),
63                app_data
64            })
65        }
66    }
67
68    pub fn name(&self) -> &str {
69        self.inner.name.as_str()
70    }
71
72    pub fn comment(&self) -> Option<&Comment> {
73        self.inner.comment.as_ref()
74    }
75
76    pub fn r#type(&self) -> &Type {
77        &self.inner.r#type
78    }
79
80    pub fn column_name(&self) -> String {
81        self.inner.column_name.lock().unwrap().clone()
82    }
83
84    pub fn set_column_name(&self, column_name: String) {
85        *self.inner.column_name.lock().unwrap() = column_name;
86    }
87
88    pub fn optionality(&self) -> Optionality {
89        self.inner.optionality.lock().unwrap().clone()
90    }
91
92    pub fn set_optionality(&self, optionality: Optionality) {
93        *self.inner.optionality.lock().unwrap() = optionality;
94    }
95
96    pub fn database_type(&self) -> DatabaseType {
97        self.inner.database_type.lock().unwrap().clone()
98    }
99
100    pub fn set_database_type(&self, database_type: DatabaseType) {
101        *self.inner.database_type.lock().unwrap() = database_type;
102    }
103
104    pub fn dependencies(&self) -> Vec<String> {
105        self.inner.dependencies.lock().unwrap().clone()
106    }
107
108    pub fn set_dependencies(&self, dependencies: Vec<String>) {
109        *self.inner.dependencies.lock().unwrap() = dependencies;
110    }
111
112    pub fn setter(&self) -> Option<Pipeline> {
113        self.inner.setter.lock().unwrap().clone()
114    }
115
116    pub fn set_setter(&self, setter: Option<Pipeline>) {
117        *self.inner.setter.lock().unwrap() = setter;
118    }
119
120    pub fn getter(&self) -> Option<Pipeline> {
121        self.inner.getter.lock().unwrap().clone()
122    }
123
124    pub fn set_getter(&self, getter: Option<Pipeline>) {
125        *self.inner.getter.lock().unwrap() = getter;
126    }
127
128    pub fn input_omissible(&self) -> bool {
129        self.inner.input_omissible.load(std::sync::atomic::Ordering::Relaxed)
130    }
131
132    pub fn set_input_omissible(&self, input_omissible: bool) {
133        self.inner.input_omissible.store(input_omissible, std::sync::atomic::Ordering::Relaxed);
134    }
135
136    pub fn output_omissible(&self) -> bool {
137        self.inner.output_omissible.load(std::sync::atomic::Ordering::Relaxed)
138    }
139
140    pub fn set_output_omissible(&self, output_omissible: bool) {
141        self.inner.output_omissible.store(output_omissible, std::sync::atomic::Ordering::Relaxed);
142    }
143
144    pub fn cached(&self) -> bool {
145        self.inner.cached.load(std::sync::atomic::Ordering::Relaxed)
146    }
147
148    pub fn set_cached(&self, cached: bool) {
149        self.inner.cached.store(cached, std::sync::atomic::Ordering::Relaxed);
150    }
151
152    pub fn index(&self) -> Option<Index> {
153        self.inner.index.lock().unwrap().clone()
154    }
155
156    pub fn set_index(&self, index: Option<Index>) {
157        *self.inner.index.lock().unwrap() = index;
158    }
159
160    pub fn data(&self) -> BTreeMap<String, Value> {
161        self.inner.data.lock().unwrap().clone()
162    }
163
164    pub fn insert_data_entry(&self, key: String, value: Value) {
165        self.inner.data.lock().unwrap().insert(key, value);
166    }
167
168    pub fn remove_data_entry(&self, key: &str) {
169        self.inner.data.lock().unwrap().remove(key);
170    }
171
172    pub fn set_data(&self, data: BTreeMap<String, Value>) {
173        *self.inner.data.lock().unwrap() = data;
174    }
175
176    pub fn data_entry(&self, key: &str) -> Option<Value> {
177        self.inner.data.lock().unwrap().get(key).cloned()
178    }
179
180    pub(crate) fn build(self, database: Database, schema: &Schema) -> Result<Property> {
181        Ok(Property {
182            inner: Arc::new(property::Inner {
183                name: self.inner.name.clone(),
184                comment: self.inner.comment.clone(),
185                r#type: self.inner.r#type.clone(),
186                column_name: self.inner.column_name.lock().unwrap().clone(),
187                optionality: self.inner.optionality.lock().unwrap().clone(),
188                database_type: {
189                    let mut database_type = self.inner.database_type.lock().unwrap().clone();
190                    if database_type.is_undetermined() {
191                        database_type = database.default_database_type(self.r#type(), schema)?;
192                    }
193                    database_type
194                },
195                dependencies: self.inner.dependencies.lock().unwrap().clone(),
196                setter: self.inner.setter.lock().unwrap().clone(),
197                getter: self.inner.getter.lock().unwrap().clone(),
198                input_omissible: self.inner.input_omissible.load(std::sync::atomic::Ordering::Relaxed),
199                output_omissible: self.inner.output_omissible.load(std::sync::atomic::Ordering::Relaxed),
200                cached: self.inner.cached.load(std::sync::atomic::Ordering::Relaxed),
201                index: self.inner.index.lock().unwrap().clone(),
202                data: self.inner.data.lock().unwrap().clone(),
203            })
204        })
205    }
206
207    pub fn app_data(&self) -> &AppData {
208        &self.inner.app_data
209    }
210}
211
212impl SetOptional for Builder {
213
214    fn set_optional(&self) {
215        self.set_optionality(Optionality::Optional);
216        self.set_input_omissible(true);
217        self.set_output_omissible(true);
218    }
219
220    fn set_required(&self) {
221        self.set_optionality(Optionality::Required);
222    }
223}
224
225impl Named for Builder {
226    fn name(&self) -> &str {
227        self.inner.name.as_str()
228    }
229}
230
231impl SetIndex for Builder {
232    fn set_index(&self, index: Index) {
233        *self.inner.index.lock().unwrap() = Some(index)
234    }
235}