#![allow(missing_docs)]
use crate::debug::TableEntry;
use crate::Database;
use crate::Query;
use crate::QueryTable;
use crate::QueryTableMut;
use crate::SweepStrategy;
use std::fmt::Debug;
use std::hash::Hash;
pub use crate::derived::DependencyStorage;
pub use crate::derived::MemoizedStorage;
pub use crate::derived::VolatileStorage;
pub use crate::input::InputStorage;
pub use crate::runtime::Revision;
pub struct CycleDetected;
pub trait DatabaseStorageTypes: Sized {
type DatabaseKey: DatabaseKey<Self>;
type DatabaseStorage: Default;
}
pub trait DatabaseOps: Sized {
fn for_each_query(&self, op: impl FnMut(&dyn QueryStorageMassOps<Self>));
}
pub trait QueryStorageMassOps<DB: Database> {
fn sweep(&self, db: &DB, strategy: SweepStrategy);
}
pub trait DatabaseKey<DB>: Clone + Debug + Eq + Hash + Send + Sync {
fn maybe_changed_since(&self, db: &DB, revision: Revision) -> bool;
}
pub trait QueryFunction<DB: Database>: Query<DB> {
fn execute(db: &DB, key: Self::Key) -> Self::Value;
}
pub trait GetQueryTable<Q: Query<Self>>: Database {
fn get_query_table(db: &Self) -> QueryTable<'_, Self, Q>;
fn get_query_table_mut(db: &mut Self) -> QueryTableMut<'_, Self, Q>;
fn database_key(db: &Self, key: Q::Key) -> Self::DatabaseKey;
}
impl<DB, Q> GetQueryTable<Q> for DB
where
DB: Database,
Q: Query<DB>,
DB: HasQueryGroup<Q::Group>,
{
fn get_query_table(db: &DB) -> QueryTable<'_, DB, Q> {
let group_storage: &Q::GroupStorage = HasQueryGroup::group_storage(db);
let query_storage = Q::group_storage(group_storage);
QueryTable::new(db, query_storage)
}
fn get_query_table_mut(db: &mut DB) -> QueryTableMut<'_, DB, Q> {
let db = &*db;
let group_storage: &Q::GroupStorage = HasQueryGroup::group_storage(db);
let query_storage = Q::group_storage(group_storage);
QueryTableMut::new(db, query_storage)
}
fn database_key(
_db: &DB,
key: <Q as Query<DB>>::Key,
) -> <DB as DatabaseStorageTypes>::DatabaseKey {
let group_key = Q::group_key(key);
<DB as HasQueryGroup<_>>::database_key(group_key)
}
}
pub trait QueryGroup<DB: Database> {
type GroupStorage;
type GroupKey;
}
pub trait HasQueryGroup<G>: Database
where
G: QueryGroup<Self>,
{
fn group_storage(db: &Self) -> &G::GroupStorage;
fn database_key(group_key: G::GroupKey) -> Self::DatabaseKey;
}
pub trait QueryStorageOps<DB, Q>: Default
where
Self: QueryStorageMassOps<DB>,
DB: Database,
Q: Query<DB>,
{
fn try_fetch(
&self,
db: &DB,
key: &Q::Key,
descriptor: &DB::DatabaseKey,
) -> Result<Q::Value, CycleDetected>;
fn maybe_changed_since(
&self,
db: &DB,
revision: Revision,
key: &Q::Key,
descriptor: &DB::DatabaseKey,
) -> bool;
fn is_constant(&self, db: &DB, key: &Q::Key) -> bool;
fn entries<C>(&self, db: &DB) -> C
where
C: std::iter::FromIterator<TableEntry<Q::Key, Q::Value>>;
}
pub trait InputQueryStorageOps<DB, Q>: Default
where
DB: Database,
Q: Query<DB>,
{
fn set(&self, db: &DB, key: &Q::Key, descriptor: &DB::DatabaseKey, new_value: Q::Value);
fn set_constant(
&self,
db: &DB,
key: &Q::Key,
descriptor: &DB::DatabaseKey,
new_value: Q::Value,
);
}
pub trait UncheckedMutQueryStorageOps<DB, Q>: Default
where
DB: Database,
Q: Query<DB>,
{
fn set_unchecked(&self, db: &DB, key: &Q::Key, new_value: Q::Value);
}