1pub mod executor;
2pub mod primitives;
3pub mod query;
4pub mod response;
5pub mod store;
6
7use crate::{
8 db::{
9 executor::{Context, DeleteExecutor, LoadExecutor, SaveExecutor, UpsertExecutor},
10 store::{DataStoreRegistry, IndexStoreRegistry},
11 },
12 runtime_error::RuntimeError,
13 traits::{CanisterKind, EntityKind, FromKey},
14};
15use std::{marker::PhantomData, thread::LocalKey};
16
17pub struct Db<C: CanisterKind> {
29 data: &'static LocalKey<DataStoreRegistry>,
30 index: &'static LocalKey<IndexStoreRegistry>,
31 _marker: PhantomData<C>,
32}
33
34impl<C: CanisterKind> Db<C> {
35 #[must_use]
36 pub const fn new(
37 data: &'static LocalKey<DataStoreRegistry>,
38 index: &'static LocalKey<IndexStoreRegistry>,
39 ) -> Self {
40 Self {
41 data,
42 index,
43 _marker: PhantomData,
44 }
45 }
46
47 #[must_use]
48 pub const fn context<E>(&self) -> Context<'_, E>
49 where
50 E: EntityKind<Canister = C>,
51 {
52 Context::new(self)
53 }
54
55 pub fn with_data<R>(&self, f: impl FnOnce(&DataStoreRegistry) -> R) -> R {
57 self.data.with(|reg| f(reg))
58 }
59
60 pub fn with_index<R>(&self, f: impl FnOnce(&IndexStoreRegistry) -> R) -> R {
62 self.index.with(|reg| f(reg))
63 }
64}
65
66impl<C: CanisterKind> Copy for Db<C> {}
70
71impl<C: CanisterKind> Clone for Db<C> {
72 fn clone(&self) -> Self {
73 *self
74 }
75}
76
77pub struct DbSession<C: CanisterKind> {
83 db: Db<C>,
84 debug: bool,
85}
86
87impl<C: CanisterKind> DbSession<C> {
88 #[must_use]
89 pub const fn new(db: Db<C>) -> Self {
91 Self { db, debug: false }
92 }
93
94 #[must_use]
95 pub const fn debug(mut self) -> Self {
97 self.debug = true;
98 self
99 }
100
101 #[must_use]
107 pub const fn load<E>(&self) -> LoadExecutor<E>
108 where
109 E: EntityKind<Canister = C>,
110 {
111 LoadExecutor::new(self.db, self.debug)
112 }
113
114 #[must_use]
118 pub const fn save<E>(&self) -> SaveExecutor<E>
119 where
120 E: EntityKind<Canister = C>,
121 {
122 SaveExecutor::new(self.db, self.debug)
123 }
124
125 #[must_use]
127 pub const fn upsert<E>(&self) -> UpsertExecutor<E>
128 where
129 E: EntityKind<Canister = C>,
130 E::PrimaryKey: FromKey,
131 {
132 UpsertExecutor::new(self.db, self.debug)
133 }
134
135 #[must_use]
137 pub const fn delete<E>(&self) -> DeleteExecutor<E>
138 where
139 E: EntityKind<Canister = C>,
140 {
141 DeleteExecutor::new(self.db, self.debug)
142 }
143
144 pub fn insert<E>(&self, entity: E) -> Result<E, RuntimeError>
150 where
151 E: EntityKind<Canister = C>,
152 {
153 self.save::<E>().insert(entity)
154 }
155
156 pub fn insert_many<E>(
158 &self,
159 entities: impl IntoIterator<Item = E>,
160 ) -> Result<Vec<E>, RuntimeError>
161 where
162 E: EntityKind<Canister = C>,
163 {
164 self.save::<E>().insert_many(entities)
165 }
166
167 pub fn replace<E>(&self, entity: E) -> Result<E, RuntimeError>
169 where
170 E: EntityKind<Canister = C>,
171 {
172 self.save::<E>().replace(entity)
173 }
174
175 pub fn replace_many<E>(
177 &self,
178 entities: impl IntoIterator<Item = E>,
179 ) -> Result<Vec<E>, RuntimeError>
180 where
181 E: EntityKind<Canister = C>,
182 {
183 self.save::<E>().replace_many(entities)
184 }
185
186 pub fn update<E>(&self, entity: E) -> Result<E, RuntimeError>
188 where
189 E: EntityKind<Canister = C>,
190 {
191 self.save::<E>().update(entity)
192 }
193
194 pub fn update_many<E>(
196 &self,
197 entities: impl IntoIterator<Item = E>,
198 ) -> Result<Vec<E>, RuntimeError>
199 where
200 E: EntityKind<Canister = C>,
201 {
202 self.save::<E>().update_many(entities)
203 }
204
205 pub fn insert_view<E>(&self, view: E::ViewType) -> Result<E::ViewType, RuntimeError>
207 where
208 E: EntityKind<Canister = C>,
209 {
210 self.save::<E>().insert_view(view)
211 }
212
213 pub fn replace_view<E>(&self, view: E::ViewType) -> Result<E::ViewType, RuntimeError>
215 where
216 E: EntityKind<Canister = C>,
217 {
218 self.save::<E>().replace_view(view)
219 }
220
221 pub fn update_view<E>(&self, view: E::ViewType) -> Result<E::ViewType, RuntimeError>
223 where
224 E: EntityKind<Canister = C>,
225 {
226 self.save::<E>().update_view(view)
227 }
228}