use idb::Index;
use wasm_bindgen::JsValue;
use crate::{Direction, KeyRange, Result};
pub struct StoreIndex {
pub(crate) index: Index,
}
impl StoreIndex {
pub fn name(&self) -> String {
self.index.name()
}
pub fn unique(&self) -> bool {
self.index.unique()
}
pub fn multi_entry(&self) -> bool {
self.index.multi_entry()
}
pub async fn get(&self, key: JsValue) -> Result<Option<JsValue>> {
self.index.get(key)?.await.map_err(Into::into)
}
pub async fn get_all_keys(
&self,
key_range: Option<KeyRange>,
limit: Option<u32>,
) -> Result<Vec<JsValue>> {
self.index
.get_all_keys(key_range.map(Into::into), limit)?
.await
.map_err(Into::into)
}
pub async fn get_all(
&self,
key_range: Option<KeyRange>,
limit: Option<u32>,
) -> Result<Vec<JsValue>> {
self.index
.get_all(key_range.map(Into::into), limit)?
.await
.map_err(Into::into)
}
pub async fn scan(
&self,
key_range: Option<KeyRange>,
limit: Option<u32>,
offset: Option<u32>,
direction: Option<Direction>,
) -> Result<Vec<(JsValue, JsValue)>> {
let cursor = self
.index
.open_cursor(key_range.map(Into::into), direction)?
.await?;
match cursor {
None => Ok(Vec::new()),
Some(cursor) => {
let mut cursor = cursor.into_managed();
let mut result = Vec::new();
match limit {
Some(limit) => {
if let Some(offset) = offset {
cursor.advance(offset).await?;
}
for _ in 0..limit {
let key = cursor.key()?;
let value = cursor.value()?;
match (key, value) {
(Some(key), Some(value)) => {
result.push((key, value));
cursor.next(None).await?;
}
_ => break,
}
}
}
None => {
if let Some(offset) = offset {
cursor.advance(offset).await?;
}
loop {
let key = cursor.key()?;
let value = cursor.value()?;
match (key, value) {
(Some(key), Some(value)) => {
result.push((key, value));
cursor.next(None).await?;
}
_ => break,
}
}
}
}
Ok(result)
}
}
}
pub async fn count(&self, key_range: Option<KeyRange>) -> Result<u32> {
self.index
.count(key_range.map(Into::into))?
.await
.map_err(Into::into)
}
}