Skip to main content

delta_funnel/orchestrator/
session.rs

1//! Rust backing model for lazy query-load orchestration.
2//!
3//! This module owns the high-level session and request data shapes that will
4//! later back the Python `Session` and `Table` API. Metadata report helpers do
5//! not contact SQL Server or execute rows unless a write path explicitly does so.
6
7mod dry_run_report;
8mod errors;
9mod handles;
10mod options;
11mod query_handoff;
12mod registry;
13mod source_report;
14mod sql_server_workflows;
15#[cfg(test)]
16mod test_support;
17
18use std::fmt;
19
20use datafusion::prelude::SessionContext;
21
22use crate::{DeltaFunnelError, datafusion_session_context};
23
24pub use crate::report::delta::SourceUsageStatus;
25pub use handles::{
26    LazyTable, LazyTableKind, MssqlOutputTarget, OutputWritePlan, PlannedMssqlOutput, RunMode,
27};
28pub use options::SessionOptions;
29pub use registry::{RegisteredDerivedTable, RegisteredSessionSource};
30pub use sql_server_workflows::{WriteAllCacheMode, WriteAllOptions};
31
32pub use crate::report::sql_server::MssqlDryRunOutputReport;
33use registry::PendingDerivedTable;
34#[cfg(test)]
35pub(crate) use sql_server_workflows::OrchestratorMssqlOutputWriter;
36
37/// Rust backing session for lazy query-load workflows.
38pub struct DeltaFunnelSession {
39    options: SessionOptions,
40    context: SessionContext,
41    next_table_id: u64,
42    sources: Vec<RegisteredSessionSource>,
43    derived_tables: Vec<RegisteredDerivedTable>,
44    pending_derived_tables: Vec<PendingDerivedTable>,
45}
46
47impl DeltaFunnelSession {
48    /// Builds a new session with validated local options.
49    ///
50    /// # Errors
51    ///
52    /// Returns the first local option validation failure before any source
53    /// loading, SQL planning, SQL Server connection, or row execution.
54    pub fn new(options: SessionOptions) -> Result<Self, DeltaFunnelError> {
55        options.validate()?;
56        let context = datafusion_session_context(options.query_options())?;
57        Ok(Self {
58            options,
59            context,
60            next_table_id: 0,
61            sources: Vec::new(),
62            derived_tables: Vec::new(),
63            pending_derived_tables: Vec::new(),
64        })
65    }
66
67    /// Returns the validated session options.
68    #[must_use]
69    pub const fn options(&self) -> &SessionOptions {
70        &self.options
71    }
72
73    /// Returns the DataFusion session context owned by this orchestrator.
74    ///
75    /// The session context is exposed so later planning steps can analyze SQL
76    /// against registered session aliases. Delta source registration should
77    /// still go through [`DeltaFunnelSession::delta_lake`] so the orchestrator's
78    /// source reports stay aligned with the DataFusion catalog.
79    #[must_use]
80    pub const fn context(&self) -> &SessionContext {
81        &self.context
82    }
83
84    /// Returns the next unassigned session-local lazy table id.
85    #[must_use]
86    pub const fn next_table_id(&self) -> u64 {
87        self.next_table_id
88    }
89}
90
91impl fmt::Debug for DeltaFunnelSession {
92    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
93        formatter
94            .debug_struct("DeltaFunnelSession")
95            .field("options", &self.options)
96            .field("sources", &self.sources)
97            .field("derived_tables", &self.derived_tables)
98            .field("next_table_id", &self.next_table_id)
99            .finish_non_exhaustive()
100    }
101}