idb_sys/index/
mod.rs

1mod index_params;
2
3pub use self::index_params::IndexParams;
4
5use wasm_bindgen::{JsCast, JsValue};
6use web_sys::IdbIndex;
7
8use crate::{CursorDirection, Error, KeyPath, ObjectStore, Query, StoreRequest};
9
10/// Provides asynchronous access to an index in a database.
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Index {
13    inner: IdbIndex,
14}
15
16impl Index {
17    /// Returns the name of the index.
18    pub fn name(&self) -> String {
19        self.inner.name()
20    }
21
22    /// Updates the name of the index.
23    pub fn set_name(&self, name: &str) {
24        self.inner.set_name(name)
25    }
26
27    /// Returns the [`ObjectStore`] the index belongs to.
28    pub fn object_store(&self) -> ObjectStore {
29        self.inner.object_store().into()
30    }
31
32    /// Returns the key path of the index.
33    pub fn key_path(&self) -> Result<Option<KeyPath>, Error> {
34        let inner_key_path = self.inner.key_path().map_err(Error::KeyPathNotFound)?;
35
36        if inner_key_path.is_null() {
37            Ok(None)
38        } else {
39            Some(inner_key_path.try_into()).transpose()
40        }
41    }
42
43    /// Returns true if the index’s `multi_entry` flag is true.
44    pub fn multi_entry(&self) -> bool {
45        self.inner.multi_entry()
46    }
47
48    /// Returns true if the index’s `unique` flag is true.
49    pub fn unique(&self) -> bool {
50        self.inner.unique()
51    }
52
53    /// Retrieves the value of the first record matching the given key or key range in query.
54    pub fn get(&self, query: impl Into<Query>) -> Result<StoreRequest, Error> {
55        self.inner
56            .get(&query.into().into())
57            .map(Into::into)
58            .map_err(Error::GetFailed)
59    }
60
61    /// Retrieves the key of the first record matching the given key or key range in query.
62    pub fn get_key(&self, query: impl Into<Query>) -> Result<StoreRequest, Error> {
63        self.inner
64            .get_key(&query.into().into())
65            .map(Into::into)
66            .map_err(Error::GetKeyFailed)
67    }
68
69    /// Retrieves the values of the records matching the given key or key range in query (up to limit if given).
70    pub fn get_all(&self, query: Option<Query>, limit: Option<u32>) -> Result<StoreRequest, Error> {
71        match (query, limit) {
72            (Some(query), Some(limit)) => self
73                .inner
74                .get_all_with_key_and_limit(&query.into(), limit)
75                .map(Into::into)
76                .map_err(Error::GetAllKeysFailed),
77            (Some(query), None) => self
78                .inner
79                .get_all_with_key(&query.into())
80                .map(Into::into)
81                .map_err(Error::GetAllKeysFailed),
82            (None, Some(limit)) => self
83                .inner
84                .get_all_with_key_and_limit(&JsValue::null(), limit)
85                .map(Into::into)
86                .map_err(Error::GetAllKeysFailed),
87            (None, None) => self
88                .inner
89                .get_all()
90                .map(Into::into)
91                .map_err(Error::GetAllKeysFailed),
92        }
93    }
94
95    /// Retrieves the keys of records matching the given key or key range in query (up to limit if given).
96    pub fn get_all_keys(
97        &self,
98        query: Option<Query>,
99        limit: Option<u32>,
100    ) -> Result<StoreRequest, Error> {
101        match (query, limit) {
102            (Some(query), Some(limit)) => self
103                .inner
104                .get_all_keys_with_key_and_limit(&query.into(), limit)
105                .map(Into::into)
106                .map_err(Error::GetAllKeysFailed),
107            (Some(query), None) => self
108                .inner
109                .get_all_keys_with_key(&query.into())
110                .map(Into::into)
111                .map_err(Error::GetAllKeysFailed),
112            (None, Some(limit)) => self
113                .inner
114                .get_all_keys_with_key_and_limit(&JsValue::null(), limit)
115                .map(Into::into)
116                .map_err(Error::GetAllKeysFailed),
117            (None, None) => self
118                .inner
119                .get_all_keys()
120                .map(Into::into)
121                .map_err(Error::GetAllKeysFailed),
122        }
123    }
124
125    /// Retrieves the number of records matching the given key or key range in query.
126    pub fn count(&self, query: Option<Query>) -> Result<StoreRequest, Error> {
127        match query {
128            None => self
129                .inner
130                .count()
131                .map(Into::into)
132                .map_err(Error::CountFailed),
133            Some(query) => self
134                .inner
135                .count_with_key(&query.into())
136                .map(Into::into)
137                .map_err(Error::CountFailed),
138        }
139    }
140
141    /// Opens a [`Cursor`](crate::Cursor) over the records matching query, ordered by direction. If query is `None`, all
142    /// records in index are matched.
143    pub fn open_cursor(
144        &self,
145        query: Option<Query>,
146        cursor_direction: Option<CursorDirection>,
147    ) -> Result<StoreRequest, Error> {
148        match (query, cursor_direction) {
149            (Some(query), Some(cursor_direction)) => self
150                .inner
151                .open_cursor_with_range_and_direction(&query.into(), cursor_direction.into())
152                .map(Into::into)
153                .map_err(Error::OpenCursorFailed),
154            (Some(query), None) => self
155                .inner
156                .open_cursor_with_range(&query.into())
157                .map(Into::into)
158                .map_err(Error::OpenCursorFailed),
159            (None, Some(cursor_direction)) => self
160                .inner
161                .open_cursor_with_range_and_direction(&JsValue::null(), cursor_direction.into())
162                .map(Into::into)
163                .map_err(Error::OpenCursorFailed),
164            (None, None) => self
165                .inner
166                .open_cursor()
167                .map(Into::into)
168                .map_err(Error::OpenCursorFailed),
169        }
170    }
171
172    /// Opens a [`KeyCursor`](crate::KeyCursor) over the records matching query, ordered by direction. If query is
173    /// `None`, all records in index are matched.
174    pub fn open_key_cursor(
175        &self,
176        query: Option<Query>,
177        cursor_direction: Option<CursorDirection>,
178    ) -> Result<StoreRequest, Error> {
179        match (query, cursor_direction) {
180            (Some(query), Some(cursor_direction)) => self
181                .inner
182                .open_key_cursor_with_range_and_direction(&query.into(), cursor_direction.into())
183                .map(Into::into)
184                .map_err(Error::OpenCursorFailed),
185            (Some(query), None) => self
186                .inner
187                .open_key_cursor_with_range(&query.into())
188                .map(Into::into)
189                .map_err(Error::OpenCursorFailed),
190            (None, Some(cursor_direction)) => self
191                .inner
192                .open_key_cursor_with_range_and_direction(&JsValue::null(), cursor_direction.into())
193                .map(Into::into)
194                .map_err(Error::OpenCursorFailed),
195            (None, None) => self
196                .inner
197                .open_key_cursor()
198                .map(Into::into)
199                .map_err(Error::OpenCursorFailed),
200        }
201    }
202}
203
204impl From<IdbIndex> for Index {
205    fn from(inner: IdbIndex) -> Self {
206        Self { inner }
207    }
208}
209
210impl From<Index> for IdbIndex {
211    fn from(index: Index) -> Self {
212        index.inner
213    }
214}
215
216impl TryFrom<JsValue> for Index {
217    type Error = Error;
218
219    fn try_from(value: JsValue) -> Result<Self, Self::Error> {
220        value
221            .dyn_into::<IdbIndex>()
222            .map(Into::into)
223            .map_err(|value| Error::UnexpectedJsType("IdbIndex", value))
224    }
225}
226
227impl From<Index> for JsValue {
228    fn from(value: Index) -> Self {
229        value.inner.into()
230    }
231}