mod catalog;
pub(crate) mod generated;
mod integrity;
mod live_page;
mod prepared_query;
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 live_page::LivePageStep;
pub use prepared_query::{PreparedExactKeyOutput, PreparedLivePageCursor, PreparedLivePageOutput};
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(crate) use write::OutputRowProjection;
pub use write::{
BoundWriteEncoder, OutputRow, PreparedOutputRows, StructuralMutation, StructuralPatch,
TrustedTypedWriteBatch, TypedAdapterError, TypedBindingError, TypedEntityAdapter,
TypedEntityBinding, TypedRowAdapter, TypedRowError, TypedWrite, TypedWriteAdapter,
TypedWriteBatchResult, TypedWriteBatchResults, TypedWriteError, TypedWriteHandle, 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::{TypedEntityDescriptor, TypedFieldDescriptor, 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 __drive_generated_startup_recovery_page(
&self,
stores: &'static std::thread::LocalKey<core::db::StoreRegistry>,
submission_key: &str,
) -> Result<core::db::GeneratedStartupDriverStep, crate::Error> {
core::db::drive_generated_startup_recovery_page(&self.inner, stores, submission_key)
.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_live_page_with_attribution(
&self,
request: &crate::db::DynamicQuery,
continuation: Option<&str>,
) -> Result<crate::db::AttributedRead<crate::db::LiveQueryPageOutput>, crate::Error> {
self.inner
.execute_public_live_page_with_attribution(request, continuation)
.map_err(Into::into)
}
pub fn execute_exact_count(
&self,
request: &crate::db::DynamicQuery,
) -> Result<u64, crate::Error> {
self.inner
.execute_public_exact_count(request)
.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)
}
#[cfg(feature = "sql")]
pub fn cancel_unadvanced_mutation_job(
&self,
job_id: crate::db::MutationJobId,
expected_sequence: u64,
) -> Result<(), crate::db::MutationJobError> {
self.inner
.cancel_unadvanced_mutation_job(job_id, expected_sequence)
}
pub fn progress_job_inventory(
&self,
) -> Result<crate::db::ProgressJobInventory, crate::db::MutationJobError> {
self.inner.progress_job_inventory()
}
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_exact_count(
&self,
binding: &TypedEntityBinding,
request: &crate::db::DynamicQuery,
) -> Result<Option<u64>, crate::Error> {
self.inner
.execute_public_exact_count_for_typed_binding(binding.inner(), request)
.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)
}
}