mod catalog;
pub(crate) mod generated;
mod integrity;
mod request;
#[cfg(feature = "sql")]
mod sql;
mod write;
use crate::{metrics::MetricsSink, traits::CanisterKind};
use icydb_core as core;
use std::{error::Error as StdError, fmt};
pub use integrity::IntegrityCheckError;
#[cfg(feature = "sql")]
pub use integrity::SqlIntegrityError;
pub use request::{
RequestExecutionFuture, RequestExecutionRoot, with_request_execution,
with_request_execution_async, with_request_execution_root,
};
#[cfg(feature = "sql")]
pub use sql::{
SqlExecutionPerfAttribution, SqlPureCoveringPerfAttribution, SqlQueryPerfAttribution,
};
pub use write::{
OutputRow, StructuralMutation, StructuralPatch, TypedAdapterError, TypedBindingError,
TypedEntityAdapter, TypedEntityBinding, TypedRowAdapter, TypedRowError, TypedWrite,
TypedWriteAdapter, TypedWriteError, WriteCell,
};
#[derive(Debug)]
pub enum ExhaustiveReadError {
Database(crate::Error),
Revision(core::db::ReadSetRevisionError),
}
impl fmt::Display for ExhaustiveReadError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Database(error) => error.fmt(formatter),
Self::Revision(error) => error.fmt(formatter),
}
}
}
impl StdError for ExhaustiveReadError {}
impl From<core::db::ExhaustiveReadError> for ExhaustiveReadError {
fn from(error: core::db::ExhaustiveReadError) -> Self {
match error {
core::db::ExhaustiveReadError::Query(error) => Self::Database(error.into()),
core::db::ExhaustiveReadError::Revision(error) => Self::Revision(error),
}
}
}
#[doc(hidden)]
pub use write::{TypedFieldBindingRequest, TypedFieldType};
pub struct DbSession<C: CanisterKind> {
inner: core::db::DbSession<C>,
}
impl<C: CanisterKind> DbSession<C> {
#[must_use]
pub const fn new(session: core::db::DbSession<C>) -> Self {
Self { inner: session }
}
#[doc(hidden)]
pub fn __continue_startup_recovery(&self) -> Result<bool, crate::Error> {
self.inner.__continue_startup_recovery().map_err(Into::into)
}
#[must_use]
pub fn debug(mut self) -> Self {
self.inner = self.inner.debug();
self
}
#[must_use]
pub fn metrics_sink(mut self, sink: &'static dyn MetricsSink) -> Self {
self.inner = self.inner.metrics_sink(sink);
self
}
#[cfg(feature = "diagnostics")]
#[must_use]
pub fn enable_request_diagnostics(&self) -> bool {
self.inner.enable_request_diagnostics()
}
#[cfg(feature = "diagnostics")]
#[must_use]
pub fn request_diagnostics(&self) -> Option<crate::db::RequestDiagnostics> {
self.inner.request_diagnostics()
}
pub fn execute_live_page(
&self,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
) -> Result<crate::db::LiveQueryPageOutput, crate::Error> {
self.inner
.execute_public_live_page(request, continuation)
.map_err(Into::into)
}
pub fn execute_trusted_live_page(
&self,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
) -> Result<crate::db::LiveQueryPageOutput, crate::Error> {
self.inner
.execute_trusted_live_page(request, continuation)
.map_err(Into::into)
}
pub fn capture_read_set_revision_proof(
&self,
entity_names: &[&str],
) -> Result<crate::db::ReadSetRevisionProof, ExhaustiveReadError> {
self.inner
.capture_read_set_revision_proof(entity_names)
.map_err(Into::into)
}
pub fn execute_exhaustive_page(
&self,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
proof: Option<&crate::db::ReadSetRevisionProof>,
) -> Result<crate::db::ExhaustiveQueryPageOutput, ExhaustiveReadError> {
self.inner
.execute_public_exhaustive_page(request, continuation, proof)
.map_err(Into::into)
}
pub fn execute_trusted_exhaustive_page(
&self,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
proof: Option<&crate::db::ReadSetRevisionProof>,
) -> Result<crate::db::ExhaustiveQueryPageOutput, ExhaustiveReadError> {
self.inner
.execute_trusted_exhaustive_page(request, continuation, proof)
.map_err(Into::into)
}
#[cfg(feature = "sql")]
pub fn start_trusted_sql_mutation_job(
&self,
job_id: crate::db::MutationJobId,
sql: &str,
) -> Result<crate::db::MutationJobState, crate::db::MutationJobError> {
self.inner.start_trusted_sql_mutation_job(job_id, sql)
}
pub fn mutation_job_state(
&self,
job_id: crate::db::MutationJobId,
) -> Result<crate::db::MutationJobState, crate::db::MutationJobError> {
self.inner.mutation_job_state(job_id)
}
#[cfg(feature = "sql")]
pub fn advance_trusted_mutation_job(
&self,
request: &crate::db::MutationJobAdvanceRequest,
) -> Result<crate::db::MutationJobAdvanceReceipt, crate::db::MutationJobError> {
self.inner.advance_trusted_mutation_job(request)
}
pub fn acknowledge_mutation_job(
&self,
job_id: crate::db::MutationJobId,
expected_terminal_sequence: u64,
) -> Result<(), crate::db::MutationJobError> {
self.inner
.acknowledge_mutation_job(job_id, expected_terminal_sequence)
}
pub fn start_resumable_job(
&self,
job_id: crate::db::ResumableJobId,
proof: crate::db::ReadSetRevisionProof,
initial_application_state: Vec<u8>,
) -> Result<crate::db::ResumableJobState, crate::db::ResumableJobError> {
self.inner
.start_resumable_job(job_id, proof, initial_application_state)
}
pub fn resumable_job_state(
&self,
job_id: crate::db::ResumableJobId,
) -> Result<crate::db::ResumableJobState, crate::db::ResumableJobError> {
self.inner.resumable_job_state(job_id)
}
pub fn acknowledge_resumable_job(
&self,
job_id: crate::db::ResumableJobId,
expected_sequence: u64,
) -> Result<(), crate::db::ResumableJobError> {
self.inner
.acknowledge_resumable_job(job_id, expected_sequence)
}
pub fn compare_proof_and_advance<E>(
&self,
request: &crate::db::ResumableJobAdvanceRequest,
operation: impl FnOnce(
&crate::db::ResumableJobState,
) -> Result<crate::db::ResumableJobAdvance, E>,
) -> Result<crate::db::ResumableJobAdvanceReceipt, crate::db::CompareProofAndAdvanceError<E>>
{
self.inner.compare_proof_and_advance(request, operation)
}
pub fn execute_public_dynamic_grouped_query(
&self,
request: &crate::db::DynamicQuery,
) -> Result<crate::db::GroupedQueryOutput, crate::Error> {
self.inner
.execute_public_dynamic_grouped_query(request)
.map_err(Into::into)
}
pub fn execute_trusted_dynamic_grouped_query(
&self,
request: &crate::db::DynamicQuery,
) -> Result<crate::db::GroupedQueryOutput, crate::Error> {
self.inner
.execute_trusted_dynamic_grouped_query(request)
.map_err(Into::into)
}
pub(crate) fn execute_public_typed_live_page(
&self,
binding: &TypedEntityBinding,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
) -> Result<Option<crate::db::LiveQueryPageOutput>, crate::Error> {
self.inner
.execute_public_live_page_for_typed_binding(binding.inner(), request, continuation)
.map_err(Into::into)
}
pub(crate) fn execute_public_typed_exhaustive_page(
&self,
binding: &TypedEntityBinding,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
proof: Option<&crate::db::ReadSetRevisionProof>,
) -> Result<Option<crate::db::ExhaustiveQueryPageOutput>, ExhaustiveReadError> {
self.inner
.execute_public_exhaustive_page_for_typed_binding(
binding.inner(),
request,
continuation,
proof,
)
.map_err(Into::into)
}
pub(crate) fn execute_public_typed_dynamic_grouped_query(
&self,
binding: &TypedEntityBinding,
request: &crate::db::DynamicQuery,
) -> Result<Option<crate::db::GroupedQueryOutput>, crate::Error> {
self.inner
.execute_public_dynamic_grouped_query_for_typed_binding(binding.inner(), request)
.map_err(Into::into)
}
pub(crate) fn execute_public_typed_exact_key_batch<K>(
&self,
binding: &TypedEntityBinding,
keys: &[K],
) -> Result<Option<core::db::ExactKeyBatchProjectionOutput>, crate::Error>
where
K: core::db::PrimaryKeyEncode,
{
self.inner
.execute_public_exact_key_batch_for_typed_binding(binding.inner(), keys)
.map_err(Into::into)
}
}