Skip to main content

icydb_core/db/session/
mod.rs

1//! Module: session
2//! Responsibility: user-facing query/write execution facade over db executors.
3//! Does not own: planning semantics, cursor validation rules, or storage mutation protocol.
4//! Boundary: converts fluent/query intent calls into executor operations and response DTOs.
5
6mod accepted_schema;
7mod catalog;
8mod integrity;
9mod mutation_job;
10mod query;
11mod read_set;
12mod response;
13mod resumable_job;
14#[cfg(feature = "sql")]
15mod sql;
16mod write;
17
18#[cfg(all(test, feature = "sql"))]
19mod tests;
20
21use crate::{
22    db::{Db, StoreRegistry},
23    traits::CanisterKind,
24};
25use std::thread::LocalKey;
26
27use crate::db::resource::request::{RequestBudgetSnapshot, RequestExecutionRoot};
28#[cfg(feature = "sql")]
29pub(in crate::db) use query::QueryPlanCacheReuse;
30#[doc(hidden)]
31pub use query::{
32    MAX_TYPED_EXACT_KEY_BATCH_INPUT_BYTES, MAX_TYPED_EXACT_KEY_BATCH_ITEMS,
33    MAX_TYPED_EXACT_KEY_BATCH_RESULT_BYTES, MAX_TYPED_EXACT_KEY_BATCH_STORED_BYTES,
34};
35pub(in crate::db) use response::finalize_structural_grouped_projection_result;
36pub(in crate::db) use response::grouped_cursor_from_bytes;
37#[cfg(feature = "sql")]
38pub use sql::{
39    SqlConstraintValidationPage, SqlConstraintValidationRevisionStatus,
40    SqlConstraintValidationState, SqlDdlExecutionStatus, SqlDdlMutationKind,
41    SqlDdlPreparationReport, SqlIntegrityError, SqlStatementDispatch, SqlStatementResult,
42    SqlStatementShellSurface, SqlStatementSurface, sql_statement_dispatch,
43    sql_statement_shell_surface, sql_statement_surface,
44};
45
46///
47/// DbSession
48///
49/// Session-scoped database handle with execution routing.
50///
51
52pub struct DbSession<C: CanisterKind> {
53    db: Db<C>,
54    #[cfg(feature = "sql")]
55    sql_returning_response_len:
56        fn(crate::db::RowProjectionOutput) -> Result<usize, icydb_schema::wire::Error>,
57}
58
59impl<C: CanisterKind> DbSession<C> {
60    /// Select the outward Wire projection envelope for precommit SQL bounds.
61    ///
62    /// The encoder must preserve `RowProjectionOutput`'s value encoding inside
63    /// a fixed envelope independent of row contents. The facade installs its
64    /// actual public response encoder; raw core sessions encode the projection.
65    /// This is session-local framing, not schema authority or mutation policy.
66    #[cfg(feature = "sql")]
67    #[doc(hidden)]
68    #[must_use]
69    pub const fn __with_sql_returning_response_len(
70        mut self,
71        encode: fn(crate::db::RowProjectionOutput) -> Result<usize, icydb_schema::wire::Error>,
72    ) -> Self {
73        self.sql_returning_response_len = encode;
74        self
75    }
76
77    /// Snapshot the aggregate request budget shared by this session's root.
78    ///
79    /// Reads the retained owner even outside its active call tree; observing
80    /// capacity neither charges work nor reserves the next execution.
81    #[must_use]
82    pub fn request_budget(&self) -> RequestBudgetSnapshot {
83        self.db.request_scope.request_budget()
84    }
85
86    /// Construct one session facade over a sealed runtime store registry.
87    #[must_use]
88    pub fn new(
89        store: &'static LocalKey<StoreRegistry>,
90        request_root: &RequestExecutionRoot,
91    ) -> Self {
92        Self {
93            db: Db::new(store, request_root.scope()),
94            #[cfg(feature = "sql")]
95            sql_returning_response_len: sql::encoded_returning_response_len,
96        }
97    }
98
99    /// Drive one bounded startup page while retaining its persisted failure owner.
100    pub(in crate::db) fn drive_startup_recovery_page_with_failure_authority(
101        &self,
102    ) -> Result<bool, crate::db::commit::StartupRecoveryFailure> {
103        self.db.drive_startup_recovery_page_with_failure_authority()
104    }
105
106    /// Construct a session from the active synchronous request scope.
107    ///
108    /// Generated zero-argument `db!()` wiring uses this entry. `None` means
109    /// that the caller did not establish a request execution boundary.
110    #[doc(hidden)]
111    #[must_use]
112    pub fn __new_from_current_request(store: &'static LocalKey<StoreRegistry>) -> Option<Self> {
113        crate::db::resource::request::current_request_scope().map(|scope| Self {
114            db: Db::new(store, scope),
115            #[cfg(feature = "sql")]
116            sql_returning_response_len: sql::encoded_returning_response_len,
117        })
118    }
119}