Skip to content

Commit

Permalink
Small API expansion & docs (#26)
Browse files Browse the repository at this point in the history
* Added getAllKeys APIs support

* get() now returns an option

* Fixed the documentation

* Renamed all_keys to get_all_keys for consistency

---------

Co-authored-by: Mathieu Amiot <[email protected]>
  • Loading branch information
John-Toohey and OtaK authored Jul 4, 2024
1 parent c6bce19 commit fd76da2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_json::Value> = serde_wasm_bindgen::from_value(employee).unwrap();
Expand Down
29 changes: 28 additions & 1 deletion src/transaction/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,39 @@ impl StoreIndex {
}

/// Gets a value from the store with given key
pub async fn get(&self, key: &JsValue) -> Result<JsValue> {
pub async fn get(&self, key: &JsValue) -> Result<Option<JsValue>> {
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<u32>,
) -> Result<JsValue> {
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
}

Expand Down
55 changes: 50 additions & 5 deletions src/transaction/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<String>> {
self.idb_store
.key_path()
Expand All @@ -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<String> {
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);
}
Expand All @@ -51,19 +55,60 @@ 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<StoreIndex> {
let idb_index = self.idb_store.index(name).map_err(Error::IndexOpenFailed)?;

Ok(StoreIndex::new(idb_index))
}

/// Gets a value from the store with given key
pub async fn get(&self, key: &JsValue) -> Result<JsValue> {
/// MDN Reference: [IDBObjectStore/get](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/get)
pub async fn get(&self, key: &JsValue) -> Result<Option<JsValue>> {
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<bool> {
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<u32>,
) -> Result<JsValue> {
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
}

Expand Down
12 changes: 6 additions & 6 deletions tests/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ async fn get_employee(rexie: &Rexie, id: u32) -> Result<Option<Employee>> {
assert!(employees.is_ok());
let employees = employees.unwrap();

let employee = employees.get(&id.into()).await?;
let employee: Option<Employee> = serde_wasm_bindgen::from_value(employee).unwrap();

Ok(employee)
Ok(employees
.get(&id.into())
.await?
.map(|value| serde_wasm_bindgen::from_value::<Employee>(value).unwrap()))
}

async fn get_all_employees(rexie: &Rexie, direction: Option<Direction>) -> Result<Vec<Employee>> {
Expand Down Expand Up @@ -228,8 +228,8 @@ async fn get_invoice(rexie: &Rexie, id: usize, year: u16) -> Result<Option<Invoi

let invoice = invoices
.get(&Array::of2(&JsValue::from_f64(id as _), &JsValue::from_f64(year as _)).into())
.await?;
let invoice: Option<Invoice> = serde_wasm_bindgen::from_value(invoice).unwrap();
.await?
.map(|value| serde_wasm_bindgen::from_value(value).unwrap());

Ok(invoice)
}
Expand Down

0 comments on commit fd76da2

Please sign in to comment.