diff --git a/src/lib.rs b/src/lib.rs index 9b64c6c..bf244b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ //! let employees = transaction.store("employees")?; //! //! // Get the employee -//! let employee = employees.get(&id.into()).await?; +//! let employee = employees.get(&id.into()).await?.unwrap(); //! //! // Convert it to `serde_json::Value` from `JsValue` //! let employee: Option = serde_wasm_bindgen::from_value(employee).unwrap(); diff --git a/src/transaction/index.rs b/src/transaction/index.rs index a0855ba..84aaf67 100644 --- a/src/transaction/index.rs +++ b/src/transaction/index.rs @@ -33,12 +33,39 @@ impl StoreIndex { } /// Gets a value from the store with given key - pub async fn get(&self, key: &JsValue) -> Result { + pub async fn get(&self, key: &JsValue) -> Result> { let request = self .idb_index .get(key) .map_err(Error::IndexedDbRequestError)?; + let response = wait_request(request, Error::IndexedDbRequestError).await?; + if response.is_undefined() || response.is_null() { + Ok(None) + } else { + Ok(Some(response)) + } + } + + /// retrieves the primary keys of all objects inside the index + /// See: [MDN:IDBIndex/getAllKeys](https://developer.mozilla.org/en-US/docs/Web/API/IDBIndex/getAllKeys) + pub async fn get_all_keys( + &self, + key_range: Option<&KeyRange>, + limit: Option, + ) -> Result { + let request = match (key_range, limit) { + (None, None) => self.idb_index.get_all_keys(), + (None, Some(limit)) => self + .idb_index + .get_all_keys_with_key_and_limit(&JsValue::UNDEFINED, limit), + (Some(key_range), None) => self.idb_index.get_all_keys_with_key(key_range.as_ref()), + (Some(key_range), Some(limit)) => self + .idb_index + .get_all_keys_with_key_and_limit(key_range.as_ref(), limit), + } + .map_err(Error::IndexedDbRequestError)?; + wait_request(request, Error::IndexedDbRequestError).await } diff --git a/src/transaction/store.rs b/src/transaction/store.rs index 79edbe3..a504609 100644 --- a/src/transaction/store.rs +++ b/src/transaction/store.rs @@ -17,17 +17,20 @@ impl Store { Self { idb_store } } - /// Returns weather the store has auto increment enabled + /// Returns whether the store has auto increment enabled + /// MDN Reference: [IDBObjectStore.autoIncrement](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/autoIncrement) pub fn auto_increment(&self) -> bool { self.idb_store.auto_increment() } /// Returns the name of the store + /// MDN Reference: [IDBObjectStore.name](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/name) pub fn name(&self) -> String { self.idb_store.name() } /// Returns the key path of the store + /// MDN Reference: [IDBObjectStore.keyPath](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/keyPath) pub fn key_path(&self) -> Result> { self.idb_store .key_path() @@ -36,12 +39,13 @@ impl Store { } /// Returns all the index names of the store + /// MDN Reference: [IDBObjectStore/indexNames](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/indexNames) pub fn index_names(&self) -> Vec { let list = self.idb_store.index_names(); + let list_len = list.length(); + let mut result = Vec::with_capacity(list_len as usize); - let mut result = Vec::new(); - - for index in 0..list.length() { + for index in 0..list_len { if let Some(s) = list.get(index) { result.push(s); } @@ -51,6 +55,7 @@ impl Store { } /// Returns index of the store with given name + /// MDN Reference: [IDBObjectStore/index](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/index) pub fn index(&self, name: &str) -> Result { let idb_index = self.idb_store.index(name).map_err(Error::IndexOpenFailed)?; @@ -58,12 +63,52 @@ impl Store { } /// Gets a value from the store with given key - pub async fn get(&self, key: &JsValue) -> Result { + /// MDN Reference: [IDBObjectStore/get](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/get) + pub async fn get(&self, key: &JsValue) -> Result> { let request = self .idb_store .get(key) .map_err(Error::IndexedDbRequestError)?; + let response = wait_request(request, Error::IndexedDbRequestError).await?; + if response.is_undefined() || response.is_null() { + Ok(None) + } else { + Ok(Some(response)) + } + } + + /// Checks if a given key exists within the store + /// MDN Reference: [IDBObjectStore/getKey](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getKey) + pub async fn key_exists(&self, key: &JsValue) -> Result { + let request = self + .idb_store + .get_key(key) + .map_err(Error::IndexedDbRequestError)?; + let result = wait_request(request, Error::IndexedDbRequestError).await?; + Ok(result.as_bool().unwrap_or_default()) + } + + /// Retrieves record keys for all objects in the object store matching the specified + /// parameter or all objects in the store if no parameters are given. + /// MDN Reference: [IDBStore/getAllKeys](https://developer.mozilla.org/en-US/docs/Web/API/IDBStore/getAllKeys) + pub async fn get_all_keys( + &self, + key_range: Option<&KeyRange>, + limit: Option, + ) -> Result { + let request = match (key_range, limit) { + (None, None) => self.idb_store.get_all_keys(), + (None, Some(limit)) => self + .idb_store + .get_all_keys_with_key_and_limit(&JsValue::UNDEFINED, limit), + (Some(key_range), None) => self.idb_store.get_all_keys_with_key(key_range.as_ref()), + (Some(key_range), Some(limit)) => self + .idb_store + .get_all_keys_with_key_and_limit(key_range.as_ref(), limit), + } + .map_err(Error::IndexedDbRequestError)?; + wait_request(request, Error::IndexedDbRequestError).await } diff --git a/tests/web.rs b/tests/web.rs index 43a8cf7..6da56a8 100644 --- a/tests/web.rs +++ b/tests/web.rs @@ -135,10 +135,10 @@ async fn get_employee(rexie: &Rexie, id: u32) -> Result> { assert!(employees.is_ok()); let employees = employees.unwrap(); - let employee = employees.get(&id.into()).await?; - let employee: Option = serde_wasm_bindgen::from_value(employee).unwrap(); - - Ok(employee) + Ok(employees + .get(&id.into()) + .await? + .map(|value| serde_wasm_bindgen::from_value::(value).unwrap())) } async fn get_all_employees(rexie: &Rexie, direction: Option) -> Result> { @@ -228,8 +228,8 @@ async fn get_invoice(rexie: &Rexie, id: usize, year: u16) -> Result = serde_wasm_bindgen::from_value(invoice).unwrap(); + .await? + .map(|value| serde_wasm_bindgen::from_value(value).unwrap()); Ok(invoice) }