1use std::collections::{BTreeMap, BTreeSet};
2use std::ops::BitOr;
3use std::sync::Arc;
4use indexmap::IndexMap;
5use maplit::{btreemap, btreeset};
6use serde::{Serialize, Serializer};
7use teo_parser::ast::model::ModelResolved;
8use teo_parser::r#type::reference::Reference;
9use teo_parser::r#type::synthesized_shape_reference::SynthesizedShapeReference;
10use teo_parser::r#type::Type;
11use crate::action::Action;
12use crate::action::action::{AGGREGATE_HANDLER, COPY_HANDLER, COPY_MANY_HANDLER, COUNT_HANDLER, CREATE_HANDLER, CREATE_MANY_HANDLER, DELETE_HANDLER, DELETE_MANY_HANDLER, FIND_FIRST_HANDLER, FIND_MANY_HANDLER, FIND_UNIQUE_HANDLER, GROUP_BY_HANDLER, UPDATE_HANDLER, UPDATE_MANY_HANDLER, UPSERT_HANDLER};
13use crate::comment::Comment;
14use crate::model::field::column_named::ColumnNamed;
15use crate::model::field::Field;
16use crate::traits::named::Named;
17use crate::model::Index;
18use crate::model::migration::Migration;
19use crate::model::property::Property;
20use crate::model::relation::Relation;
21use crate::namespace::Namespace;
22use crate::pipeline::pipeline::Pipeline;
23use crate::traits::documentable::Documentable;
24use crate::value::Value;
25
26#[derive(Debug, Clone)]
27pub struct Model {
28 pub(super) inner: Arc<Inner>,
29}
30
31#[derive(Debug, Serialize)]
32pub(super) struct Inner {
33 pub(super) path: Vec<String>,
34 pub(super) parser_path: Vec<usize>,
35 pub(super) namespace_path: Vec<String>,
36 pub(super) comment: Option<Comment>,
37 #[serde(rename = "tableName")]
38 pub(super) table_name: String,
39 pub(super) actions: Vec<Action>,
40 #[serde(rename = "generateClient")]
41 pub(super) generate_client: bool,
42 #[serde(rename = "generateEntity")]
43 pub(super) generate_entity: bool,
44 #[serde(rename = "showInStudio")]
45 pub(super) show_in_studio: bool,
46 #[serde(rename = "synthesizeShapes")]
47 pub(super) synthesize_shapes: bool,
48 pub(super) fields: IndexMap<String, Field>,
49 pub(super) relations: IndexMap<String, Relation>,
50 pub(super) properties: IndexMap<String, Property>,
51 pub(super) indexes: IndexMap<String, Index>,
52 #[serde(rename = "primaryIndex")]
53 pub(super) primary_index: String,
54 #[serde(rename = "beforeSave")]
55 pub(super) before_save: Pipeline,
56 #[serde(rename = "afterSave")]
57 pub(super) after_save: Pipeline,
58 #[serde(rename = "beforeDelete")]
59 pub(super) before_delete: Pipeline,
60 #[serde(rename = "afterDelete")]
61 pub(super) after_delete: Pipeline,
62 #[serde(rename = "canRead")]
63 pub(super) can_read: Pipeline,
64 #[serde(rename = "canMutate")]
65 pub(super) can_mutate: Pipeline,
66 pub(super) migration: Migration,
67 pub(super) builtin_handlers: Vec<Action>,
68 pub(super) data: BTreeMap<String, Value>,
69 pub(super) cache: Cache,
70}
71
72impl PartialEq for Model {
73
74 fn eq(&self, other: &Self) -> bool {
75 self.inner.path == other.inner.path
76 }
77}
78
79impl Model {
80
81 pub fn new() -> Self {
82 Self {
83 inner: Arc::new(Inner {
84 path: vec![],
85 parser_path: vec![],
86 namespace_path: vec![],
87 table_name: "".to_string(),
88 generate_client: true,
89 generate_entity: true,
90 show_in_studio: true,
91 synthesize_shapes: true,
92 comment: None,
93 fields: Default::default(),
94 relations: Default::default(),
95 properties: Default::default(),
96 indexes: Default::default(),
97 primary_index: "".to_string(),
98 before_save: Pipeline::new(),
99 after_save: Pipeline::new(),
100 before_delete: Pipeline::new(),
101 after_delete: Pipeline::new(),
102 can_read: Pipeline::new(),
103 can_mutate: Pipeline::new(),
104 actions: vec![],
105 migration: Default::default(),
106 data: btreemap! {},
107 cache: Cache::new(),
108 builtin_handlers: vec![],
109 })
110 }
111 }
112
113 pub fn path(&self) -> &Vec<String> {
114 &self.inner.path
115 }
116
117 pub fn parser_path(&self) -> &Vec<usize> {
118 &self.inner.parser_path
119 }
120
121 pub fn namespace_path(&self) -> &Vec<String> {
122 &self.inner.namespace_path
123 }
125
126 pub fn table_name(&self) -> &str {
127 &self.inner.table_name
128 }
129
130 pub fn actions(&self) -> &Vec<Action> {
131 &self.inner.actions
132 }
133
134 pub fn generate_client(&self) -> bool {
135 self.inner.generate_client
136 }
137
138 pub fn generate_entity(&self) -> bool {
139 self.inner.generate_entity
140 }
141
142 pub fn show_in_studio(&self) -> bool {
143 self.inner.show_in_studio
144 }
145
146 pub fn synthesize_shapes(&self) -> bool {
147 self.inner.synthesize_shapes
148 }
149
150 pub fn fields(&self) -> &IndexMap<String, Field> {
151 &self.inner.fields
152 }
153
154 pub fn relations(&self) -> &IndexMap<String, Relation> {
155 &self.inner.relations
156 }
157
158 pub fn properties(&self) -> &IndexMap<String, Property> {
159 &self.inner.properties
160 }
161
162 pub fn indexes(&self) -> &IndexMap<String, Index> {
163 &self.inner.indexes
164 }
165
166 pub fn primary_index_name(&self) -> &str {
167 &self.inner.primary_index
168 }
169
170 pub fn primary_index(&self) -> Option<&Index> {
171 self.indexes().values().find(|i| i.r#type().is_primary())
172 }
173
174
175 pub fn before_save(&self) -> &Pipeline {
176 &self.inner.before_save
177 }
178
179 pub fn after_save(&self) -> &Pipeline {
180 &self.inner.after_save
181 }
182
183 pub fn before_delete(&self) -> &Pipeline {
184 &self.inner.before_delete
185 }
186
187 pub fn after_delete(&self) -> &Pipeline {
188 &self.inner.after_delete
189 }
190
191 pub fn can_read(&self) -> &Pipeline {
192 &self.inner.can_read
193 }
194
195 pub fn can_mutate(&self) -> &Pipeline {
196 &self.inner.can_mutate
197 }
198
199 pub fn migration(&self) -> &Migration {
200 &self.inner.migration
201 }
202
203 pub fn data(&self) -> &BTreeMap<String, Value> {
204 &self.inner.data
205 }
206
207 pub fn cache(&self) -> &Cache {
208 &self.inner.cache
209 }
210
211 pub fn field(&self, name: &str) -> Option<&Field> {
212 self.fields().get(name).filter(|f| !f.dropped())
213 }
214
215 pub fn dropped_field(&self, name: &str) -> Option<&Field> {
216 self.fields().get(name).filter(|f| f.dropped())
217 }
218
219 pub fn relation(&self, name: &str) -> Option<&Relation> {
220 self.relations().get(name)
221 }
222
223 pub fn property(&self, name: &str) -> Option<&Property> {
224 self.properties().get(name)
225 }
226
227 pub fn field_with_column_name(&self, name: &str) -> Option<&Field> {
228 self.fields().values().find(|f| f.column_name() == name)
229 }
230
231 pub fn property_with_column_name(&self, name: &str) -> Option<&Property> {
232 self.properties().values().find(|p| p.column_name() == name)
233 }
234
235 pub(crate) fn allowed_keys_for_aggregate(&self, name: &str) -> BTreeSet<&str> {
236 match name {
237 "_count" => self.cache().scalar_keys.iter().map(|k| k.as_str()).collect::<BTreeSet<&str>>().bitor(&btreeset!{"_all"}),
238 "_min" | "_max" => self.cache().scalar_keys.iter().map(|k| k.as_str()).collect(),
239 _ => self.cache().scalar_number_keys.iter().map(|k| k.as_str()).collect(),
240 }
241 }
242
243 pub fn allows_drop_when_migrate(&self) -> bool {
244 self.migration().drop
245 }
246
247 pub fn input_type_for_builtin_handler(&self, handler: Action) -> Type {
248 match handler {
249 FIND_UNIQUE_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::find_unique_args(self.as_type_reference())),
250 FIND_FIRST_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::find_first_args(self.as_type_reference())),
251 FIND_MANY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::find_many_args(self.as_type_reference())),
252 CREATE_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::create_args(self.as_type_reference())),
253 UPDATE_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::update_args(self.as_type_reference())),
254 COPY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::copy_args(self.as_type_reference())),
255 UPSERT_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::upsert_args(self.as_type_reference())),
256 DELETE_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::delete_args(self.as_type_reference())),
257 CREATE_MANY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::create_many_args(self.as_type_reference())),
258 UPDATE_MANY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::update_many_args(self.as_type_reference())),
259 COPY_MANY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::copy_many_args(self.as_type_reference())),
260 DELETE_MANY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::delete_many_args(self.as_type_reference())),
261 COUNT_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::count_args(self.as_type_reference())),
262 AGGREGATE_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::aggregate_args(self.as_type_reference())),
263 GROUP_BY_HANDLER => Type::SynthesizedShapeReference(SynthesizedShapeReference::group_by_args(self.as_type_reference())),
264 _ => unreachable!()
265 }
266 }
267
268 pub fn output_type_for_builtin_handler(&self, handler: Action, namespace: &Namespace) -> Type {
269 let data = namespace.interface_at_path(&vec!["std".to_owned(), "Data".to_owned()]).unwrap().as_type_reference();
270 let data_meta = namespace.interface_at_path(&vec!["std".to_owned(), "DataMeta".to_owned()]).unwrap().as_type_reference();
271 let paging_info = namespace.interface_at_path(&vec!["std".to_owned(), "PagingInfo".to_owned()]).unwrap().as_type_reference();
272 match handler {
273 FIND_UNIQUE_HANDLER => {
274 Type::InterfaceObject(data, vec![
275 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
276 ])
277 },
278 FIND_FIRST_HANDLER => {
279 Type::InterfaceObject(data, vec![
280 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
281 ])
282 },
283 FIND_MANY_HANDLER => {
284 Type::InterfaceObject(data_meta, vec![
285 Type::Array(Box::new(Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference())))),
286 Type::InterfaceObject(paging_info, vec![])
287 ])
288 },
289 CREATE_HANDLER => {
290 Type::InterfaceObject(data, vec![
291 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
292 ])
293 },
294 UPDATE_HANDLER => {
295 Type::InterfaceObject(data, vec![
296 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
297 ])
298 },
299 COPY_HANDLER => {
300 Type::InterfaceObject(data, vec![
301 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
302 ])
303 },
304 UPSERT_HANDLER => {
305 Type::InterfaceObject(data, vec![
306 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
307 ])
308 },
309 DELETE_HANDLER => {
310 Type::InterfaceObject(data, vec![
311 Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference()))
312 ])
313 },
314 CREATE_MANY_HANDLER => {
315 Type::InterfaceObject(data_meta, vec![
316 Type::Array(Box::new(Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference())))),
317 Type::InterfaceObject(paging_info, vec![])
318 ])
319 },
320 UPDATE_MANY_HANDLER => {
321 Type::InterfaceObject(data_meta, vec![
322 Type::Array(Box::new(Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference())))),
323 Type::InterfaceObject(paging_info, vec![])
324 ])
325 },
326 COPY_MANY_HANDLER => {
327 Type::InterfaceObject(data_meta, vec![
328 Type::Array(Box::new(Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference())))),
329 Type::InterfaceObject(paging_info, vec![])
330 ])
331 },
332 DELETE_MANY_HANDLER => {
333 Type::InterfaceObject(data_meta, vec![
334 Type::Array(Box::new(Type::SynthesizedShapeReference(SynthesizedShapeReference::result(self.as_type_reference())))),
335 Type::InterfaceObject(paging_info, vec![])
336 ])
337 },
338 COUNT_HANDLER => {
339 Type::InterfaceObject(data, vec![
340 Type::Int64
341 ])
342 },
343 AGGREGATE_HANDLER => {
344 Type::InterfaceObject(data, vec![
345 Type::SynthesizedShapeReference(SynthesizedShapeReference::aggregate_result(self.as_type_reference()))
346 ])
347 },
348 GROUP_BY_HANDLER => {
349 Type::InterfaceObject(data, vec![
350 Type::SynthesizedShapeReference(SynthesizedShapeReference::group_by_result(self.as_type_reference()))
351 ])
352 },
353 _ => unreachable!()
354 }
355 }
356
357 fn as_type_reference(&self) -> Reference {
358 Reference::new(self.parser_path().clone(), self.path().clone())
359 }
360
361 pub fn builtin_handlers(&self) -> &Vec<Action> {
362 &self.inner.builtin_handlers
363 }
364}
365
366#[derive(Debug, Serialize)]
367pub struct Cache {
368 #[serde(rename = "allKeys")]
369 pub all_keys: Vec<String>,
370 #[serde(rename = "inputKeys")]
371 pub input_keys: Vec<String>,
372 #[serde(rename = "saveKeys")]
373 pub save_keys: Vec<String>,
374 #[serde(rename = "saveKeysAndVirtualKeys")]
375 pub save_keys_and_virtual_keys: Vec<String>,
376 #[serde(rename = "outputKeys")]
377 pub output_keys: Vec<String>,
378 #[serde(rename = "queryKeys")]
379 pub query_keys: Vec<String>,
380 #[serde(rename = "uniqueQueryKeys")]
381 pub unique_query_keys: Vec<BTreeSet<String>>,
382 #[serde(rename = "sortKeys")]
383 pub sort_keys: Vec<String>,
384 #[serde(rename = "autoKeys")]
385 pub auto_keys: Vec<String>,
386 #[serde(rename = "denyRelationKeys")]
387 pub deny_relation_keys: Vec<String>,
388 #[serde(rename = "scalarKeys")]
389 pub scalar_keys: Vec<String>,
390 #[serde(rename = "scalarNumberKeys")]
391 pub scalar_number_keys: Vec<String>,
392 #[serde(rename = "localOutputKeys")]
393 pub local_output_keys: Vec<String>,
394 #[serde(rename = "relationOutputKeys")]
395 pub relation_output_keys: Vec<String>,
396 #[serde(rename = "fieldPropertyMap")]
397 pub field_property_map: BTreeMap<String, Vec<String>>,
398 #[serde(rename = "hasVirtualFields")]
399 pub has_virtual_fields: bool,
400 pub shape: ModelResolved,
401}
402
403impl Cache {
404
405 pub(crate) fn new() -> Self {
406 Cache {
407 all_keys: vec![],
408 input_keys: vec![],
409 save_keys: vec![],
410 save_keys_and_virtual_keys: vec![],
411 output_keys: vec![],
412 query_keys: vec![],
413 unique_query_keys: vec![],
414 sort_keys: vec![],
415 auto_keys: vec![],
416 deny_relation_keys: vec![],
417 scalar_keys: vec![],
418 scalar_number_keys: vec![],
419 local_output_keys: vec![],
420 relation_output_keys: vec![],
421 field_property_map: Default::default(),
422 has_virtual_fields: false,
423 shape: ModelResolved::new(),
424 }
425 }
426}
427
428impl Named for Model {
429
430 fn name(&self) -> &str {
431 self.path().last().map(|s| s.as_str()).unwrap()
432 }
433}
434
435impl Documentable for Model {
436
437 fn comment(&self) -> Option<&Comment> {
438 self.inner.comment.as_ref()
439 }
440
441 fn kind(&self) -> &'static str {
442 "model"
443 }
444}
445
446impl Serialize for Model {
447 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
448 where
449 S: Serializer
450 {
451 self.inner.serialize(serializer)
452 }
453}