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 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 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}