teo_runtime/model/property/
builder.rs1use 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}