teo_runtime/model/field/
builder.rs

1use std::collections::BTreeMap;
2use std::sync::{Arc, Mutex};
3use std::sync::atomic::AtomicBool;
4use maplit::btreemap;
5use teo_parser::ast::schema::Schema;
6use teo_parser::availability::Availability;
7use teo_parser::r#type::Type;
8use teo_result::Result;
9use crate::app::data::AppData;
10use crate::comment::Comment;
11use crate::database::database::Database;
12use crate::database::r#type::DatabaseType;
13use crate::model::Field;
14use crate::model::field::{field, Index, Migration};
15use crate::model::field::indexable::SetIndex;
16use crate::model::field::set_optional::SetOptional;
17use crate::optionality::Optionality;
18use crate::pipeline::Pipeline;
19use crate::readwrite::read::Read;
20use crate::readwrite::write::Write;
21use crate::traits::named::Named;
22use crate::Value;
23
24#[derive(Clone)]
25pub struct Builder {
26    inner: Arc<Inner>
27}
28
29struct Inner {
30    name: String,
31    comment: Option<Comment>,
32    r#type: Type,
33    availability: Availability,
34    column_name: Arc<Mutex<String>>,
35    foreign_key: AtomicBool,
36    dropped: AtomicBool,
37    migration: Arc<Mutex<Option<Migration>>>,
38    database_type: Arc<Mutex<DatabaseType>>,
39    optionality: Arc<Mutex<Optionality>>,
40    copy: AtomicBool,
41    read: Arc<Mutex<Read>>,
42    write: Arc<Mutex<Write>>,
43    atomic: AtomicBool,
44    r#virtual: AtomicBool,
45    input_omissible: AtomicBool,
46    output_omissible: AtomicBool,
47    index: Arc<Mutex<Option<Index>>>,
48    queryable: AtomicBool,
49    sortable: AtomicBool,
50    auto: AtomicBool,
51    auto_increment: AtomicBool,
52    default: Arc<Mutex<Option<Value>>>,
53    on_set: Arc<Mutex<Pipeline>>,
54    on_save: Arc<Mutex<Pipeline>>,
55    on_output: Arc<Mutex<Pipeline>>,
56    can_mutate: Arc<Mutex<Pipeline>>,
57    can_read: Arc<Mutex<Pipeline>>,
58    data: Arc<Mutex<BTreeMap<String, Value>>>,
59    app_data: AppData,
60}
61
62impl Builder {
63    pub fn new(name: String, comment: Option<Comment>, r#type: Type, availability: Availability, app_data: AppData) -> Self {
64        Self {
65            inner: Arc::new(Inner {
66                name: name.clone(),
67                comment,
68                r#type,
69                availability,
70                column_name: Arc::new(Mutex::new(name)),
71                foreign_key: AtomicBool::new(false),
72                dropped: AtomicBool::new(false),
73                migration: Arc::new(Mutex::new(None)),
74                database_type: Arc::new(Mutex::new(DatabaseType::Undetermined)),
75                optionality: Arc::new(Mutex::new(Optionality::Required)),
76                copy: AtomicBool::new(true),
77                read: Arc::new(Mutex::new(Read::Read)),
78                write: Arc::new(Mutex::new(Write::Write)),
79                atomic: Default::default(),
80                r#virtual: AtomicBool::new(false),
81                input_omissible: AtomicBool::new(false),
82                output_omissible: AtomicBool::new(false),
83                index: Arc::new(Mutex::new(None)),
84                queryable: AtomicBool::new(true),
85                sortable: AtomicBool::new(true),
86                auto: AtomicBool::new(false),
87                auto_increment: AtomicBool::new(false),
88                default: Arc::new(Mutex::new(None)),
89                on_set: Arc::new(Mutex::new(Pipeline::new())),
90                on_save: Arc::new(Mutex::new(Pipeline::new())),
91                on_output: Arc::new(Mutex::new(Pipeline::new())),
92                can_mutate: Arc::new(Mutex::new(Pipeline::new())),
93                can_read: Arc::new(Mutex::new(Pipeline::new())),
94                data: Arc::new(Mutex::new(btreemap! {})),
95                app_data,
96            })
97        }
98    }
99
100    pub fn name(&self) -> String {
101        self.inner.name.clone()
102    }
103
104    pub fn comment(&self) -> Option<&Comment> {
105        self.inner.comment.as_ref()
106    }
107
108    pub fn r#type(&self) -> &Type {
109        &self.inner.r#type
110    }
111
112    pub fn availability(&self) -> Availability {
113        self.inner.availability
114    }
115
116    pub fn column_name(&self) -> String {
117        self.inner.column_name.lock().unwrap().clone()
118    }
119
120    pub fn set_column_name(&self, column_name: String) {
121        *self.inner.column_name.lock().unwrap() = column_name;
122    }
123
124    pub fn foreign_key(&self) -> bool {
125        self.inner.foreign_key.load(std::sync::atomic::Ordering::Relaxed)
126    }
127
128    pub fn set_foreign_key(&self, foreign_key: bool) {
129        self.inner.foreign_key.store(foreign_key, std::sync::atomic::Ordering::Relaxed);
130    }
131
132    pub fn dropped(&self) -> bool {
133        self.inner.dropped.load(std::sync::atomic::Ordering::Relaxed)
134    }
135
136    pub fn set_dropped(&self, dropped: bool) {
137        self.inner.dropped.store(dropped, std::sync::atomic::Ordering::Relaxed);
138    }
139
140    pub fn migration(&self) -> Option<Migration> {
141        self.inner.migration.lock().unwrap().clone()
142    }
143
144    pub fn set_migration(&self, migration: Option<Migration>) {
145        *self.inner.migration.lock().unwrap() = migration;
146    }
147
148    pub fn database_type(&self) -> DatabaseType {
149        self.inner.database_type.lock().unwrap().clone()
150    }
151
152    pub fn set_database_type(&self, database_type: DatabaseType) {
153        *self.inner.database_type.lock().unwrap() = database_type;
154    }
155
156    pub fn optionality(&self) -> Optionality {
157        self.inner.optionality.lock().unwrap().clone()
158    }
159
160    pub fn set_optionality(&self, optionality: Optionality) {
161        *self.inner.optionality.lock().unwrap() = optionality;
162    }
163
164    pub fn copy(&self) -> bool {
165        self.inner.copy.load(std::sync::atomic::Ordering::Relaxed)
166    }
167
168    pub fn set_copy(&self, copy: bool) {
169        self.inner.copy.store(copy, std::sync::atomic::Ordering::Relaxed);
170    }
171
172    pub fn read(&self) -> Read {
173        self.inner.read.lock().unwrap().clone()
174    }
175
176    pub fn set_read(&self, read: Read) {
177        *self.inner.read.lock().unwrap() = read;
178    }
179
180    pub fn write(&self) -> Write {
181        self.inner.write.lock().unwrap().clone()
182    }
183
184    pub fn set_write(&self, write: Write) {
185        *self.inner.write.lock().unwrap() = write;
186    }
187
188    pub fn atomic(&self) -> bool {
189        self.inner.atomic.load(std::sync::atomic::Ordering::Relaxed)
190    }
191
192    pub fn set_atomic(&self, atomic: bool) {
193        self.inner.atomic.store(atomic, std::sync::atomic::Ordering::Relaxed);
194    }
195
196    pub fn r#virtual(&self) -> bool {
197        self.inner.r#virtual.load(std::sync::atomic::Ordering::Relaxed)
198    }
199
200    pub fn set_virtual(&self, r#virtual: bool) {
201        self.inner.r#virtual.store(r#virtual, std::sync::atomic::Ordering::Relaxed);
202    }
203
204    pub fn input_omissible(&self) -> bool {
205        self.inner.input_omissible.load(std::sync::atomic::Ordering::Relaxed)
206    }
207
208    pub fn set_input_omissible(&self, input_omissible: bool) {
209        self.inner.input_omissible.store(input_omissible, std::sync::atomic::Ordering::Relaxed);
210    }
211
212    pub fn output_omissible(&self) -> bool {
213        self.inner.output_omissible.load(std::sync::atomic::Ordering::Relaxed)
214    }
215
216    pub fn set_output_omissible(&self, output_omissible: bool) {
217        self.inner.output_omissible.store(output_omissible, std::sync::atomic::Ordering::Relaxed);
218    }
219
220    pub fn index(&self) -> Option<Index> {
221        self.inner.index.lock().unwrap().clone()
222    }
223
224    pub fn set_index(&self, index: Option<Index>) {
225        *self.inner.index.lock().unwrap() = index;
226    }
227
228    pub fn queryable(&self) -> bool {
229        self.inner.queryable.load(std::sync::atomic::Ordering::Relaxed)
230    }
231
232    pub fn set_queryable(&self, queryable: bool) {
233        self.inner.queryable.store(queryable, std::sync::atomic::Ordering::Relaxed);
234    }
235
236    pub fn sortable(&self) -> bool {
237        self.inner.sortable.load(std::sync::atomic::Ordering::Relaxed)
238    }
239
240    pub fn set_sortable(&self, sortable: bool) {
241        self.inner.sortable.store(sortable, std::sync::atomic::Ordering::Relaxed);
242    }
243
244    pub fn auto(&self) -> bool {
245        self.inner.auto.load(std::sync::atomic::Ordering::Relaxed)
246    }
247
248    pub fn set_auto(&self, auto: bool) {
249        self.inner.auto.store(auto, std::sync::atomic::Ordering::Relaxed);
250    }
251
252    pub fn auto_increment(&self) -> bool {
253        self.inner.auto_increment.load(std::sync::atomic::Ordering::Relaxed)
254    }
255
256    pub fn set_auto_increment(&self, auto_increment: bool) {
257        self.inner.auto_increment.store(auto_increment, std::sync::atomic::Ordering::Relaxed);
258    }
259
260    pub fn default(&self) -> Option<Value> {
261        self.inner.default.lock().unwrap().clone()
262    }
263
264    pub fn set_default(&self, default: Option<Value>) {
265        *self.inner.default.lock().unwrap() = default;
266    }
267
268    pub fn on_set(&self) -> Pipeline {
269        self.inner.on_set.lock().unwrap().clone()
270    }
271
272    pub fn set_on_set(&self, on_set: Pipeline) {
273        *self.inner.on_set.lock().unwrap() = on_set;
274    }
275
276    pub fn on_save(&self) -> Pipeline {
277        self.inner.on_save.lock().unwrap().clone()
278    }
279
280    pub fn set_on_save(&self, on_save: Pipeline) {
281        *self.inner.on_save.lock().unwrap() = on_save;
282    }
283
284    pub fn on_output(&self) -> Pipeline {
285        self.inner.on_output.lock().unwrap().clone()
286    }
287
288    pub fn set_on_output(&self, on_output: Pipeline) {
289        *self.inner.on_output.lock().unwrap() = on_output;
290    }
291
292    pub fn can_mutate(&self) -> Pipeline {
293        self.inner.can_mutate.lock().unwrap().clone()
294    }
295
296    pub fn set_can_mutate(&self, can_mutate: Pipeline) {
297        *self.inner.can_mutate.lock().unwrap() = can_mutate;
298    }
299
300    pub fn can_read(&self) -> Pipeline {
301        self.inner.can_read.lock().unwrap().clone()
302    }
303
304    pub fn set_can_read(&self, can_read: Pipeline) {
305        *self.inner.can_read.lock().unwrap() = can_read;
306    }
307
308    pub fn data(&self) -> BTreeMap<String, Value> {
309        self.inner.data.lock().unwrap().clone()
310    }
311
312    pub fn insert_data_entry(&self, key: String, value: Value) {
313        self.inner.data.lock().unwrap().insert(key, value);
314    }
315
316    pub fn remove_data_entry(&self, key: &str) {
317        self.inner.data.lock().unwrap().remove(key);
318    }
319
320    pub fn set_data(&self, data: BTreeMap<String, Value>) {
321        *self.inner.data.lock().unwrap() = data;
322    }
323
324    pub fn data_entry(&self, key: &str) -> Option<Value> {
325        self.inner.data.lock().unwrap().get(key).cloned()
326    }
327
328    pub fn build(self, database: Database, schema: &Schema) -> Result<Field> {
329        let field = Field {
330            inner: Arc::new(field::Inner {
331                name: self.inner.name.clone(),
332                comment: self.inner.comment.clone(),
333                r#type: self.inner.r#type.clone(),
334                availability: self.inner.availability,
335                column_name: self.inner.column_name.lock().unwrap().clone(),
336                foreign_key: self.inner.foreign_key.load(std::sync::atomic::Ordering::Relaxed),
337                dropped: self.inner.dropped.load(std::sync::atomic::Ordering::Relaxed),
338                migration: self.inner.migration.lock().unwrap().clone(),
339                database_type: {
340                    let mut database_type = self.inner.database_type.lock().unwrap().clone();
341                    // set default database type
342                    if database_type.is_undetermined() {
343                        database_type = database.default_database_type(self.r#type(), schema)?
344                    }
345                    database_type
346                },
347                optionality: self.inner.optionality.lock().unwrap().clone(),
348                copy: {
349                    // do not copy primary field and unique field
350                    let mut copy = self.inner.copy.load(std::sync::atomic::Ordering::Relaxed);
351                    if self.index().is_some() && self.index().unwrap().r#type().is_unique_or_primary() {
352                        copy = false;
353                    }
354                    copy
355                },
356                read: self.inner.read.lock().unwrap().clone(),
357                write: self.inner.write.lock().unwrap().clone(),
358                atomic: self.inner.atomic.load(std::sync::atomic::Ordering::Relaxed),
359                r#virtual: self.inner.r#virtual.load(std::sync::atomic::Ordering::Relaxed),
360                input_omissible: self.inner.input_omissible.load(std::sync::atomic::Ordering::Relaxed),
361                output_omissible: self.inner.output_omissible.load(std::sync::atomic::Ordering::Relaxed),
362                index: self.inner.index.lock().unwrap().clone(),
363                queryable: self.inner.queryable.load(std::sync::atomic::Ordering::Relaxed),
364                sortable: self.inner.sortable.load(std::sync::atomic::Ordering::Relaxed),
365                auto: self.inner.auto.load(std::sync::atomic::Ordering::Relaxed),
366                auto_increment: self.inner.auto_increment.load(std::sync::atomic::Ordering::Relaxed),
367                default: self.inner.default.lock().unwrap().clone(),
368                on_set: self.inner.on_set.lock().unwrap().clone(),
369                on_save: self.inner.on_save.lock().unwrap().clone(),
370                on_output: self.inner.on_output.lock().unwrap().clone(),
371                can_mutate: self.inner.can_mutate.lock().unwrap().clone(),
372                can_read: self.inner.can_read.lock().unwrap().clone(),
373                data: self.inner.data.lock().unwrap().clone(),
374            })
375        };
376        Ok(field)
377    }
378
379    pub fn app_data(&self) -> &AppData {
380        &self.inner.app_data
381    }
382}
383
384impl Named for Builder {
385    fn name(&self) -> &str {
386        self.inner.name.as_str()
387    }
388}
389
390impl SetIndex for Builder {
391    fn set_index(&self, index: Index) {
392        self.inner.index.lock().unwrap().replace(index);
393    }
394}
395
396impl SetOptional for Builder {
397    fn set_optional(&self) {
398        self.set_optionality(Optionality::Optional);
399        self.set_input_omissible(true);
400        self.set_output_omissible(true);
401    }
402
403    fn set_required(&self) {
404        self.set_optionality(Optionality::Required);
405    }
406}