use crate::{
db::{
Db,
data::{DecodedDataStoreKey, RawRow},
index::{IndexEntryValue, IndexStore, RawIndexStoreKey},
key_taxonomy::PrimaryKeyValue,
},
error::InternalError,
traits::CanisterKind,
types::EntityTag,
};
use std::{cell::RefCell, ops::Bound, thread::LocalKey};
#[derive(Clone, Copy)]
pub(in crate::db) struct IndexReadContract<'a> {
store_path: &'a str,
unique: bool,
}
impl<'a> IndexReadContract<'a> {
#[must_use]
pub(in crate::db) const fn new(store_path: &'a str, unique: bool) -> Self {
Self { store_path, unique }
}
#[must_use]
pub(in crate::db) const fn store_path(self) -> &'a str {
self.store_path
}
#[must_use]
pub(in crate::db) const fn unique(self) -> bool {
self.unique
}
}
pub(in crate::db) trait StructuralPrimaryRowReader {
fn read_primary_row(&self, key: &DecodedDataStoreKey) -> Result<Option<RawRow>, InternalError>;
fn has_primary_row_override(&self, _key: &DecodedDataStoreKey) -> Result<bool, InternalError> {
Ok(false)
}
}
impl<C: CanisterKind> StructuralPrimaryRowReader for Db<C> {
fn read_primary_row(&self, key: &DecodedDataStoreKey) -> Result<Option<RawRow>, InternalError> {
let runtime_entity = self.accepted_runtime_entity_for_tag(key.entity_tag())?;
let store = self.recovered_store(runtime_entity.store_path())?;
let raw_key = key.to_raw()?;
Ok(store.with_data(|data_store| data_store.get(&raw_key)))
}
}
pub(in crate::db) trait StructuralIndexEntryReader {
fn read_index_entry(
&self,
index_store: &'static LocalKey<RefCell<IndexStore>>,
key: &RawIndexStoreKey,
) -> Result<Option<IndexEntryValue>, InternalError>;
fn read_index_keys_in_raw_range(
&self,
entity_path: &str,
entity_tag: EntityTag,
index_store: &'static LocalKey<RefCell<IndexStore>>,
index: IndexReadContract<'_>,
bounds: (&Bound<RawIndexStoreKey>, &Bound<RawIndexStoreKey>),
limit: usize,
) -> Result<Vec<PrimaryKeyValue>, InternalError>;
}