darkbird/darkbird/
schema.rs1use 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}