darkbird/darkbird/
schema.rs

1use anymap::AnyMap;
2use std::{hash::Hash, collections::HashSet};
3use serde::{Serialize, de::DeserializeOwned};
4
5use crate::{Options, document::Document, Storage, VecStorage};
6
7use super::{database::Database, storage_redis::RedisStorage};
8
9
10
11pub struct Schema {
12    datastores: AnyMap,
13    names: HashSet<String>
14}
15
16impl Schema {
17
18    pub fn new() -> Schema {
19        Schema { 
20            datastores: AnyMap::new(),
21            names: HashSet::new()
22        }
23    }
24
25
26    pub async fn with_datastore<'a, K, Doc>(mut self, opts: Options<'a>) -> Result<Schema, SchemaError> 
27    where
28        Doc: Serialize + DeserializeOwned + Clone + Sync + Send + 'static + Document,
29        K:  Serialize
30            + DeserializeOwned
31            + PartialOrd
32            + Ord
33            + PartialEq
34            + Eq
35            + Hash
36            + Clone
37            + Send
38            + Sync
39            + 'static
40    {
41
42        if self.names.contains(opts.storage_name) {
43            return Err(SchemaError::DatastoreAlreadyExist(opts.storage_name.to_owned()))
44        }
45
46        if let Some(_) = self.datastores.get::<Storage<K, Doc>>() {
47            return Err(SchemaError::DatastoreAlreadyExist(opts.storage_name.to_owned()))
48        }
49
50        match Storage::<K, Doc>::open(opts).await {
51            Err(e) => Err(SchemaError::Err(e)),
52            Ok(ds) => {
53                self.datastores.insert(ds);
54                Ok(self)
55            }
56        }
57        
58    }
59
60
61    pub async fn with_vecstore<'a>(mut self, opts: Options<'a>) -> Result<Schema, SchemaError> {
62
63        if self.names.contains(opts.storage_name) {
64            return Err(SchemaError::DatastoreAlreadyExist(opts.storage_name.to_owned()))
65        }
66
67        if let Some(_) = self.datastores.get::<VecStorage>() {
68            return Err(SchemaError::DatastoreAlreadyExist(opts.storage_name.to_owned()))
69        }
70
71        match VecStorage::open(opts).await {
72            Err(e) => Err(SchemaError::Err(e)),
73            Ok(ds) => {
74                self.datastores.insert(ds);
75                Ok(self)
76            }
77        }
78        
79    }
80
81
82
83    pub async fn with_redisstore<K, Doc>(mut self, storage_name: &str) -> Result<Schema, SchemaError> 
84    where
85        Doc: Clone + Sync + Send + 'static,
86        K:  
87            PartialOrd
88            + Ord
89            + PartialEq
90            + Eq
91            + Hash
92            + Clone
93            + Send
94            + Sync
95            + 'static
96    {
97
98        if self.names.contains(storage_name) {
99            return Err(SchemaError::DatastoreAlreadyExist(storage_name.to_owned()))
100        }
101
102        if let Some(_) = self.datastores.get::<RedisStorage<K, Doc>>() {
103            return Err(SchemaError::DatastoreAlreadyExist(storage_name.to_owned()))
104        }
105
106        self.datastores.insert(RedisStorage::<K, Doc>::new());
107        Ok(self)
108        
109    }
110
111
112
113
114    pub fn build(self) -> Database {
115        Database::open(self.datastores)
116    }
117
118}
119
120
121
122#[derive(Debug)]
123pub enum SchemaError {
124    DatastoreAlreadyExist(String),
125    Err(String)
126}