1use crate::database::index::{Index, IndexOptions};
2use anyhow::anyhow;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
6pub struct EntityName(pub String);
7impl From<&str> for EntityName {
8 fn from(s: &str) -> Self {
9 Self(s.to_string())
10 }
11}
12impl Into<EntityName> for String {
13 fn into(self) -> EntityName {
14 EntityName(self)
15 }
16}
17impl std::fmt::Display for EntityName {
18 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
19 write!(f, "{}", self.0)
20 }
21}
22
23#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
24pub struct EntityAssociation {
25 pub entity_name: EntityName,
26 pub from: String,
27 pub to: String,
28 pub alias: EntityName,
30}
31
32#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
33pub struct PrimaryKey(pub String);
34
35#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
36pub struct Entity {
37 pub name: EntityName,
38 pub primary_key: PrimaryKey,
39 pub associations: Vec<EntityAssociation>,
40 pub indexes: Vec<Index>,
41}
42
43impl Entity {
44 pub fn new(s: &str) -> Self {
51 Entity {
52 name: EntityName::from(s),
53 primary_key: PrimaryKey("_id".to_string()),
54 associations: vec![],
55 indexes: vec![],
56 }
57 }
58
59 pub fn primary_key(&mut self, key: &str) -> Self {
60 self.primary_key = PrimaryKey(key.to_string());
61 self.clone()
62 }
63
64 pub fn add_index(
65 &mut self,
66 name: &str,
67 keys: Vec<&str>,
68 options: Option<IndexOptions>,
69 ) -> Result<Self, anyhow::Error> {
70 if self.indexes.iter().any(|i| i.name == name) {
71 return Err(anyhow!("An index with the name '{}' already exists.", name));
72 }
73 self.indexes.push(Index {
74 name: name.to_string(),
75 keys: keys.iter().map(|c| c.to_string()).collect(),
76 options,
77 });
78 Ok(self.clone())
79 }
80
81 pub fn associate<'a, N>(
82 &mut self,
83 entity_name: N,
84 from: &str,
85 to: &str,
86 alias: Option<&str>,
87 ) -> Result<Self, String>
88 where
89 N: Into<EntityName> + Clone,
90 {
91 let alias = alias.map_or_else(|| entity_name.clone().into(), |a| a.into());
92
93 self.associations.push(EntityAssociation {
94 entity_name: entity_name.clone().into(),
95 from: from.to_string(),
96 to: to.to_string(),
97 alias,
98 });
99
100 Ok(self.clone())
101 }
102}