teo_runtime/model/relation/
builder.rs1use std::collections::BTreeMap;
2use std::sync::{Arc, Mutex};
3use std::sync::atomic::{AtomicBool, Ordering};
4use teo_parser::r#type::Type;
5use crate::app::data::AppData;
6use crate::comment::Comment;
7use crate::model::{Field, Relation};
8use crate::model::relation::delete::Delete;
9use crate::model::relation::relation;
10use crate::model::relation::update::Update;
11use crate::optionality::Optionality;
12use crate::traits::named::Named;
13use crate::Value;
14
15#[derive(Clone)]
16pub struct Builder {
17 inner: Arc<Inner>
18}
19
20pub struct Inner {
21 name: String,
22 comment: Option<Comment>,
23 r#type: Type,
24 optionality: Arc<Mutex<Optionality>>,
25 model: Arc<Mutex<Vec<String>>>,
26 through: Arc<Mutex<Option<Vec<String>>>>,
27 local: Arc<Mutex<Option<String>>>,
28 foreign: Arc<Mutex<Option<String>>>,
29 is_vec: AtomicBool,
30 fields: Arc<Mutex<Vec<String>>>,
31 references: Arc<Mutex<Vec<String>>>,
32 delete: Arc<Mutex<Delete>>,
33 update: Arc<Mutex<Update>>,
34 delete_specified: AtomicBool,
35 update_specified: AtomicBool,
36 data: Arc<Mutex<BTreeMap<String, Value>>>,
37 app_data: AppData,
38}
39
40impl Builder {
41 pub fn new(name: String, comment: Option<Comment>, r#type: Type, app_data: AppData) -> Self {
42 Self {
43 inner: Arc::new(Inner {
44 name,
45 comment,
46 r#type,
47 optionality: Arc::new(Mutex::new(Optionality::Optional)),
48 model: Arc::new(Mutex::new(vec![])),
49 through: Arc::new(Mutex::new(None)),
50 local: Arc::new(Mutex::new(None)),
51 foreign: Arc::new(Mutex::new(None)),
52 is_vec: AtomicBool::new(false),
53 fields: Arc::new(Mutex::new(vec![])),
54 references: Arc::new(Mutex::new(vec![])),
55 delete: Arc::new(Mutex::new(Delete::Nullify)),
56 update: Arc::new(Mutex::new(Update::Nullify)),
57 delete_specified: AtomicBool::new(false),
58 update_specified: AtomicBool::new(false),
59 data: Arc::new(Mutex::new(BTreeMap::new())),
60 app_data,
61 })
62 }
63 }
64
65 pub fn name(&self) -> &str {
66 self.inner.name.as_str()
67 }
68
69 pub fn comment(&self) -> Option<&Comment> {
70 self.inner.comment.as_ref()
71 }
72
73 pub fn r#type(&self) -> &Type {
74 &self.inner.r#type
75 }
76
77 pub fn optionality(&self) -> Optionality {
78 self.inner.optionality.lock().unwrap().clone()
79 }
80
81 pub fn set_optionality(&self, optionality: Optionality) {
82 *self.inner.optionality.lock().unwrap() = optionality;
83 }
84
85 pub fn model(&self) -> Vec<String> {
86 self.inner.model.lock().unwrap().clone()
87 }
88
89 pub fn set_model(&self, model: Vec<String>) {
90 *self.inner.model.lock().unwrap() = model;
91 }
92
93 pub fn through(&self) -> Option<Vec<String>> {
94 self.inner.through.lock().unwrap().clone()
95 }
96
97 pub fn set_through(&self, through: Option<Vec<String>>) {
98 *self.inner.through.lock().unwrap() = through;
99 }
100
101 pub fn local(&self) -> Option<String> {
102 self.inner.local.lock().unwrap().clone()
103 }
104
105 pub fn set_local(&self, local: Option<String>) {
106 *self.inner.local.lock().unwrap() = local;
107 }
108
109 pub fn foreign(&self) -> Option<String> {
110 self.inner.foreign.lock().unwrap().clone()
111 }
112
113 pub fn set_foreign(&self, foreign: Option<String>) {
114 *self.inner.foreign.lock().unwrap() = foreign;
115 }
116
117 pub fn is_vec(&self) -> bool {
118 self.inner.is_vec.load(std::sync::atomic::Ordering::Relaxed)
119 }
120
121 pub fn set_is_vec(&self, is_vec: bool) {
122 self.inner.is_vec.store(is_vec, std::sync::atomic::Ordering::Relaxed);
123 }
124
125 pub fn fields(&self) -> Vec<String> {
126 self.inner.fields.lock().unwrap().clone()
127 }
128
129 pub fn set_fields(&self, fields: Vec<String>) {
130 *self.inner.fields.lock().unwrap() = fields;
131 }
132
133 pub fn references(&self) -> Vec<String> {
134 self.inner.references.lock().unwrap().clone()
135 }
136
137 pub fn set_references(&self, references: Vec<String>) {
138 *self.inner.references.lock().unwrap() = references;
139 }
140
141 pub fn delete(&self) -> Delete {
142 *self.inner.delete.lock().unwrap()
143 }
144
145 pub fn set_delete(&self, delete: Delete) {
146 *self.inner.delete.lock().unwrap() = delete;
147 self.inner.delete_specified.store(true, Ordering::Relaxed);
148 }
149
150 pub fn update(&self) -> Update {
151 *self.inner.update.lock().unwrap()
152 }
153
154 pub fn set_update(&self, update: Update) {
155 *self.inner.update.lock().unwrap() = update;
156 self.inner.update_specified.store(true, Ordering::Relaxed);
157 }
158
159 pub fn has_foreign_key(&self, fields: Vec<&Field>) -> bool {
160 if self.through().is_some() {
161 false
162 } else {
163 self.fields().iter().find(|name| fields.iter().find(|f| f.name() == name.as_str() && f.foreign_key()).is_some()).is_some()
164 }
165 }
166
167 pub fn data(&self) -> BTreeMap<String, Value> {
168 self.inner.data.lock().unwrap().clone()
169 }
170
171 pub fn insert_data_entry(&self, key: String, value: Value) {
172 self.inner.data.lock().unwrap().insert(key, value);
173 }
174
175 pub fn remove_data_entry(&self, key: &str) {
176 self.inner.data.lock().unwrap().remove(key);
177 }
178
179 pub fn set_data(&self, data: BTreeMap<String, Value>) {
180 *self.inner.data.lock().unwrap() = data;
181 }
182
183 pub fn data_entry(&self, key: &str) -> Option<Value> {
184 self.inner.data.lock().unwrap().get(key).cloned()
185 }
186
187 pub(crate) fn build(self, fields: Vec<&Field>) -> Relation {
188 let has_foreign_key = self.has_foreign_key(fields);
189 let r#type = self.r#type();
190 let delete_rule = if !self.inner.delete_specified.load(Ordering::Relaxed) {
191 if r#type.is_optional() {
193 if !has_foreign_key {
194 Delete::NoAction
195 } else {
196 Delete::Nullify
197 }
198 } else if r#type.is_array() {
199 Delete::NoAction
200 } else {
201 if !has_foreign_key {
202 Delete::NoAction
203 } else {
204 Delete::Cascade
205 }
206 }
207 } else {
208 self.delete()
209 };
210 let update_rule = if !self.inner.update_specified.load(Ordering::Relaxed) {
211 if r#type.is_optional() {
213 if !has_foreign_key {
214 Update::Nullify
215 } else {
216 Update::NoAction
217 }
218 } else if r#type.is_array() {
219 Update::NoAction
220 } else {
221 if !has_foreign_key {
222 Update::NoAction
223 } else {
224 Update::Update
225 }
226 }
227 } else {
228 self.update()
229 };
230 let relation = Relation {
231 inner: Arc::new(relation::Inner {
232 name: self.inner.name.clone(),
233 comment: self.inner.comment.clone(),
234 r#type: self.inner.r#type.clone(),
235 optionality: self.optionality(),
236 model: self.model(),
237 through: self.through(),
238 local: self.local(),
239 foreign: self.foreign(),
240 is_vec: self.is_vec(),
241 fields: self.fields(),
242 references: self.references(),
243 delete: delete_rule,
244 update: update_rule,
245 has_foreign_key,
246 data: self.data(),
247 })
248 };
249 relation
250 }
251
252 pub fn app_data(&self) -> &AppData {
253 &self.inner.app_data
254 }
255}