indexed_db_futures/
query_source.rs

1//! Common functionality for making queries.
2
3use sealed::sealed;
4use wasm_bindgen::prelude::*;
5
6pub use get_all::{GetAll, GetAllKeys, GetAllRecords};
7use internal_macros::errdoc;
8
9use crate::internal_utils::SystemRepr;
10use crate::{KeyPath, KeyRange};
11pub use get::Get;
12pub use get_key::GetKey;
13use internal::QuerySourceInternal;
14
15pub use count::Count;
16
17iffeat! {
18    #[cfg(feature = "cursors")]
19    pub(crate) mod cursor;
20    pub use cursor::{AnyCursorBuilder, CursorBuilder, KeyCursorBuilder};
21}
22
23mod count;
24mod get;
25pub(crate) mod get_all;
26mod get_key;
27
28/// Common functionality for making queries.
29#[sealed]
30pub trait QuerySource {
31    /// Count the number of documents in the index/object store.
32    #[errdoc(QuerySource(InvalidStateError, TransactionInactiveError, DataError))]
33    fn count(&self) -> Count<Self>
34    where
35        Self: Sized;
36
37    /// Get one record from the object store or index. Returns the first match if a non-[only](KeyRange::Only) key is
38    /// provided and multiple records match.
39    #[errdoc(QuerySource(InvalidStateError, TransactionInactiveError, DataError))]
40    fn get<V, K, I>(&self, key: I) -> Get<Self, K, V>
41    where
42        Self: Sized,
43        I: Into<KeyRange<K>>;
44
45    /// Return the first matching key selected by the specified query.
46    #[errdoc(QuerySource(TransactionInactiveError, InvalidStateError, DataError))]
47    fn get_key<K, I>(&self, key_range: I) -> GetKey<Self, K>
48    where
49        Self: Sized,
50        I: Into<KeyRange<K>>;
51
52    /// Get all records in the object store or index.
53    #[errdoc(QuerySource(InvalidStateError, TransactionInactiveError, DataError))]
54    fn get_all<V>(&self) -> GetAllRecords<Self, V>
55    where
56        Self: Sized;
57
58    /// Get all keys in the object store or index.
59    #[errdoc(QuerySource(InvalidStateError, TransactionInactiveError, DataError))]
60    fn get_all_keys<K>(&self) -> GetAllKeys<Self, K>
61    where
62        Self: Sized;
63
64    /// Get the index/object store key path.
65    fn key_path(&self) -> Option<KeyPath>;
66
67    /// Get the index/object store name.
68    fn name(&self) -> String;
69
70    /// Set the index/object store name.
71    #[errdoc(QuerySource(InvalidStateError, TransactionInactiveError, ConstraintError))]
72    fn set_name(&self, name: &str);
73
74    iffeat! {
75        #[cfg(feature = "cursors")]
76
77        /// Open a cursor that iterates over the records in the index or object store.
78        /// Resolves to `None` if the cursor is empty.
79        #[errdoc(Cursor(TransactionInactiveError, DataErrorOpen, InvalidStateErrorOpen))]
80        fn open_cursor(&self) -> CursorBuilder<Self> where Self: Sized;
81
82        /// Open a cursor that iterates over the keys in the index or object store.
83        /// Resolves to `None` if the cursor is empty.
84        #[errdoc(Cursor(TransactionInactiveError, DataErrorOpen, InvalidStateErrorOpen))]
85        fn open_key_cursor(&self) -> KeyCursorBuilder<Self> where Self: Sized;
86    }
87}
88
89#[sealed]
90impl<T: SystemRepr<Repr = R>, R: QuerySourceInternal> QuerySource for T {
91    #[inline]
92    fn name(&self) -> String {
93        self.as_sys().name()
94    }
95
96    #[inline]
97    fn set_name(&self, name: &str) {
98        self.as_sys().set_name(name);
99    }
100
101    #[inline]
102    fn count(&self) -> Count<Self> {
103        Count::new(self)
104    }
105
106    fn key_path(&self) -> Option<KeyPath> {
107        match self.as_sys().key_path() {
108            Ok(path) if !path.is_null() => Some(path.into()),
109            _ => None,
110        }
111    }
112
113    fn get<V, K, I>(&self, key: I) -> Get<Self, K, V>
114    where
115        I: Into<KeyRange<K>>,
116    {
117        Get::new(self, key.into())
118    }
119
120    fn get_key<K, I>(&self, key_range: I) -> GetKey<Self, K>
121    where
122        I: Into<KeyRange<K>>,
123    {
124        GetKey::new(self, key_range.into())
125    }
126
127    #[inline]
128    fn get_all<V>(&self) -> GetAllRecords<Self, V> {
129        GetAllRecords::new(self)
130    }
131
132    #[inline]
133    fn get_all_keys<K>(&self) -> GetAllKeys<Self, K> {
134        GetAllKeys::new(self)
135    }
136
137    iffeat! {
138        #[cfg(feature = "cursors")]
139        #[inline]
140        fn open_cursor(&self) -> CursorBuilder<Self> {
141            CursorBuilder::new(self)
142        }
143
144        #[inline]
145        fn open_key_cursor(&self) -> KeyCursorBuilder<Self> {
146            KeyCursorBuilder::new(self)
147        }
148    }
149}
150
151pub(crate) mod internal {
152    use wasm_bindgen::prelude::*;
153
154    /// Internal representation of a [`QuerySource`](super::QuerySource).
155    #[::sealed::sealed(pub(super))]
156    pub trait QuerySourceInternal {
157        #[doc(hidden)]
158        fn name(&self) -> String;
159
160        #[doc(hidden)]
161        fn set_name(&self, name: &str);
162
163        #[doc(hidden)]
164        fn count(&self) -> Result<web_sys::IdbRequest, JsValue>;
165
166        #[doc(hidden)]
167        fn count_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
168
169        #[doc(hidden)]
170        fn key_path(&self) -> Result<JsValue, JsValue>;
171
172        #[doc(hidden)]
173        fn get(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
174
175        #[doc(hidden)]
176        fn get_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
177
178        #[doc(hidden)]
179        fn get_all(&self) -> Result<web_sys::IdbRequest, JsValue>;
180
181        #[doc(hidden)]
182        fn get_all_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
183
184        #[doc(hidden)]
185        fn get_all_with_key_and_limit(
186            &self,
187            key: &JsValue,
188            limit: u32,
189        ) -> Result<web_sys::IdbRequest, JsValue>;
190
191        #[doc(hidden)]
192        fn get_all_keys(&self) -> Result<web_sys::IdbRequest, JsValue>;
193
194        #[doc(hidden)]
195        fn get_all_keys_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
196
197        #[doc(hidden)]
198        fn get_all_keys_with_key_and_limit(
199            &self,
200            key: &JsValue,
201            limit: u32,
202        ) -> Result<web_sys::IdbRequest, JsValue>;
203
204        iffeat! {
205            #[cfg(feature = "cursors")]
206            #[doc(hidden)]
207            fn open_cursor(&self) -> Result<web_sys::IdbRequest, JsValue>;
208
209            #[doc(hidden)]
210            fn open_cursor_with_range(&self, range: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
211
212            #[doc(hidden)]
213            fn open_cursor_with_range_and_direction(
214                &self,
215                range: &JsValue,
216                direction: web_sys::IdbCursorDirection,
217            ) -> Result<web_sys::IdbRequest, JsValue>;
218
219            #[doc(hidden)]
220            fn open_key_cursor(&self) -> Result<web_sys::IdbRequest, JsValue>;
221
222            #[doc(hidden)]
223            fn open_key_cursor_with_range(&self, range: &JsValue) -> Result<web_sys::IdbRequest, JsValue>;
224
225            #[doc(hidden)]
226            fn open_key_cursor_with_range_and_direction(
227                &self,
228                range: &JsValue,
229                direction: web_sys::IdbCursorDirection,
230            ) -> Result<web_sys::IdbRequest, JsValue>;
231        }
232    }
233}
234
235macro_rules! impl_internal {
236    ($for: ty) => {
237        #[::sealed::sealed]
238        impl internal::QuerySourceInternal for $for {
239            #[inline]
240            fn name(&self) -> String {
241                <$for>::name(self)
242            }
243
244            #[inline]
245            fn set_name(&self, name: &str) {
246                <$for>::set_name(self, name);
247            }
248
249            #[inline]
250            fn count(&self) -> Result<web_sys::IdbRequest, JsValue> {
251                <$for>::count(self)
252            }
253
254            #[inline]
255            fn count_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
256                <$for>::count_with_key(self, key)
257            }
258
259            #[inline]
260            fn key_path(&self) -> Result<JsValue, JsValue> {
261                <$for>::key_path(self)
262            }
263
264            #[inline]
265            fn get(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
266                <$for>::get(self, key)
267            }
268
269            #[inline]
270            fn get_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
271                <$for>::get_key(self, key)
272            }
273
274            #[inline]
275            fn get_all(&self) -> Result<web_sys::IdbRequest, JsValue> {
276                <$for>::get_all(self)
277            }
278
279            #[inline]
280            fn get_all_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
281                <$for>::get_all_with_key(self, key)
282            }
283
284            #[inline]
285            fn get_all_with_key_and_limit(
286                &self,
287                key: &JsValue,
288                limit: u32,
289            ) -> Result<web_sys::IdbRequest, JsValue> {
290                <$for>::get_all_with_key_and_limit(self, key, limit)
291            }
292
293            #[inline]
294            fn get_all_keys(&self) -> Result<web_sys::IdbRequest, JsValue> {
295                <$for>::get_all_keys(self)
296            }
297
298            #[inline]
299            fn get_all_keys_with_key(&self, key: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
300                <$for>::get_all_keys_with_key(self, key)
301            }
302
303            #[inline]
304            fn get_all_keys_with_key_and_limit(
305                &self,
306                key: &JsValue,
307                limit: u32,
308            ) -> Result<web_sys::IdbRequest, JsValue> {
309                <$for>::get_all_keys_with_key_and_limit(self, key, limit)
310            }
311
312            iffeat! {
313                #[cfg(feature = "cursors")]
314                #[inline]
315                fn open_cursor(&self) -> Result<web_sys::IdbRequest, JsValue> {
316                    <$for>::open_cursor(self)
317                }
318
319                #[inline]
320                fn open_cursor_with_range(&self, range: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
321                    <$for>::open_cursor_with_range(self, range)
322                }
323
324                #[inline]
325                fn open_cursor_with_range_and_direction(
326                    &self,
327                    range: &JsValue,
328                    direction: web_sys::IdbCursorDirection,
329                ) -> Result<web_sys::IdbRequest, JsValue> {
330                    <$for>::open_cursor_with_range_and_direction(self, range, direction)
331                }
332
333                #[inline]
334                fn open_key_cursor(&self) -> Result<web_sys::IdbRequest, JsValue> {
335                    <$for>::open_key_cursor(self)
336                }
337
338                #[inline]
339                 fn open_key_cursor_with_range(&self, range: &JsValue) -> Result<web_sys::IdbRequest, JsValue> {
340                    <$for>::open_key_cursor_with_range(self, range)
341                }
342
343                #[inline]
344                fn open_key_cursor_with_range_and_direction(
345                    &self,
346                    range: &JsValue,
347                    direction: web_sys::IdbCursorDirection,
348                ) -> Result<web_sys::IdbRequest, JsValue> {
349                    <$for>::open_key_cursor_with_range_and_direction(self, range, direction)
350                }
351            }
352        }
353    };
354}
355
356impl_internal!(web_sys::IdbObjectStore);
357
358#[cfg(feature = "indices")]
359impl_internal!(web_sys::IdbIndex);