diff --git a/Cargo.lock b/Cargo.lock index b9d13af357..d2737da3f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1286,6 +1286,13 @@ dependencies = [ "tempfile", ] +[[package]] +name = "sqlbuild-host" +version = "0.164.0" +dependencies = [ + "sqlbuild-core", +] + [[package]] name = "sqlbuild-model-config" version = "0.164.0" @@ -1324,6 +1331,7 @@ dependencies = [ "sqlbuild-core", "sqlbuild-cursor", "sqlbuild-discovery", + "sqlbuild-host", "sqlbuild-model-config", "sqlbuild-pysource", "sqlbuild-recall", diff --git a/Cargo.toml b/Cargo.toml index 63d94fcfd5..71c8b3c0ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "crates/sqlbuild-cache", "crates/sqlbuild-sqltext", "crates/sqlbuild-config", + "crates/sqlbuild-host", "crates/sqlbuild-recall", "crates/sqlbuild-discovery", "crates/sqlbuild-scopes", @@ -33,6 +34,7 @@ order = [ "sqlbuild-cache", "sqlbuild-sqltext", "sqlbuild-config", + "sqlbuild-host", "sqlbuild-recall", "sqlbuild-model-config", "sqlbuild-discovery", @@ -105,6 +107,7 @@ sqlbuild-config = { path = "crates/sqlbuild-config" } sqlbuild-core = { path = "crates/sqlbuild-core" } sqlbuild-cursor = { path = "crates/sqlbuild-cursor" } sqlbuild-discovery = { path = "crates/sqlbuild-discovery" } +sqlbuild-host = { path = "crates/sqlbuild-host" } sqlbuild-render = { path = "crates/sqlbuild-render" } sqlbuild-refactor = { path = "crates/sqlbuild-refactor" } sqlbuild-rules = { path = "crates/sqlbuild-rules" } diff --git a/crates/README.md b/crates/README.md index ec54e19504..9f316d1b3e 100644 --- a/crates/README.md +++ b/crates/README.md @@ -13,6 +13,7 @@ that can be tested and benchmarked with `cargo test` alone. | `sqlbuild-cache` | The shared native store every native cache uses (one atomically replaced, checksummed file per cache kind, keyed by content digests) and the one fingerprinting scheme for cache keys: the content digest and the project file fingerprint. | | `sqlbuild-sqltext` | Lexical SQL text without polyglot: comment, quote and parenthesis scanning, the rules quote policy, model header tokenization and matching, static variable substitution, static reference extraction, and the general reference scan with table-function call arguments under each adapter's lexical rules. | | `sqlbuild-config` | Configuration file reading without Python: TOML, YAML 1.2 with the core schema and merge keys, and typed project and local config readers for the fields discovery needs. It also writes the workspace files `sqb playground` and `sqb skills` create from packaged templates and skills. Errors carry their kind and position; YAML outside the supported subset is an `Unsupported` error. | +| `sqlbuild-host` | The contract of the permanent Python edges as plain Rust: the catalogue of `sqlbuild._native_host` entries and the trait that resolves them, the per-thread compile timing collector with its process clock, the compile diagnostic sink, and the executor result types the Python result dataclasses and enums mirror. `sqlbuild-python` implements the traits. | | `sqlbuild-discovery` | Native project discovery and the only implementation of the model, SQL test, scenario, source and schema file collections and the declaration layout: the shared directory walk with Python's glob and sort semantics, file reading with Python's newline handling and read errors, and parsing of authored files with Python's exact discovery messages. Results are plain data the Python discovery facade materialises. | | `sqlbuild-scopes` | Declaration scopes, visibility, relationship grants, placement, report queries and the offline scope cache, including dialect-aware SQL-test and scenario scans. | | `sqlbuild-model-config` | MODEL configuration, columns and audits, template expansion over caller values, and dynamic-column name patterns using Rust regex syntax. | @@ -31,8 +32,8 @@ Dependencies point one way, from the top of this graph to the bottom: ```text sqlbuild-python -> sqlbuild-refactor -> sqlbuild-rules -> sqlbuild-analysis -> sqlbuild-attachments - -> sqlbuild-model-config -> sqlbuild-scopes -> sqlbuild-render -> sqlbuild-discovery -> sqlbuild-config - -> sqlbuild-sqltext -> sqlbuild-cache -> sqlbuild-pysource -> sqlbuild-state -> sqlbuild-cursor -> sqlbuild-core + -> sqlbuild-model-config -> sqlbuild-scopes -> sqlbuild-render -> sqlbuild-discovery -> sqlbuild-host + -> sqlbuild-config -> sqlbuild-sqltext -> sqlbuild-cache -> sqlbuild-pysource -> sqlbuild-state -> sqlbuild-cursor -> sqlbuild-core sqlbuild-cli -> sqlbuild-cache, sqlbuild-core ``` @@ -58,6 +59,14 @@ version other than its manifest's, because the version is part of the build iden `fensu check` applies the Rust structure rules inside each crate: other crates use items through `main/` entry points, `models.rs`, `types.rs` and `constants.rs`, not through `_helpers/`. +Inside `sqlbuild-python`, the custom rule XSB075 orders the `bindings/_helpers` modules in layers +that follow the planned crate split: shared Python plumbing (`infra`), then the glue of the lower +crates (`front`), the compiled project (`project`), planning and compilation as siblings (`plan`, +`compile`), command output (`output`), command handlers (`commands`) and registration +(`registry`). A module may import only from lower layers; `plan` and `compile` may not import each +other. `module_layers` in `fensu.toml` assigns every helper module a layer. `pending_budgets` is +empty: every import points down, and a new upward import fails the check. + ## Python module paths `sqlbuild-python` and `sqlbuild-cli` import Python by module path strings. The repository test diff --git a/crates/sqlbuild-host/Cargo.toml b/crates/sqlbuild-host/Cargo.toml new file mode 100644 index 0000000000..2ab1f950f4 --- /dev/null +++ b/crates/sqlbuild-host/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sqlbuild-host" +version.workspace = true +description = "The contract of the permanent Python edges: host entries and traits, compile timings, diagnostics and executor results." +edition.workspace = true +license.workspace = true +publish.workspace = true +rust-version.workspace = true + +[dependencies] +sqlbuild-core.workspace = true + +[lints] +workspace = true diff --git a/crates/sqlbuild-host/src/compile_context/_helpers/active.rs b/crates/sqlbuild-host/src/compile_context/_helpers/active.rs new file mode 100644 index 0000000000..dc30140e1e --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/_helpers/active.rs @@ -0,0 +1,21 @@ +//! The thread's active collector slot. + +use std::cell::RefCell; + +use crate::compile_context::types::CompileTimingsHandle; + +thread_local! { + static ACTIVE: RefCell> = const { RefCell::new(None) }; +} + +/// Make `collector` the thread's active collector; return the one it replaces. +pub(crate) fn replace_active( + collector: Option, +) -> Option { + ACTIVE.with(|active| active.replace(collector)) +} + +/// The thread's active collector, if a compile is collecting. +pub(crate) fn active() -> Option { + ACTIVE.with(|active| active.borrow().clone()) +} diff --git a/crates/sqlbuild-host/src/compile_context/_helpers/mod.rs b/crates/sqlbuild-host/src/compile_context/_helpers/mod.rs new file mode 100644 index 0000000000..45b46e7edf --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/_helpers/mod.rs @@ -0,0 +1 @@ +pub(crate) mod active; diff --git a/crates/sqlbuild-host/src/compile_context/main/add_compile_timing.rs b/crates/sqlbuild-host/src/compile_context/main/add_compile_timing.rs new file mode 100644 index 0000000000..b1709cc841 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/add_compile_timing.rs @@ -0,0 +1,14 @@ +//! Add elapsed time to one compile phase. + +use crate::compile_context::_helpers::active::active; + +/// Add elapsed nanoseconds to a phase when a collector is active. +pub fn add_compile_timing(phase: &str, elapsed_ns: u64) { + if let Some(collector) = active() { + *collector + .borrow_mut() + .elapsed_ns + .entry(phase.to_owned()) + .or_default() += elapsed_ns; + } +} diff --git a/crates/sqlbuild-host/src/compile_context/main/collect_compile_timings.rs b/crates/sqlbuild-host/src/compile_context/main/collect_compile_timings.rs new file mode 100644 index 0000000000..e898c0ff20 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/collect_compile_timings.rs @@ -0,0 +1,17 @@ +//! Collect the timings one compile records on this thread. + +use std::rc::Rc; + +use crate::compile_context::_helpers::active::replace_active; +use crate::compile_context::types::CompileTimingsHandle; + +/// Run `body` with a fresh collector active on this thread, restoring the previous one after. +pub fn collect_compile_timings( + body: impl FnOnce(&CompileTimingsHandle) -> Result, +) -> Result { + let collector: CompileTimingsHandle = Rc::default(); + let previous: Option = replace_active(Some(Rc::clone(&collector))); + let result: Result = body(&collector); + let _ = replace_active(previous); + result +} diff --git a/crates/sqlbuild-host/src/compile_context/main/mod.rs b/crates/sqlbuild-host/src/compile_context/main/mod.rs new file mode 100644 index 0000000000..09aa8c4097 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/mod.rs @@ -0,0 +1,6 @@ +pub mod add_compile_timing; +pub mod collect_compile_timings; +pub mod record_compile_cpu_timing; +pub mod record_compile_metric; +pub mod record_compile_timing; +pub mod timing_milliseconds; diff --git a/crates/sqlbuild-host/src/compile_context/main/record_compile_cpu_timing.rs b/crates/sqlbuild-host/src/compile_context/main/record_compile_cpu_timing.rs new file mode 100644 index 0000000000..df0d2ba258 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/record_compile_cpu_timing.rs @@ -0,0 +1,21 @@ +//! Record the process CPU time of one compile phase. + +use crate::compile_context::_helpers::active::active; +use crate::compile_context::main::add_compile_timing::add_compile_timing; +use crate::compile_context::types::ProcessClock; + +/// Record the process CPU time `body` spans, including its worker threads, under `phase`. +pub fn record_compile_cpu_timing( + clock: &C, + phase: &str, + body: impl FnOnce() -> Result, +) -> Result { + if active().is_none() { + return body(); + } + let started: u64 = clock.process_time_ns()?; + let result: Result = body(); + let ended: u64 = clock.process_time_ns()?; + add_compile_timing(phase, ended.saturating_sub(started)); + result +} diff --git a/crates/sqlbuild-host/src/compile_context/main/record_compile_metric.rs b/crates/sqlbuild-host/src/compile_context/main/record_compile_metric.rs new file mode 100644 index 0000000000..043e0229a2 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/record_compile_metric.rs @@ -0,0 +1,14 @@ +//! Add to one compile metric. + +use crate::compile_context::_helpers::active::active; + +/// Add a non-negative metric value when a collector is active. +pub fn record_compile_metric(metric: &str, value: i64) { + if let Some(collector) = active() { + *collector + .borrow_mut() + .metrics + .entry(metric.to_owned()) + .or_default() += u64::try_from(value).unwrap_or(0); + } +} diff --git a/crates/sqlbuild-host/src/compile_context/main/record_compile_timing.rs b/crates/sqlbuild-host/src/compile_context/main/record_compile_timing.rs new file mode 100644 index 0000000000..5a1505ca1c --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/record_compile_timing.rs @@ -0,0 +1,23 @@ +//! Record the wall time of one compile phase. + +use std::time::Instant; + +use crate::compile_context::_helpers::active::active; +use crate::compile_context::main::add_compile_timing::add_compile_timing; + +/// Record the wall time `body` spans under `phase` when a collector is active. +pub fn record_compile_timing( + phase: &str, + body: impl FnOnce() -> Result, +) -> Result { + if active().is_none() { + return body(); + } + let started: Instant = Instant::now(); + let result: Result = body(); + add_compile_timing( + phase, + u64::try_from(started.elapsed().as_nanos()).unwrap_or(u64::MAX), + ); + result +} diff --git a/crates/sqlbuild-host/src/compile_context/main/timing_milliseconds.rs b/crates/sqlbuild-host/src/compile_context/main/timing_milliseconds.rs new file mode 100644 index 0000000000..ab25b290c4 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/main/timing_milliseconds.rs @@ -0,0 +1,11 @@ +//! A collector's timings as `--json` reports them. + +use sqlbuild_core::compile_timings::main::compile_timing_milliseconds::compile_timing_milliseconds; + +use crate::compile_context::types::CompileTimingsHandle; + +/// Every reported phase in milliseconds, then every metric. +#[must_use] +pub fn timing_milliseconds(collector: &CompileTimingsHandle) -> Vec<(&'static str, u64)> { + compile_timing_milliseconds(&collector.borrow()) +} diff --git a/crates/sqlbuild-host/src/compile_context/mod.rs b/crates/sqlbuild-host/src/compile_context/mod.rs new file mode 100644 index 0000000000..adaef052a2 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/mod.rs @@ -0,0 +1,8 @@ +//! Per-compile host state: the thread's timing collector and the diagnostic sink producers report into. + +pub(crate) mod _helpers; +pub mod main; +pub mod types; + +#[cfg(test)] +mod tests; diff --git a/crates/sqlbuild-host/src/compile_context/tests.rs b/crates/sqlbuild-host/src/compile_context/tests.rs new file mode 100644 index 0000000000..0e0f588512 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/tests.rs @@ -0,0 +1,6 @@ +#[path = "tests/test_collect_compile_timings.rs"] +mod collect_compile_timings; +#[path = "tests/helpers.rs"] +mod helpers; +#[path = "tests/test_types.rs"] +mod test_types; diff --git a/crates/sqlbuild-host/src/compile_context/tests/helpers.rs b/crates/sqlbuild-host/src/compile_context/tests/helpers.rs new file mode 100644 index 0000000000..1b071ac2ca --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/tests/helpers.rs @@ -0,0 +1,45 @@ +use sqlbuild_core::compile_timings::models::CompileTimings; + +use crate::compile_context::main::add_compile_timing::add_compile_timing; +use crate::compile_context::main::collect_compile_timings::collect_compile_timings; +use crate::compile_context::main::record_compile_cpu_timing::record_compile_cpu_timing; +use crate::compile_context::main::record_compile_metric::record_compile_metric; +use crate::compile_context::main::record_compile_timing::record_compile_timing; +use crate::compile_context::main::timing_milliseconds::timing_milliseconds; +use crate::compile_context::tests::test_types::SteppingClock; + +/// Record one timing, one CPU timing, two metric values and one wall timing. +fn record_all(clock: &SteppingClock) -> Result<(), ()> { + add_compile_timing("attachment_ms", 2_000_000); + record_compile_cpu_timing(clock, "model_analysis_cpu_ms", || Ok(()))?; + record_compile_metric("analysis_cache_misses", 3); + record_compile_metric("analysis_cache_misses", -1); + record_compile_timing("test_planning_ms", || Ok(())) +} + +/// The timings `record_all` leaves in a collection around it. +pub(super) fn collected(clock: &SteppingClock) -> Option { + collect_compile_timings(|collector| { + record_all(clock)?; + Ok::<_, ()>(collector.borrow().clone()) + }) + .ok() +} + +/// No timings: `record_all` runs outside any collection. +pub(super) fn uncollected(clock: &SteppingClock) -> Option { + record_all(clock).ok().and(None) +} + +/// The outer collection's first phase in milliseconds after a nested collection ends. +pub(super) fn outer_attachment_ms(inner_ns: u64, outer_ns: u64) -> Option { + collect_compile_timings(|outer| { + collect_compile_timings(|_inner| { + add_compile_timing("attachment_ms", inner_ns); + Ok::<(), ()>(()) + })?; + add_compile_timing("attachment_ms", outer_ns); + Ok::<_, ()>(timing_milliseconds(outer)[0].1) + }) + .ok() +} diff --git a/crates/sqlbuild-host/src/compile_context/tests/test_collect_compile_timings.rs b/crates/sqlbuild-host/src/compile_context/tests/test_collect_compile_timings.rs new file mode 100644 index 0000000000..cbce588f37 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/tests/test_collect_compile_timings.rs @@ -0,0 +1,84 @@ +use std::cell::Cell; + +use crate::compile_context::tests::helpers::{collected, outer_attachment_ms, uncollected}; +use crate::compile_context::tests::test_types::{ + NestingTestCase, RecordingTestCase, SteppingClock, +}; + +#[test] +fn given_recorders_when_a_compile_collects_then_only_the_active_collector_receives_them() { + let test_cases = [ + RecordingTestCase { + description: "a collecting compile receives every recording", + run: collected, + expected_elapsed_ns: Some(2_000_000), + expected_cpu_ns: Some(5), + expected_metric: Some(3), + expected_wall_recorded: true, + }, + RecordingTestCase { + description: "recordings outside a collection are dropped", + run: uncollected, + expected_elapsed_ns: None, + expected_cpu_ns: None, + expected_metric: None, + expected_wall_recorded: false, + }, + ]; + for test_case in test_cases { + let clock = SteppingClock { + now: Cell::new(0), + step: 5, + }; + let timings = (test_case.run)(&clock); + let phase = |name: &str| { + timings + .as_ref() + .and_then(|t| t.elapsed_ns.get(name).copied()) + }; + assert_eq!( + phase("attachment_ms"), + test_case.expected_elapsed_ns, + "{}", + test_case.description + ); + assert_eq!( + phase("model_analysis_cpu_ms"), + test_case.expected_cpu_ns, + "{}", + test_case.description + ); + assert_eq!( + timings + .as_ref() + .and_then(|t| t.metrics.get("analysis_cache_misses").copied()), + test_case.expected_metric, + "{}", + test_case.description + ); + assert_eq!( + phase("test_planning_ms").is_some(), + test_case.expected_wall_recorded, + "{}", + test_case.description + ); + } +} + +#[test] +fn given_a_nested_collection_when_it_ends_then_the_outer_collector_is_active_again() { + let test_cases = [NestingTestCase { + description: "the inner collection's timing stays out of the outer one", + inner_ns: 9_000_000, + outer_ns: 1_000_000, + expected_outer_ms: 1, + }]; + for test_case in test_cases { + assert_eq!( + outer_attachment_ms(test_case.inner_ns, test_case.outer_ns), + Some(test_case.expected_outer_ms), + "{}", + test_case.description + ); + } +} diff --git a/crates/sqlbuild-host/src/compile_context/tests/test_types.rs b/crates/sqlbuild-host/src/compile_context/tests/test_types.rs new file mode 100644 index 0000000000..797b01666f --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/tests/test_types.rs @@ -0,0 +1,37 @@ +use std::cell::Cell; + +use sqlbuild_core::compile_timings::models::CompileTimings; + +use crate::compile_context::types::ProcessClock; + +pub(super) struct RecordingTestCase { + pub(super) description: &'static str, + pub(super) run: fn(&SteppingClock) -> Option, + pub(super) expected_elapsed_ns: Option, + pub(super) expected_cpu_ns: Option, + pub(super) expected_metric: Option, + pub(super) expected_wall_recorded: bool, +} + +pub(super) struct NestingTestCase { + pub(super) description: &'static str, + pub(super) inner_ns: u64, + pub(super) outer_ns: u64, + pub(super) expected_outer_ms: u64, +} + +/// A clock that advances by `step` nanoseconds on every read. +pub(super) struct SteppingClock { + pub(super) now: Cell, + pub(super) step: u64, +} + +impl ProcessClock for SteppingClock { + type Error = (); + + fn process_time_ns(&self) -> Result { + let now: u64 = self.now.get() + self.step; + self.now.set(now); + Ok(now) + } +} diff --git a/crates/sqlbuild-host/src/compile_context/types.rs b/crates/sqlbuild-host/src/compile_context/types.rs new file mode 100644 index 0000000000..9503c11578 --- /dev/null +++ b/crates/sqlbuild-host/src/compile_context/types.rs @@ -0,0 +1,31 @@ +//! The timing collector handle, the process clock and the compile diagnostic sink. + +use std::cell::RefCell; +use std::rc::Rc; + +use sqlbuild_core::compile_timings::models::CompileTimings; + +/// One compile invocation's collector, shared by every recorder on its thread. +pub type CompileTimingsHandle = Rc>; + +/// The process CPU clock, including worker threads, as the host reads it. +pub trait ProcessClock { + /// Why the clock could not be read. + type Error; + + /// The process CPU time in nanoseconds. + fn process_time_ns(&self) -> Result; +} + +/// The compile's diagnostic sink: the active collection, or the first error when none collects. +pub trait CompileDiagnosticSink { + /// What identifies one diagnostic; a repeated key keeps the first diagnostic. + type Key: ?Sized; + /// One compile diagnostic. + type Diagnostic: ?Sized; + /// The failure a diagnostic becomes when no collection is active, or a reporting failure. + type Error; + + /// Record `diagnostic` under `key` in the active collection, or fail with it when none is. + fn report(&self, key: &Self::Key, diagnostic: &Self::Diagnostic) -> Result<(), Self::Error>; +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/adapter.rs b/crates/sqlbuild-host/src/entries/_helpers/adapter.rs similarity index 75% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/adapter.rs rename to crates/sqlbuild-host/src/entries/_helpers/adapter.rs index 79b2ec1b1a..9f98191093 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/adapter.rs +++ b/crates/sqlbuild-host/src/entries/_helpers/adapter.rs @@ -1,55 +1,6 @@ -//! Adapter runtime entry points: adapter discovery, relation inspection, type system and the shapes adapters consume. +//! Every adapter entry of `sqlbuild._native_host`. -use crate::bindings::_helpers::native_host::models::{HostEdge, HostEntry, HostId, HostKind}; - -/// One adapter entry of `sqlbuild._native_host`, indexing `ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum AdapterHost { - BaseAdapter, - AdapterUserError, - ColumnInfo, - ExpressionInferenceProfile, - RelationInfo, - RelationLookup, - RetentionRequest, - RowDiffSampling, - RowDiffTolerance, - RowDiffTolerances, - TableFreshnessMetadata, - TableFreshnessRequest, - BuiltinAdapter, - FrameworkType, - LifeCycleEventKind, - MigrationTransfer, - RetentionScope, - TableFreshnessStatus, - AdapterSupportsSessionWarehouse, - BuiltinAdapterClasses, - DiscoverProjectAdapters, - ResolveAdapter, - GetColumnsForInspection, - ListRelationsForInspection, - ActiveInspectionCatalog, - InspectionQuerySink, - OpenInspectionCatalog, - RecordInspectionQuery, - BuildRelationLookup, - ResolveRelationLocationQualifiedName, - RunBoundedInspections, - RunRecordedInspectionQuery, - InspectionQueryRecord, - StatementMetadataEffect, - ConditionalResultNullability, - FirstArgNullability, - NormalizeRelationType, - NormalizeType, - SafeCastNullability, - ConnectRecallStore, - RunRecallQuery, - RunRecallCommand, - InsertRecallRows, - CloseRecallStore, -} +use crate::entries::models::{HostEdge, HostEntry, HostKind}; /// Every adapter entry, in `AdapterHost` order. pub(crate) const ENTRIES: &[HostEntry] = &[ @@ -274,19 +225,3 @@ pub(crate) const ENTRIES: &[HostEntry] = &[ edge: HostEdge::Adapter, }, ]; - -impl AdapterHost { - /// The entry's position in `HOST_ENTRIES`, usable in constant tables. - pub(crate) const fn id(self) -> HostId { - HostId { - edge: HostEdge::Adapter, - index: self as usize, - } - } -} - -impl From for HostId { - fn from(entry: AdapterHost) -> Self { - entry.id() - } -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/executor.rs b/crates/sqlbuild-host/src/entries/_helpers/executor.rs similarity index 80% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/executor.rs rename to crates/sqlbuild-host/src/entries/_helpers/executor.rs index 2f31d6fa79..5e0d635827 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/executor.rs +++ b/crates/sqlbuild-host/src/entries/_helpers/executor.rs @@ -1,176 +1,6 @@ -//! Executor hand-off and results, and the runtime services commands run inside. +//! Every executor entry of `sqlbuild._native_host`. -use crate::bindings::_helpers::native_host::models::{HostEdge, HostEntry, HostId, HostKind}; - -/// One executor entry of `sqlbuild._native_host`, indexing `ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum ExecutorHost { - ProjectRelation, - ProjectRelationIndex, - RelationName, - CostResourceContext, - RunCostSummary, - CostCapability, - CostStatus, - BoundSentinel, - ReadProcessResources, - SqlPrivateRecordMarker, - DiagnosticsContext, - LogDebugEvent, - LogSql, - ProcessResourceReporting, - ProcessResourceUsage, - ExecutorInputError, - CurrentAuditResultProjection, - AuditExecutionResult, - BuildCallbacks, - BuildCustomizations, - BuildExecutionResult, - BuildInitialState, - BuildRuntimeParams, - FunctionExecutionResult, - SeedExecutionResult, - BuildStatus, - BuildDestinationTransientModels, - BuildDestinationRetentionRequests, - CopyCloneFingerprints, - RunPrephaseCloneStream, - ExecuteClone, - CloneExecutionInput, - CloneItemResult, - CloneSourceEntries, - CloneStatus, - QueryDiffArtifactLifecycle, - FullDiffSizeGuardError, - ExecuteQueryDiff, - ExecuteDiff, - DiffExecutionOptions, - DiffExecutionResult, - FullDiffSizeLimits, - RowDiffSamplingOverride, - ExecuteJanitorPlan, - JanitorArchiveCandidate, - JanitorArchivedRelation, - JanitorBlockedSchema, - JanitorDeleteCandidate, - JanitorDirectStatePruneCandidate, - JanitorOldNameView, - JanitorOldNameViewPlanning, - JanitorPlan, - JanitorQueryDiffArtifactCandidate, - JanitorRelationKey, - JanitorSkippedRelation, - JanitorSkippedSchema, - RunLoadPipeline, - LoadCallbacks, - LoadExecutionResult, - LoadRuntimeParams, - MigrationRelationForLocation, - IsCompatibilityView, - AuditExecutionError, - WarehouseConnectionError, - TemporaryTestFunctionError, - RaiseWarehouseConnectionFailure, - AuditPipelineCallbacks, - RunAuditPipelineWithCallbacks, - RunBuildPipeline, - RunScenarioCapturePipeline, - RunScenarioLocalTestPipeline, - RunScenarioTestPipeline, - RunSeedPipeline, - RunTestPipeline, - SelectScenarioSnapshotCaptureCandidates, - TestPipelineCallbacks, - RunItemTimeouts, - ScenarioTestSettings, - ExecutePythonChecks, - ExecuteIngressPythonLoaderNodes, - RunIngressPythonLoaderNodes, - CreateReadSidePythonExecutionTracker, - IngressCallbacks, - PythonCheckCallbacks, - PythonCheckExecutionResult, - PythonNodeExecutionResult, - PythonNodeRunState, - PythonNodeRuntime, - ModelExecutionResult, - ScenarioCaptureSettings, - ScenarioLocalReplaySource, - ScenarioSnapshotCaptureLimits, - ExecutionStatus, - SqlTestExecutionResult, - MicrobatchEventCodec, - MicrobatchColumns, - MicrobatchColumnTypes, - MicrobatchDirectIndexes, - MicrobatchGenerationWildcard, - MicrobatchTableName, - MicrobatchStateError, - MicrobatchCoverageProjection, - MicrobatchInterval, - ProjectedMicrobatchInterval, - ReplayRequirementProjection, - ReplayRequirementState, - TextComputeLogTee, - CaptureAlreadyExistsError, - CaptureNotFoundError, - CaptureStateError, - ComputeLogMetadataError, - ComputeLogPathError, - InvalidCaptureIdError, - InvalidComputeLogCursorError, - InvalidComputeLogLimitError, - CaptureByteCounts, - CaptureInventory, - CaptureInventoryItem, - CaptureMetadata, - ComputeLogReadChunk, - FinalCaptureMetadata, - PruneResult, - ComputeLogStream, - ConnectionHooks, - ExecutionResourceKind, - ExecutionHistoryStorageError, - IntegrityConflictError, - InvalidCursorError, - InvalidEventError, - InvalidFilterError, - InvalidLimitError, - ProjectionConsistencyError, - UnsupportedSchemaVersionError, - EventPage, - RunPage, - RunRecord, - StoredEvent, - RunStatus, - ExecutionDurationLimitError, - ExecutionDeadlineScope, - EventDispatcher, - OperationLifecycle, - ObservabilityValidationError, - CreateLifecycleEvent, - CurrentExecutionIdentity, - DiagnosticLogToJson, - DispatcherScope, - InvocationExternalContextScope, - InvocationScope, - LifecycleEventFromJson, - LifecycleEventToJson, - RunScope, - DiagnosticLog, - LifecycleEvent, - OperationAttributes, - CommandOutputValidationError, - OutputCaptureInputError, - ConfiguredOutputCaptureScope, - BoundCommandOutputSink, - CommandOutputCaptureSummary, - CommandOutputRecord, - OutputCaptureContext, - CommandOutputStream, - OutputRecordPriority, - SqlValueRenderingError, -} +use crate::entries::models::{HostEdge, HostEntry, HostKind}; /// Every executor entry, in `ExecutorHost` order. pub(crate) const ENTRIES: &[HostEntry] = &[ @@ -1000,19 +830,3 @@ pub(crate) const ENTRIES: &[HostEntry] = &[ edge: HostEdge::Executor, }, ]; - -impl ExecutorHost { - /// The entry's position in `HOST_ENTRIES`, usable in constant tables. - pub(crate) const fn id(self) -> HostId { - HostId { - edge: HostEdge::Executor, - index: self as usize, - } - } -} - -impl From for HostId { - fn from(entry: ExecutorHost) -> Self { - entry.id() - } -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/facade.rs b/crates/sqlbuild-host/src/entries/_helpers/facade.rs similarity index 64% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/facade.rs rename to crates/sqlbuild-host/src/entries/_helpers/facade.rs index c46ee8fe55..f19f9a7c41 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/facade.rs +++ b/crates/sqlbuild-host/src/entries/_helpers/facade.rs @@ -1,25 +1,6 @@ -//! Public facade entry points: the CLI entry point, compile reuse and the package itself. +//! Every facade entry of `sqlbuild._native_host`. -use crate::bindings::_helpers::native_host::models::{HostEdge, HostEntry, HostId, HostKind}; - -/// One facade entry of `sqlbuild._native_host`, indexing `ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum FacadeHost { - PackageFile, - DispatchWithComputeLogs, - ProviderSettingsInputs, - StartupInputs, - CompileReuseRequest, - AuditEvaluationMode, - AuditOutcome, - AuditSeverity, - ThresholdOperator, - AttachedAuditTargetKind, - FunctionLanguage, - SqlTestMode, - CursorAlgebraError, - SharedInputError, -} +use crate::entries::models::{HostEdge, HostEntry, HostKind}; /// Every facade entry, in `FacadeHost` order. pub(crate) const ENTRIES: &[HostEntry] = &[ @@ -94,19 +75,3 @@ pub(crate) const ENTRIES: &[HostEntry] = &[ edge: HostEdge::Facade, }, ]; - -impl FacadeHost { - /// The entry's position in `HOST_ENTRIES`, usable in constant tables. - pub(crate) const fn id(self) -> HostId { - HostId { - edge: HostEdge::Facade, - index: self as usize, - } - } -} - -impl From for HostId { - fn from(entry: FacadeHost) -> Self { - entry.id() - } -} diff --git a/crates/sqlbuild-host/src/entries/_helpers/mod.rs b/crates/sqlbuild-host/src/entries/_helpers/mod.rs new file mode 100644 index 0000000000..82f94c1b77 --- /dev/null +++ b/crates/sqlbuild-host/src/entries/_helpers/mod.rs @@ -0,0 +1,5 @@ +pub(crate) mod adapter; +pub(crate) mod executor; +pub(crate) mod facade; +pub(crate) mod third_party; +pub(crate) mod user_code; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/third_party.rs b/crates/sqlbuild-host/src/entries/_helpers/third_party.rs similarity index 74% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/third_party.rs rename to crates/sqlbuild-host/src/entries/_helpers/third_party.rs index 8c65bee3db..2319edd97b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/third_party.rs +++ b/crates/sqlbuild-host/src/entries/_helpers/third_party.rs @@ -1,48 +1,6 @@ -//! Glue around Python-only third-party integrations: dbt, dlt, ingestr, Dagster and rivers. +//! Every third party entry of `sqlbuild._native_host`. -use crate::bindings::_helpers::native_host::models::{HostEdge, HostEntry, HostId, HostKind}; - -/// One third-party entry of `sqlbuild._native_host`, indexing `ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum ThirdPartyHost { - AssetSelectionCommands, - CheckMetadataExcludedKeys, - CloneCommand, - CompletedExecutionStatuses, - DagsterAssetEnabledField, - DagsterAssetNodeKinds, - DagsterCheckEnabledField, - DagsterCheckNameField, - DagsterDirectKindNodeKinds, - DefaultSelectableNodeKinds, - ExplicitSelectionFlags, - InsufficientCheckStatus, - LiveEventCommands, - LoaderNodeKind, - LoadSelectableNodeKinds, - MaterializableNodeKinds, - ModelNodeKind, - ScenarioCheckKind, - SourceNodeKind, - StandaloneCheckCommands, - SuccessExecutionStatus, - ViewMaterializationType, - WarningCheckSeverity, - DagsterDagInputError, - LoadDbtYaml, - RenderSelectedDbtProfileOutput, - DbtProfileError, - DltIntegrationKind, - DltIntegrationError, - DltLoaderFunction, - DltResourceConfig, - DltSourceConfig, - IngestrIntegrationKind, - IngestrIntegrationError, - IngestrLoaderFunction, - IngestrSourceConfig, - RiversAssetNodeKinds, -} +use crate::entries::models::{HostEdge, HostEntry, HostKind}; /// Every third-party entry, in `ThirdPartyHost` order. pub(crate) const ENTRIES: &[HostEntry] = &[ @@ -232,19 +190,3 @@ pub(crate) const ENTRIES: &[HostEntry] = &[ edge: HostEdge::ThirdParty, }, ]; - -impl ThirdPartyHost { - /// The entry's position in `HOST_ENTRIES`, usable in constant tables. - pub(crate) const fn id(self) -> HostId { - HostId { - edge: HostEdge::ThirdParty, - index: self as usize, - } - } -} - -impl From for HostId { - fn from(entry: ThirdPartyHost) -> Self { - entry.id() - } -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/user_code.rs b/crates/sqlbuild-host/src/entries/_helpers/user_code.rs similarity index 77% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/user_code.rs rename to crates/sqlbuild-host/src/entries/_helpers/user_code.rs index 20586f35a0..7deafb99c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/user_code.rs +++ b/crates/sqlbuild-host/src/entries/_helpers/user_code.rs @@ -1,64 +1,6 @@ -//! Entry points that run user Python: macros, Python nodes, providers, custom rules and sinks. +//! Every user code entry of `sqlbuild._native_host`. -use crate::bindings::_helpers::native_host::models::{HostEdge, HostEntry, HostId, HostKind}; - -/// One user-code entry of `sqlbuild._native_host`, indexing `ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum UserCodeHost { - PythonResourceRows, - TargetContextWithMacroCallStore, - InventoryProjectMacros, - LoadProjectMacros, - MacroInvocationContext, - DiscoverCommandOutputSinkFunctions, - ImportPythonRootModule, - InstallPythonRootPackage, - LoadMaterializeFunction, - LoadProviderModule, - LoadPythonNodeModule, - LoadSinkModule, - ModuleFunctions, - ModuleProviderClasses, - ParameterAnnotations, - ProviderUsages, - RequiresArguments, - RestorePythonRootModules, - SourceLine, - ValidateEventExporterSignature, - ValidateDiscoveredInputs, - DiscoverRuntimeExtensions, - RunWithMacroBridge, - MacroStoreModulePaths, - ActiveMacroBridge, - LoadCustomMaterializations, - PythonNodeDependencyKey, - PythonNodeIdentity, - BuildHookIdentities, - PythonNodeKind, - PythonNodeStatus, - ProviderInputError, - BuildProviderSession, - ReadAssetDefinition, - ReadAuditFactoryDefinition, - ReadCheckDefinition, - ReadFactoryDefinition, - ReadHookDefinition, - ReadLoaderDefinition, - ReadTaskDefinition, - AuditCase, - RelationRenderer, - SqlResourceRef, - PythonCheckSeverity, - SqlResourceRefKind, - LoadCustomRules, - CustomRulePayloads, - EventExporterInputError, - EventExporterStateError, - InvokeLifecycleEventSink, - RunCommandOutputSinks, - GetLifecycleEventSinkDefinition, - InvokeRecallSink, -} +use crate::entries::models::{HostEdge, HostEntry, HostKind}; /// Every user-code entry, in `UserCodeHost` order. pub(crate) const ENTRIES: &[HostEntry] = &[ @@ -328,19 +270,3 @@ pub(crate) const ENTRIES: &[HostEntry] = &[ edge: HostEdge::UserCode, }, ]; - -impl UserCodeHost { - /// The entry's position in `HOST_ENTRIES`, usable in constant tables. - pub(crate) const fn id(self) -> HostId { - HostId { - edge: HostEdge::UserCode, - index: self as usize, - } - } -} - -impl From for HostId { - fn from(entry: UserCodeHost) -> Self { - entry.id() - } -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/constants.rs b/crates/sqlbuild-host/src/entries/constants.rs similarity index 53% rename from crates/sqlbuild-python/src/bindings/_helpers/native_host/constants.rs rename to crates/sqlbuild-host/src/entries/constants.rs index aa58559825..dd4d7bbcb8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/constants.rs +++ b/crates/sqlbuild-host/src/entries/constants.rs @@ -1,17 +1,16 @@ //! The host module and the one table of every entry native code may reach through it. -use crate::bindings::_helpers::native_host::models::HostEntry; -use crate::bindings::_helpers::native_host::{adapter, executor, facade, third_party, user_code}; +use crate::entries::_helpers::{adapter, executor, facade, third_party, user_code}; +use crate::entries::models::HostEntry; /// The only `sqlbuild` Python module native code imports by path. -pub(crate) const HOST_MODULE: &str = "sqlbuild._native_host"; +pub const HOST_MODULE: &str = "sqlbuild._native_host"; /// The module a custom-rule host process runs with `python -m`, a user-code edge reached by path. -pub(crate) const CUSTOM_HOST_LAUNCH_MODULE: &str = - "sqlbuild.rule_engine._helpers.host.custom_host_launch"; +pub const CUSTOM_HOST_LAUNCH_MODULE: &str = "sqlbuild.rule_engine._helpers.host.custom_host_launch"; /// The host module function naming each entry's target module and attribute. -pub(crate) const HOST_TARGETS_FUNCTION: &str = "host_targets"; +pub const HOST_TARGETS_FUNCTION: &str = "host_targets"; /// Every host entry, one group per edge in `HostEdge` order. -pub(crate) const HOST_ENTRIES: [&[HostEntry]; 5] = [ +pub const HOST_ENTRIES: [&[HostEntry]; 5] = [ adapter::ENTRIES, user_code::ENTRIES, executor::ENTRIES, diff --git a/crates/sqlbuild-host/src/entries/main/host_entry_labels.rs b/crates/sqlbuild-host/src/entries/main/host_entry_labels.rs new file mode 100644 index 0000000000..6270c6f4ad --- /dev/null +++ b/crates/sqlbuild-host/src/entries/main/host_entry_labels.rs @@ -0,0 +1,13 @@ +//! Every host entry as `_native.HOST_ENTRIES` lists it. + +use crate::entries::constants::HOST_ENTRIES; + +/// Each entry's `(name, kind, edge)` labels, in `HOST_ENTRIES` order. +#[must_use] +pub fn host_entry_labels() -> Vec<(&'static str, &'static str, &'static str)> { + HOST_ENTRIES + .iter() + .flat_map(|group| group.iter()) + .map(|entry| (entry.name, entry.kind.label(), entry.edge.label())) + .collect() +} diff --git a/crates/sqlbuild-host/src/entries/main/mod.rs b/crates/sqlbuild-host/src/entries/main/mod.rs new file mode 100644 index 0000000000..c24c30e801 --- /dev/null +++ b/crates/sqlbuild-host/src/entries/main/mod.rs @@ -0,0 +1 @@ +pub mod host_entry_labels; diff --git a/crates/sqlbuild-host/src/entries/mod.rs b/crates/sqlbuild-host/src/entries/mod.rs new file mode 100644 index 0000000000..6dbd6a0464 --- /dev/null +++ b/crates/sqlbuild-host/src/entries/mod.rs @@ -0,0 +1,7 @@ +//! Host entries: the staying-Python names native code reaches through `sqlbuild._native_host`. + +pub(crate) mod _helpers; +pub mod constants; +pub mod main; +pub mod models; +pub mod types; diff --git a/crates/sqlbuild-host/src/entries/models.rs b/crates/sqlbuild-host/src/entries/models.rs new file mode 100644 index 0000000000..85ba45b08f --- /dev/null +++ b/crates/sqlbuild-host/src/entries/models.rs @@ -0,0 +1,478 @@ +//! Host entries: the staying-Python names native code reaches through `sqlbuild._native_host`. + +/// What a host entry resolves to. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HostKind { + Function, + Class, + Exception, + Value, +} + +impl HostKind { + /// The kind as the import test and `_native.HOST_ENTRIES` spell it. + pub const fn label(self) -> &'static str { + match self { + Self::Function => "function", + Self::Class => "class", + Self::Exception => "exception", + Self::Value => "value", + } + } +} + +/// Which boundary a host entry crosses; also its group in `HOST_ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HostEdge { + Adapter, + UserCode, + Executor, + ThirdParty, + Facade, +} + +impl HostEdge { + /// The edge as `_native.HOST_ENTRIES` spells it. + pub const fn label(self) -> &'static str { + match self { + Self::Adapter => "adapter", + Self::UserCode => "user_code", + Self::Executor => "executor", + Self::ThirdParty => "third_party", + Self::Facade => "facade", + } + } +} + +/// One host entry: its `sqlbuild._native_host` name, kind and edge. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct HostEntry { + pub name: &'static str, + pub kind: HostKind, + pub edge: HostEdge, +} + +/// A host entry by edge and position, from any edge's entry enum. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct HostId { + pub edge: HostEdge, + pub index: usize, +} + +/// One adapter entry of `sqlbuild._native_host`, indexing its `ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AdapterHost { + BaseAdapter, + AdapterUserError, + ColumnInfo, + ExpressionInferenceProfile, + RelationInfo, + RelationLookup, + RetentionRequest, + RowDiffSampling, + RowDiffTolerance, + RowDiffTolerances, + TableFreshnessMetadata, + TableFreshnessRequest, + BuiltinAdapter, + FrameworkType, + LifeCycleEventKind, + MigrationTransfer, + RetentionScope, + TableFreshnessStatus, + AdapterSupportsSessionWarehouse, + BuiltinAdapterClasses, + DiscoverProjectAdapters, + ResolveAdapter, + GetColumnsForInspection, + ListRelationsForInspection, + ActiveInspectionCatalog, + InspectionQuerySink, + OpenInspectionCatalog, + RecordInspectionQuery, + BuildRelationLookup, + ResolveRelationLocationQualifiedName, + RunBoundedInspections, + RunRecordedInspectionQuery, + InspectionQueryRecord, + StatementMetadataEffect, + ConditionalResultNullability, + FirstArgNullability, + NormalizeRelationType, + NormalizeType, + SafeCastNullability, + ConnectRecallStore, + RunRecallQuery, + RunRecallCommand, + InsertRecallRows, + CloseRecallStore, +} + +impl AdapterHost { + /// The entry's position in `HOST_ENTRIES`, usable in constant tables. + pub const fn id(self) -> HostId { + HostId { + edge: HostEdge::Adapter, + index: self as usize, + } + } +} + +impl From for HostId { + fn from(entry: AdapterHost) -> Self { + entry.id() + } +} + +/// One user-code entry of `sqlbuild._native_host`, indexing its `ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UserCodeHost { + PythonResourceRows, + TargetContextWithMacroCallStore, + InventoryProjectMacros, + LoadProjectMacros, + MacroInvocationContext, + DiscoverCommandOutputSinkFunctions, + ImportPythonRootModule, + InstallPythonRootPackage, + LoadMaterializeFunction, + LoadProviderModule, + LoadPythonNodeModule, + LoadSinkModule, + ModuleFunctions, + ModuleProviderClasses, + ParameterAnnotations, + ProviderUsages, + RequiresArguments, + RestorePythonRootModules, + SourceLine, + ValidateEventExporterSignature, + ValidateDiscoveredInputs, + DiscoverRuntimeExtensions, + RunWithMacroBridge, + MacroStoreModulePaths, + ActiveMacroBridge, + LoadCustomMaterializations, + PythonNodeDependencyKey, + PythonNodeIdentity, + BuildHookIdentities, + PythonNodeKind, + PythonNodeStatus, + ProviderInputError, + BuildProviderSession, + ReadAssetDefinition, + ReadAuditFactoryDefinition, + ReadCheckDefinition, + ReadFactoryDefinition, + ReadHookDefinition, + ReadLoaderDefinition, + ReadTaskDefinition, + AuditCase, + RelationRenderer, + SqlResourceRef, + PythonCheckSeverity, + SqlResourceRefKind, + LoadCustomRules, + CustomRulePayloads, + EventExporterInputError, + EventExporterStateError, + InvokeLifecycleEventSink, + RunCommandOutputSinks, + GetLifecycleEventSinkDefinition, + InvokeRecallSink, +} + +impl UserCodeHost { + /// The entry's position in `HOST_ENTRIES`, usable in constant tables. + pub const fn id(self) -> HostId { + HostId { + edge: HostEdge::UserCode, + index: self as usize, + } + } +} + +impl From for HostId { + fn from(entry: UserCodeHost) -> Self { + entry.id() + } +} + +/// One executor entry of `sqlbuild._native_host`, indexing its `ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ExecutorHost { + ProjectRelation, + ProjectRelationIndex, + RelationName, + CostResourceContext, + RunCostSummary, + CostCapability, + CostStatus, + BoundSentinel, + ReadProcessResources, + SqlPrivateRecordMarker, + DiagnosticsContext, + LogDebugEvent, + LogSql, + ProcessResourceReporting, + ProcessResourceUsage, + ExecutorInputError, + CurrentAuditResultProjection, + AuditExecutionResult, + BuildCallbacks, + BuildCustomizations, + BuildExecutionResult, + BuildInitialState, + BuildRuntimeParams, + FunctionExecutionResult, + SeedExecutionResult, + BuildStatus, + BuildDestinationTransientModels, + BuildDestinationRetentionRequests, + CopyCloneFingerprints, + RunPrephaseCloneStream, + ExecuteClone, + CloneExecutionInput, + CloneItemResult, + CloneSourceEntries, + CloneStatus, + QueryDiffArtifactLifecycle, + FullDiffSizeGuardError, + ExecuteQueryDiff, + ExecuteDiff, + DiffExecutionOptions, + DiffExecutionResult, + FullDiffSizeLimits, + RowDiffSamplingOverride, + ExecuteJanitorPlan, + JanitorArchiveCandidate, + JanitorArchivedRelation, + JanitorBlockedSchema, + JanitorDeleteCandidate, + JanitorDirectStatePruneCandidate, + JanitorOldNameView, + JanitorOldNameViewPlanning, + JanitorPlan, + JanitorQueryDiffArtifactCandidate, + JanitorRelationKey, + JanitorSkippedRelation, + JanitorSkippedSchema, + RunLoadPipeline, + LoadCallbacks, + LoadExecutionResult, + LoadRuntimeParams, + MigrationRelationForLocation, + IsCompatibilityView, + AuditExecutionError, + WarehouseConnectionError, + TemporaryTestFunctionError, + RaiseWarehouseConnectionFailure, + AuditPipelineCallbacks, + RunAuditPipelineWithCallbacks, + RunBuildPipeline, + RunScenarioCapturePipeline, + RunScenarioLocalTestPipeline, + RunScenarioTestPipeline, + RunSeedPipeline, + RunTestPipeline, + SelectScenarioSnapshotCaptureCandidates, + TestPipelineCallbacks, + RunItemTimeouts, + ScenarioTestSettings, + ExecutePythonChecks, + ExecuteIngressPythonLoaderNodes, + RunIngressPythonLoaderNodes, + CreateReadSidePythonExecutionTracker, + IngressCallbacks, + PythonCheckCallbacks, + PythonCheckExecutionResult, + PythonNodeExecutionResult, + PythonNodeRunState, + PythonNodeRuntime, + ModelExecutionResult, + ScenarioCaptureSettings, + ScenarioLocalReplaySource, + ScenarioSnapshotCaptureLimits, + ExecutionStatus, + SqlTestExecutionResult, + MicrobatchEventCodec, + MicrobatchColumns, + MicrobatchColumnTypes, + MicrobatchDirectIndexes, + MicrobatchGenerationWildcard, + MicrobatchTableName, + MicrobatchStateError, + MicrobatchCoverageProjection, + MicrobatchInterval, + ProjectedMicrobatchInterval, + ReplayRequirementProjection, + ReplayRequirementState, + TextComputeLogTee, + CaptureAlreadyExistsError, + CaptureNotFoundError, + CaptureStateError, + ComputeLogMetadataError, + ComputeLogPathError, + InvalidCaptureIdError, + InvalidComputeLogCursorError, + InvalidComputeLogLimitError, + CaptureByteCounts, + CaptureInventory, + CaptureInventoryItem, + CaptureMetadata, + ComputeLogReadChunk, + FinalCaptureMetadata, + PruneResult, + ComputeLogStream, + ConnectionHooks, + ExecutionResourceKind, + ExecutionHistoryStorageError, + IntegrityConflictError, + InvalidCursorError, + InvalidEventError, + InvalidFilterError, + InvalidLimitError, + ProjectionConsistencyError, + UnsupportedSchemaVersionError, + EventPage, + RunPage, + RunRecord, + StoredEvent, + RunStatus, + ExecutionDurationLimitError, + ExecutionDeadlineScope, + EventDispatcher, + OperationLifecycle, + ObservabilityValidationError, + CreateLifecycleEvent, + CurrentExecutionIdentity, + DiagnosticLogToJson, + DispatcherScope, + InvocationExternalContextScope, + InvocationScope, + LifecycleEventFromJson, + LifecycleEventToJson, + RunScope, + DiagnosticLog, + LifecycleEvent, + OperationAttributes, + CommandOutputValidationError, + OutputCaptureInputError, + ConfiguredOutputCaptureScope, + BoundCommandOutputSink, + CommandOutputCaptureSummary, + CommandOutputRecord, + OutputCaptureContext, + CommandOutputStream, + OutputRecordPriority, + SqlValueRenderingError, +} + +impl ExecutorHost { + /// The entry's position in `HOST_ENTRIES`, usable in constant tables. + pub const fn id(self) -> HostId { + HostId { + edge: HostEdge::Executor, + index: self as usize, + } + } +} + +impl From for HostId { + fn from(entry: ExecutorHost) -> Self { + entry.id() + } +} + +/// One third-party entry of `sqlbuild._native_host`, indexing its `ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ThirdPartyHost { + AssetSelectionCommands, + CheckMetadataExcludedKeys, + CloneCommand, + CompletedExecutionStatuses, + DagsterAssetEnabledField, + DagsterAssetNodeKinds, + DagsterCheckEnabledField, + DagsterCheckNameField, + DagsterDirectKindNodeKinds, + DefaultSelectableNodeKinds, + ExplicitSelectionFlags, + InsufficientCheckStatus, + LiveEventCommands, + LoaderNodeKind, + LoadSelectableNodeKinds, + MaterializableNodeKinds, + ModelNodeKind, + ScenarioCheckKind, + SourceNodeKind, + StandaloneCheckCommands, + SuccessExecutionStatus, + ViewMaterializationType, + WarningCheckSeverity, + DagsterDagInputError, + LoadDbtYaml, + RenderSelectedDbtProfileOutput, + DbtProfileError, + DltIntegrationKind, + DltIntegrationError, + DltLoaderFunction, + DltResourceConfig, + DltSourceConfig, + IngestrIntegrationKind, + IngestrIntegrationError, + IngestrLoaderFunction, + IngestrSourceConfig, + RiversAssetNodeKinds, +} + +impl ThirdPartyHost { + /// The entry's position in `HOST_ENTRIES`, usable in constant tables. + pub const fn id(self) -> HostId { + HostId { + edge: HostEdge::ThirdParty, + index: self as usize, + } + } +} + +impl From for HostId { + fn from(entry: ThirdPartyHost) -> Self { + entry.id() + } +} + +/// One facade entry of `sqlbuild._native_host`, indexing its `ENTRIES`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum FacadeHost { + PackageFile, + DispatchWithComputeLogs, + ProviderSettingsInputs, + StartupInputs, + CompileReuseRequest, + AuditEvaluationMode, + AuditOutcome, + AuditSeverity, + ThresholdOperator, + AttachedAuditTargetKind, + FunctionLanguage, + SqlTestMode, + CursorAlgebraError, + SharedInputError, +} + +impl FacadeHost { + /// The entry's position in `HOST_ENTRIES`, usable in constant tables. + pub const fn id(self) -> HostId { + HostId { + edge: HostEdge::Facade, + index: self as usize, + } + } +} + +impl From for HostId { + fn from(entry: FacadeHost) -> Self { + entry.id() + } +} diff --git a/crates/sqlbuild-host/src/entries/types.rs b/crates/sqlbuild-host/src/entries/types.rs new file mode 100644 index 0000000000..4983beb15a --- /dev/null +++ b/crates/sqlbuild-host/src/entries/types.rs @@ -0,0 +1,14 @@ +//! The resolution of host entries, which the Python boundary implements. + +use crate::entries::models::HostId; + +/// Resolves host entries to the boundary's values, the one way native code reaches Python. +pub trait HostEntries { + /// A resolved entry: a function, class, exception or value. + type Entry; + /// Why an entry could not be resolved. + type Error; + + /// The entry `id` names, resolved on every call. + fn entry(&self, id: HostId) -> Result; +} diff --git a/crates/sqlbuild-host/src/lib.rs b/crates/sqlbuild-host/src/lib.rs new file mode 100644 index 0000000000..5b2fa7d7d7 --- /dev/null +++ b/crates/sqlbuild-host/src/lib.rs @@ -0,0 +1,11 @@ +//! The contract of the permanent Python edges: host entries, timings, diagnostics and results. + +#![forbid(unsafe_code)] + +pub mod compile_context; +pub mod entries; +pub mod models; +pub mod types; + +#[cfg(test)] +mod tests; diff --git a/crates/sqlbuild-host/src/models.rs b/crates/sqlbuild-host/src/models.rs new file mode 100644 index 0000000000..f397ffa72e --- /dev/null +++ b/crates/sqlbuild-host/src/models.rs @@ -0,0 +1,668 @@ +//! Executor results as Rust data: one type per Python result dataclass and string enum. + +use std::path::PathBuf; + +use crate::types::ResultEnum; + +/// Whether a build succeeded. Mirrors `sqlbuild.executor.build.types.BuildStatus`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum BuildStatus { + Success, + Failed, +} + +impl ResultEnum for BuildStatus { + const ALL: &'static [Self] = &[Self::Success, Self::Failed]; + + fn value(self) -> &'static str { + match self { + Self::Success => "success", + Self::Failed => "failed", + } + } +} + +/// How one executed node ended. Mirrors `sqlbuild.executor.scheduling.types.ExecutionStatus`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ExecutionStatus { + Success, + Failed, + Skipped, +} + +impl ResultEnum for ExecutionStatus { + const ALL: &'static [Self] = &[Self::Success, Self::Failed, Self::Skipped]; + + fn value(self) -> &'static str { + match self { + Self::Success => "success", + Self::Failed => "failed", + Self::Skipped => "skipped", + } + } +} + +/// The model phase a failure happened in. Mirrors `sqlbuild.executor.run.types.ExecutionPhase`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ExecutionPhase { + PreHook, + Staging, + SchemaChange, + TypeEnforcement, + Contract, + Audit, + Promotion, + Dml, + PostHook, + Fingerprint, + MicrobatchState, + CustomMaterialization, +} + +impl ResultEnum for ExecutionPhase { + const ALL: &'static [Self] = &[ + Self::PreHook, + Self::Staging, + Self::SchemaChange, + Self::TypeEnforcement, + Self::Contract, + Self::Audit, + Self::Promotion, + Self::Dml, + Self::PostHook, + Self::Fingerprint, + Self::MicrobatchState, + Self::CustomMaterialization, + ]; + + fn value(self) -> &'static str { + match self { + Self::PreHook => "pre_hook", + Self::Staging => "staging", + Self::SchemaChange => "schema_change", + Self::TypeEnforcement => "type_enforcement", + Self::Contract => "contract", + Self::Audit => "audit", + Self::Promotion => "promotion", + Self::Dml => "dml", + Self::PostHook => "post_hook", + Self::Fingerprint => "fingerprint", + Self::MicrobatchState => "microbatch_state", + Self::CustomMaterialization => "custom_materialization", + } + } +} + +/// Whether a hook ran before or after its model. Mirrors `sqlbuild.executor.run.types.HookPhase`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HookPhase { + PreHooks, + PostHooks, +} + +impl ResultEnum for HookPhase { + const ALL: &'static [Self] = &[Self::PreHooks, Self::PostHooks]; + + fn value(self) -> &'static str { + match self { + Self::PreHooks => "pre_hooks", + Self::PostHooks => "post_hooks", + } + } +} + +/// How a skipped node blocks its dependents. Mirrors `sqlbuild.compiler.python_nodes.types.SkipMode`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum SkipMode { + Soft, + Hard, +} + +impl ResultEnum for SkipMode { + const ALL: &'static [Self] = &[Self::Soft, Self::Hard]; + + fn value(self) -> &'static str { + match self { + Self::Soft => "soft", + Self::Hard => "hard", + } + } +} + +/// What a microbatch limit does when reached. Mirrors `sqlbuild._native.MicrobatchLimitAction`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum MicrobatchLimitAction { + CapFromEnd, + CapFromStart, + Error, + Warn, +} + +impl ResultEnum for MicrobatchLimitAction { + const ALL: &'static [Self] = &[ + Self::CapFromEnd, + Self::CapFromStart, + Self::Error, + Self::Warn, + ]; + + fn value(self) -> &'static str { + match self { + Self::CapFromEnd => "cap_from_end", + Self::CapFromStart => "cap_from_start", + Self::Error => "error", + Self::Warn => "warn", + } + } +} + +/// The kind of resource a load wrote. Mirrors `sqlbuild.runtime.contracts.types.ExecutionResourceKind`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ExecutionResourceKind { + Source, + Loader, + Seed, + Udf, + TableFn, + View, + Table, + Custom, + Snapshot, +} + +impl ResultEnum for ExecutionResourceKind { + const ALL: &'static [Self] = &[ + Self::Source, + Self::Loader, + Self::Seed, + Self::Udf, + Self::TableFn, + Self::View, + Self::Table, + Self::Custom, + Self::Snapshot, + ]; + + fn value(self) -> &'static str { + match self { + Self::Source => "source", + Self::Loader => "loader", + Self::Seed => "seed", + Self::Udf => "udf", + Self::TableFn => "table_fn", + Self::View => "view", + Self::Table => "table", + Self::Custom => "custom", + Self::Snapshot => "snapshot", + } + } +} + +/// How one SQL test or step ended. Mirrors `sqlbuild.executor.testing.types.SqlTestOutcome`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum SqlTestOutcome { + Pass, + Fail, + Error, + Timeout, +} + +impl ResultEnum for SqlTestOutcome { + const ALL: &'static [Self] = &[Self::Pass, Self::Fail, Self::Error, Self::Timeout]; + + fn value(self) -> &'static str { + match self { + Self::Pass => "pass", + Self::Fail => "fail", + Self::Error => "error", + Self::Timeout => "timeout", + } + } +} + +/// The kind of item a timeout stopped. Mirrors `sqlbuild.runtime.execution_limits.types.ItemKind`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ItemKind { + Test, + Scenario, + Model, +} + +impl ResultEnum for ItemKind { + const ALL: &'static [Self] = &[Self::Test, Self::Scenario, Self::Model]; + + fn value(self) -> &'static str { + match self { + Self::Test => "test", + Self::Scenario => "scenario", + Self::Model => "model", + } + } +} + +/// Whether a timed-out query was cancelled. Mirrors `sqlbuild.runtime.execution_limits.types.CancellationOutcome`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CancellationOutcome { + Confirmed, + Unknown, + Failed, + Unsupported, + NotNeeded, +} + +impl ResultEnum for CancellationOutcome { + const ALL: &'static [Self] = &[ + Self::Confirmed, + Self::Unknown, + Self::Failed, + Self::Unsupported, + Self::NotNeeded, + ]; + + fn value(self) -> &'static str { + match self { + Self::Confirmed => "confirmed", + Self::Unknown => "unknown", + Self::Failed => "failed", + Self::Unsupported => "unsupported", + Self::NotNeeded => "not_needed", + } + } +} + +/// Where an audit is attached. Mirrors `sqlbuild.compiler.auditing.types.AuditAttachmentKind`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AuditAttachmentKind { + Source, + Seed, + Model, + End, +} + +impl ResultEnum for AuditAttachmentKind { + const ALL: &'static [Self] = &[Self::Source, Self::Seed, Self::Model, Self::End]; + + fn value(self) -> &'static str { + match self { + Self::Source => "source", + Self::Seed => "seed", + Self::Model => "model", + Self::End => "end", + } + } +} + +/// How a failing audit is reported. Mirrors `sqlbuild.compiler.auditing.types.AuditSeverity`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AuditSeverity { + Warn, + Error, +} + +impl ResultEnum for AuditSeverity { + const ALL: &'static [Self] = &[Self::Warn, Self::Error]; + + fn value(self) -> &'static str { + match self { + Self::Warn => "warn", + Self::Error => "error", + } + } +} + +/// How one audit ended. Mirrors `sqlbuild.compiler.auditing.types.AuditOutcome`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AuditOutcome { + Pass, + Warn, + Error, + Insufficient, +} + +impl ResultEnum for AuditOutcome { + const ALL: &'static [Self] = &[Self::Pass, Self::Warn, Self::Error, Self::Insufficient]; + + fn value(self) -> &'static str { + match self { + Self::Pass => "pass", + Self::Warn => "warn", + Self::Error => "error", + Self::Insufficient => "insufficient", + } + } +} + +/// The phases an audit runs in. Mirrors `sqlbuild.compiler.auditing.types.AuditRunScope`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AuditRunScope { + Final, + DeltaAndFinal, +} + +impl ResultEnum for AuditRunScope { + const ALL: &'static [Self] = &[Self::Final, Self::DeltaAndFinal]; + + fn value(self) -> &'static str { + match self { + Self::Final => "final", + Self::DeltaAndFinal => "delta_and_final", + } + } +} + +/// The resource an attached audit checks. Mirrors `sqlbuild.compiler.compile.types.AttachedAuditTargetKind`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AttachedAuditTargetKind { + Model, + Source, + Seed, +} + +impl ResultEnum for AttachedAuditTargetKind { + const ALL: &'static [Self] = &[Self::Model, Self::Source, Self::Seed]; + + fn value(self) -> &'static str { + match self { + Self::Model => "model", + Self::Source => "source", + Self::Seed => "seed", + } + } +} + +/// Whether an audit counts violations or measures a value. Mirrors `sqlbuild.compiler.auditing.types.AuditEvaluationMode`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AuditEvaluationMode { + Violations, + Measurement, +} + +impl ResultEnum for AuditEvaluationMode { + const ALL: &'static [Self] = &[Self::Violations, Self::Measurement]; + + fn value(self) -> &'static str { + match self { + Self::Violations => "violations", + Self::Measurement => "measurement", + } + } +} + +/// The kind of one lifecycle event. Mirrors `sqlbuild.adapter.contract.types.LifeCycleEventKind`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum LifeCycleEventKind { + Sql, + Log, +} + +impl ResultEnum for LifeCycleEventKind { + const ALL: &'static [Self] = &[Self::Sql, Self::Log]; + + fn value(self) -> &'static str { + match self { + Self::Sql => "sql", + Self::Log => "log", + } + } +} + +/// The wall time of a build's preparation and execution. Mirrors `sqlbuild.executor.build.models.BuildExecutionTimings`. +#[derive(Clone, Debug, PartialEq)] +pub struct BuildExecutionTimings { + pub connection_preparation_seconds: Option, + pub schema_preparation_seconds: Option, + pub execution_seconds: Option, +} + +/// One SQL statement or log line a node emitted. Mirrors `sqlbuild.adapter.contract.models.LifeCycleEvent`. +#[derive(Clone, Debug, PartialEq)] +pub struct LifeCycleEvent { + pub kind: LifeCycleEventKind, + pub content: String, +} + +/// One pre- or post-hook of a model. Mirrors `sqlbuild.executor.run.models.HookExecutionResult`. +#[derive(Clone, Debug, PartialEq)] +pub struct HookExecutionResult { + pub phase: HookPhase, + pub index: i64, + pub hook_type: String, + pub label: String, + pub status: ExecutionStatus, + pub skip_mode: Option, + pub skip_reason: Option, + pub error_message: Option, +} + +/// One partition interval a microbatch run accounted for. Mirrors `sqlbuild.executor.run.models.MicrobatchAccountingInterval`. +#[derive(Clone, Debug, PartialEq)] +pub struct MicrobatchAccountingInterval { + pub partition_start: String, + pub partition_end: String, + pub accounting_status: String, + pub fingerprint_status: String, + pub model_version_hash: Option, + pub completion_type: Option, + pub event_id: Option, +} + +/// One executed audit. Mirrors `sqlbuild.executor.auditing.models.AuditExecutionResult`; `V` is a host value. +#[derive(Clone, Debug, PartialEq)] +pub struct AuditExecutionResult { + pub audit_name: String, + pub audit_definition_name: String, + pub attachment_kind: AuditAttachmentKind, + pub severity: AuditSeverity, + pub outcome: AuditOutcome, + pub row_count: i64, + pub executed_sql: String, + pub run_scope_phase: AuditRunScope, + pub attached_target_kind: Option, + pub attached_target_name: Option, + pub attached_column_name: Option, + pub reused: bool, + pub evaluation_mode: AuditEvaluationMode, + pub measured_value: Option, + pub sample_count: Option, + pub sample_unit: Option, + pub minimum_samples: Option, + pub thresholds: Option, + pub evidence_rows: Vec>, + pub evidence_truncated: bool, + pub evidence_error: Option, + pub evidence_sql: Option, + pub audit_description: Option, + pub execution_error: Option, + pub audit_meta: Option>, +} + +/// One executed model. Mirrors `sqlbuild.executor.run.models.ModelExecutionResult`; `V` is a host value. +#[derive(Clone, Debug, PartialEq)] +pub struct ModelExecutionResult { + pub model_name: String, + pub status: ExecutionStatus, + pub failed_phase: Option, + pub staging_relation: Option, + pub promoted_relation: Option, + pub duration_ms: Option, + pub batch_count: Option, + pub batch_size: Option, + pub rows_affected: Option, + pub cursor_range_start: Option, + pub cursor_range_end: Option, + pub cursor_type: Option, + pub cursor_grain: Option, + pub empty_cursor_inputs: Vec, + pub waiting_on_empty_inputs: bool, + pub future_cursor_safety: Option, + pub maximum_start_safety: Option, + pub audit_results: Vec>, + pub warning_messages: Vec, + pub lifecycle_events: Vec, + pub hook_results: Vec, + pub skip_mode: Option, + pub skip_reason: Option, + pub error_code: Option, + pub error_help: Option, + pub error_message: Option, + pub failed_sql: Option, + pub microbatch_run_type: Option, + pub microbatch_strategy: Option, + pub microbatch_plan_reason: Option, + pub microbatch_recovery_batch_count: i64, + pub microbatch_known_gap_count: i64, + pub microbatch_unaccounted_interval_count: i64, + pub microbatch_synthetic_completion_count: i64, + pub microbatch_unknown_fingerprint_count: i64, + pub microbatch_contiguous_frontier: Option, + pub microbatch_unaccounted_partition_policy: Option, + pub microbatch_replay_requirement_id: Option, + pub microbatch_required_model_version_hash: Option, + pub microbatch_physical_generation_id: Option, + pub microbatch_concurrent_enabled: bool, + pub microbatch_batch_concurrency: i64, + pub microbatch_global_concurrency: i64, + pub microbatch_replay_requirement_state: Option, + pub microbatch_accounting_intervals: Vec, + pub microbatch_limit: Option, + pub microbatch_limit_count: Option, + pub microbatch_limit_action: Option, + pub microbatch_limit_warning: Option, +} + +/// One loaded seed. Mirrors `sqlbuild.executor.build.models.SeedExecutionResult`. +#[derive(Clone, Debug, PartialEq)] +pub struct SeedExecutionResult { + pub seed_name: String, + pub status: ExecutionStatus, + pub duration_ms: Option, + pub lifecycle_events: Vec, + pub error_code: Option, + pub error_help: Option, + pub error_message: Option, + pub warning_messages: Vec, +} + +/// One created function. Mirrors `sqlbuild.executor.build.models.FunctionExecutionResult`. +#[derive(Clone, Debug, PartialEq)] +pub struct FunctionExecutionResult { + pub function_name: String, + pub status: ExecutionStatus, + pub function_kind: String, + pub duration_ms: Option, + pub error_code: Option, + pub error_help: Option, + pub error_message: Option, + pub warning_messages: Vec, + pub lifecycle_events: Vec, +} + +/// One source or loader load. Mirrors `sqlbuild.executor.load.models.LoadExecutionResult`; `V` is a host value. +#[derive(Clone, Debug, PartialEq)] +pub struct LoadExecutionResult { + pub source_name: String, + pub loader_name: String, + pub status: ExecutionStatus, + pub target: String, + pub resource_kind: ExecutionResourceKind, + pub staging_relation: Option, + pub rows_loaded: i64, + pub duration_ms: Option, + pub lifecycle_events: Vec, + pub skip_mode: Option, + pub skip_reason: Option, + pub error_message: Option, + pub result_payload: Option, + pub result_metadata: Vec<(String, V)>, + pub result_materialized: Option, + pub warning_messages: Vec, +} + +/// One sampled row a SQL test step found missing or unexpected. Mirrors `sqlbuild.executor.testing.models.SqlTestDifferenceSample`. +#[derive(Clone, Debug, PartialEq)] +pub struct SqlTestDifferenceSample { + pub values: Vec<(String, String)>, +} + +/// One column whose actual and expected types differ. Mirrors `sqlbuild.executor.testing.models.SqlTestColumnDifference`. +#[derive(Clone, Debug, PartialEq)] +pub struct SqlTestColumnDifference { + pub name: String, + pub actual: String, + pub expected: String, +} + +/// One model step of a SQL test. Mirrors `sqlbuild.executor.testing.models.StepResult`. +#[derive(Clone, Debug, PartialEq)] +pub struct StepResult { + pub model_name: String, + pub outcome: SqlTestOutcome, + pub actual_row_count: i64, + pub expected_row_count: i64, + pub mismatched_row_count: i64, + pub unexpected_row_count: Option, + pub missing_row_count: Option, + pub unexpected_samples: Vec, + pub missing_samples: Vec, + pub column_differences: Vec, + pub error_code: Option, + pub error_help: Option, + pub error_message: Option, +} + +/// The timeout that stopped one item. Mirrors `sqlbuild.runtime.execution_limits.models.ItemTimeoutReport`. +#[derive(Clone, Debug, PartialEq)] +pub struct ItemTimeoutReport { + pub kind: ItemKind, + pub name: String, + pub limit: String, + pub source: String, + pub elapsed_seconds: f64, + pub query_ids: Vec, + pub cancellation: CancellationOutcome, + pub cancellation_detail: Option, +} + +/// One executed SQL test case. Mirrors `sqlbuild.executor.testing.models.SqlTestExecutionResult`; `V` is a host value. +#[derive(Clone, Debug, PartialEq)] +pub struct SqlTestExecutionResult { + pub test_name: String, + pub outcome: SqlTestOutcome, + pub source_path: Option, + pub block_index: Option, + pub parent_name: Option, + pub case_name: Option, + pub case_index: Option, + pub case_fingerprint: Option, + pub parameter_schema: Vec, + pub parameter_values: Vec<(String, V)>, + pub step_results: Vec, + pub error_code: Option, + pub error_help: Option, + pub error_message: Option, + pub real_model_count: Option, + pub timeout: Option, +} + +/// Everything one build executed, as the executor returns it. Mirrors `sqlbuild.executor.build.models.BuildExecutionResult`; `V` is a host value. +#[derive(Clone, Debug, PartialEq)] +pub struct BuildExecutionResult { + pub status: BuildStatus, + pub model_results: Vec>, + pub seed_results: Vec, + pub function_results: Vec, + pub load_results: Vec>, + pub test_results: Vec>, + pub source_audit_results: Vec>, + pub end_audit_results: Vec>, + pub success_count: i64, + pub failure_count: i64, + pub timeout_count: i64, + pub skipped_count: i64, + pub warning_count: i64, + pub insufficient_count: i64, + pub audit_result_projection_attempted_count: i64, + pub audit_result_projection_written_count: i64, + pub audit_result_projection_failed_count: i64, + pub timings: BuildExecutionTimings, +} diff --git a/crates/sqlbuild-host/src/tests.rs b/crates/sqlbuild-host/src/tests.rs new file mode 100644 index 0000000000..63ac8a7896 --- /dev/null +++ b/crates/sqlbuild-host/src/tests.rs @@ -0,0 +1,6 @@ +#[path = "tests/test_enum_values.rs"] +mod enum_values; +#[path = "tests/helpers.rs"] +mod helpers; +#[path = "tests/test_types.rs"] +mod test_types; diff --git a/crates/sqlbuild-host/src/tests/helpers.rs b/crates/sqlbuild-host/src/tests/helpers.rs new file mode 100644 index 0000000000..5189e6d67f --- /dev/null +++ b/crates/sqlbuild-host/src/tests/helpers.rs @@ -0,0 +1,14 @@ +use crate::types::ResultEnum; + +/// Every member's Python value, in definition order. +pub(super) fn values() -> Vec<&'static str> { + T::ALL.iter().map(|member| member.value()).collect() +} + +/// Each member read back from its Python value, as that value. +pub(super) fn parsed() -> Vec> { + T::ALL + .iter() + .map(|member| T::from_value(member.value()).map(ResultEnum::value)) + .collect() +} diff --git a/crates/sqlbuild-host/src/tests/test_enum_values.rs b/crates/sqlbuild-host/src/tests/test_enum_values.rs new file mode 100644 index 0000000000..00773a54d5 --- /dev/null +++ b/crates/sqlbuild-host/src/tests/test_enum_values.rs @@ -0,0 +1,155 @@ +use crate::models::{ + AttachedAuditTargetKind, AuditAttachmentKind, AuditEvaluationMode, AuditOutcome, AuditRunScope, + AuditSeverity, BuildStatus, CancellationOutcome, ExecutionPhase, ExecutionResourceKind, + ExecutionStatus, HookPhase, ItemKind, LifeCycleEventKind, MicrobatchLimitAction, SkipMode, + SqlTestOutcome, +}; +use crate::tests::helpers::{parsed, values}; +use crate::tests::test_types::EnumValueTestCase; + +#[test] +fn given_result_enums_when_read_by_value_then_they_match_the_python_members() { + let test_cases = [ + EnumValueTestCase { + description: "BuildStatus round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["success", "failed"], + }, + EnumValueTestCase { + description: "ExecutionStatus round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["success", "failed", "skipped"], + }, + EnumValueTestCase { + description: "ExecutionPhase round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec![ + "pre_hook", + "staging", + "schema_change", + "type_enforcement", + "contract", + "audit", + "promotion", + "dml", + "post_hook", + "fingerprint", + "microbatch_state", + "custom_materialization", + ], + }, + EnumValueTestCase { + description: "HookPhase round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["pre_hooks", "post_hooks"], + }, + EnumValueTestCase { + description: "SkipMode round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["soft", "hard"], + }, + EnumValueTestCase { + description: "MicrobatchLimitAction round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["cap_from_end", "cap_from_start", "error", "warn"], + }, + EnumValueTestCase { + description: "ExecutionResourceKind round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec![ + "source", "loader", "seed", "udf", "table_fn", "view", "table", "custom", + "snapshot", + ], + }, + EnumValueTestCase { + description: "SqlTestOutcome round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["pass", "fail", "error", "timeout"], + }, + EnumValueTestCase { + description: "ItemKind round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["test", "scenario", "model"], + }, + EnumValueTestCase { + description: "CancellationOutcome round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec![ + "confirmed", + "unknown", + "failed", + "unsupported", + "not_needed", + ], + }, + EnumValueTestCase { + description: "AuditAttachmentKind round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["source", "seed", "model", "end"], + }, + EnumValueTestCase { + description: "AuditSeverity round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["warn", "error"], + }, + EnumValueTestCase { + description: "AuditOutcome round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["pass", "warn", "error", "insufficient"], + }, + EnumValueTestCase { + description: "AuditRunScope round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["final", "delta_and_final"], + }, + EnumValueTestCase { + description: "AttachedAuditTargetKind round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["model", "source", "seed"], + }, + EnumValueTestCase { + description: "AuditEvaluationMode round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["violations", "measurement"], + }, + EnumValueTestCase { + description: "LifeCycleEventKind round-trips its Python values", + values: values::(), + parsed: parsed::(), + expected_values: vec!["sql", "log"], + }, + ]; + for test_case in test_cases { + assert_eq!( + test_case.values, test_case.expected_values, + "{}", + test_case.description + ); + assert_eq!( + test_case.parsed, + test_case + .expected_values + .iter() + .map(|value| Some(*value)) + .collect::>(), + "{}", + test_case.description + ); + } +} diff --git a/crates/sqlbuild-host/src/tests/test_types.rs b/crates/sqlbuild-host/src/tests/test_types.rs new file mode 100644 index 0000000000..5d4ccd7815 --- /dev/null +++ b/crates/sqlbuild-host/src/tests/test_types.rs @@ -0,0 +1,6 @@ +pub(super) struct EnumValueTestCase { + pub(super) description: &'static str, + pub(super) values: Vec<&'static str>, + pub(super) parsed: Vec>, + pub(super) expected_values: Vec<&'static str>, +} diff --git a/crates/sqlbuild-host/src/types.rs b/crates/sqlbuild-host/src/types.rs new file mode 100644 index 0000000000..cf7f6463d5 --- /dev/null +++ b/crates/sqlbuild-host/src/types.rs @@ -0,0 +1,18 @@ +//! What every executor result enum provides. + +/// A Rust mirror of one Python string enum of executor results. +pub trait ResultEnum: Copy + 'static { + /// Every member, in Python definition order. + const ALL: &'static [Self]; + + /// The member's Python value. + fn value(self) -> &'static str; + + /// The member whose Python value is `value`. + fn from_value(value: &str) -> Option { + Self::ALL + .iter() + .copied() + .find(|member| member.value() == value) + } +} diff --git a/crates/sqlbuild-python/Cargo.toml b/crates/sqlbuild-python/Cargo.toml index a1d6a32b0a..854e25fc40 100644 --- a/crates/sqlbuild-python/Cargo.toml +++ b/crates/sqlbuild-python/Cargo.toml @@ -31,6 +31,7 @@ sqlbuild-config.workspace = true sqlbuild-core.workspace = true sqlbuild-cursor.workspace = true sqlbuild-discovery.workspace = true +sqlbuild-host.workspace = true sqlbuild-model-config.workspace = true sqlbuild-pysource.workspace = true sqlbuild-recall.workspace = true diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/getters.rs new file mode 100644 index 0000000000..017033ba67 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/getters.rs @@ -0,0 +1,36 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_binding_catalog, +}]; + +fn read_binding_catalog<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "schemas" => (&this.schemas).into_bound_py_any(py), + "dialect" => (&this.dialect).into_bound_py_any(py), + "quoted_ignore_case" => (&this.quoted_ignore_case).into_bound_py_any(py), + "analysis_shapes" => (&this.analysis_shapes).into_bound_py_any(py), + "expression_shapes" => (&this.expression_shapes).into_bound_py_any(py), + "native" => (&this.native).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/mod.rs index f7aa48b0a2..39fd6f893b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/mod.rs @@ -2,13 +2,11 @@ pub(crate) mod binding_catalog; pub(crate) mod binding_locations; mod catalog; pub(crate) mod conversions; -pub(crate) mod explicit_references; -pub(crate) mod model_reads; +pub(crate) mod getters; pub(crate) mod normalization; pub(crate) mod normalization_results; mod positions; pub(crate) mod queries; -pub(crate) mod reference_facts; pub(crate) mod relation_names; mod required_columns; pub(crate) mod schema_request; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/queries.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/queries.rs index f06cda8421..2a4e486aae 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/queries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/queries.rs @@ -65,7 +65,7 @@ fn analyze_project_queries_compact_json(py: Python<'_>, request_json: &str) -> P pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { crate::bindings::_helpers::analysis::binding_catalog::register(module)?; crate::bindings::_helpers::analysis::required_columns::register(module)?; - crate::bindings::_helpers::analysis::explicit_references::register(module)?; + crate::bindings::_helpers::references::explicit_references::register(module)?; crate::bindings::_helpers::analysis::binding_locations::register(module)?; module.add_function(wrap_pyfunction!(query_fingerprint, module)?)?; module.add_function(wrap_pyfunction!(schema_validation_json, module)?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs index 706bc92199..0b39e7ebad 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs @@ -1,7 +1,7 @@ //! Fixture column inference computed once per fixture body and inference profile. use crate::bindings::_helpers::analysis_session::fixture_columns::infer_fixture_column_facts; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::records::fields::field as native_field; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/getters.rs new file mode 100644 index 0000000000..e05ca49747 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/getters.rs @@ -0,0 +1,33 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_native_model_analysis_session, +}]; + +fn read_native_model_analysis_session<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "fact_models" => this.fact_models().into_bound_py_any(py), + "cache_stats" => this.cache_stats().into_bound_py_any(py), + "sharing" => this.sharing().into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/mod.rs index 64da3a80e1..fae540de91 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod fixture_columns; pub(crate) mod fixture_inferences; +pub(crate) mod getters; pub(crate) mod model_analyses; pub(crate) mod models; pub(crate) mod nullability_rules; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs index 840a961495..583038d3f1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{IntoPyDict, PyDict, PyDictMethods, PyFrozenSet, PyString}; use sqlbuild_analysis::assembly::analysis_session::types::Shapes; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; use crate::bindings::_helpers::project_assembly::declared_relations::DeclaredShapes; @@ -22,12 +23,11 @@ use crate::bindings::_helpers::cache::native_store::{content_digest, current_cod use crate::bindings::_helpers::compile_driver::analysis_cache::{ AnalysisCacheCounts, record_analysis_cache_metrics, }; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::model_input_view::{ AttachedSchema, NativeModelInput, attached_schema, input_model_name, input_query_sql, input_reference_rows, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; @@ -224,7 +224,7 @@ fn run_session<'py>( .finished_session() .and_then(|finished| finished.relation_tables()) { - crate::bindings::_helpers::compile_delta::context::capture(|capture| { + crate::bindings::_helpers::compile_context::delta::capture(|capture| { capture.relations = Some(tables.clone()); }); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs index 4143d02422..c31963b621 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs @@ -6,9 +6,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::record_behaviours::lineage_facts::{ - confidence_member, transform_kind_member, -}; +use crate::bindings::_helpers::lineage::lineage_facts::{confidence_member, transform_kind_member}; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, record_class}; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs index bdf1ddf33d..94a47c4c04 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs @@ -3,11 +3,11 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_analysis::assembly::analysis_session::types::{Pairs, Shapes}; +use sqlbuild_host::entries::models::AdapterHost; use crate::bindings::_helpers::analysis::binding_catalog::{ BindingCatalog, CASE_SENSITIVE_BINDING_DIALECTS, CatalogKey, NATIVE_DIALECT_ALIASES, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs index 30dd79b759..7c9f654882 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs @@ -341,7 +341,7 @@ pub(crate) fn start_model_analysis_session( ) -> PyResult { let py: Python<'_> = catalog.py(); let mut request: SessionRequest = - crate::bindings::_helpers::compile_delta::context::inject_relations(session_request( + crate::bindings::_helpers::compile_context::delta::inject_relations(session_request( request, ))?; let rule_failure: RuleFailure = RuleFailure::default(); @@ -352,7 +352,7 @@ pub(crate) fn start_model_analysis_session( .compiler_detach(|| start_analysis_session(request, catalog)) .map_err(|reason| internal_error(&reason))?; let cache: Option<(PathBuf, String)> = - cache.filter(|_| crate::bindings::_helpers::compile_delta::context::injection().is_none()); + cache.filter(|_| crate::bindings::_helpers::compile_context::delta::injection().is_none()); let mut cache_path: Option = None; let mut cache_stats: Option = None; if let Some((path, environment)) = cache { @@ -452,7 +452,7 @@ fn session_request(request: RequestRow) -> SessionRequest { dynamic_families_by_table: families_by_table(dynamic_families_by_table), models: models.into_iter().map(model_request).collect(), forced_order: None, - retain_relations: crate::bindings::_helpers::compile_delta::context::capturing(), + retain_relations: crate::bindings::_helpers::compile_context::delta::capturing(), } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs index 6555702ee3..620d94adcf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs @@ -10,19 +10,19 @@ use sqlbuild_core::audit_command::main::render_audit_header::render_audit_header use sqlbuild_core::audit_command::main::render_audit_summary::render_audit_summary; use sqlbuild_core::audit_command::models::AuditCounts; use sqlbuild_core::cli_text::models::CliStyle; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords, within}; use crate::bindings::_helpers::build_progress::audit_progress::AuditProgressReporter; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; use crate::bindings::_helpers::command_runtime::invocation::resolve_reported_command_invocation; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_static_pipeline_result; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords, within}; -use crate::bindings::_helpers::compile_driver::selection_phases::compile_static_command_context; +use crate::bindings::_helpers::compile_driver::static_context::compile_static_command_context; use crate::bindings::_helpers::cost_telemetry::context::CostContext; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::command_plans::build_audit_command_plan; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs b/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs index fbf561bba0..075eb63128 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs @@ -6,9 +6,9 @@ use pyo3::prelude::{ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_analysis::auditing::main::evaluate_measurement::evaluate_measurement as evaluate; use sqlbuild_analysis::auditing::models::{MeasurementOutcome, Thresholds}; +use sqlbuild_host::entries::models::FacadeHost; use crate::bindings::_helpers::auditing::identity::thresholds as read_thresholds; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/mod.rs index dca87c66e6..b74d618669 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/mod.rs @@ -2,3 +2,4 @@ mod fields; pub(crate) mod project_vars; mod python_nodes; pub(crate) mod registration; +pub(crate) mod sql_values; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs index 7d3c5dc290..43990d41a6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs @@ -1,6 +1,7 @@ //! Project variable values rendered as the text SQL and config interpolation inserts. -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use sqlbuild_host::entries::models::FacadeHost; + use crate::bindings::_helpers::native_host::host; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs index 688f801583..98a0f80822 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs @@ -10,14 +10,13 @@ use pyo3::types::{ use pyo3::types::{PyTupleMethods, PyTypeMethods}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::identifier_text::main::is_lowercase_identifier::is_lowercase_identifier; +use sqlbuild_host::entries::models::{FacadeHost, UserCodeHost}; use sqlbuild_model_config::header_metadata::main::json_meta_problem::json_meta_problem; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; const RANDOM_MODULE: &str = "random"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/sql_values.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs rename to crates/sqlbuild-python/src/bindings/_helpers/authored_values/sql_values.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/call_arguments.rs b/crates/sqlbuild-python/src/bindings/_helpers/boundary/call_arguments.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/call_arguments.rs rename to crates/sqlbuild-python/src/bindings/_helpers/boundary/call_arguments.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/boundary/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/boundary/mod.rs index ae146797c9..003e71517d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/boundary/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/boundary/mod.rs @@ -2,9 +2,11 @@ mod positional; mod allocator; +pub(crate) mod call_arguments; pub(crate) mod config_values; pub(crate) mod expected_errors; pub(crate) mod keyword_request; pub(crate) mod oracles; pub(crate) mod panics; mod positional_records; +pub(crate) mod python_calls; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs b/crates/sqlbuild-python/src/bindings/_helpers/boundary/python_calls.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs rename to crates/sqlbuild-python/src/bindings/_helpers/boundary/python_calls.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs index c9ebbe86e0..1802b57764 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs @@ -4,7 +4,9 @@ use std::time::Instant; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; use crate::bindings::_helpers::build_command::completion::{ complete_direct_build, finalize_exceptional_cost, finalize_no_work_with_timings, record_pending_cost, write_partial_timings, @@ -15,11 +17,8 @@ use crate::bindings::_helpers::build_command::planning::{ compile_build_plan, enforce_build_plan_policies, run_defer_clone_prephase, write_compile_target, write_plan_text, }; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; fn run_with_providers(context: &BuildContext<'_>) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs index 96930b3e0d..4e931cd9b7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs @@ -9,7 +9,9 @@ use sqlbuild_core::build_command::main::python_node_failed::python_node_failed; use sqlbuild_core::build_command::main::render_phase_timings::render_phase_timings; use sqlbuild_core::build_command::models::PhaseTimings; use sqlbuild_core::cli_text::models::CliStyle; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; use crate::bindings::_helpers::build_command::execution::{ Outcome, Preparation, write_run_context, }; @@ -19,7 +21,6 @@ use crate::bindings::_helpers::build_command::support::{ }; use crate::bindings::_helpers::build_progress::footer::format_build_footer; use crate::bindings::_helpers::compile_driver::pipeline_entries::plan_has_executable_work; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; use crate::bindings::_helpers::compile_outputs::runtime_target::{ write_python_check_runtime_target, write_runtime_target, }; @@ -27,7 +28,6 @@ use crate::bindings::_helpers::cost_report::degradation::{ finalize_build_cost as finalize_cost, render_build_cost, }; use crate::bindings::_helpers::cost_report::functions::cost_output_payload; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs index 1868d5f7cc..ce26daf791 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs @@ -10,16 +10,16 @@ use pyo3::{IntoPyObject, IntoPyObjectExt, pyfunction, wrap_pyfunction}; use sqlbuild_core::build_command::constants::EXECUTION_LIMIT_BUILD_NOTE; use sqlbuild_core::build_command::errors::BuildCommandError; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; use crate::bindings::_helpers::build_command::invocation::BuildContext; use crate::bindings::_helpers::build_command::policies::build_command_error; use crate::bindings::_helpers::build_command::policies::enforce_model_execution_limit_binding; use crate::bindings::_helpers::clone::clone_pipeline::run_clone_pipeline_with_options; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::clone_plans::{ resolve_clone_boundary, resolve_skipped_view_chain, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs index d20adc24a2..8813268d4d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs @@ -8,7 +8,9 @@ use sqlbuild_config::effective::models::EffectiveConcurrency; use sqlbuild_core::build_command::main::render_run_context::render_run_context; use sqlbuild_core::build_command::models::{RunContextFacts, SelectorFileFact}; use sqlbuild_core::cli_text::models::CliStyle; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords, within}; use crate::bindings::_helpers::build_command::invocation::BuildContext; use crate::bindings::_helpers::build_command::lifecycle::{ DirectPythonLifecycle, LifecycleInputs, prepare_direct_python_lifecycle, @@ -17,21 +19,19 @@ use crate::bindings::_helpers::build_command::support::{ boolean, display_text, emit, frozenset, joined, keyword_relay, line_writer, none, text, tuple, }; use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::check::check_core::{ build_check_relation_targets, load_results_by_loader_name, record_python_run_state_results, relevant_check_functions, }; use crate::bindings::_helpers::check::check_results::write_check_results; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; use crate::bindings::_helpers::command_runtime::warehouses::describe_connection_warehouse; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords, within}; use crate::bindings::_helpers::compile_driver::relation_targets::build_project_relation_targets; use crate::bindings::_helpers::cost_telemetry::context::CostContext; use crate::bindings::_helpers::cursor::overrides::{cursor_integer, cursor_timestamp}; use crate::bindings::_helpers::freshness::publication::append_freshness_records; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_resolution::cursor_overrides::type_cursor_overrides; use crate::bindings::_helpers::records::construct::new_record; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs index c2fca8e628..a81e8e6660 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs @@ -8,17 +8,17 @@ use sqlbuild_core::build_command::errors::BuildCommandError; use sqlbuild_core::build_command::main::duration_limit_error::duration_limit_error; use sqlbuild_core::build_command::models::DurationLimit; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::build_command::policies::build_command_error; use crate::bindings::_helpers::build_command::support::{boolean, or_none, text}; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_settings_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs index 9f2a8137b0..6f9e9476c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs @@ -10,16 +10,16 @@ use pyo3::{pyclass, pymethods}; use sqlbuild_core::build_command::main::render_python_node_rows::render_python_node_rows; use sqlbuild_core::build_command::models::PythonNodeRow; use sqlbuild_core::cli_text::models::CliStyle; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::build_command::support::{ boolean, emit, frozenset, or_none, text, tuple, }; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::compile_driver::relation_targets::build_project_relation_targets; use crate::bindings::_helpers::compile_driver::relation_targets::build_python_relation_targets; use crate::bindings::_helpers::graph::python_lifecycle::build_python_sql_run_lifecycle; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_scope::loaders::build_intermediate_source_map; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs index dc05338074..19dec1b29a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs @@ -6,19 +6,19 @@ use sqlbuild_core::build_command::constants::{ SNAPSHOT_FULL_REFRESH_BUILD_HELP, TABLE_TYPE_DOWNGRADE_BUILD_HELP, }; use sqlbuild_core::build_command::models::PlanSafetyGates; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; use crate::bindings::_helpers::build_command::defer_clone::run_defer_clone_boundary_prephase; use crate::bindings::_helpers::build_command::invocation::BuildContext; use crate::bindings::_helpers::build_command::policies::{enforce_plan_policies, model_limit}; use crate::bindings::_helpers::build_command::support::{ boolean, emit, joined, keyword_relay, none, }; -use crate::bindings::_helpers::cli::progress_text::with_verbose_inspection; -use crate::bindings::_helpers::compile_driver::pipeline::run_compile_pipeline; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; +use crate::bindings::_helpers::build_progress::progress_text::with_verbose_inspection; +use crate::bindings::_helpers::compile_driver::plan_pipeline::run_compile_pipeline; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::manifest::builder::build_manifest; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::plan_text::format_plan; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs index 7bfc43886a..e00364441e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs @@ -16,7 +16,7 @@ use sqlbuild_core::build_command::models::{ TableTypeFact, }; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs index 30feeb51c3..2f888513f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs @@ -6,7 +6,7 @@ use pyo3::types::{ }; use pyo3::{IntoPyObject, pyclass, pymethods}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; const DATETIME_MODULE: &str = "datetime"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs index 2fde1ae5fe..c00bddbda1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs @@ -16,12 +16,12 @@ use sqlbuild_core::nested_progress::main::render_audit_row::render_audit_row; use sqlbuild_core::nested_progress::main::render_group_header::render_group_header; use sqlbuild_core::nested_progress::models::AuditAggregate; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, within}; use crate::bindings::_helpers::build_progress::result_text::{audit_text, optional, text}; use crate::bindings::_helpers::build_progress::terminal::{ CLEAR_LINE, HIDE_CURSOR, SHOW_CURSOR, claim, consume_terminal, flush, projector, release, shared_lines, tty_flag, write, }; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, within}; use crate::bindings::_helpers::records::fields::field as native_field; /// The identity an audit plan entry or result reports to the progress projector. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs index f0d8d137c0..17dcb39cca 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs @@ -20,6 +20,7 @@ use sqlbuild_core::build_progress::models::{ }; use sqlbuild_core::cli_text::models::CliStyle; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported, within}; use crate::bindings::_helpers::build_progress::plan_facts::{BuildPlanFacts, build_plan_facts}; use crate::bindings::_helpers::build_progress::result_text::{ function_text, load_text, model_text, optional, seed_text, test_text, text, @@ -29,7 +30,6 @@ use crate::bindings::_helpers::build_progress::terminal::{ consume_terminal, flush, join_spinner, projector, release, shared_lines, start_spinner, terminal_columns, tty_flag, write, }; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported, within}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::result_output::event_writer::ExecutionEventWriter; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/getters.rs new file mode 100644 index 0000000000..d399ac6fad --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/getters.rs @@ -0,0 +1,55 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; +use crate::bindings::_helpers::build_progress::transient_lines::TransientLineCoordinator; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_build_progress_callbacks, + }, + GetterEntry { + class: class_of::, + read: read_transient_line_coordinator, + }, +]; + +fn read_build_progress_callbacks<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "elapsed" => this.elapsed().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_transient_line_coordinator<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "lock" => (&this.lock).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/mod.rs index 10bc878014..be876d6c6e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/mod.rs @@ -1,8 +1,12 @@ pub(crate) mod audit_progress; pub(crate) mod build_callbacks; pub(crate) mod footer; +pub(crate) mod getters; pub(crate) mod nested_progress; pub(crate) mod plan_facts; +pub(crate) mod progress; +pub(crate) mod progress_reporters; +pub(crate) mod progress_text; pub(crate) mod registration; pub(crate) mod result_text; pub(crate) mod terminal; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs index 89cd2617dd..3a812ed3ed 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs @@ -12,13 +12,13 @@ use sqlbuild_core::nested_progress::main::render_nested_item::render_nested_item use sqlbuild_core::nested_progress::main::render_nested_spinner_line::render_nested_spinner_line; use sqlbuild_core::nested_progress::models::{NestedChildRow, NestedItem, NestedLayout}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, within}; use crate::bindings::_helpers::build_progress::result_text::text; use crate::bindings::_helpers::build_progress::terminal::{ CLEAR_LINE, HIDE_CURSOR, SHOW_CURSOR, SPINNER_FRAMES, SPINNER_TICK_SECONDS, claim, consume_terminal, flush, join_spinner, projector, release, shared_lines, start_spinner, terminal_columns, tty_flag, write, }; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, within}; use crate::bindings::_helpers::records::fields::field as native_field; const MIN_NAME_WIDTH: usize = 50; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs similarity index 99% rename from crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs rename to crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs index 9e4501a2cd..f9ea84f47e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs @@ -17,8 +17,8 @@ use sqlbuild_core::progress::models::{ }; use sqlbuild_core::terminal_events::models::TerminalRequest; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::build_progress::transient_lines::shared_transient_line_coordinator; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_reporters.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs rename to crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_reporters.rs index 036656306a..785eba46c4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_reporters.rs @@ -12,11 +12,11 @@ use sqlbuild_core::progress::main::connection_phase_line::connection_phase_line; use sqlbuild_core::progress::main::connection_start_message::connection_start_message; use sqlbuild_core::progress::main::is_planning_completion_message::is_planning_completion_message; -use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::cli::progress::{ +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::build_progress::progress::{ NativeProgressProjector, current_projector, projector_operation_active, write_persistent, }; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::build_progress::transient_status::status_reporter; const CONNECTION_OPTIONS: (&[&str], &[&str]) = ( &["adapter_name", "stream"], diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_text.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs rename to crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_text.rs index 29c1214b2f..239ebba854 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_text.rs @@ -14,10 +14,10 @@ use sqlbuild_core::progress::main::format_expectation_name::format_expectation_n use sqlbuild_core::progress::main::format_inspection_record::format_inspection_record; use sqlbuild_core::progress::models::{ExpectationStep, InspectionRecord}; use sqlbuild_core::progress::types::DifferenceSample; +use sqlbuild_host::entries::models::AdapterHost; -use crate::bindings::_helpers::cli::progress::write_persistent; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, within}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, within}; +use crate::bindings::_helpers::build_progress::progress::write_persistent; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs index d54cfcf1cf..049d1d71db 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs @@ -1,21 +1,30 @@ //! Executor result objects read into the plain data build progress output renders. +use std::collections::HashMap; + +use pyo3::exceptions::PyValueError; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; +use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_core::build_progress::models::{ AuditResultText, BuildResultText, ErrorText, HookResultText, LifecycleEventText, LoadRowText, ModelResultText, NodeResultText, PythonNodeText, SkipText, TestResultText, TestStepText, }; +use sqlbuild_core::json::main::dumps::dumps; +use sqlbuild_core::json::models::{JsonDialect, StdlibJsonOptions}; use sqlbuild_core::progress::main::format_expectation_detail::format_expectation_detail; +use sqlbuild_core::test_command::main::parameterized_test_label::parameterized_test_label; +use sqlbuild_core::test_command::models::TestParameter; -use crate::bindings::_helpers::cli::progress_text::expectation_step; +use crate::bindings::_helpers::build_progress::progress_text::expectation_step; use crate::bindings::_helpers::plan_output::display::{cursor_bound_display, inclusive_cursor_end}; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::sql_test_command::test_command::test_label; +use crate::bindings::_helpers::result_output::integration_values::json_value; const SQL_EVENT: &str = "sql"; const PRE_HOOKS: &str = "pre_hooks"; const MEASUREMENT: &str = "measurement"; const FAILED: &str = "failed"; +const DECIMAL_KIND: &str = "decimal"; pub(crate) fn text(value: &Bound<'_, PyAny>, name: &str) -> PyResult { Ok(native_field(value, name)?.str()?.to_string()) @@ -241,3 +250,62 @@ pub(crate) fn build_text(result: &Bound<'_, PyAny>) -> PyResult end_audits: audits(result, "end_audit_results")?, }) } + +/// The label of one test or result: its name, plus source and values for parameterized cases. +pub(crate) fn test_label(item: &Bound<'_, PyAny>, name_field: &str) -> PyResult { + let name: String = native_field(item, name_field)?.extract()?; + let source_path: Bound<'_, PyAny> = item.getattr("source_path")?; + let values: Vec> = native_field(item, "parameter_values")? + .try_iter()? + .collect::>()?; + if source_path.is_none() || values.is_empty() { + return Ok(name); + } + let mut schema: HashMap> = HashMap::new(); + for declaration in item.getattr("parameter_schema")?.try_iter()? { + let declaration: Bound<'_, PyAny> = declaration?; + schema.insert(declaration.getattr("name")?.extract()?, declaration); + } + let mut parameters: Vec = Vec::new(); + for pair in values { + let (value_name, value): (String, Bound<'_, PyAny>) = pair.extract()?; + let declaration: &Bound<'_, PyAny> = schema + .get(&value_name) + .ok_or_else(|| pyo3::exceptions::PyKeyError::new_err(value_name.clone()))?; + let raw: Bound<'_, PyAny> = value.getattr("value")?; + let kind: String = value.getattr("kind")?.getattr("value")?.extract()?; + let payload: Bound<'_, PyAny> = if kind == DECIMAL_KIND { + raw.str()?.into_any() + } else { + raw + }; + parameters.push(TestParameter { + name: value_name, + value_type: native_field(&native_field(declaration, "value_type")?, "value")? + .extract()?, + nullable: declaration.getattr("nullable")?.is_truthy()?, + rendered: compact_json(&payload)?, + }); + } + let path: String = source_path.call_method0("as_posix")?.extract()?; + Ok(parameterized_test_label(&name, Some(&path), ¶meters)) +} + +/// A payload as `json.dumps(payload, ensure_ascii=True, separators=(",", ":"))`. +fn compact_json(payload: &Bound<'_, PyAny>) -> PyResult { + let Some(value) = json_value(payload)? else { + let options: Bound<'_, PyDict> = PyDict::new(payload.py()); + options.set_item("ensure_ascii", true)?; + options.set_item("separators", (",", ":"))?; + return payload + .py() + .import("json")? + .call_method("dumps", (payload,), Some(&options))? + .extract(); + }; + dumps( + &value, + &JsonDialect::Stdlib(StdlibJsonOptions::new(None).with_separators(",", ":")), + ) + .map_err(|error| PyValueError::new_err(format!("{error:?}"))) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs index 69a035167b..4e2dc10511 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs @@ -4,9 +4,9 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::types::{PyBool, PyDict, PyDictMethods, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; use crate::bindings::_helpers::build_progress::transient_lines::shared_coordinator; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::records::fields::field as native_field; const DEFAULT_TERMINAL_SIZE: (i64, i64) = (120, 24); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs index c4d48bba4a..5bb373c562 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs @@ -6,8 +6,8 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::sync::PyOnceLock; use pyo3::{pyclass, pyfunction, pymethods, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::build_progress::terminal::tty_flag; -use crate::bindings::_helpers::compile_driver::python_calls::imported; /// The stream a transient line is drawn on and the renderer that owns it. type ActiveLine = (Py, Py); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs index 2d34cf8a75..28661d4698 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs @@ -8,11 +8,11 @@ use pyo3::{pyclass, pymethods}; use sqlbuild_core::cli_text::models::CliStyle; use sqlbuild_core::progress::main::format_status_spinner_line::format_status_spinner_line; +use crate::bindings::_helpers::boundary::python_calls::{imported, within}; use crate::bindings::_helpers::build_progress::terminal::{ CLEAR_LINE, HIDE_CURSOR, SHOW_CURSOR, SPINNER_FRAMES, SPINNER_TICK_SECONDS, claim, flush, join_spinner, release, shared_lines, start_spinner, terminal_columns, tty_flag, write, }; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, within}; use crate::bindings::_helpers::records::fields::field as native_field; const NO_PROGRESS_VARIABLE: &str = "SQLBUILD_NO_PROGRESS"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs b/crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs index b11fdbce05..ea7afd7c27 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs @@ -14,10 +14,10 @@ use sqlbuild_cache::digest::main::installed_code_identity::installed_code_identi use sqlbuild_cache::digest::types::ContentDigest; use sqlbuild_cache::store::main::open_native_store::open_native_store; use sqlbuild_cache::store::models::NativeStore; +use sqlbuild_host::entries::models::FacadeHost; use std::collections::HashSet; use std::path::{Path, PathBuf}; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::ids::NativeAttr; use crate::bindings::_helpers::records::registry; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs b/crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs index 8842001e16..2dc14a49c5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs @@ -7,14 +7,14 @@ use sqlbuild_cache::digest::main::content_digest::content_digest; use sqlbuild_cache::digest::main::hex_digest::hex_digest; use sqlbuild_cache::digest::types::ContentDigest; use sqlbuild_cache::store::models::NativeStore; +use sqlbuild_host::compile_context::main::record_compile_metric::record_compile_metric; use std::path::PathBuf; use std::sync::Mutex; use std::sync::atomic::{AtomicUsize, Ordering}; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cache::native_store::current_code_identity; use crate::bindings::_helpers::cache::native_store::{open_store, save_store}; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_metric; -use crate::bindings::_helpers::compile_driver::python_calls::imported; const SCAN_CACHE_LOGGER: &str = "sqlbuild.compile"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs index 385086be84..5352acf42c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs @@ -1,12 +1,14 @@ //! `sqb check`: run the selected Python checks after their Python dependencies. -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; + +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_static_pipeline_result; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::relation_targets::build_project_relation_targets; use crate::bindings::_helpers::compile_driver::relation_targets::build_python_relation_targets; -use crate::bindings::_helpers::compile_driver::selection_phases::compile_static_command_context; +use crate::bindings::_helpers::compile_driver::static_context::compile_static_command_context; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::graph::algorithms::transitive_closure_many; use crate::bindings::_helpers::graph::execution_gates::sql_ref_key; @@ -30,6 +32,7 @@ use sqlbuild_core::check_command::main::validate_check_selection::validate_check use sqlbuild_core::check_command::models::CheckResultText; use sqlbuild_core::cli_text::models::CliStyle; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::check::check_core::{ ReadSideInputs, load_results_by_loader_name, record_python_run_state_results, run_read_side_dependencies, @@ -38,13 +41,10 @@ use crate::bindings::_helpers::check::check_results::{ check_result_text, results_json, write_results, }; use crate::bindings::_helpers::command_runtime::invocation::resolve_reported_command_invocation; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::compile_outputs::runtime_target::write_python_check_runtime_target; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; use crate::bindings::_helpers::graph::python_selection::python_node_names; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs index aa6932e110..2f64d0e6d3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs @@ -1,6 +1,8 @@ //! Python check planning: run-state recording, dependency relations and read-side preflight. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost, UserCodeHost}; + +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::relation_targets::build_python_relation_targets; use crate::bindings::_helpers::graph::python_selection::resolve_python_check_excludes; use crate::bindings::_helpers::planner_phases::objects::object; @@ -13,12 +15,9 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::build_command::errors::BuildCommandError; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::build_command::policies::build_command_error; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs index 04acf9bd3a..d9c236d62d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs @@ -14,8 +14,8 @@ use sqlbuild_core::check_command::models::{CheckGrouping, CheckResultText, Check use sqlbuild_core::cli_text::models::CliStyle; use sqlbuild_core::json::models::JsonValue; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::result_output::integration_values::json_value; use crate::bindings::_helpers::result_output::terminal_index::current_terminal_event_index; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs index cdc5fde694..8a2589e5e1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs @@ -52,7 +52,7 @@ use sqlbuild_cli::dispatch::models::{ use sqlbuild_core::format_command::main::format_path_selectors::format_path_selectors; use sqlbuild_core::text::main::python_strip::python_strip; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, within}; +use crate::bindings::_helpers::boundary::python_calls::{imported, within}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs index 92c5486ca8..61fb26ea65 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs @@ -13,6 +13,9 @@ use sqlbuild_cli::dispatch::main::failure_report::failure_report; use sqlbuild_cli::dispatch::main::invocation_policy::invocation_policy; use sqlbuild_cli::dispatch::models::{CommandFacts, CommandFailure, InvocationPolicy}; +use sqlbuild_host::entries::models::{ExecutorHost, FacadeHost}; + +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords, within}; use crate::bindings::_helpers::build_progress::transient_lines::shared_transient_line_coordinator; use crate::bindings::_helpers::cli::argv::parse_cli_invocation; use crate::bindings::_helpers::cli::dispatch::{command_facts, dispatch_command}; @@ -21,12 +24,7 @@ use crate::bindings::_helpers::cli::observability::{ CliObservabilityScope, cli_observability_scope, }; use crate::bindings::_helpers::compile_command::report::format_compile_error_json; -use crate::bindings::_helpers::compile_driver::python_calls::{ - call_with, imported, keywords, within, -}; -use crate::bindings::_helpers::diff_report::registration::render_diff_error_json; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use crate::bindings::_helpers::diff_report::output::render_diff_error_json; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::output_capture::records::invocation_context; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/mod.rs index 118be0fbed..871fd065d2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/mod.rs @@ -4,8 +4,5 @@ pub(crate) mod entry; pub(crate) mod launch_state; pub(crate) mod namespace; pub(crate) mod observability; -pub(crate) mod progress; -pub(crate) mod progress_reporters; -pub(crate) mod progress_text; pub(crate) mod registration; pub(crate) mod surrogates; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs index a5f2f695c3..fb81e25eea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs @@ -13,17 +13,16 @@ use sqlbuild_cli::dispatch::main::closing_status::closing_status; use sqlbuild_cli::dispatch::main::event_export_warning::event_export_warning; use sqlbuild_cli::dispatch::models::{ExportSummary, ExporterLoss}; use sqlbuild_core::event_export::constants::DEFAULT_EVENT_EXPORT_SHUTDOWN_TIMEOUT_SECONDS; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::build_progress::progress::NativeProgressProjector; +use crate::bindings::_helpers::build_progress::progress::machine_output_mode; use crate::bindings::_helpers::cli::launch_state::withhold_launch_record; -use crate::bindings::_helpers::cli::progress::NativeProgressProjector; -use crate::bindings::_helpers::cli::progress::machine_output_mode; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope; use crate::bindings::_helpers::event_exporting::scope::event_exporter_command_scope; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::recall::console::write_stderr; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/registration.rs index 7f26b84889..84a52f27ab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/registration.rs @@ -2,10 +2,8 @@ use pyo3::prelude::{Bound, PyModule, PyResult}; -use crate::bindings::_helpers::cli::{ - argv, entry, launch_state, namespace, observability, progress, progress_reporters, - progress_text, -}; +use crate::bindings::_helpers::build_progress::{progress, progress_reporters, progress_text}; +use crate::bindings::_helpers::cli::{argv, entry, launch_state, namespace, observability}; use crate::bindings::_helpers::{ audit_command, build_command, build_progress, check, clone, command_runtime, compute_logs, contract_command, cost_command, cost_report, cost_telemetry, dbt_command, dbt_events, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs index 098bca4a05..06194488c5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs @@ -17,8 +17,11 @@ use sqlbuild_core::clone_text::main::render_clone_header::render_clone_header; use sqlbuild_core::clone_text::main::validate_clone_policy::validate_clone_policy; use sqlbuild_core::clone_text::main::validate_clone_target_names::validate_clone_target_names; use sqlbuild_core::clone_text::models::CloneItemText; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; use crate::bindings::_helpers::clone::clone_execution::{ destination_entry_count, execute_clone_plan, resource_types_by_name, }; @@ -27,14 +30,11 @@ use crate::bindings::_helpers::clone::clone_progress::{clone_item_text, write_li use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_target_connection_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::native_host::connections::connection_failure; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs index 1c0aa53e7b..d5afb129b8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs @@ -7,14 +7,14 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyFrozenSet, PyString}; use sqlbuild_core::clone_text::main::clone_relation_flow_text::clone_relation_flow_text; use sqlbuild_core::clone_text::models::FingerprintProgress; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; use crate::bindings::_helpers::clone::clone_command::Invocation; use crate::bindings::_helpers::clone::clone_progress::{ CloneFingerprintReporter, CloneItemPrinter, }; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs index 36e5c150f1..34e409d3c7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs @@ -5,8 +5,8 @@ use pyo3::types::{PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::boundary::keyword_request::Request; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::planner_entries::clone_plans::run_clone_planning; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs index d142cba47f..2b6eaa279a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs @@ -5,9 +5,9 @@ use pyo3::prelude::{ }; use pyo3::types::{PyDict, PyDictMethods}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::AdapterHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs index 008b378149..1e502bab25 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs @@ -12,19 +12,17 @@ use sqlbuild_config::command_connection::constants::{ use sqlbuild_config::command_connection::main::missing_connection_error::missing_connection_error; use sqlbuild_config::command_connection::main::snowflake_key_warning::snowflake_key_warning; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; +use sqlbuild_host::entries::models::ThirdPartyHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported, keywords}; use crate::bindings::_helpers::command_runtime::runtime_errors::raised; use crate::bindings::_helpers::command_runtime::warehouses::{WarehouseInputs, apply_warehouse}; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_connection_config; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, imported, keywords, -}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::dbt_interop::profile_connection::resolve_raw_dbt_profile_connection; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; const CONNECTION_OPTIONS: (&[&str], &[&str]) = ( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs index 92558b69c3..64e2663f1b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs @@ -3,13 +3,13 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyBool; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs index f056830088..da4b96cf18 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs @@ -16,19 +16,19 @@ use sqlbuild_config::command_connection::main::unsupported_cli_warehouse::unsupp use sqlbuild_config::command_connection::models::AuthoredWarehouse; use sqlbuild_core::text::main::python_strip::python_strip; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_model_config::templates::models::TemplateOptions; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::command_runtime::runtime_errors::{ expected_resolution_error, raised, }; use crate::bindings::_helpers::command_runtime::warehouse_scope::current_command_warehouse_scope; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_runtime_config; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::discovery::configuration::discover_project_configuration; use crate::bindings::_helpers::model_config::template_data::expanded_template_data; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs index 68a6c51b19..6a5e490b73 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs @@ -4,8 +4,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString}; -use crate::bindings::_helpers::compiled_project::model_input_view::input_reference_rows; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::model_input_view::input_reference_rows; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs index 1c55a14c72..cff75cd247 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs @@ -4,8 +4,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::pyfunction; use pyo3::types::PyTuple; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::cache::sql_test_scan_store::SqlTestScanCache; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::compile_driver::stage_work::{DECLARATION_SCOPES, count_stage}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs index 26c7721cb9..80ad38ac57 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs @@ -6,7 +6,7 @@ use pyo3::types::{PyDict, PyString, PyTuple}; use sqlbuild_model_config::templates::models::TemplateOptions; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::contracts::effective_config::effective_config_connection; use crate::bindings::_helpers::contracts::effective_config::effective_config_settings; use crate::bindings::_helpers::contracts::effective_config::effective_config_vars; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_config.rs index 3195beb87c..67381e1650 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_config.rs @@ -5,7 +5,7 @@ use pyo3::pyfunction; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use crate::bindings::_helpers::compile_attachment::storage_policies::inherited_storage; -use crate::bindings::_helpers::compiled_project::loop_classes::table_backed; +use crate::bindings::_helpers::input_loops::loop_classes::table_backed; use crate::bindings::_helpers::model_config::model_config_builder::NativeModelConfigBuilder; use crate::bindings::_helpers::model_config::unicode_environment::unicode_environment; use crate::bindings::_helpers::records::construct::{new_record, new_record_with, record_class}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs index ee385e3913..d8a3636880 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs @@ -5,16 +5,16 @@ use pyo3::pyfunction; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyString, PyTuple}; use sqlbuild_analysis::assembly::project::main::sql_analysis_opt_out_help::sql_analysis_opt_out_help; +use sqlbuild_host::entries::models::UserCodeHost; + use crate::bindings::_helpers::attachments::cursor_intrinsics::reserved_cursor_markers; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::compile_attachment::model_config::native_model_config_session; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; -use crate::bindings::_helpers::compiled_project::loop_classes::model_loop_classes; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopSwitches, NativeModelLoop}; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; +use crate::bindings::_helpers::input_loops::loop_classes::model_loop_classes; +use crate::bindings::_helpers::input_loops::model_loop::{LoopSwitches, NativeModelLoop}; use crate::bindings::_helpers::model_config::contract_classes::contract_classes; use crate::bindings::_helpers::model_config::model_validator::NativeModelValidator; use crate::bindings::_helpers::model_config::unicode_environment::unicode_environment; @@ -25,7 +25,6 @@ use crate::bindings::_helpers::render::declaration_values::ConstantRendering; use crate::bindings::_helpers::render::macro_expansion_result::macro_expansion_classes; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; @@ -230,7 +229,7 @@ pub(crate) fn build_model_inputs<'py>( vec![ ( "report_diagnostic", - pyo3::wrap_pyfunction!(crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic, py)?.into_any(), + pyo3::wrap_pyfunction!(crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic, py)?.into_any(), ), ( "record_template_reads", @@ -266,7 +265,7 @@ pub(crate) fn build_model_inputs<'py>( )?; let syntax: Bound<'py, PyAny> = native_field(context, "sql_lexical_syntax")?; let native_loop: Bound<'py, PyAny> = - crate::bindings::_helpers::compiled_project::model_loop::NativeModelLoop::new( + crate::bindings::_helpers::input_loops::model_loop::NativeModelLoop::new( ( validator.unbind(), contract_classes(py)?.unbind(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs index 4dfc17cce2..db6644020c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs @@ -1,22 +1,24 @@ //! The SQL expansion inputs lint uses to expand authored SQL outside a compile. -use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; use pyo3::types::{PyBool, PyDict, PyDictMethods}; +use sqlbuild_host::entries::models::UserCodeHost; + +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_attachment::declaration_scope::build_declaration_scope; use crate::bindings::_helpers::compile_attachment::declaration_scope::rebind_declaration_scope; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_vars; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_collection_rendering; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::render::declaration_indexes::public_declaration_indexes; use pyo3::IntoPyObjectExt; @@ -80,69 +82,6 @@ fn local_declarations<'py>(discovered: &Bound<'py, PyAny>) -> PyResult, - pub(crate) loaded_macros: Py, - pub(crate) macro_context: Py, - pub(crate) enums: Py, - pub(crate) constants: Py, - pub(crate) value_renderer: Py, - pub(crate) collection_rendering: Py, - /// Each model file's own declarations, by file path. - pub(crate) local_declarations: Py, - pub(crate) declaration_resolver: Py, -} - -impl SqlExpansionInputs { - /// The inputs a `SqlExpansionContext` record holds. - pub(crate) fn from_record(record: &Bound<'_, PyAny>) -> PyResult { - let field = - |name: &str| -> PyResult> { Ok(native_field(record, name)?.unbind()) }; - Ok(Self { - effective_vars: field("effective_vars")?, - loaded_macros: field("loaded_macros")?, - macro_context: field("macro_context")?, - enums: field("enums")?, - constants: field("constants")?, - value_renderer: field("value_renderer")?, - collection_rendering: field("collection_rendering")?, - local_declarations: native_field(record, "local_declarations")? - .downcast_into::()? - .unbind(), - declaration_resolver: field("declaration_resolver")?, - }) - } - - /// These inputs as a `SqlExpansionContext` record. - pub(crate) fn record<'py>(&self, py: Python<'py>) -> PyResult> { - new_record_with( - py, - RecordId::SqlExpansionContext, - &[ - ("effective_vars", self.effective_vars.bind(py).clone()), - ("loaded_macros", self.loaded_macros.bind(py).clone()), - ("macro_context", self.macro_context.bind(py).clone()), - ("enums", self.enums.bind(py).clone()), - ("constants", self.constants.bind(py).clone()), - ("value_renderer", self.value_renderer.bind(py).clone()), - ( - "collection_rendering", - self.collection_rendering.bind(py).clone(), - ), - ( - "local_declarations", - self.local_declarations.bind(py).clone().into_any(), - ), - ( - "declaration_resolver", - self.declaration_resolver.bind(py).clone(), - ), - ], - ) - } -} - /// Where SQL expansion inputs come from: the project, its discovery and the scope to reuse. pub(crate) struct ExpansionSources<'py> { pub(crate) project_dir: Bound<'py, PyAny>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs index 04843b64d5..0a536f34de 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs @@ -4,11 +4,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::compile_attachment::effective_config::project_vars; use crate::bindings::_helpers::compile_command::constants::{ COMPILE_CACHE_DISABLE_ENV_VAR, COMPILE_CACHE_DISABLE_VALUE, RETIRED_CACHE_DIRECTORY_NAMES, }; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::frontier::cache_directory::cache_directory; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/artifact_batch.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/artifact_batch.rs index a0bcf70fb8..1fc3984b85 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/artifact_batch.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/artifact_batch.rs @@ -4,12 +4,12 @@ use std::path::PathBuf; use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; +use sqlbuild_host::compile_context::main::add_compile_timing::add_compile_timing; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; use crate::bindings::_helpers::compile_command::reuse_recording::{ ArtifactRecorder, artifact_written, artifact_written_at, }; -use crate::bindings::_helpers::compile_driver::compile_timings::add_compile_timing; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_timing; use crate::bindings::_helpers::compile_outputs::artifacts::{ BackgroundArtifactWriter, write_compiled_artifacts, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/getters.rs new file mode 100644 index 0000000000..c46490d7fb --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/getters.rs @@ -0,0 +1,111 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; +use crate::bindings::_helpers::compile_command::prepared_artifacts::PreparedCompileArtifacts; +use crate::bindings::_helpers::compile_command::reuse_recording::{ + CompileArtifactWrites, RecordedCompileOutput, +}; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_compile_reuse_attempt, + }, + GetterEntry { + class: class_of::, + read: read_prepared_compile_artifacts, + }, + GetterEntry { + class: class_of::, + read: read_compile_artifact_writes, + }, + GetterEntry { + class: class_of::, + read: read_recorded_compile_output, + }, +]; + +fn read_compile_reuse_attempt<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "outcome" => (&this.outcome).into_bound_py_any(py), + "project_dir" => (&this.project_dir).into_bound_py_any(py), + "started" => (&this.started).into_bound_py_any(py), + "check_ms" => (&this.check_ms).into_bound_py_any(py), + "exit_code" => (&this.exit_code).into_bound_py_any(py), + "entry_path" => (&this.entry_path).into_bound_py_any(py), + "native" => (&this.native).into_bound_py_any(py), + "selected_target" => (&this.selected_target).into_bound_py_any(py), + "json_output" => (&this.json_output).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_prepared_compile_artifacts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "enabled" => this.enabled().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_compile_artifact_writes<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "artifacts" => this + .artifacts(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_recorded_compile_output<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "stderr_lines" => this.stderr_lines(py).into_bound_py_any(py), + "stdout" => this.stdout(py).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/mod.rs index a10d21a019..53a8cc1556 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod artifact_batch; pub(crate) mod constants; +pub(crate) mod getters; pub(crate) mod models; pub(crate) mod prepared_artifacts; pub(crate) mod registration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs index 5a5a0ab866..037eea53f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs @@ -4,8 +4,8 @@ use pyo3::prelude::{Bound, Py, PyAny, PyResult, Python}; use pyo3::types::PyDict; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::compile_command::constants::REUSE_ATTEMPT_FIELDS; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; /// Result of checking for a reusable compile, carried into a full compile on a miss. #[pyclass(module = "sqlbuild._native", frozen, get_all)] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs index 16f06e3c38..de793bf5cc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs @@ -7,6 +7,9 @@ use pyo3::prelude::{ use pyo3::types::{PyCFunction, PyDict, PyFrozenSet, PyTuple}; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, imported, keywords, +}; use crate::bindings::_helpers::compile_command::reuse_recording::CompileArtifactWrites; use crate::bindings::_helpers::compile_command::target_writer::{ PlannedStaticSqlTests, plan_static_sql_tests, @@ -14,9 +17,6 @@ use crate::bindings::_helpers::compile_command::target_writer::{ use crate::bindings::_helpers::compile_command::target_writer::{ Prepared, planning_diagnostics, publish_staged_target, staging_changed, write_static_target, }; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, keywords, -}; use crate::bindings::_helpers::compile_driver::stage_work::{ BACKGROUND_SQL_TEST_PLANS, count_stage, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs index d06d17d092..9b8cd39722 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs @@ -10,16 +10,16 @@ use sqlbuild_core::cli_text::main::semantic_coverage_notice::semantic_coverage_n use sqlbuild_core::cli_text::models::{ CliStyle, CompileTextReport, DiagnosticText, LineageNote, LocationText, ModelLine, RelatedText, }; +use sqlbuild_host::entries::models::UserCodeHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::compile_command::surrogates::SurrogateText; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::compile_outputs::json_report::{ emit_json_report, emit_orjson_report, }; use crate::bindings::_helpers::discovery::constants::SQL_HOOK_OUTPUT_FIELDS; use crate::bindings::_helpers::discovery::hook_entries::hook_entries; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; @@ -163,7 +163,7 @@ impl<'py> ReportInputs<'py> { return Ok(PyDict::new(py)); } let reasons: Bound<'py, PyDict> = semantic_coverage(&self.project)?; - if crate::bindings::_helpers::compile_delta::context::injection().is_some() { + if crate::bindings::_helpers::compile_context::delta::injection().is_some() { return Ok(reasons); } let Some(names) = self.selected_names(MODEL_TYPE)? else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs index 1544d28982..445eda2c01 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs @@ -12,9 +12,13 @@ use sqlbuild_cli::replay::main::write_launch_record::write_launch_record as writ use sqlbuild_core::command_output::constants::INVOCATION_CONTEXT_ENV; use sqlbuild_cli::replay::constants::{LAUNCH_RECORD_DIRECTORY, LAUNCH_RECORD_FORMAT}; +use sqlbuild_host::entries::models::{ExecutorHost, FacadeHost}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::build_progress::progress::{ + NativeProgressProjector, current_projector, +}; use crate::bindings::_helpers::cli::launch_state::launch_record_path; -use crate::bindings::_helpers::cli::progress::{NativeProgressProjector, current_projector}; use crate::bindings::_helpers::compile_command::constants::{ COMPILE_CACHE_DISABLE_ENV_VAR, COMPILE_CACHE_DISABLE_VALUE, COMPILE_COMMAND_NAME, COMPILED_DIRECTORY_NAME, COMPUTE_LOG_DIRECTORY_NAME, EXCLUDED_DIRECTORIES, @@ -31,19 +35,17 @@ use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; use crate::bindings::_helpers::compile_command::runtime_identity::{ invocation_identity, redirected_output_files, runtime_identity, }; +use crate::bindings::_helpers::compile_context::delta; use crate::bindings::_helpers::compile_delta::driver::{ self, DELTA_VERIFY_ENV_VAR, DeltaOutcome, delta_enabled, env_enabled, }; -use crate::bindings::_helpers::compile_delta::{context, verify}; +use crate::bindings::_helpers::compile_delta::verify; use crate::bindings::_helpers::compile_driver::command::run_compile_command; use crate::bindings::_helpers::compile_driver::phases::{elapsed_ms, monotonic}; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::compile_outputs::json_report::plain_json; use crate::bindings::_helpers::compile_outputs::reuse::{ReuseCheckPy, check_compile_reuse}; use crate::bindings::_helpers::frontier::cache_directory::cache_directory; use crate::bindings::_helpers::macro_bridge::first_compile::keep_delta_claim; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::fields::field as native_field; @@ -511,7 +513,7 @@ pub(crate) fn run_compile<'py>(request: &Bound<'py, PyAny>) -> PyResult( None => Ok(()), } }; - context::reset(); + delta::reset(); let project_dir: Bound<'py, PyAny> = native_field(attempt, "project_dir")?; let cache: Bound<'py, PyAny> = cache_directory(&project_dir)?; let compiled_root: PathBuf = std::path::absolute( @@ -583,7 +585,7 @@ fn compiled_with_delta<'py>( &format!("delta compile fell back: {reason}").into_bound_py_any(py)?, )?; } - context::start_capture(); + delta::start_capture(); return run_compile_command(py, request.clone(), Some(attempt.clone())); } DeltaOutcome::Finished(finished) => verify::hold_expected(verify::Expected { @@ -600,7 +602,7 @@ fn compiled_with_delta<'py>( ..verify::Expected::default() }), } - context::start_capture(); + delta::start_capture(); let full: PyResult = run_compile_command(py, request.clone(), Some(attempt.clone())); let raised: Option = full.as_ref().err().map(ToString::to_string); let differences: Vec = verify::differences(raised); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs index 7b1471283a..400b3c3faf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs @@ -11,20 +11,19 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString, PyStri use pyo3::{IntoPyObjectExt, pyclass, pyfunction, pymethods, wrap_pyfunction}; use sqlbuild_core::posix_path::main::posix_abspath::posix_abspath; +use sqlbuild_host::entries::models::{FacadeHost, UserCodeHost}; +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, imported, keywords, +}; use crate::bindings::_helpers::compile_command::constants::{ BYTES_PER_MEBIBYTE, REUSE_BYPASS_TIMING, REUSE_CHECK_TIMING, REUSE_HIT_TIMING, REUSE_LOGGER_NAME, REUSE_MISS_TIMING, REUSE_STORE_DONE_PREFIX, REUSE_STORE_NOTICE_BYTES, REUSE_STORE_NOTICE_PATHS, REUSE_STORE_SKIPPED_PREFIX, }; use crate::bindings::_helpers::compile_command::reuse_attempt::{reuse_rules, write_launch_record}; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, keywords, -}; use crate::bindings::_helpers::compile_outputs::reuse::artifact_digest; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; const MISS_OUTCOME: &str = "miss"; @@ -299,7 +298,7 @@ pub(crate) fn print_to<'py>( impl RecordedCompileOutput { /// Print one stderr result line, such as a note, and record it; a delta only records it. pub(crate) fn print_stderr_line(&self, line: Bound<'_, PyString>) -> PyResult<()> { - if crate::bindings::_helpers::compile_delta::context::injection().is_none() { + if crate::bindings::_helpers::compile_context::delta::injection().is_none() { print_to(line.py(), "stderr", &line)?; } self.locked().0.push(line.unbind()); @@ -525,7 +524,7 @@ fn record<'py>(facts: &CompileFacts<'py>) -> PyResult { ("rules", reuse_rules(py, true)?.into_any()), ], )?; - if let Some(mut capture) = crate::bindings::_helpers::compile_delta::context::take_capture() { + if let Some(mut capture) = crate::bindings::_helpers::compile_context::delta::take_capture() { capture.environment_names = native_field(&facts.input_reads, "environment_names")?.extract()?; let json_output: bool = facts.json_output.is_truthy()?; @@ -538,7 +537,7 @@ fn record<'py>(facts: &CompileFacts<'py>) -> PyResult { if let Ok(sections) = image.encode() { pending = Some(sections); } - crate::bindings::_helpers::compile_delta::context::set_pending_image(pending); + crate::bindings::_helpers::compile_context::delta::set_pending_image(pending); } Err(reason) => { crate::bindings::_helpers::compile_command::reuse_attempt::reuse_debug( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs index 1e3fd55db4..af0aaa811d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs @@ -5,7 +5,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; use sqlbuild_cli::replay::main::output_file_identities::output_file_identities; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::NativeAttr; use crate::bindings::_helpers::records::registry; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs index 3be85bc159..1564f7d679 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs @@ -11,7 +11,7 @@ use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; use sqlbuild_cache::startup_inputs::main::startup_stamps::startup_stamps; use sqlbuild_cache::startup_inputs::models::{StartupLocations, StartupStamp}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; const OS_MODULE: &str = "os"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index 25c5bdb758..ffeb324443 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -12,8 +12,13 @@ use pyo3::{IntoPyObjectExt, pyclass, pyfunction, wrap_pyfunction}; use sqlbuild_cache::artifacts::main::new_sql_test_record::new_sql_test_record; use sqlbuild_cache::artifacts::main::reusable_sql_test_record::reusable_sql_test_record; use sqlbuild_cache::artifacts::models::SqlTestArtifactRecord; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::analysis::sql_test_comparisons::single_comparison_sql; +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, imported, keywords, within, +}; use crate::bindings::_helpers::compile_command::artifact_batch::ArtifactBatch; use crate::bindings::_helpers::compile_command::constants::RACY_WINDOW_NS; use crate::bindings::_helpers::compile_command::reuse_recording::{ @@ -23,10 +28,6 @@ use crate::bindings::_helpers::compile_command::test_artifact_cache::{ IdentityContext, artifact_identity_payload, artifact_record_key_payload, identity_context, payload_digests, read_cache, write_cache, yield_interpreter, }; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_timing; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, keywords, within, -}; use crate::bindings::_helpers::compile_driver::stage_work::{ SQL_TEST_ARTIFACT_PLANS, SQL_TEST_MODEL_CHAINS, count_stage, }; @@ -36,16 +37,15 @@ use crate::bindings::_helpers::compile_outputs::artifacts::{ use crate::bindings::_helpers::compile_outputs::runtime_target::{ compiled_sql_test_path, planned_sql_test_path, }; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::planner_entries::plan_output::sql_test_model_chain_names_by_key; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::sql_test_glue::plan_driver::plan_compiled_sql_test_artifacts; +use crate::bindings::_helpers::sql_test_glue::plan_driver::sql_test_model_chain_names_by_key; const COMPILED_DIR: &str = "compiled"; const MODELS_DIR: &str = "models"; @@ -617,7 +617,7 @@ fn write_static_tests<'py>( } } let cache_dir: Bound<'py, PyAny> = native_field(project, "compile_cache_dir")?; - if crate::bindings::_helpers::compile_delta::context::injection().is_some() { + if crate::bindings::_helpers::compile_context::delta::injection().is_some() { let mut kept: HashMap = read_cache(&cache_dir)?; for (key, record) in records.drain(..) { kept.insert(key, record); @@ -638,7 +638,7 @@ pub(crate) fn write_static_target<'py>( ) -> PyResult> { let py: Python<'py> = target_dir.py(); let remove_stale_files: bool = prepared_target(target_dir)? - && crate::bindings::_helpers::compile_delta::context::injection().is_none(); + && crate::bindings::_helpers::compile_context::delta::injection().is_none(); let mut batch: ArtifactBatch = ArtifactBatch::new(remove_stale_files, prepared.recorder); let mut managed: Vec> = Vec::new(); let mut managed_models: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs index 97c3b49e45..b815114b3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs @@ -12,7 +12,7 @@ use sqlbuild_cache::artifacts::models::{SqlTestArtifactRecord, StoredSqlTestReco use sqlbuild_cache::digest::main::bytes_digest::bytes_digest; use sqlbuild_cache::digest::main::hex_digest::hex_digest; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::compile_outputs::json_report::{compact_sorted_json, orjson_sorted}; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_context/compile_timings.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/compile_timings.rs new file mode 100644 index 0000000000..b9746ab7f5 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/compile_timings.rs @@ -0,0 +1,21 @@ +//! The process clock compile CPU timings read: Python's `time.process_time_ns`. + +use pyo3::PyErr; +use pyo3::prelude::{PyAnyMethods, PyResult, Python}; +use sqlbuild_host::compile_context::types::ProcessClock; + +use crate::bindings::_helpers::boundary::python_calls::imported; + +/// The process CPU clock of one interpreter, including its worker threads. +#[derive(Clone, Copy)] +pub(crate) struct PythonProcessClock<'py>(pub(crate) Python<'py>); + +impl ProcessClock for PythonProcessClock<'_> { + type Error = PyErr; + + fn process_time_ns(&self) -> PyResult { + imported(self.0, "time", "process_time_ns")? + .call0()? + .extract() + } +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/coverage.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/coverage.rs similarity index 83% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/coverage.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/coverage.rs index 0b40ab3fd1..1c14d9a98d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/coverage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/coverage.rs @@ -2,29 +2,12 @@ use std::collections::{BTreeSet, HashMap, HashSet}; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; + /// The reason a model that opts out of SQL analysis is partial. pub(crate) const ANALYSIS_DISABLED: &str = "SQL analysis disabled"; const INVALID_DEPENDENCY: &str = "depends on invalid model"; -/// What one model contributes to the partial-check reasons, apart from its dependencies. -#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub(crate) struct ModelCoverage { - pub(crate) name: String, - /// The model opts out of SQL analysis. - pub(crate) disabled: bool, - /// The model has a binding error, which makes every model reading it partial. - pub(crate) blocked: bool, - /// Its own reasons, sorted; those from invalid dependencies are derived. - pub(crate) partial: Vec, -} - -impl ModelCoverage { - /// Whether the model adds anything to the reasons. - pub(crate) fn notable(&self) -> bool { - self.disabled || self.blocked || !self.partial.is_empty() - } -} - /// Each model's partial-check reasons, in `order`, which pairs each model with its upstream. pub(crate) fn coverage_reasons( order: &[(String, Vec)], diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/context.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/delta.rs similarity index 83% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/context.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/delta.rs index 1f2d422c3d..3b9826048f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/delta.rs @@ -3,12 +3,77 @@ use std::collections::{BTreeMap, BTreeSet}; use std::sync::{Arc, Mutex, MutexGuard, PoisonError}; +use pyo3::prelude::PyResult; + use sqlbuild_analysis::assembly::analysis_session::models::{RelationTables, SessionRequest}; use sqlbuild_cache::project_reuse::types::ImageSections; -use sqlbuild_rules::models::RetainedRows; +use sqlbuild_rules::engine::main::retained_request::retained_request; +use sqlbuild_rules::models::{EvaluateRequest, RetainedRows}; + +/// Whether edits that report or raise errors compile as deltas; until then they fall back. +pub(crate) const ERRORS_ON_DELTA_PATH: bool = true; -use crate::bindings::_helpers::compile_delta::coverage::ModelCoverage; -use crate::bindings::_helpers::compile_delta::image::PendingRules; +/// One model's header keys with the digest of each authored value, sorted by key. +pub(crate) type HeaderKeys = Vec<(String, String)>; + +/// What one model contributes to the partial-check reasons, apart from its dependencies. +#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub(crate) struct ModelCoverage { + pub(crate) name: String, + /// The model opts out of SQL analysis. + pub(crate) disabled: bool, + /// The model has a binding error, which makes every model reading it partial. + pub(crate) blocked: bool, + /// Its own reasons, sorted; those from invalid dependencies are derived. + pub(crate) partial: Vec, +} + +impl ModelCoverage { + /// Whether the model adds anything to the reasons. + pub(crate) fn notable(&self) -> bool { + self.disabled || self.blocked || !self.partial.is_empty() + } +} + +/// A stored compile's built-in rules request, as decoded for a delta compile. +#[derive(Clone, Debug)] +pub(crate) struct BaseRules { + pub(crate) request: EvaluateRequest, + /// Each model's payload digest, which keys its cached findings, in model order. + pub(crate) digests: Vec, +} + +impl BaseRules { + /// The rows a compile retained, decoded. + pub(crate) fn decoded(retained: &RetainedRows) -> Option { + Some(Self { + request: retained_request(retained)?, + digests: retained.digests.clone(), + }) + } +} + +/// A stored rules request, decoding on its own thread or decoded already. +#[derive(Debug)] +pub(crate) enum PendingRules { + Decoding(std::thread::JoinHandle>), + Ready(Box), +} + +impl PendingRules { + /// The decoded request, or `None` when it could not be decoded. + pub(crate) fn resolved(self) -> Option { + match self { + Self::Decoding(handle) => { + let Ok(rules) = handle.join() else { + return None; + }; + rules + } + Self::Ready(rules) => Some(*rules), + } + } +} /// The facts a full compile leaves for its project image beyond its analysis record. #[derive(Debug, Default)] @@ -40,8 +105,7 @@ pub(crate) struct ImageCapture { /// The template environment names the compile read. pub(crate) environment_names: Vec, /// Each discovered model's header keys, by model file path. - pub(crate) header_keys: - BTreeMap, + pub(crate) header_keys: BTreeMap, /// Each model file's SQL lint cache key, in project model order. pub(crate) lint_model_keys: Option>, /// Each other SQL file's lint cache key, in walk order. @@ -240,8 +304,7 @@ pub(crate) fn delta_unsupported(reason: &str) -> pyo3::PyErr { /// In a delta compile that leaves errors to full compiles, stop once `failed` reports one. pub(crate) fn stop_on_errors(failed: bool) -> pyo3::PyResult<()> { - let errors_on_delta_path: bool = - crate::bindings::_helpers::compile_delta::driver::ERRORS_ON_DELTA_PATH; + let errors_on_delta_path: bool = ERRORS_ON_DELTA_PATH; if failed && !errors_on_delta_path && injection().is_some() { return Err(delta_unsupported("the edit reports errors")); } @@ -342,3 +405,14 @@ pub(crate) fn reset() { set_pending_image(None); set_record_merge(None); } + +/// Run a capture hook; a failure only rules the compile out as a delta base. +pub(crate) fn guarded(hook: impl FnOnce() -> PyResult<()>) -> PyResult<()> { + if !capturing() { + return Ok(()); + } + if let Err(error) = hook() { + capture_unsupported(&format!("an image fact could not be recorded: {error}")); + } + Ok(()) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/diagnostic_collector.rs similarity index 66% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/diagnostic_collector.rs index d533ab80a3..a233eaf5be 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/diagnostic_collector.rs @@ -6,8 +6,9 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{PyErr, pyclass, pyfunction, pymethods, wrap_pyfunction}; +use sqlbuild_host::compile_context::types::CompileDiagnosticSink; -use crate::bindings::_helpers::compile_driver::python_calls::{context_variable, imported}; +use crate::bindings::_helpers::boundary::python_calls::{context_variable, imported}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; @@ -94,6 +95,46 @@ pub(crate) fn collect_compile_diagnostics( ) } +/// The compile diagnostic sink of one interpreter: the entered collection, else the first error. +#[derive(Clone, Copy)] +pub(crate) struct PythonCompileDiagnostics<'py>(pub(crate) Python<'py>); + +impl<'py> CompileDiagnosticSink for PythonCompileDiagnostics<'py> { + type Key = Bound<'py, PyAny>; + type Diagnostic = Bound<'py, PyAny>; + type Error = PyErr; + + fn report(&self, key: &Bound<'py, PyAny>, diagnostic: &Bound<'py, PyAny>) -> PyResult<()> { + let py: Python<'py> = self.0; + let collector: Bound<'_, PyAny> = active_collector(py)?.call_method0("get")?; + if let Ok(collector) = collector.cast::() { + return collector.get().add(py, key, diagnostic); + } + let location: Bound<'_, PyAny> = native_field(diagnostic, "location")?; + let path: Bound<'_, PyAny> = native_field(diagnostic, "path")?; + let pointer: String = if !location.is_none() { + format!( + "\n --> {}:{}", + native_field(&location, "path")? + .call_method0("as_posix")? + .str()?, + native_field(&location, "line")?.str()? + ) + } else if !path.is_none() { + format!("\n --> {}", path.call_method0("as_posix")?.str()?) + } else { + String::new() + }; + let keywords: Bound<'_, PyDict> = PyDict::new(py); + keywords.set_item("code", native_field(diagnostic, "code")?)?; + keywords.set_item("help", native_field(diagnostic, "help")?)?; + let message: String = format!("{}{pointer}", native_field(diagnostic, "message")?.str()?); + Err(PyErr::from_value( + error_class(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?, + )) + } +} + /// Record a diagnostic in the active collection, or raise it when none is active. #[pyfunction] #[pyo3(signature = (*, key, diagnostic))] @@ -101,33 +142,7 @@ pub(crate) fn report_compile_diagnostic( key: &Bound<'_, PyAny>, diagnostic: &Bound<'_, PyAny>, ) -> PyResult<()> { - let py: Python<'_> = key.py(); - let collector: Bound<'_, PyAny> = active_collector(py)?.call_method0("get")?; - if let Ok(collector) = collector.cast::() { - return collector.get().add(py, key, diagnostic); - } - let location: Bound<'_, PyAny> = native_field(diagnostic, "location")?; - let path: Bound<'_, PyAny> = native_field(diagnostic, "path")?; - let pointer: String = if !location.is_none() { - format!( - "\n --> {}:{}", - native_field(&location, "path")? - .call_method0("as_posix")? - .str()?, - native_field(&location, "line")?.str()? - ) - } else if !path.is_none() { - format!("\n --> {}", path.call_method0("as_posix")?.str()?) - } else { - String::new() - }; - let keywords: Bound<'_, PyDict> = PyDict::new(py); - keywords.set_item("code", native_field(diagnostic, "code")?)?; - keywords.set_item("help", native_field(diagnostic, "help")?)?; - let message: String = format!("{}{pointer}", native_field(diagnostic, "message")?.str()?); - Err(PyErr::from_value( - error_class(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?, - )) + PythonCompileDiagnostics(key.py()).report(key, diagnostic) } pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_context/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/getters.rs new file mode 100644 index 0000000000..ba7bdfdfea --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/getters.rs @@ -0,0 +1,63 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::compile_context::diagnostic_collector::CollectedCompileDiagnostics; +use crate::bindings::_helpers::compile_context::input_reads::CompileInputReads; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_collected_compile_diagnostics, + }, + GetterEntry { + class: class_of::, + read: read_compile_input_reads, + }, +]; + +fn read_collected_compile_diagnostics<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "diagnostics" => this + .diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_compile_input_reads<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "environment_names" => this + .environment_names(py) + .and_then(|value| value.into_bound_py_any(py)), + "settings_classes" => this + .settings_classes(py) + .and_then(|value| value.into_bound_py_any(py)), + "read_run_id" => this.read_run_id().into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image_codec.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/image_codec.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image_codec.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/image_codec.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/image_facts.rs similarity index 96% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image_facts.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/image_facts.rs index 301c9528db..91ec31a92c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/image_facts.rs @@ -5,7 +5,7 @@ use pyo3::types::PyStringMethods; use sqlbuild_cache::digest::main::bytes_digest::bytes_digest; use sqlbuild_cache::digest::main::hex_digest::hex_digest; -use crate::bindings::_helpers::compile_delta::context::{capture, capture_unsupported}; +use crate::bindings::_helpers::compile_context::delta::{capture, capture_unsupported}; use crate::bindings::_helpers::records::fields::field as native_field; /// Record the digest of one model's scope usages, which decide declaration placement. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/input_reads.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/input_reads.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_context/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/mod.rs new file mode 100644 index 0000000000..41e63c7466 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/mod.rs @@ -0,0 +1,11 @@ +//! Per-compile state below the compile driver: collectors and the delta-compile slots. + +pub(crate) mod compile_timings; +pub(crate) mod coverage; +pub(crate) mod delta; +pub(crate) mod diagnostic_collector; +pub(crate) mod getters; +pub(crate) mod image_codec; +pub(crate) mod image_facts; +pub(crate) mod input_reads; +pub(crate) mod yaml_cache; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/yaml_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/yaml_cache.rs similarity index 83% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/yaml_cache.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compile_context/yaml_cache.rs index 01fa3cb588..ac531495a0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/yaml_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_context/yaml_cache.rs @@ -9,7 +9,12 @@ use sqlbuild_config::models::{ConfigDate, ConfigDateTime, ConfigTime, ConfigValu use sqlbuild_core::text::main::decode_text::decode_text; use sqlbuild_discovery::yaml_files::models::YamlFileOutcome; -use crate::bindings::_helpers::compile_delta::image_codec::{Decoder, Encoder}; +use crate::bindings::_helpers::compile_context::delta::injection; +use crate::bindings::_helpers::compile_context::image_codec::{Decoder, Encoder}; + +/// The source YAML key that lists sources, and the key naming each source. +const SOURCES_KEY: &str = "sources"; +const NAME_KEY: &str = "name"; /// The native store kind holding loaded YAML documents. pub(crate) const YAML_STORE_KIND: &str = "yaml-documents"; @@ -245,7 +250,7 @@ impl DocumentStore { /// In a delta compile, the document store beside its reuse slots, when it opens. pub(crate) fn open_documents(py: pyo3::Python<'_>) -> Option { - let path: PathBuf = crate::bindings::_helpers::compile_delta::context::injection()? + let path: PathBuf = crate::bindings::_helpers::compile_context::delta::injection()? .yaml_store .clone()?; match crate::bindings::_helpers::cache::native_store::open_store( @@ -282,3 +287,49 @@ pub(crate) fn save_documents(py: pyo3::Python<'_>, documents: &DocumentStore) { &[], ); } + +/// In a delta reading only some sources, drop every other loaded source YAML entry. +pub(crate) fn retain_read_sources( + outcomes: &mut [sqlbuild_discovery::yaml_files::models::YamlFileOutcome], +) { + use sqlbuild_config::models::ConfigValue; + use sqlbuild_discovery::yaml_files::models::YamlFileOutcome; + let Some(injection) = injection() else { + return; + }; + let Some(read) = injection.source_names.as_ref() else { + return; + }; + fn text(value: &ConfigValue) -> Option<&str> { + match value { + ConfigValue::String(text) => Some(text.as_str()), + _ => None, + } + } + for outcome in outcomes { + let YamlFileOutcome::Loaded { + value: ConfigValue::Map(entries), + .. + } = outcome + else { + continue; + }; + for (key, value) in entries { + if text(key) != Some(SOURCES_KEY) { + continue; + } + let ConfigValue::List(sources) = value else { + continue; + }; + sources.retain(|source| { + let name: Option<&str> = source.as_map().and_then(|entries| { + entries + .iter() + .find(|(key, _)| text(key) == Some(NAME_KEY)) + .and_then(|(_, name)| text(name)) + }); + name.is_none_or(|name| read.contains(name)) + }); + } + } +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/driver.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/driver.rs index 6051989506..127756794c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/driver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/driver.rs @@ -11,26 +11,31 @@ use sqlbuild_cache::project_reuse::main::read_delta_output::read_delta_output; use sqlbuild_cache::project_reuse::models::{DeltaBase, DeltaCandidate, ProjectFileChanges}; use sqlbuild_cache::project_reuse::types::ImageSections; -use crate::bindings::_helpers::cli::progress::{NativeProgressProjector, current_projector}; +use crate::bindings::_helpers::build_progress::progress::{ + NativeProgressProjector, current_projector, +}; use crate::bindings::_helpers::compile_command::reuse_attempt::reuse_debug; use crate::bindings::_helpers::compile_command::reuse_recording::{ RecordedCompileOutput, print_to, }; -use crate::bindings::_helpers::compile_delta::context::{ +use crate::bindings::_helpers::compile_context::delta::BaseRules; +use crate::bindings::_helpers::compile_context::delta::ERRORS_ON_DELTA_PATH; +use crate::bindings::_helpers::compile_context::delta::PendingRules; +use crate::bindings::_helpers::compile_context::delta::{ CapturedDiagnostic, CapturedModel, CapturedTest, DeltaInjection, ImageCapture, RecordMerge, start_capture, take_capture, take_delta_unsupported, with_injection, }; -use crate::bindings::_helpers::compile_delta::header_keys::{ - HeaderChange, custom_rule_reads, header_change, -}; use crate::bindings::_helpers::compile_delta::image::{ - BaseRules, ImageGate, ImageRelations, ImageRules, PendingRules, ProjectImage, + ImageGate, ImageRelations, ImageRules, ProjectImage, }; use crate::bindings::_helpers::compile_delta::splice::{SpliceScope, spliced_report}; use crate::bindings::_helpers::compile_driver::command::{ PhasesOutcome, resolved_request, unrecorded_compile, }; use crate::bindings::_helpers::compile_outputs::reuse::NativeReuseAttempt; +use crate::bindings::_helpers::discovery::header_keys::{ + HeaderChange, custom_rule_reads, header_change, +}; use crate::bindings::_helpers::records::fields::field as native_field; /// Set to `1` to always compile the whole project. @@ -41,8 +46,6 @@ const ENABLED_VALUE: &str = "1"; /// Rerunning more models than this, or this share of the project, compiles the whole project. const MAX_RERUN_MODELS: usize = 500; const MAX_RERUN_PERCENT: usize = 5; -/// Whether edits that report or raise errors compile as deltas; until then they fall back. -pub(crate) const ERRORS_ON_DELTA_PATH: bool = true; /// How many times a changed relation shape may pull its dependents into the delta. const MAX_ROUNDS: usize = 4; const MODELS_ROOT: &str = "models/"; @@ -284,7 +287,7 @@ fn lent_injection( yaml_store: store_path .parent() .and_then(std::path::Path::parent) - .map(crate::bindings::_helpers::compile_delta::yaml_cache::yaml_store_path), + .map(crate::bindings::_helpers::compile_context::yaml_cache::yaml_store_path), project_dir, source_paths: image .models @@ -1196,8 +1199,8 @@ pub(crate) fn commit( for line in &stderr_lines { print_to(py, STDERR, line.as_str())?; } - crate::bindings::_helpers::compile_delta::context::set_pending_image(image); - crate::bindings::_helpers::compile_delta::context::set_record_merge(Some(merge)); + crate::bindings::_helpers::compile_context::delta::set_pending_image(image); + crate::bindings::_helpers::compile_context::delta::set_record_merge(Some(merge)); crate::bindings::_helpers::compile_driver::command::store_and_print( (&request, attempt), &output, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image.rs index 6a44449683..aebdc05f91 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/image.rs @@ -5,15 +5,15 @@ use std::collections::{BTreeMap, BTreeSet}; use sqlbuild_analysis::assembly::analysis_session::models::RelationTables; use sqlbuild_analysis::assembly::analysis_session::types::Shapes; use sqlbuild_cache::project_reuse::types::ImageSections; -use sqlbuild_rules::engine::main::retained_request::retained_request; -use sqlbuild_rules::models::{EvaluateRequest, RetainedRows}; +use sqlbuild_rules::models::RetainedRows; -use crate::bindings::_helpers::compile_delta::context::{ +use crate::bindings::_helpers::compile_context::delta::HeaderKeys; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; +use crate::bindings::_helpers::compile_context::delta::{BaseRules, PendingRules}; +use crate::bindings::_helpers::compile_context::delta::{ CapturedDiagnostic, CapturedModel, CapturedTest, ImageCapture, ModelShape, }; -use crate::bindings::_helpers::compile_delta::coverage::ModelCoverage; -use crate::bindings::_helpers::compile_delta::header_keys::HeaderKeys; -use crate::bindings::_helpers::compile_delta::image_codec::{Decoder, Encoder}; +use crate::bindings::_helpers::compile_context::image_codec::{Decoder, Encoder}; /// Changes whenever the image's meaning changes, so an older image is never read. pub(crate) const IMAGE_FORMAT: &str = "sqlbuild-project-image-v8"; @@ -49,24 +49,6 @@ pub(crate) struct ProjectImage { pub(crate) rules: Option, } -/// A stored compile's built-in rules request, as decoded for a delta compile. -#[derive(Clone, Debug)] -pub(crate) struct BaseRules { - pub(crate) request: EvaluateRequest, - /// Each model's payload digest, which keys its cached findings, in model order. - pub(crate) digests: Vec, -} - -impl BaseRules { - /// The rows a compile retained, decoded. - pub(crate) fn decoded(retained: &RetainedRows) -> Option { - Some(Self { - request: retained_request(retained)?, - digests: retained.digests.clone(), - }) - } -} - /// An image's rules request: decoding from a stored image, or as a compile just retained it. #[derive(Debug)] pub(crate) enum ImageRules { @@ -74,13 +56,6 @@ pub(crate) enum ImageRules { Retained(RetainedRows), } -/// A stored rules request, decoding on its own thread or decoded already. -#[derive(Debug)] -pub(crate) enum PendingRules { - Decoding(std::thread::JoinHandle>), - Ready(Box), -} - impl ImageRules { /// The rules request still decoding from a stored image, if this is one. pub(crate) fn pending(self) -> Option { @@ -99,21 +74,6 @@ impl ImageRules { } } -impl PendingRules { - /// The decoded request, or `None` when it could not be decoded. - pub(crate) fn resolved(self) -> Option { - match self { - Self::Decoding(handle) => { - let Ok(rules) = handle.join() else { - return None; - }; - rules - } - Self::Ready(rules) => Some(*rules), - } - } -} - /// The value `bytes` hold as JSON, or `None` when they are malformed. fn from_json(bytes: &[u8]) -> Option { let Ok(value) = serde_json::from_slice(bytes) else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/lint_hooks.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/lint_hooks.rs index 95d66e6339..3eabed2a52 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/lint_hooks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/lint_hooks.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use pyo3::PyResult; -use crate::bindings::_helpers::compile_delta::context::{ +use crate::bindings::_helpers::compile_context::delta::{ capture, capturing, delta_unsupported, injection, }; use sqlbuild_core::format_command::constants::LINT_DIRECTORY_NAMES; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/mod.rs index 50b7b9c359..0865da1a64 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/mod.rs @@ -1,13 +1,7 @@ -pub(crate) mod context; -pub(crate) mod coverage; pub(crate) mod driver; -pub(crate) mod header_keys; pub(crate) mod image; -pub(crate) mod image_codec; -pub(crate) mod image_facts; pub(crate) mod lint_hooks; pub(crate) mod report_hooks; pub(crate) mod rules_rows; pub(crate) mod splice; pub(crate) mod verify; -pub(crate) mod yaml_cache; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/report_hooks.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/report_hooks.rs index 8ea8654232..8e72e599b3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/report_hooks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/report_hooks.rs @@ -1,25 +1,20 @@ //! Where the compile's report and output stages leave image facts or take a delta's injection. -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyStringMethods, PyTuple, PyTupleMethods}; use sqlbuild_core::cli_text::models::ModelLine; use crate::bindings::_helpers::compile_command::report::diagnostic_item; -use crate::bindings::_helpers::compile_delta::context::{ - CapturedDiagnostic, CapturedModel, CapturedTest, ModelShape, capture, capture_unsupported, - capturing, delta_unsupported, injection, -}; -use crate::bindings::_helpers::compile_delta::coverage::{ - ModelCoverage, coverage_reasons, merged_coverage, merged_order, +use crate::bindings::_helpers::compile_context::delta::guarded; +use crate::bindings::_helpers::compile_context::delta::{ + CapturedDiagnostic, CapturedModel, CapturedTest, capture, capturing, injection, }; use crate::bindings::_helpers::compile_outputs::json_report::plain_json; use crate::bindings::_helpers::graph::project_graph::NativeProjectGraph; use crate::bindings::_helpers::records::fields::field as native_field; -const SOURCES_KEY: &str = "sources"; -const NAME_KEY: &str = "name"; /// The graph key kind of a model. const MODEL_KIND: &str = "model"; @@ -153,112 +148,6 @@ pub(crate) fn captured_diagnostic(diagnostic: &Bound<'_, PyAny>) -> PyResult)>, - fresh: Vec, -) -> PyResult)>> { - let (order, facts): (Vec<(String, Vec)>, Vec) = match injection() { - None => ( - order, - fresh.into_iter().filter(ModelCoverage::notable).collect(), - ), - Some(injection) => { - let Some(stored) = &injection.coverage else { - return Err(delta_unsupported( - "the stored compile recorded no semantic coverage", - )); - }; - ( - merged_order(&injection.coverage_order, &order), - merged_coverage(stored, &fresh), - ) - } - }; - let reasons: Vec<(String, Vec)> = coverage_reasons(&order, &facts); - if capturing() { - capture(|capture| { - if capture.coverage.is_none() { - capture.coverage = Some(facts); - } - }); - } - Ok(reasons) -} - -/// In a delta compile, publish the shapes of every model it does not compile again first. -pub(crate) fn inject_model_shapes( - models: &[Bound<'_, PyAny>], - shapes: &Bound<'_, PyDict>, -) -> PyResult<()> { - let Some(injection) = injection() else { - return Ok(()); - }; - let mut rerun: HashSet = HashSet::with_capacity(models.len()); - for model in models { - rerun.insert(native_field(model, "name")?.extract()?); - } - let py = shapes.py(); - for (name, columns) in &injection.model_shapes { - if rerun.contains(name) { - continue; - } - let shape: Bound<'_, PyDict> = PyDict::new(py); - for (column, column_type) in columns { - shape.set_item(column, column_type)?; - } - shapes.set_item(name, shape)?; - } - Ok(()) -} - -/// Record the model shapes the first semantic shape pass published. -fn record_model_shapes_inner( - project: &Bound<'_, PyAny>, - shapes: &Bound<'_, PyDict>, -) -> PyResult<()> { - if !capturing() { - return Ok(()); - } - let mut names: HashSet = HashSet::new(); - for model in native_field(project, "models")?.try_iter()? { - names.insert(native_field(&model?, "name")?.extract()?); - } - if let Some(injection) = injection() { - names.extend(injection.model_shapes.iter().map(|(name, _)| name.clone())); - } - let mut published: Vec = Vec::new(); - for (name, shape) in shapes.iter() { - let name: String = name.extract()?; - if !names.contains(&name) { - continue; - } - let shape: Bound<'_, PyDict> = shape.cast_into()?; - let mut columns: Vec<(String, String)> = Vec::with_capacity(shape.len()); - for (column, column_type) in shape.iter() { - columns.push((column.extract()?, column_type.extract()?)); - } - published.push((name, columns)); - } - capture(|capture| { - if capture.model_shapes.is_none() { - capture.model_shapes = Some(published); - } - }); - Ok(()) -} - -/// Run a capture hook; a failure only rules the compile out as a delta base. -fn guarded(hook: impl FnOnce() -> PyResult<()>) -> PyResult<()> { - if !capturing() { - return Ok(()); - } - if let Err(error) = hook() { - capture_unsupported(&format!("an image fact could not be recorded: {error}")); - } - Ok(()) -} - /// Record which models each SQL test's compiled artifact is keyed by. pub(crate) fn record_test_chains( tests: &Bound<'_, PyAny>, @@ -275,14 +164,6 @@ pub(crate) fn record_compile_facts( guarded(|| record_compile_facts_inner(graph, diagnostics)) } -/// Record the model shapes the first semantic shape pass published. -pub(crate) fn record_model_shapes( - project: &Bound<'_, PyAny>, - shapes: &Bound<'_, PyDict>, -) -> PyResult<()> { - guarded(|| record_model_shapes_inner(project, shapes)) -} - /// In a delta, add the text of files that stored diagnostics point into but were not rerun. pub(crate) fn complete_source_texts( project: &Bound<'_, PyAny>, @@ -316,49 +197,3 @@ pub(crate) fn complete_source_texts( } Ok(()) } - -/// In a delta reading only some sources, drop every other loaded source YAML entry. -pub(crate) fn retain_read_sources( - outcomes: &mut [sqlbuild_discovery::yaml_files::models::YamlFileOutcome], -) { - use sqlbuild_config::models::ConfigValue; - use sqlbuild_discovery::yaml_files::models::YamlFileOutcome; - let Some(injection) = injection() else { - return; - }; - let Some(read) = injection.source_names.as_ref() else { - return; - }; - fn text(value: &ConfigValue) -> Option<&str> { - match value { - ConfigValue::String(text) => Some(text.as_str()), - _ => None, - } - } - for outcome in outcomes { - let YamlFileOutcome::Loaded { - value: ConfigValue::Map(entries), - .. - } = outcome - else { - continue; - }; - for (key, value) in entries { - if text(key) != Some(SOURCES_KEY) { - continue; - } - let ConfigValue::List(sources) = value else { - continue; - }; - sources.retain(|source| { - let name: Option<&str> = source.as_map().and_then(|entries| { - entries - .iter() - .find(|(key, _)| text(key) == Some(NAME_KEY)) - .and_then(|(_, name)| text(name)) - }); - name.is_none_or(|name| read.contains(name)) - }); - } - } -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/rules_rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/rules_rows.rs index fa160532fd..a22e5f2103 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/rules_rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/rules_rows.rs @@ -5,8 +5,9 @@ use std::collections::HashMap; use pyo3::PyResult; use sqlbuild_rules::models::{EvaluateRequest, Model, SqlTestFact}; -use crate::bindings::_helpers::compile_delta::context::{delta_unsupported, injection}; -use crate::bindings::_helpers::compile_delta::image::{BaseRules, PendingRules}; +use crate::bindings::_helpers::compile_context::delta::BaseRules; +use crate::bindings::_helpers::compile_context::delta::PendingRules; +use crate::bindings::_helpers::compile_context::delta::{delta_unsupported, injection}; /// In a delta, the whole project's rules request with the rerun rows taken from `request`. pub(crate) fn whole_project_request(request: EvaluateRequest) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs index fad8c21398..9840e1a8f1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs @@ -5,20 +5,20 @@ use std::time::Instant; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyString, PyTuple, PyTupleMethods}; use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{ + Status, call_with, imported, keywords, within, +}; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::project::build_project_graph_with_analysis_selection; -use crate::bindings::_helpers::compile_driver::python_calls::{ - Status, call_with, imported, keywords, within, -}; use crate::bindings::_helpers::compile_driver::stage_work::{ COLUMN_LINEAGE, MODEL_CONTRACTS, count_stage, }; use crate::bindings::_helpers::contracts::contract_diagnostics::evaluate_model_contracts; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::lineage::project_lineage::build_project_column_lineage; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::selectors::select_project_graph; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; @@ -150,7 +150,7 @@ pub(crate) fn analyze<'py>( let selection: &Bound<'py, PyAny> = &options.analysis_selection; let enabled: bool = !(native_field(selection, "select")?.is_truthy()? || native_field(selection, "exclude")?.is_truthy()?) - && crate::bindings::_helpers::compile_delta::context::injection().is_none(); + && crate::bindings::_helpers::compile_context::delta::injection().is_none(); let early_lint: Bound<'py, EarlySqlLint> = Bound::new(py, EarlySqlLint::new(enabled))?; let early_rules: EarlyRulesScope = EarlyRulesScope::new(); let analysis: PyResult> = @@ -210,7 +210,7 @@ fn analyzed<'py>( driver.graph((&discovered, &adapter), &lint_dialect)?; let project: Bound<'py, PyAny> = native_field(&graph, "project")?; let graph_failed: bool = any_error(&native_field(&project, "diagnostics")?)?; - crate::bindings::_helpers::compile_delta::context::stop_on_errors(graph_failed)?; + crate::bindings::_helpers::compile_context::delta::stop_on_errors(graph_failed)?; let mut early_lint_wait_ms: Bound<'py, PyAny> = 0_i64.into_pyobject(py)?.into_any(); if graph_failed { if let Some(early_rules) = early_rules { @@ -220,7 +220,7 @@ fn analyzed<'py>( } let (lineage, lineage_ms): (Bound<'py, PyAny>, u64) = driver.lineage(&graph, &dialect)?; let contracts: ContractPhase<'py> = driver.contracts(&project, &dialect)?; - crate::bindings::_helpers::compile_delta::context::stop_on_errors(any_error(&native_field( + crate::bindings::_helpers::compile_context::delta::stop_on_errors(any_error(&native_field( &contracts.result, "diagnostics", )?)?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs index 73dc556a63..38b47677aa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs @@ -7,9 +7,9 @@ use pyo3::prelude::{ use pyo3::types::{PyBool, PyDict, PyDictMethods, PyList, PyListMethods, PySlice, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_cache::digest::main::sha256_hex::sha256_hex; +use sqlbuild_host::compile_context::main::record_compile_metric::record_compile_metric; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_metric; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::planner_identity::json_values::{COMPACT, unicode_sorted_dumps}; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs index e397f943bc..e5ff81ab37 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs @@ -6,20 +6,18 @@ use pyo3::exceptions::{PyRuntimeError, PyValueError}; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyCFunction, PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::analysis::explicit_references::explicit_reference_report; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, within}; +use crate::bindings::_helpers::compile_context::diagnostic_collector::collect_compile_diagnostics; use crate::bindings::_helpers::compile_driver::assembly_project::assembled_project; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::collect_compile_diagnostics; use crate::bindings::_helpers::compile_driver::project::lineage_mode; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, within, -}; -use crate::bindings::_helpers::compiled_project::records::project_with; -use crate::bindings::_helpers::compiled_project::records::record_model_analyses; +use crate::bindings::_helpers::compiled_views::records::project_with; +use crate::bindings::_helpers::compiled_views::records::record_model_analyses; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::references::explicit_references::explicit_reference_report; const STAGE_REACHED: &str = "assembly stopped before the requested stage"; const EXPRESSION_SHAPES_STAGE: &str = "expression_shapes"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs index 0f447a7cf2..1066cc15a4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs @@ -6,6 +6,9 @@ use pyo3::types::{PyBool, PyDict, PyDictMethods, PyFrozenSet, PyString, PyTuple, use sqlbuild_analysis::assembly::analysis_session::main::native_dialect::native_dialect; use sqlbuild_analysis::assembly::analysis_session::types::Pairs; +use sqlbuild_host::compile_context::main::record_compile_cpu_timing::record_compile_cpu_timing; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; +use sqlbuild_host::entries::models::AdapterHost; use crate::bindings::_helpers::analysis::binding_catalog::{ BindingCatalog, CatalogKey, ignores_quoted_case, @@ -15,18 +18,15 @@ use crate::bindings::_helpers::analysis_session::model_analyses::{ }; use crate::bindings::_helpers::analysis_session::profile_inputs::text_pairs; use crate::bindings::_helpers::analysis_session::stage_functions::expression_source_shapes; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compile_context::compile_timings::PythonProcessClock; use crate::bindings::_helpers::compile_driver::analysis_cache::analysis_cache_context; use crate::bindings::_helpers::compile_driver::assembly::{AssemblyRequest, AssemblyStage}; -use crate::bindings::_helpers::compile_driver::compile_timings::{ - record_compile_cpu_timing, record_compile_timing, -}; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::stage_work::{ EXPRESSION_SHAPES, MODEL_ANALYSIS, count_stage, }; -use crate::bindings::_helpers::compiled_project::model_input_view::attached_schema; -use crate::bindings::_helpers::compiled_project::source_views::read_source_view; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::compiled_views::model_input_view::attached_schema; +use crate::bindings::_helpers::compiled_views::source_views::read_source_view; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::project_assembly::declared_relations::{ DeclaredRelations, DeclaredShapes, declared_relations, @@ -391,7 +391,7 @@ fn model_analyses<'py>( py.None().into_bound(py) }; record_compile_timing("model_analysis_ms", || { - record_compile_cpu_timing(py, "model_analysis_cpu_ms", || { + record_compile_cpu_timing(&PythonProcessClock(py), "model_analysis_cpu_ms", || { let mut model_inputs: Vec> = Vec::new(); for model_input in native_field(inputs, "model_inputs")?.try_iter()? { let model_input: Bound<'py, PyAny> = model_input?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs index 187d1043e0..a625255390 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs @@ -4,7 +4,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyTuple}; use crate::bindings::_helpers::attachments::cursor_intrinsics::validated_model_cursor_sql; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::records::construct::{ enum_member, new_record, new_record_with, record_class, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs index 5caef70872..5eb41c050a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs @@ -13,7 +13,7 @@ use crate::bindings::_helpers::boundary::panics::NativeCompilerError; use crate::bindings::_helpers::compile_driver::assembly_analysis::{ AnalysisContext, model_stem, selected_for_analysis, }; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; use crate::bindings::_helpers::hand_built::compiled_model::compiled_model as hand_built_model; use crate::bindings::_helpers::project_assembly::syntax_checks::model_placeholders; use crate::bindings::_helpers::project_assembly::syntax_validation::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs index 85444d1942..f9178da352 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs @@ -5,6 +5,9 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyString, PyStringMethods, PyTu use sqlbuild_analysis::assembly::project::main::configured_namespace::configured_namespace; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::assembly::{AssemblyRequest, AssemblyStage}; use crate::bindings::_helpers::compile_driver::assembly_analysis::{ AnalysisContext, analysis_context, and_not, @@ -17,14 +20,12 @@ use crate::bindings::_helpers::compile_driver::assembly_models::{ binding_rows, compiled_models, project_binding_diagnostics, }; use crate::bindings::_helpers::compile_driver::assembly_sql_tests::assembled_sql_tests; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::stage_work::{SEMANTIC_COMPLETION, count_stage}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; use crate::bindings::_helpers::contracts::spec_resolution::{ resolve_effective_adapter_name, resolve_effective_scenario_config, }; use crate::bindings::_helpers::model_config::template_data::early_model_templates; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; @@ -108,7 +109,7 @@ pub(crate) fn assembled_project<'py>( let native: Bound<'py, PyAny> = native_project_facts(inputs, &context, names, &native_session)?; let resources: Bound<'py, PyAny> = native_field(&native, "resources")?; let scope_index: Bound<'py, PyAny> = scope_index_with_compile_usages(inputs)?; - if crate::bindings::_helpers::compile_delta::context::injection().is_none() { + if crate::bindings::_helpers::compile_context::delta::injection().is_none() { report_scope_index_errors(&scope_index)?; } let target_values: Bound<'py, PyAny> = effective_target_values(inputs)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs index 22beebcb4b..346e0dd2cb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs @@ -4,9 +4,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyList, PyTuple, PyTupleMethods}; use crate::bindings::_helpers::boundary::panics::NativeCompilerError; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; +use crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::compile_driver::assembly_checks::test_model_query_overrides; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; use crate::bindings::_helpers::compile_driver::stage_work::{SQL_TEST_ASSEMBLY, count_stage}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs index cc4d880e2a..624495ceca 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs @@ -6,8 +6,14 @@ use pyo3::types::{ PyBool, PyDict, PyDictMethods, PyList, PyListMethods, PyMapping, PyString, PyTuple, }; use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; +use sqlbuild_host::compile_context::main::collect_compile_timings::collect_compile_timings; +use sqlbuild_host::compile_context::main::timing_milliseconds::timing_milliseconds; +use sqlbuild_host::compile_context::types::CompileTimingsHandle; use std::rc::Rc; +use crate::bindings::_helpers::boundary::python_calls::{ + Status, call_with, imported, keywords, within, +}; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; use crate::bindings::_helpers::compile_command::report::{ @@ -17,18 +23,12 @@ use crate::bindings::_helpers::compile_command::reuse_recording::write_reusable_ use crate::bindings::_helpers::compile_command::reuse_recording::{ CompileArtifactWrites, RecordedCompileOutput, compile_reuse_timings, new_artifact_recorder, }; +use crate::bindings::_helpers::compile_context::input_reads::record_compile_input_reads; use crate::bindings::_helpers::compile_driver::analysis::analyze; -use crate::bindings::_helpers::compile_driver::compile_timings::{ - CompileTimingsHandle, collect_compile_timings, timing_milliseconds, -}; -use crate::bindings::_helpers::compile_driver::input_reads::record_compile_input_reads; use crate::bindings::_helpers::compile_driver::phases::{ elapsed_ms, manifest_payload, monotonic, resolved_dag_path, sql_test_planning_diagnostics, target_dir, write_artifacts, write_dag_artifact, }; -use crate::bindings::_helpers::compile_driver::python_calls::{ - Status, call_with, imported, keywords, within, -}; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; @@ -265,7 +265,7 @@ pub(crate) fn compile_phases<'py>( .getattr("skip_write")? .is_truthy()?; let staging: bool = - !skip_write && crate::bindings::_helpers::compile_delta::context::injection().is_none(); + !skip_write && crate::bindings::_helpers::compile_context::delta::injection().is_none(); let (outcome, input_reads, artifact_writes): ( CommandOutcome<'py>, Bound<'py, PyAny>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs deleted file mode 100644 index 869a6289d7..0000000000 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! The active compile timing collector of the current thread, as a context variable held it. - -use std::cell::RefCell; -use std::rc::Rc; -use std::time::Instant; - -use pyo3::prelude::{PyAnyMethods, PyResult, Python}; -use sqlbuild_core::compile_timings::main::compile_timing_milliseconds::compile_timing_milliseconds; -use sqlbuild_core::compile_timings::models::CompileTimings; - -use crate::bindings::_helpers::compile_driver::python_calls::imported; - -/// One compile invocation's collector, shared by every recorder on its thread. -pub(crate) type CompileTimingsHandle = Rc>; - -thread_local! { - static ACTIVE: RefCell> = const { RefCell::new(None) }; -} - -/// Run `body` with a fresh collector active on this thread, restoring the previous one after. -pub(crate) fn collect_compile_timings( - body: impl FnOnce(&CompileTimingsHandle) -> PyResult, -) -> PyResult { - let collector: CompileTimingsHandle = Rc::default(); - let previous: Option = - ACTIVE.with(|active| active.replace(Some(Rc::clone(&collector)))); - let result: PyResult = body(&collector); - ACTIVE.with(|active| active.replace(previous)); - result -} - -/// Every reported phase in milliseconds, then every metric. -pub(crate) fn timing_milliseconds(collector: &CompileTimingsHandle) -> Vec<(&'static str, u64)> { - compile_timing_milliseconds(&collector.borrow()) -} - -/// Add elapsed nanoseconds to a phase when a collector is active. -pub(crate) fn add_compile_timing(phase: &str, elapsed_ns: u64) { - if let Some(collector) = active() { - *collector - .borrow_mut() - .elapsed_ns - .entry(phase.to_owned()) - .or_default() += elapsed_ns; - } -} - -/// Add a non-negative metric value when a collector is active. -pub(crate) fn record_compile_metric(metric: &str, value: i64) { - if let Some(collector) = active() { - *collector - .borrow_mut() - .metrics - .entry(metric.to_owned()) - .or_default() += u64::try_from(value).unwrap_or(0); - } -} - -/// Record the wall time `body` spans under `phase` when a collector is active. -pub(crate) fn record_compile_timing( - phase: &str, - body: impl FnOnce() -> PyResult, -) -> PyResult { - if active().is_none() { - return body(); - } - let started: Instant = Instant::now(); - let result: PyResult = body(); - add_compile_timing( - phase, - u64::try_from(started.elapsed().as_nanos()).unwrap_or(u64::MAX), - ); - result -} - -/// Record the process CPU time `body` spans, including its worker threads, under `phase`. -pub(crate) fn record_compile_cpu_timing( - py: Python<'_>, - phase: &str, - body: impl FnOnce() -> PyResult, -) -> PyResult { - if active().is_none() { - return body(); - } - let started: u64 = process_time_ns(py)?; - let result: PyResult = body(); - let ended: u64 = process_time_ns(py)?; - add_compile_timing(phase, ended.saturating_sub(started)); - result -} - -fn process_time_ns(py: Python<'_>) -> PyResult { - imported(py, "time", "process_time_ns")?.call0()?.extract() -} - -fn active() -> Option { - ACTIVE.with(|active| active.borrow().clone()) -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs index 9d29ac2895..de81d80402 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs @@ -4,15 +4,16 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyString, PyTuple}; use sqlbuild_config::project::main::unsupported_target_warehouse::unsupported_target_warehouse; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; -use crate::bindings::_helpers::contracts::project_config::{ - resolve_config_file_path, validate_local_sql_analysis, -}; use crate::bindings::_helpers::contracts::spec_resolution::{ resolve_effective_adapter_name, resolve_target_config, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::discovery::project_config::{ + resolve_config_file_path, validate_local_sql_analysis, +}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs index dc41bfd071..d7a2d6915b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs @@ -10,7 +10,7 @@ use sqlbuild_model_config::templates::main::deferred_target_segments::deferred_t use sqlbuild_model_config::templates::models::DeferredSegment; use crate::bindings::_helpers::authored_values::project_vars::render_project_var_text; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs index c211dbd8e3..1923978e58 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs @@ -12,9 +12,9 @@ use sqlbuild_analysis::diff_selection::errors::SelectorError; use sqlbuild_analysis::diff_selection::main::resolve_diff_selection::resolve_diff_selection; use sqlbuild_analysis::diff_selection::models::DiffGraph; -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::graph::views::project_lineage_views; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs index f116a462bd..df3d5adf9a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs @@ -4,17 +4,16 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::types::{PyDict, PySet, PySetMethods, PyTuple}; use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; + +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, keywords, within, +}; use crate::bindings::_helpers::compile_driver::config_validation::{ ProjectConfiguration, reject_invalid_project_configuration, }; use crate::bindings::_helpers::compile_driver::integration_loaders::integration_loader_functions; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, within, -}; use crate::bindings::_helpers::compile_driver::stage_work::{PROJECT_DISCOVERIES, count_stage}; -use crate::bindings::_helpers::contracts::project_config::{ - load_local_config_file, load_project_config_file, -}; use crate::bindings::_helpers::discovery::declaration_records::{ discover_adapter_file, discover_audit_files, discover_constant_files, discover_enum_files, discover_macro_files, discover_model_schema_files, discover_seed_files, @@ -29,6 +28,9 @@ use crate::bindings::_helpers::discovery::imported_python_nodes::{ use crate::bindings::_helpers::discovery::model_records::{ ModelFileSelection, discovered_model_files, }; +use crate::bindings::_helpers::discovery::project_config::{ + load_local_config_file, load_project_config_file, +}; use crate::bindings::_helpers::discovery::python_function_files::discover_python_function_files; use crate::bindings::_helpers::discovery::python_paths::reject_unsupported_python_paths; use crate::bindings::_helpers::discovery::snapshot::in_snapshot; @@ -40,9 +42,7 @@ use crate::bindings::_helpers::discovery::yaml_records::{ }; use crate::bindings::_helpers::event_exporting::scope::configure_discovered_event_exporters; use crate::bindings::_helpers::frontier::compile_frontier::{FrontierStage, produced}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; @@ -250,7 +250,7 @@ fn assembled_inputs<'py>( )? .is_truthy()? { - crate::bindings::_helpers::compile_delta::context::stop_capture(); + crate::bindings::_helpers::compile_context::delta::stop_capture(); } let sql_analysis_override: &Bound<'py, PyAny> = request.sql_analysis_enabled_override.bind(py); let sql_analysis_enabled: Bound<'py, PyAny> = if !sql_analysis_override.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs index 8fa39e7c42..40a7468d44 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs @@ -3,23 +3,23 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, keywords, within, +}; use crate::bindings::_helpers::compile_attachment::declaration_scope::build_declaration_scope; use crate::bindings::_helpers::compile_attachment::effective_config::{ build_effective_connection, build_effective_settings, build_effective_vars, }; use crate::bindings::_helpers::compile_attachment::model_inputs::build_model_inputs; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::collect_compile_diagnostics; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, within, -}; -use crate::bindings::_helpers::compiled_project::attachment::{attach_checks, attach_resources}; +use crate::bindings::_helpers::compile_context::diagnostic_collector::collect_compile_diagnostics; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::records::{compile_inputs_view, inputs_with}; +use crate::bindings::_helpers::compiled_views::records::{compile_inputs_view, inputs_with}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; +use crate::bindings::_helpers::input_loops::attachment::{attach_checks, attach_resources}; use crate::bindings::_helpers::model_config::template_data::run_id; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/integration_loaders.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/integration_loaders.rs index 1d1d6a7af9..941b4514f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/integration_loaders.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/integration_loaders.rs @@ -4,10 +4,10 @@ use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyTuple; use sqlbuild_discovery::yaml_entries::main::integration_loader_name::integration_loader_name; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/mod.rs index b450d2fac9..cf1caa44ca 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/mod.rs @@ -8,25 +8,23 @@ pub(crate) mod assembly_models; pub(crate) mod assembly_project; pub(crate) mod assembly_sql_tests; pub(crate) mod command; -pub(crate) mod compile_timings; pub(crate) mod config_validation; pub(crate) mod deferral; -pub(crate) mod diagnostic_collector; pub(crate) mod diff; pub(crate) mod discovery; -pub(crate) mod input_reads; pub(crate) mod inputs; pub(crate) mod integration_loaders; pub(crate) mod phases; pub(crate) mod pipeline; pub(crate) mod pipeline_entries; +pub(crate) mod plan_pipeline; pub(crate) mod plan_result; pub(crate) mod project; -pub(crate) mod python_calls; pub(crate) mod python_plan_entries; pub(crate) mod registration; pub(crate) mod relation_targets; pub(crate) mod selection_phases; pub(crate) mod stage_work; +pub(crate) mod static_context; pub(crate) mod target_defaults; pub(crate) mod targets; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs index f05d96721a..c42732965b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs @@ -4,13 +4,13 @@ use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyTuple; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{Status, call_with, imported}; use crate::bindings::_helpers::compile_command::artifact_batch::ArtifactBatch; use crate::bindings::_helpers::compile_command::reuse_recording::ArtifactRecorder; use crate::bindings::_helpers::compile_command::target_writer::{ Prepared, planning_diagnostics, write_static_target, }; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{Status, call_with, imported}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::dag_artifact::artifact::build_dag_json; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs index f9fea09a33..42cb2d73d6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs @@ -4,41 +4,24 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PySet, PySetMethods}; use pyo3::{IntoPyObject, PyErr, pyfunction, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_connection_config; use crate::bindings::_helpers::compile_driver::phases::monotonic; -use crate::bindings::_helpers::compile_driver::pipeline_entries::{ - compile_analysis_selection, project_graph, -}; -use crate::bindings::_helpers::compile_driver::plan_result::{ - PlanningInputs, connection_with_hooks, pipeline_result, -}; +use crate::bindings::_helpers::compile_driver::pipeline_entries::compile_analysis_selection; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; -use crate::bindings::_helpers::compile_driver::selection_phases::{ - apply_unit_test_selectors, resolve_configured_rule_selection, -}; use crate::bindings::_helpers::diagnostics::trackers::current_tracker; -use crate::bindings::_helpers::frontier::stage_capture::write_plan_capture; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; -use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::rules::results::{format_rules_result, rules_progress}; -use crate::bindings::_helpers::rules::rule_dispatch::evaluate_rules; -use crate::bindings::_helpers::rules::rules_config::load_rules_config; - -const GENERIC_DIALECT: &str = "generic"; /// The current build's phase timing tracker, when one is recording. -fn timing_tracker(py: Python<'_>) -> PyResult> { +pub(crate) fn timing_tracker(py: Python<'_>) -> PyResult> { current_tracker(py) } /// Report `message` through `on_progress` when a callback is set. -fn progress(on_progress: &Bound<'_, PyAny>, message: &str) -> PyResult<()> { +pub(crate) fn progress(on_progress: &Bound<'_, PyAny>, message: &str) -> PyResult<()> { if !on_progress.is_none() { on_progress.call1((message,))?; } @@ -72,7 +55,7 @@ pub(crate) fn compile_project_phase<'py>( } /// `compile_project_phase` with resolved arguments. -fn compiled_phase<'py>( +pub(crate) fn compiled_phase<'py>( (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), options: &Bound<'py, PyAny>, on_progress: &Bound<'py, PyAny>, @@ -206,179 +189,7 @@ fn reject_compile_errors( Err(PyErr::from_value(error)) } -/// Run compile inputs, assembly, planning, and manifest generation. -#[pyfunction] -#[pyo3(signature = (**options))] -pub(crate) fn run_compile_pipeline<'py>( - py: Python<'py>, - options: Option>, -) -> PyResult> { - let arguments: KeywordArguments<'py> = KeywordArguments::read( - py, - "run_compile_pipeline", - options, - (&["discovered_inputs", "adapter"], &["options", "hooks"]), - )?; - let discovered: Bound<'py, PyAny> = arguments.value("discovered_inputs")?; - let adapter: Bound<'py, PyAny> = arguments.value("adapter")?; - let options: Bound<'py, PyAny> = - apply_unit_test_selectors(&arguments.value("options")?, &discovered)?; - let hooks: Bound<'py, PyAny> = arguments.value("hooks")?; - let hooks: Bound<'py, PyAny> = if hooks.is_none() { - host::entry(py, ExecutorHost::ConnectionHooks)?.call0()? - } else { - hooks - }; - let on_progress: Bound<'py, PyAny> = native_field(&hooks, "on_progress")?; - let compiled: Bound<'py, PyAny> = - compiled_phase((&discovered, &adapter), &options, &on_progress)?; - let project: Bound<'py, PyAny> = native_field(&compiled, "project")?; - let graph: Bound<'py, PyAny> = project_graph(&project)?; - run_rules_gate( - (&discovered, &adapter), - (&options, &on_progress), - (&project, &graph), - )?; - planned((&discovered, &adapter), (&options, &hooks), &compiled) -} - -/// Run the configured rules and stop the command when any of them finds a fault. -fn run_rules_gate<'py>( - (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), - (options, on_progress): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), - (project, graph): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), -) -> PyResult<()> { - let py: Python<'py> = discovered.py(); - let rules_error: Bound<'py, PyAny> = error_class(py, ErrorId::Rules)?; - let project_dir: Bound<'py, PyAny> = native_field(discovered, "project_dir")?; - if project_dir.is_none() { - return Err(PyErr::from_value( - rules_error.call1(("compiler rules require a resolved project directory",))?, - )); - } - let mut config: Bound<'py, PyAny> = - load_rules_config(py, project_dir.extract()?)?.into_bound(py); - if native_field(options, "no_cache")?.is_truthy()? { - let cache: Bound<'py, PyAny> = new_record_with( - py, - RecordId::RulesCacheConfig, - &[("enabled", false.into_pyobject(py)?.to_owned().into_any())], - )?; - config = replaced(&config, &[("cache", cache)])?; - } - progress(on_progress, "Evaluating configured rules...")?; - let started: f64 = monotonic(py)?; - let dialect: Bound<'py, PyAny> = adapter.call_method0("sql_analysis_dialect")?; - let dialect: Bound<'py, PyAny> = if dialect.is_truthy()? { - dialect - } else { - GENERIC_DIALECT.into_pyobject(py)?.into_any() - }; - let selected_keys: Bound<'py, PyAny> = - resolve_configured_rule_selection(options, discovered, project)?; - let result: Bound<'py, PyAny> = evaluate_rules( - py, - Some(keywords( - py, - &[ - ("graph", graph.clone()), - ("discovered_inputs", discovered.clone()), - ("config", config), - ("project_dir", project_dir), - ("dialect", dialect), - ("selected_keys", selected_keys), - ( - "no_sql_analysis", - native_field(options, "no_sql_validation")?, - ), - ], - )?), - )?; - if !on_progress.is_none() { - let elapsed: f64 = monotonic(py)? - started; - let message: String = rules_progress(elapsed, &result, true)?; - on_progress.call1((message,))?; - } - let findings: Bound<'py, PyAny> = native_field(&result, "findings")?; - if !findings.is_truthy()? { - return Ok(()); - } - let summary: Bound<'py, PyAny> = new_record_with( - py, - RecordId::RulesResult, - &[ - ("findings", findings), - ( - "evaluated_models", - native_field(&result, "evaluated_models")?, - ), - ( - "unevaluated_resources", - native_field(&result, "unevaluated_resources")?, - ), - ("cache_hits", native_field(&result, "cache_hits")?), - ("cache_misses", native_field(&result, "cache_misses")?), - ], - )?; - let rendered: String = format_rules_result(&summary, false)?; - Err(PyErr::from_value(rules_error.call1((format!( - "configured compiler rules failed:\n{rendered}" - ),))?)) -} - -/// Open the planning connection, plan, and record the compile and planning times. -fn planned<'py>( - (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), - (options, hooks): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), - compiled: &Bound<'py, PyAny>, -) -> PyResult> { - let py: Python<'py> = discovered.py(); - let tracker: Bound<'py, PyAny> = timing_tracker(py)?; - let started: f64 = monotonic(py)?; - let mut connection: Option> = None; - let result: PyResult> = (|| { - let opened: Bound<'py, PyAny> = connection_with_hooks( - adapter, - &native_field(compiled, "connection_config")?, - hooks, - )?; - connection = Some(opened.clone()); - pipeline_result( - &PlanningInputs { - discovered_inputs: discovered, - adapter, - connection: &opened, - }, - &native_field(compiled, "project")?, - options, - &native_field(hooks, "on_progress")?, - ) - })(); - if let Some(connection) = connection.filter(|connection| !connection.is_none()) { - adapter.call_method1("close", (connection,))?; - } - let planning_seconds: f64 = monotonic(py)? - started; - if !tracker.is_none() { - tracker.setattr("planning_seconds", planning_seconds)?; - } - let result: Bound<'py, PyAny> = result?; - write_plan_capture(&native_field(&result, "plan_output")?)?; - replaced( - &result, - &[ - ( - "compile_seconds", - native_field(compiled, "compile_seconds")?, - ), - ( - "planning_seconds", - planning_seconds.into_pyobject(py)?.into_any(), - ), - ], - ) -} - pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(compile_project_phase, module)?)?; - module.add_function(wrap_pyfunction!(run_compile_pipeline, module)?) + Ok(()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs index 1ea5787e8d..31f6c834e0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs @@ -4,8 +4,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyFloat}; use pyo3::{pyfunction, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::compile_driver::pipeline::compile_project_phase; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::graph::project_graph::{CompiledProjectGraph, NativeProjectGraph}; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_pipeline.rs new file mode 100644 index 0000000000..b10e4dd7e7 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_pipeline.rs @@ -0,0 +1,208 @@ +//! The compile-and-plan pipeline of execution commands: compile, rules gate, then planning. + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; +use pyo3::types::PyDict; +use pyo3::{IntoPyObject, PyErr, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; +use crate::bindings::_helpers::compile_driver::phases::monotonic; +use crate::bindings::_helpers::compile_driver::pipeline::{ + compiled_phase, progress, timing_tracker, +}; +use crate::bindings::_helpers::compile_driver::pipeline_entries::project_graph; +use crate::bindings::_helpers::compile_driver::plan_result::{ + PlanningInputs, connection_with_hooks, pipeline_result, +}; +use crate::bindings::_helpers::compile_driver::selection_phases::{ + apply_unit_test_selectors, resolve_configured_rule_selection, +}; +use crate::bindings::_helpers::frontier::stage_capture::write_plan_capture; +use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; +use crate::bindings::_helpers::records::construct::new_record_with; +use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::replaced; +use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::rules::results::{format_rules_result, rules_progress}; +use crate::bindings::_helpers::rules::rule_dispatch::evaluate_rules; +use crate::bindings::_helpers::rules::rules_config::load_rules_config; + +const GENERIC_DIALECT: &str = "generic"; + +/// Run compile inputs, assembly, planning, and manifest generation. +#[pyfunction] +#[pyo3(signature = (**options))] +pub(crate) fn run_compile_pipeline<'py>( + py: Python<'py>, + options: Option>, +) -> PyResult> { + let arguments: KeywordArguments<'py> = KeywordArguments::read( + py, + "run_compile_pipeline", + options, + (&["discovered_inputs", "adapter"], &["options", "hooks"]), + )?; + let discovered: Bound<'py, PyAny> = arguments.value("discovered_inputs")?; + let adapter: Bound<'py, PyAny> = arguments.value("adapter")?; + let options: Bound<'py, PyAny> = + apply_unit_test_selectors(&arguments.value("options")?, &discovered)?; + let hooks: Bound<'py, PyAny> = arguments.value("hooks")?; + let hooks: Bound<'py, PyAny> = if hooks.is_none() { + host::entry(py, ExecutorHost::ConnectionHooks)?.call0()? + } else { + hooks + }; + let on_progress: Bound<'py, PyAny> = native_field(&hooks, "on_progress")?; + let compiled: Bound<'py, PyAny> = + compiled_phase((&discovered, &adapter), &options, &on_progress)?; + let project: Bound<'py, PyAny> = native_field(&compiled, "project")?; + let graph: Bound<'py, PyAny> = project_graph(&project)?; + run_rules_gate( + (&discovered, &adapter), + (&options, &on_progress), + (&project, &graph), + )?; + planned((&discovered, &adapter), (&options, &hooks), &compiled) +} + +/// Run the configured rules and stop the command when any of them finds a fault. +fn run_rules_gate<'py>( + (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), + (options, on_progress): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), + (project, graph): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), +) -> PyResult<()> { + let py: Python<'py> = discovered.py(); + let rules_error: Bound<'py, PyAny> = error_class(py, ErrorId::Rules)?; + let project_dir: Bound<'py, PyAny> = native_field(discovered, "project_dir")?; + if project_dir.is_none() { + return Err(PyErr::from_value( + rules_error.call1(("compiler rules require a resolved project directory",))?, + )); + } + let mut config: Bound<'py, PyAny> = + load_rules_config(py, project_dir.extract()?)?.into_bound(py); + if native_field(options, "no_cache")?.is_truthy()? { + let cache: Bound<'py, PyAny> = new_record_with( + py, + RecordId::RulesCacheConfig, + &[("enabled", false.into_pyobject(py)?.to_owned().into_any())], + )?; + config = replaced(&config, &[("cache", cache)])?; + } + progress(on_progress, "Evaluating configured rules...")?; + let started: f64 = monotonic(py)?; + let dialect: Bound<'py, PyAny> = adapter.call_method0("sql_analysis_dialect")?; + let dialect: Bound<'py, PyAny> = if dialect.is_truthy()? { + dialect + } else { + GENERIC_DIALECT.into_pyobject(py)?.into_any() + }; + let selected_keys: Bound<'py, PyAny> = + resolve_configured_rule_selection(options, discovered, project)?; + let result: Bound<'py, PyAny> = evaluate_rules( + py, + Some(keywords( + py, + &[ + ("graph", graph.clone()), + ("discovered_inputs", discovered.clone()), + ("config", config), + ("project_dir", project_dir), + ("dialect", dialect), + ("selected_keys", selected_keys), + ( + "no_sql_analysis", + native_field(options, "no_sql_validation")?, + ), + ], + )?), + )?; + if !on_progress.is_none() { + let elapsed: f64 = monotonic(py)? - started; + let message: String = rules_progress(elapsed, &result, true)?; + on_progress.call1((message,))?; + } + let findings: Bound<'py, PyAny> = native_field(&result, "findings")?; + if !findings.is_truthy()? { + return Ok(()); + } + let summary: Bound<'py, PyAny> = new_record_with( + py, + RecordId::RulesResult, + &[ + ("findings", findings), + ( + "evaluated_models", + native_field(&result, "evaluated_models")?, + ), + ( + "unevaluated_resources", + native_field(&result, "unevaluated_resources")?, + ), + ("cache_hits", native_field(&result, "cache_hits")?), + ("cache_misses", native_field(&result, "cache_misses")?), + ], + )?; + let rendered: String = format_rules_result(&summary, false)?; + Err(PyErr::from_value(rules_error.call1((format!( + "configured compiler rules failed:\n{rendered}" + ),))?)) +} + +/// Open the planning connection, plan, and record the compile and planning times. +fn planned<'py>( + (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), + (options, hooks): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), + compiled: &Bound<'py, PyAny>, +) -> PyResult> { + let py: Python<'py> = discovered.py(); + let tracker: Bound<'py, PyAny> = timing_tracker(py)?; + let started: f64 = monotonic(py)?; + let mut connection: Option> = None; + let result: PyResult> = (|| { + let opened: Bound<'py, PyAny> = connection_with_hooks( + adapter, + &native_field(compiled, "connection_config")?, + hooks, + )?; + connection = Some(opened.clone()); + pipeline_result( + &PlanningInputs { + discovered_inputs: discovered, + adapter, + connection: &opened, + }, + &native_field(compiled, "project")?, + options, + &native_field(hooks, "on_progress")?, + ) + })(); + if let Some(connection) = connection.filter(|connection| !connection.is_none()) { + adapter.call_method1("close", (connection,))?; + } + let planning_seconds: f64 = monotonic(py)? - started; + if !tracker.is_none() { + tracker.setattr("planning_seconds", planning_seconds)?; + } + let result: Bound<'py, PyAny> = result?; + write_plan_capture(&native_field(&result, "plan_output")?)?; + replaced( + &result, + &[ + ( + "compile_seconds", + native_field(compiled, "compile_seconds")?, + ), + ( + "planning_seconds", + planning_seconds.into_pyobject(py)?.into_any(), + ), + ], + ) +} + +pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { + module.add_function(wrap_pyfunction!(run_compile_pipeline, module)?)?; + Ok(()) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs index 33d0a026eb..3dfb61f1cc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs @@ -1,10 +1,12 @@ //! Plan a compiled project over an open warehouse connection, and open that connection. +use sqlbuild_host::entries::models::UserCodeHost; + +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::deferral::build_deferred_locations; use crate::bindings::_helpers::compile_driver::deferral::gather_deferred_relations; use crate::bindings::_helpers::compile_driver::deferral::resolve_deferred_target_config; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_project_graph_from_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::python_plan_entries::{ build_python_run_plan_outputs, python_read_source_names_for, }; @@ -16,12 +18,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet}; use pyo3::{pyfunction, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::compile_driver::phases::monotonic; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::graph::python_node_graph::run_selection_from_inputs; use crate::bindings::_helpers::native_host::connections::connection_failure; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs index f4797bbd99..2b63c48a50 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs @@ -4,11 +4,12 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::types::{PyBool, PyCFunction, PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_timing; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::compile_driver::inputs::{InputsRequest, attached_inputs}; use crate::bindings::_helpers::compile_driver::phases::monotonic; use crate::bindings::_helpers::compile_driver::pipeline_entries::project_graph; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::compile_driver::target_defaults::{ TargetDefaults, apply_target_defaults, }; @@ -19,13 +20,13 @@ use crate::bindings::_helpers::compile_driver::targets::{ use crate::bindings::_helpers::frontier::compile_frontier::{FrontierStage, bridged, produced}; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::assembly::assemble_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::selection_phases::resolve_analysis_model_names; use crate::bindings::_helpers::compile_driver::stage_work::{ PROJECT_GRAPHS, PROMOTION_CONFLICTS, count_stage, }; -use crate::bindings::_helpers::compiled_project::records::project_with; +use crate::bindings::_helpers::compiled_views::records::project_with; use crate::bindings::_helpers::contracts::contract_diagnostics::promotion_conflict_diagnostics; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_collection_rendering; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs index aa36e9c03d..5cc96f7285 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs @@ -1,5 +1,7 @@ //! Display-ready Python plan entries and Python-aware selection warnings of a plan. +use sqlbuild_host::entries::models::UserCodeHost; + use crate::bindings::_helpers::graph::python_lifecycle::build_python_sql_run_lifecycle; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with, record_class}; use crate::bindings::_helpers::records::fields::replaced; @@ -12,12 +14,9 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_analysis::python_plan::main::ordered_python_names::ordered_python_names; use sqlbuild_analysis::python_plan::main::upstream_closure::upstream_closure; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/registration.rs index 620f94f94a..52a5cce413 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/registration.rs @@ -3,10 +3,11 @@ use pyo3::prelude::{Bound, PyModule, PyModuleMethods, PyResult}; use pyo3::wrap_pyfunction; +use crate::bindings::_helpers::compile_context::{diagnostic_collector, input_reads}; use crate::bindings::_helpers::compile_driver::{ - analysis, analysis_cache, assembly, command, deferral, diagnostic_collector, diff, discovery, - input_reads, inputs, pipeline, pipeline_entries, plan_result, project, python_plan_entries, - relation_targets, selection_phases, stage_work, targets, + analysis, analysis_cache, assembly, command, deferral, diff, discovery, inputs, pipeline, + pipeline_entries, plan_pipeline, plan_result, project, python_plan_entries, relation_targets, + selection_phases, stage_work, static_context, targets, }; pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { @@ -19,6 +20,7 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { input_reads::register(module)?; discovery::register(module)?; pipeline::register(module)?; + plan_pipeline::register(module)?; pipeline_entries::register(module)?; plan_result::register(module)?; deferral::register(module)?; @@ -27,6 +29,7 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { python_plan_entries::register(module)?; relation_targets::register(module)?; selection_phases::register(module)?; + static_context::register(module)?; module.add_function(wrap_pyfunction!( stage_work::compile_stage_work_info, module diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs index 51bfadbfb3..c1d3c505cb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs @@ -5,13 +5,10 @@ use pyo3::prelude::{ }; use pyo3::types::{PyDict, PyDictMethods, PySet, PySetMethods, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{AdapterHost, UserCodeHost}; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::references::source_relations::render_source_relation; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs index be3b267a95..d8f52aed64 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs @@ -1,20 +1,12 @@ //! Unit-test selector splitting, analysis and rule selection, and static command compilation. use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; -use pyo3::types::{PyDict, PyFrozenSet}; +use pyo3::types::PyFrozenSet; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::boundary::keyword_request::Request; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; use crate::bindings::_helpers::compile_driver::assembly::assemble_project; -use crate::bindings::_helpers::compile_driver::deferral::{ - build_deferred_locations, resolve_deferred_target_config, -}; -use crate::bindings::_helpers::compile_driver::pipeline::compile_project_phase; use crate::bindings::_helpers::compile_driver::pipeline_entries::compile_analysis_selection; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; -use crate::bindings::_helpers::planner_entries::command_plans::{ - resolve_static_command_scope, resolve_static_relation_context, -}; use crate::bindings::_helpers::planner_phases::scopes::resolve_planner_scopes; use crate::bindings::_helpers::planner_selection::unit_tests::split_project_unit_test_selectors; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; @@ -31,7 +23,7 @@ fn unselective(selection: &Bound<'_, PyAny>) -> PyResult { } /// Options whose selectors name only resources, with unit tests selected apart. -fn unit_test_selectors_applied<'py>( +pub(crate) fn unit_test_selectors_applied<'py>( options: &Bound<'py, PyAny>, discovered: &Bound<'py, PyAny>, ) -> PyResult> { @@ -167,172 +159,9 @@ pub(crate) fn resolve_analysis_model_names<'py>( Ok(PyFrozenSet::new(py, models.try_iter()?.collect::>>()?)?.into_any()) } -/// Locations of the deferred target's relations, when the options defer to one. -fn deferred_locations<'py>( - (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), - options: &Bound<'py, PyAny>, - project: &Bound<'py, PyAny>, -) -> PyResult> { - let py: Python<'py> = project.py(); - let defer_to: Bound<'py, PyAny> = native_field(options, "defer_to")?; - if defer_to.is_none() { - return Ok(py.None().into_bound(py)); - } - let deferred_target: Bound<'py, PyAny> = resolve_deferred_target_config( - py, - Some(keywords( - py, - &[ - ("discovered_inputs", discovered.clone()), - ("defer_to", defer_to), - ( - "current_target_name", - native_field(project, "effective_target_name")?, - ), - ], - )?), - )?; - Ok(build_deferred_locations( - py, - Some(keywords( - py, - &[ - ("project", project.clone()), - ("deferred_target_config", deferred_target), - ("effective_vars", native_field(project, "effective_vars")?), - ("default_schema", adapter.call_method0("default_schema")?), - ( - "default_database", - adapter.call_method0("default_database")?, - ), - ( - "render_qualified_name", - native_field(adapter, "render_qualified_name")?, - ), - ], - )?), - )? - .into_any()) -} - -/// Run canonical compile, selector, and relation phases without build planning. -#[pyfunction] -#[pyo3(signature = (**request))] -pub(crate) fn compile_static_command_context<'py>( - request: Option<&Bound<'py, PyDict>>, -) -> PyResult> { - let request: Request<'_, 'py> = Request::new("compile_static_command_context", request)?; - let py: Python<'py> = request.py(); - let none = || py.None().into_bound(py); - let discovered: Bound<'py, PyAny> = request.get("discovered_inputs")?; - let adapter: Bound<'py, PyAny> = request.get("adapter")?; - let options: Bound<'py, PyAny> = - unit_test_selectors_applied(&request.get("options")?, &discovered)?; - let mut selected_keys: Bound<'py, PyAny> = - request.optional("selected_keys")?.unwrap_or_else(none); - if selected_keys.is_none() - && !native_field(&options, "sql_test_selection")? - .getattr("models_selected")? - .is_truthy()? - { - selected_keys = PyFrozenSet::empty(py)?.into_any(); - } - let compiled: Bound<'py, PyAny> = compile_project_phase( - py, - Some(keywords( - py, - &[ - ("discovered_inputs", discovered.clone()), - ("adapter", adapter.clone()), - ("options", options.clone()), - ( - "on_progress", - request.optional("on_progress")?.unwrap_or_else(none), - ), - ], - )?), - )?; - let project: Bound<'py, PyAny> = native_field(&compiled, "project")?; - let deferred: Bound<'py, PyAny> = - deferred_locations((&discovered, &adapter), &options, &project)?; - let scope: Bound<'py, PyAny> = resolve_static_command_scope( - &project, - &new_record_with( - py, - RecordId::PlannerSelection, - &[ - ("select", native_field(&options, "select")?), - ("exclude", native_field(&options, "exclude")?), - ("selected_keys", selected_keys), - ( - "sql_test_selection", - native_field(&options, "sql_test_selection")?, - ), - ], - )?, - native_field(&options, "auto_load_sources")?.extract()?, - )?; - let relations: Bound<'py, PyAny> = resolve_static_relation_context( - py, - Some(keywords( - py, - &[ - ("project", project.clone()), - ("adapter", adapter), - ("scope", scope.clone()), - ( - "deferral", - new_record_with( - py, - RecordId::DeferralInputs, - &[ - ("deferred_locations", deferred), - ( - "defer_sources_to", - native_field(&options, "defer_sources_to")?, - ), - ( - "source_deferral_enabled", - native_field(&options, "source_deferral_enabled")?, - ), - ], - )?, - ), - ( - "project_config", - native_field(&discovered, "project_config")?, - ), - ("local_config", native_field(&discovered, "local_config")?), - ( - "relation_keys", - request.optional("relation_keys")?.unwrap_or_else(none), - ), - ], - )?), - )?; - new_record_with( - py, - RecordId::StaticCommandContext, - &[ - ("project", project), - ("scope", scope), - ("relations", relations), - ( - "connection_config", - native_field(&compiled, "connection_config")?, - ), - ( - "compile_seconds", - native_field(&compiled, "compile_seconds")?, - ), - ], - ) -} - pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(apply_unit_test_selectors, module)?)?; module.add_function(wrap_pyfunction!(resolve_configured_rule_selection, module)?)?; module.add_function(wrap_pyfunction!(resolve_analysis_model_names, module)?)?; - module.add_function(wrap_pyfunction!(compile_static_command_context, module)?)?; Ok(()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/static_context.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/static_context.rs new file mode 100644 index 0000000000..3ab1dc70e1 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/static_context.rs @@ -0,0 +1,186 @@ +//! The static command context of audit, check, seed and test commands: scope and relations. + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; +use pyo3::types::{PyDict, PyFrozenSet}; +use pyo3::{pyfunction, wrap_pyfunction}; + +use crate::bindings::_helpers::boundary::keyword_request::Request; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compile_driver::deferral::{ + build_deferred_locations, resolve_deferred_target_config, +}; +use crate::bindings::_helpers::compile_driver::pipeline::compile_project_phase; +use crate::bindings::_helpers::compile_driver::selection_phases::unit_test_selectors_applied; +use crate::bindings::_helpers::planner_entries::command_plans::{ + resolve_static_command_scope, resolve_static_relation_context, +}; +use crate::bindings::_helpers::records::construct::new_record_with; +use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::ids::RecordId; + +/// Locations of the deferred target's relations, when the options defer to one. +fn deferred_locations<'py>( + (discovered, adapter): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), + options: &Bound<'py, PyAny>, + project: &Bound<'py, PyAny>, +) -> PyResult> { + let py: Python<'py> = project.py(); + let defer_to: Bound<'py, PyAny> = native_field(options, "defer_to")?; + if defer_to.is_none() { + return Ok(py.None().into_bound(py)); + } + let deferred_target: Bound<'py, PyAny> = resolve_deferred_target_config( + py, + Some(keywords( + py, + &[ + ("discovered_inputs", discovered.clone()), + ("defer_to", defer_to), + ( + "current_target_name", + native_field(project, "effective_target_name")?, + ), + ], + )?), + )?; + Ok(build_deferred_locations( + py, + Some(keywords( + py, + &[ + ("project", project.clone()), + ("deferred_target_config", deferred_target), + ("effective_vars", native_field(project, "effective_vars")?), + ("default_schema", adapter.call_method0("default_schema")?), + ( + "default_database", + adapter.call_method0("default_database")?, + ), + ( + "render_qualified_name", + native_field(adapter, "render_qualified_name")?, + ), + ], + )?), + )? + .into_any()) +} + +/// Run canonical compile, selector, and relation phases without build planning. +#[pyfunction] +#[pyo3(signature = (**request))] +pub(crate) fn compile_static_command_context<'py>( + request: Option<&Bound<'py, PyDict>>, +) -> PyResult> { + let request: Request<'_, 'py> = Request::new("compile_static_command_context", request)?; + let py: Python<'py> = request.py(); + let none = || py.None().into_bound(py); + let discovered: Bound<'py, PyAny> = request.get("discovered_inputs")?; + let adapter: Bound<'py, PyAny> = request.get("adapter")?; + let options: Bound<'py, PyAny> = + unit_test_selectors_applied(&request.get("options")?, &discovered)?; + let mut selected_keys: Bound<'py, PyAny> = + request.optional("selected_keys")?.unwrap_or_else(none); + if selected_keys.is_none() + && !native_field(&options, "sql_test_selection")? + .getattr("models_selected")? + .is_truthy()? + { + selected_keys = PyFrozenSet::empty(py)?.into_any(); + } + let compiled: Bound<'py, PyAny> = compile_project_phase( + py, + Some(keywords( + py, + &[ + ("discovered_inputs", discovered.clone()), + ("adapter", adapter.clone()), + ("options", options.clone()), + ( + "on_progress", + request.optional("on_progress")?.unwrap_or_else(none), + ), + ], + )?), + )?; + let project: Bound<'py, PyAny> = native_field(&compiled, "project")?; + let deferred: Bound<'py, PyAny> = + deferred_locations((&discovered, &adapter), &options, &project)?; + let scope: Bound<'py, PyAny> = resolve_static_command_scope( + &project, + &new_record_with( + py, + RecordId::PlannerSelection, + &[ + ("select", native_field(&options, "select")?), + ("exclude", native_field(&options, "exclude")?), + ("selected_keys", selected_keys), + ( + "sql_test_selection", + native_field(&options, "sql_test_selection")?, + ), + ], + )?, + native_field(&options, "auto_load_sources")?.extract()?, + )?; + let relations: Bound<'py, PyAny> = resolve_static_relation_context( + py, + Some(keywords( + py, + &[ + ("project", project.clone()), + ("adapter", adapter), + ("scope", scope.clone()), + ( + "deferral", + new_record_with( + py, + RecordId::DeferralInputs, + &[ + ("deferred_locations", deferred), + ( + "defer_sources_to", + native_field(&options, "defer_sources_to")?, + ), + ( + "source_deferral_enabled", + native_field(&options, "source_deferral_enabled")?, + ), + ], + )?, + ), + ( + "project_config", + native_field(&discovered, "project_config")?, + ), + ("local_config", native_field(&discovered, "local_config")?), + ( + "relation_keys", + request.optional("relation_keys")?.unwrap_or_else(none), + ), + ], + )?), + )?; + new_record_with( + py, + RecordId::StaticCommandContext, + &[ + ("project", project), + ("scope", scope), + ("relations", relations), + ( + "connection_config", + native_field(&compiled, "connection_config")?, + ), + ( + "compile_seconds", + native_field(&compiled, "compile_seconds")?, + ), + ], + ) +} + +pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { + module.add_function(wrap_pyfunction!(compile_static_command_context, module)?)?; + Ok(()) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs index a09a843ed4..cdba9e1d1e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs @@ -3,11 +3,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyTuple; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::function_views::NativeCompiledFunction; -use crate::bindings::_helpers::compiled_project::records::project_with; -use crate::bindings::_helpers::compiled_project::seed_views::NativeCompiledSeed; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::function_views::NativeCompiledFunction; +use crate::bindings::_helpers::compiled_views::records::project_with; +use crate::bindings::_helpers::compiled_views::seed_views::NativeCompiledSeed; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs index 47226c8cda..dd9f0a762b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs @@ -22,7 +22,7 @@ use sqlbuild_core::text::main::python_strip::python_strip; use sqlbuild_model_config::templates::models::TemplateOptions; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::model_config::template_data::expanded_template_data; /// Connection settings that identify the warehouse two targets write to. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs index 96f3d65137..d2c57c1434 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs @@ -68,7 +68,7 @@ pub(crate) fn emit_json_report(report: &Bound<'_, PyAny>) -> PyResult { if let Some(error) = conversion.stdlib_error { return Err(error); } - crate::bindings::_helpers::compile_delta::context::capture(|capture| { + crate::bindings::_helpers::compile_context::delta::capture(|capture| { capture.stdlib_json = true; }); emitted( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs index 6563157e15..e07ab58f5f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs @@ -225,11 +225,11 @@ impl NativeReuseAttempt { artifacts_written: record.artifacts_written, dag_path: record.dag_path, json_output: record.json_output, - image: crate::bindings::_helpers::compile_delta::context::take_pending_image(), + image: crate::bindings::_helpers::compile_context::delta::take_pending_image(), vouched_target_stamps: None, }; if let Some(merge) = - crate::bindings::_helpers::compile_delta::context::take_record_merge() + crate::bindings::_helpers::compile_context::delta::take_record_merge() { for stamp in &merge.kept { compile diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs index e733e70446..3ce0e1ffaf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs @@ -13,10 +13,10 @@ use sqlbuild_analysis::target_paths::main::runtime_sql_text::runtime_sql_text; use sqlbuild_analysis::target_paths::main::sql_test_output_path::sql_test_output_path; use sqlbuild_analysis::target_paths::models::SqlTestPathFacts; use sqlbuild_core::text::main::python_isspace::python_isspace; +use sqlbuild_host::entries::models::AdapterHost; use crate::bindings::_helpers::analysis::sql_test_comparisons::single_comparison_sql; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_records/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_records/constants.rs index cc28328048..1252dbe77e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_records/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_records/constants.rs @@ -1,7 +1,7 @@ //! Layouts of the compile and discovery value records hosted natively. -use crate::bindings::_helpers::native_host::facade::FacadeHost; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use sqlbuild_host::entries::models::{FacadeHost, UserCodeHost}; + use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::records::models::{FieldDefault, FieldSpec, RecordSpec}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment_inputs.rs new file mode 100644 index 0000000000..8f6eef3210 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment_inputs.rs @@ -0,0 +1,295 @@ +//! The resource rows and settings the compile attaches into the project, and the installed runs. + +use std::collections::HashMap; +use std::sync::OnceLock; + +use pyo3::FromPyObject; +use pyo3::exceptions::PyRuntimeError; +use pyo3::prelude::{Bound, Py, PyAny, PyResult, Python}; +use pyo3::types::{PyDict, PyString}; + +use crate::bindings::_helpers::cache::sql_test_scan_store::SqlTestScanStore; +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::audit_views::NativeAuditInput; +use crate::bindings::_helpers::compiled_views::function_views::NativeFunctionInput; +use crate::bindings::_helpers::compiled_views::source_views::NativeSourceInput; + +const ATTACHMENT_UNINSTALLED: &str = "the native module registered no resource attachment"; + +static INSTALLED: OnceLock = OnceLock::new(); + +/// One discovered source: its file's path, the discovered file and the entry. +pub(crate) type SourceRow = (String, Py, Py); + +/// `(default contract, whether expressions are syntax-checked, source kind)`. +pub(crate) type SourceSettings = (Option, bool, Py); + +positional_record! { + extract; + /// A function's paths, stem, discovered file, header values, body and SQL file contents. + pub(crate) struct FunctionRow { + pub(crate) file_path: String, + pub(crate) relative_path: String, + pub(crate) name: String, + pub(crate) function_file: Py, + pub(crate) header_values: Py, + pub(crate) body: String, + pub(crate) contents: Option, + } +} + +positional_record! { + extract; + /// Adapter, validation, raw default and target namespaces, inheritance and resource kind. + pub(crate) struct FunctionSettings { + pub(crate) adapter_name: String, + pub(crate) validate: bool, + pub(crate) defaults: (Option, Option), + pub(crate) target: Option<(Option, Option)>, + pub(crate) inherit: bool, + pub(crate) kind: Py, + } +} + +/// A test case's discovered case, name and parameter values in authored order. +pub(crate) type TestCaseRow = (Py, String, Vec<(String, Py)>); + +positional_record! { + extract; + /// A test block, its name, SQL, mode, declared parameter names, cases and authored SQL span. + pub(crate) struct TestBlockRow { + pub(crate) block: Py, + pub(crate) name: Option, + pub(crate) sql_body: String, + pub(crate) mode: String, + pub(crate) parameters: Vec, + pub(crate) cases: Vec, + pub(crate) sql_body_span: Option<(usize, usize)>, + } +} + +positional_record! { + extract; + /// A test file's paths, stem, discovered file, contents and blocks. + pub(crate) struct TestFileRow { + pub(crate) file_path: String, + pub(crate) relative_path: String, + pub(crate) stem: String, + pub(crate) file: Py, + pub(crate) contents: String, + pub(crate) blocks: Vec, + } +} + +/// What every SQL test and scenario of one compile resolves and records with. +#[derive(FromPyObject)] +#[pyo3(from_item_all)] +pub(crate) struct SqlTestSettings { + /// `CompileSqlTestInput`, its model and direct payloads, and `CompileSqlTestCte`. + pub(crate) test_input: Py, + pub(crate) model_payload: Py, + pub(crate) direct_payload: Py, + pub(crate) test_cte: Py, + /// `CompileSqlScenarioInput` and `CompileSqlScenarioCte`. + pub(crate) scenario_input: Py, + pub(crate) scenario_cte: Py, + /// `SqlTestMode` by value. + pub(crate) modes: Py, + /// The `ResourceKind`s of tests and scenarios, and the runtime `UsageKind`. + pub(crate) test_kind: Py, + pub(crate) scenario_kind: Py, + pub(crate) runtime_usage: Py, + /// The adapter's typed scalar renderer, returning `(text, None)` or `(None, error)`. + pub(crate) render_parameter: Py, + pub(crate) adapter_name: String, + /// `SourceLocation`, for helper problems located natively. + pub(crate) source_location: Py, + /// The shared scan store with the scan algorithm and lexical rules keying it, if any. + pub(crate) scan_store: Option>, + pub(crate) scan_key: (String, String), +} + +/// The attached SQL test inputs, then scenario inputs. +pub(crate) type AttachedSqlTests = (Vec>, Vec>); + +positional_record! { + extract; + /// A scenario file's paths, discovered file, contents, SQL body and name. + pub(crate) struct ScenarioRow { + pub(crate) file_path: String, + pub(crate) relative_path: String, + pub(crate) scenario_file: Py, + pub(crate) contents: String, + pub(crate) sql_body: String, + pub(crate) name: String, + } +} + +positional_record! { + extract, into; + /// An audit block, its name, SQL body, evidence SQL, measurement flag and header values. + pub(crate) struct AuditBlockRow { + pub(crate) block: Py, + pub(crate) name: Option, + pub(crate) sql_body: String, + pub(crate) evidence_sql: Option, + pub(crate) measurement: bool, + pub(crate) header: Py, + } +} + +positional_record! { + extract, into; + /// An audit file's paths, stem, discovered file, generic flag, contents and blocks. + pub(crate) struct AuditFileRow { + pub(crate) file_path: String, + pub(crate) relative_path: String, + pub(crate) stem: String, + pub(crate) file: Py, + pub(crate) generic: bool, + pub(crate) contents: String, + pub(crate) blocks: Vec, + } +} + +/// What every audit in one compile resolves against, and the Python values it builds with. +#[derive(FromPyObject)] +#[pyo3(from_item_all)] +pub(crate) struct AuditSettings { + pub(crate) default_severity: Option, + pub(crate) default_run_scope: Option, + /// Built-in generic definitions as audit file rows, overridden by project definitions. + pub(crate) builtins: Vec, + /// `DeclarationIdentity`, and the singular and generic audit `DeclarationKind`s. + pub(crate) declaration_identity: Py, + pub(crate) singular_kind: Py, + pub(crate) audit_kind: Py, + /// `ResourceKind` by value, for the resources singular audits read and attach to. + pub(crate) resource_kinds: Py, +} + +/// A loader's description, relative path and whether that path is a YAML file. +pub(crate) type LoaderRow = (Option, String, bool); + +positional_record! { + extract; + /// A Python resource's kind, name, description (a `str` that may hold surrogates), location, help. + pub(crate) struct PythonResourceRow { + pub(crate) kind: String, + pub(crate) name: String, + pub(crate) description: Option>, + pub(crate) location: Py, + pub(crate) help: String, + } +} + +positional_record! { + extract; + /// A scenario's name, relative path, contents and authored header description. + pub(crate) struct ScenarioDescriptionRow { + pub(crate) name: String, + pub(crate) path: String, + pub(crate) contents: String, + pub(crate) raw: Py, + } +} + +positional_record! { + extract; + /// A SQL hook file's name, relative path, contents and description. + pub(crate) struct HookDescriptionRow { + pub(crate) name: String, + pub(crate) path: String, + pub(crate) contents: String, + pub(crate) description: Option, + } +} + +/// What the resource diagnostics read beyond the owner, and the Python values they build. +#[derive(FromPyObject)] +#[pyo3(from_item_all)] +pub(crate) struct DiagnosticSettings { + /// `CompilerDiagnostic`, `SourceLocation`, `Path` and `CompileInputError`. + pub(crate) compiler_diagnostic: Py, + pub(crate) compile_error: Py, + pub(crate) source_location: Py, + pub(crate) path_class: Py, + /// Every discovered model file, whose headers attach audit factories. + pub(crate) model_files: Vec>, + /// Each discovered audit factory's name, relative path and line. + pub(crate) audit_factories: Vec<(String, String, usize)>, + /// Each scenario's name, relative path, contents and authored header description. + pub(crate) scenarios: Vec, + /// Each SQL hook file's name, relative path, contents and description. + pub(crate) sql_hooks: Vec, + /// Each loader by name. + pub(crate) loaders: HashMap, + /// Python-defined resources: kind, name, description, location and help, read by Python. + pub(crate) python_resources: Vec, +} + +/// The orphaned audit factory warnings, then the missing descriptions, then the cursor errors. +pub(crate) type ResourceDiagnostics<'py> = ( + Vec>, + Vec>, + Vec>, +); + +/// Attaches the project's sources, given their rows and settings. +pub(crate) type AttachSources = fn( + &Bound<'_, NativeCompiledProject>, + Vec, + SourceSettings, +) -> PyResult>; + +/// Attaches the project's SQL, then Python, functions. +pub(crate) type AttachFunctions = fn( + &Bound<'_, NativeCompiledProject>, + (Vec, Vec), + FunctionSettings, +) -> PyResult>; + +/// Reads the project's resource diagnostics. +pub(crate) type ResourceDiagnosticsRun = for<'py> fn( + &NativeCompiledProject, + Python<'py>, + &DiagnosticSettings, +) -> PyResult>; + +/// Attaches the project's SQL test files, then its scenarios. +pub(crate) type AttachSqlTests = fn( + &Bound<'_, NativeCompiledProject>, + Vec, + Vec, + SqlTestSettings, +) -> PyResult; + +/// Attaches the project's audits; returns their views and the built-in shadow warnings. +pub(crate) type AttachAudits = + for<'py> fn( + &Bound<'py, NativeCompiledProject>, + Vec, + AuditSettings, + ) -> PyResult<(Vec, Vec>)>; + +/// The compile's runs behind the project's attachment methods. +#[derive(Clone, Copy, Debug)] +pub(crate) struct ResourceAttachment { + pub(crate) sources: AttachSources, + pub(crate) functions: AttachFunctions, + pub(crate) diagnostics: ResourceDiagnosticsRun, + pub(crate) sql_tests: AttachSqlTests, + pub(crate) audits: AttachAudits, +} + +/// Install the compile's attachment runs once, at registration. +pub(crate) fn install(attachment: ResourceAttachment) { + let _ = INSTALLED.get_or_init(|| attachment); +} + +/// The installed attachment runs. +pub(crate) fn resource_attachment() -> PyResult<&'static ResourceAttachment> { + INSTALLED + .get() + .ok_or_else(|| PyRuntimeError::new_err(ATTACHMENT_UNINSTALLED)) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/mod.rs index a56686891e..bbd4e1a61a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/mod.rs @@ -1,39 +1,6 @@ -pub(crate) mod attachment; -pub(crate) mod audit_loop; -pub(crate) mod audit_views; -pub(crate) mod compiled_model_analysis; -pub(crate) mod compiled_model_view; -pub(crate) mod expanded_offsets; -pub(crate) mod function_loop; -pub(crate) mod function_views; -pub(crate) mod inputs_view; -pub(crate) mod loop_classes; -pub(crate) mod model_input_view; -pub(crate) mod model_loop; -pub(crate) mod model_loop_calls; -pub(crate) mod model_loop_config; -pub(crate) mod model_loop_contracts; -pub(crate) mod model_loop_external; -pub(crate) mod model_loop_header; -pub(crate) mod model_loop_hooks; -pub(crate) mod model_loop_host; -pub(crate) mod model_loop_inputs; -pub(crate) mod model_loop_macros; -pub(crate) mod model_loop_named; -pub(crate) mod model_loop_opt_out; -pub(crate) mod model_loop_prepass; -pub(crate) mod model_loop_python_hooks; -pub(crate) mod model_loop_schema; -pub(crate) mod model_loop_visibility; +pub(crate) mod attachment_inputs; pub(crate) mod project; -pub(crate) mod project_view; -pub(crate) mod records; pub(crate) mod registration; -pub(crate) mod resource_diagnostics; -pub(crate) mod scenario_loop; +pub(crate) mod rows; pub(crate) mod schema_facts; -pub(crate) mod seed_views; -pub(crate) mod source_loop; -pub(crate) mod source_views; -pub(crate) mod sql_test_loop; pub(crate) mod values; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs index 6189299d1d..ac37b569e5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs @@ -3,14 +3,6 @@ use std::collections::{BTreeMap, HashMap}; use std::sync::Mutex; -use crate::bindings::_helpers::compiled_project::resource_diagnostics::{ - DiagnosticSettings, ResourceDiagnostics, resource_diagnostics, -}; -use crate::bindings::_helpers::compiled_project::scenario_loop::ScenarioRow; -use crate::bindings::_helpers::compiled_project::sql_test_loop::{ - AttachedSqlTests, SqlTestSettings, TestFileRow, -}; - use pyo3::exceptions::{PyIndexError, PyRuntimeError}; use pyo3::prelude::{ Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRef, PyResult, Python, @@ -28,42 +20,44 @@ use sqlbuild_analysis::compiled_project::models::{ }; use crate::bindings::_helpers::boundary::panics::NativeCompilerError; -use crate::bindings::_helpers::compiled_project::audit_loop::{ - AttachmentOwner, AuditFileRow, AuditSettings, model_owner, resource_owner, -}; -use crate::bindings::_helpers::compiled_project::audit_views::{ - AuditRecord, NativeAuditInput, NativeCompiledAudit, +use crate::bindings::_helpers::compiled_project::attachment_inputs::AttachedSqlTests; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditFileRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::DiagnosticSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::ResourceDiagnostics; +use crate::bindings::_helpers::compiled_project::attachment_inputs::ScenarioRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SourceRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SourceSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SqlTestSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::TestFileRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::resource_attachment; +use crate::bindings::_helpers::compiled_project::values::{object_value, plain_value}; +use crate::bindings::_helpers::compiled_views::audit_views::{ + AttachedAudit, AuditRecord, NativeAuditInput, NativeCompiledAudit, }; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ CompiledViewClasses, InferredRow, NativeCompiledModel, }; -use crate::bindings::_helpers::compiled_project::function_loop::{FunctionRow, FunctionSettings}; -use crate::bindings::_helpers::compiled_project::function_views::{ +use crate::bindings::_helpers::compiled_views::function_views::{ AttachedFunction, FunctionRecord, NativeCompiledFunction, NativeFunctionInput, ObjectKeyRow, }; -use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_views::inputs_view::NativeInputsView; +use crate::bindings::_helpers::compiled_views::model_input_view::{ ModelInputRecord, NativeModelInput, }; -use crate::bindings::_helpers::compiled_project::model_loop::NativeModelLoop; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; -use crate::bindings::_helpers::compiled_project::seed_views::{ - NativeCompiledSeed, NativeSeedInput, SeedNamespace, SeedParts, SeedRecord, paired_seeds, +use crate::bindings::_helpers::compiled_views::project_view::NativeProjectView; +use crate::bindings::_helpers::compiled_views::seed_views::{ + NativeCompiledSeed, NativeSeedInput, SeedNamespace, SeedRecord, paired_seeds, }; -use crate::bindings::_helpers::compiled_project::source_loop::{SourceRow, SourceSettings}; -use crate::bindings::_helpers::compiled_project::source_views::{ - AttachedSource, NativeCompiledSource, NativeSourceInput, SourceNamespace, SourceRecord, +use crate::bindings::_helpers::compiled_views::source_views::{ + NativeCompiledSource, NativeSourceInput, SourceNamespace, SourceRecord, }; -use crate::bindings::_helpers::compiled_project::values::{object_value, plain_value}; -use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::declaration_values::ConstantRendering; pub(crate) const CONTRACT_KEY: &str = "contract"; const INPUT_CLASSES_UNSET: &str = "no model loop recorded inputs into this project"; -const RELATIVE_PATH_ATTRIBUTE: &str = "relative_path"; -const SOURCE_OWNER: &str = "source"; -const SEED_OWNER: &str = "seed"; const ATTACHMENT_LOOP_UNSET: &str = "no model loop was kept to attach this project's resources"; pub(crate) const INCREMENTAL_MODE_KEY: &str = "incremental_mode"; const MATERIALIZED_KEY: &str = "materialized"; @@ -153,7 +147,7 @@ pub(crate) struct NativeCompiledProject { /// Each singular, then model-, source- and seed-attached, audit in attachment order. audits: Vec, /// The model loop and its constant rendering, which attach the project's other resources. - attachment: Option<(Py, Py)>, + attachment: Option<(Py, Py)>, } impl NativeCompiledProject { @@ -191,72 +185,11 @@ impl NativeCompiledProject { self.graph_builds += 1; } - /// Each schema-attached model, then each source and seed, with the audits attached to it. - fn attachment_owners<'py>(&self, py: Python<'py>) -> PyResult>> { - let mut owners: Vec> = Vec::new(); - for record in &self.inputs { - let (Some(schema), Some(fact)) = (&record.schema, self.input_schema_fact(record)) - else { - continue; - }; - owners.push(model_owner( - record.name.clone(), - record.model_file.get().relative_text(py)?, - ( - schema.audits.bind(py), - (schema.columns.as_ref(), &fact.columns), - ), - )?); - } - for source in &self.sources { - let attached: &AttachedSource = source.attached(); - let path: String = - native_field(attached.source_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? - .str()? - .to_string(); - owners.push(resource_owner( - SOURCE_OWNER, - attached.name.clone(), - (path.clone(), path), - ( - attached.audits.bind(py).as_any(), - attached.columns.bind(py).as_any(), - ), - )?); - } - for seed in &self.seeds { - let SeedParts { - name, - seed_file, - schema_entry, - schema_file, - } = seed.parts(); - let schema_entry: &Bound<'py, PyAny> = schema_entry.bind(py); - owners.push(resource_owner( - SEED_OWNER, - name.to_owned(), - ( - native_field(seed_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? - .str()? - .to_string(), - native_field(schema_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? - .str()? - .to_string(), - ), - ( - &native_field(schema_entry, "audits")?, - &native_field(schema_entry, "columns")?, - ), - )?); - } - Ok(owners) - } - /// The kept model loop and its constant rendering. - fn attachment_loop( + pub(crate) fn attachment_loop( &self, py: Python<'_>, - ) -> PyResult<(Py, Py)> { + ) -> PyResult<(Py, Py)> { match &self.attachment { Some((model_loop, host)) => Ok((model_loop.clone_ref(py), host.clone_ref(py))), None => Err(PyRuntimeError::new_err(ATTACHMENT_LOOP_UNSET)), @@ -266,12 +199,28 @@ impl NativeCompiledProject { /// Keep the model loop and its constant rendering for attaching the project's other resources. pub(crate) fn keep_attachment_loop( &mut self, - model_loop: Py, + model_loop: Py, host: Py, ) { self.attachment = Some((model_loop, host)); } + /// Retain attached functions; return the index of the first. + pub(crate) fn extend_functions(&mut self, attached: Vec) -> usize { + let first: usize = self.functions.len(); + self.functions + .extend(attached.into_iter().map(FunctionRecord::new)); + first + } + + /// Retain attached audits; return the index of the first. + pub(crate) fn extend_audits(&mut self, attached: Vec) -> usize { + let first: usize = self.audits.len(); + self.audits + .extend(attached.into_iter().map(AuditRecord::new)); + first + } + /// Every attached audit, in attachment order. pub(crate) fn audits(&self) -> &[AuditRecord] { &self.audits @@ -469,15 +418,7 @@ impl NativeCompiledProject { rows: Vec, settings: SourceSettings, ) -> PyResult> { - if rows.is_empty() { - return Ok(Vec::new()); - } - let py: Python<'_> = slf.py(); - let (model_loop, host) = slf.borrow().attachment_loop(py)?; - model_loop - .bind(py) - .get() - .run_sources(slf, host.bind(py), rows, settings) + (resource_attachment()?.sources)(slf, rows, settings) } /// Attach every SQL, then Python, function with the kept loop; return each one's view. @@ -486,32 +427,7 @@ impl NativeCompiledProject { rows: (Vec, Vec), settings: FunctionSettings, ) -> PyResult> { - let py: Python<'_> = slf.py(); - let (model_loop, host) = slf.borrow().attachment_loop(py)?; - let models: Vec<(String, Vec)> = slf - .borrow() - .inputs - .iter() - .map(|record| { - Ok(( - record.model_file.get().relative_text(py)?, - record.references.clone(), - )) - }) - .collect::>()?; - let attached: Vec = - model_loop - .bind(py) - .get() - .run_functions(host.bind(py), rows, settings, &models)?; - let first: usize = slf.borrow().functions.len(); - let count: usize = attached.len(); - slf.borrow_mut() - .functions - .extend(attached.into_iter().map(FunctionRecord::new)); - Ok((first..first + count) - .map(|index| NativeFunctionInput::new(slf.clone().unbind(), index)) - .collect()) + (resource_attachment()?.functions)(slf, rows, settings) } /// The orphaned audit factory warnings, missing descriptions and cursor-input errors. @@ -520,7 +436,7 @@ impl NativeCompiledProject { py: Python<'py>, settings: DiagnosticSettings, ) -> PyResult> { - resource_diagnostics(self, py, &settings) + (resource_attachment()?.diagnostics)(self, py, &settings) } /// Attach every SQL test case, then every scenario, with the kept loop. @@ -530,26 +446,7 @@ impl NativeCompiledProject { scenarios: Vec, settings: SqlTestSettings, ) -> PyResult { - let py: Python<'_> = slf.py(); - let (model_loop, host) = slf.borrow().attachment_loop(py)?; - let arities: HashMap = slf - .borrow() - .functions - .iter() - .filter(|record| !record.attached.return_columns.is_empty()) - .map(|record| { - ( - record.attached.name.clone(), - record.attached.arguments.len(), - ) - }) - .collect(); - model_loop.bind(py).get().run_sql_tests( - host.bind(py), - (&files, &scenarios), - &settings, - arities, - ) + (resource_attachment()?.sql_tests)(slf, files, scenarios, settings) } /// Attach singular, then resource-attached, audits; return views and override warnings. @@ -558,27 +455,8 @@ impl NativeCompiledProject { files: Vec, settings: AuditSettings, ) -> PyResult<(Vec, Vec>)> { - let py: Python<'py> = slf.py(); - let (model_loop, host) = slf.borrow().attachment_loop(py)?; - let owners: Vec> = slf.borrow().attachment_owners(py)?; - let (attached, shadows) = - model_loop - .bind(py) - .get() - .run_audits(host.bind(py), &files, owners, &settings)?; - let first: usize = slf.borrow().audits.len(); - let count: usize = attached.len(); - slf.borrow_mut() - .audits - .extend(attached.into_iter().map(AuditRecord::new)); - Ok(( - (first..first + count) - .map(|index| NativeAuditInput::new(slf.clone().unbind(), index)) - .collect(), - shadows, - )) + (resource_attachment()?.audits)(slf, files, settings) } - /// Keep the scope dependency keys native project assembly resolved, in audit order. fn record_audit_scope_deps(&mut self, deps: Vec>) -> PyResult<()> { for (index, keys) in deps.into_iter().enumerate() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/registration.rs index 826d439918..fd619ffe5f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/registration.rs @@ -1,9 +1,10 @@ use pyo3::prelude::{Bound, PyModule, PyResult}; +use crate::bindings::_helpers::{compiled_views, input_loops}; + +/// Register the compiled project, then its input loops, then its views and records. pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { crate::bindings::_helpers::compiled_project::project::register(module)?; - crate::bindings::_helpers::compiled_project::model_loop::register(module)?; - crate::bindings::_helpers::compiled_project::attachment::register(module)?; - crate::bindings::_helpers::compiled_project::expanded_offsets::register(module)?; - crate::bindings::_helpers::compiled_project::records::register(module) + input_loops::registration::register(module)?; + compiled_views::registration::register(module) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/rows.rs new file mode 100644 index 0000000000..ed1a1bbe64 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/rows.rs @@ -0,0 +1,13 @@ +//! Positional rows shared by the compiled views and the input loops that fill them. + +positional_record! { + extract, into; + /// `(kind, name, package, call argument count)`. + #[derive(Clone, Debug, PartialEq, Eq)] + pub(crate) struct ReferenceRow { + pub(crate) kind: String, + pub(crate) name: String, + pub(crate) package: Option, + pub(crate) call_argument_count: Option, + } +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/audit_views.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/audit_views.rs index 7ddaf506dc..f620ecffef 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/audit_views.rs @@ -6,13 +6,13 @@ use pyo3::sync::PyOnceLock; use pyo3::types::PyTuple; use pyo3::{FromPyObject, IntoPyObjectExt, pyclass, pymethods}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::object_key; -use crate::bindings::_helpers::compiled_project::function_views::ObjectKeyRow; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::compiled_model_view::object_key; +use crate::bindings::_helpers::compiled_views::function_views::ObjectKeyRow; +use crate::bindings::_helpers::compiled_views::model_input_view::{ InputViewClasses, reference_tuple, view_classes, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::scopes::scope_report_objects::json_to_python; use sqlbuild_core::json::models::JsonValue; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_analysis.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_analysis.rs index f42801729b..e1b1151385 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_analysis.rs @@ -18,14 +18,12 @@ use sqlbuild_analysis::semantic_validation::models::{DiagnosticRow, Expansion}; use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ CompiledViewClasses, InferredRow, }; -use crate::bindings::_helpers::compiled_project::model_input_view::ModelInputRecord; +use crate::bindings::_helpers::compiled_views::model_input_view::ModelInputRecord; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; -use crate::bindings::_helpers::record_behaviours::lineage_facts::{ - confidence_member, transform_kind_member, -}; +use crate::bindings::_helpers::lineage::lineage_facts::{confidence_member, transform_kind_member}; const COMPILE_PHASE: &str = "compile"; const MODEL_RESOURCE: &str = "model"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_view.rs similarity index 99% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_view.rs index fc157b5c91..0123c3f6e1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_view.rs @@ -14,20 +14,20 @@ use sqlbuild_analysis::compiled_project::models::{ CompiledModelFacts, DynamicProofFact, ModelAnalysisFact, }; -use crate::bindings::_helpers::compiled_project::compiled_model_analysis::{ +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::compiled_model_analysis::{ AnalysisRecord, ProofArgument, SessionArgument, analysis_record, }; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_views::model_input_view::{ InputViewClasses, ModelInputRecord, model_relation_key_row, query_sql_text, read_input, read_input_with_owner, references, rejected_opt_out, schema_entry, view_classes, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::relation_keys::RelationKeyRow; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; use crate::bindings::_helpers::graph::project_graph::ResourceRow; use crate::bindings::_helpers::model_config::header_metadata::HeaderColumns; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::rules::relation_keys::RelationKeyRow; const DATABASE_KEY: &str = "database"; const SCHEMA_KEY: &str = "schema"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/function_views.rs similarity index 99% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/function_views.rs index 80158fa8b8..e7c8175d35 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/function_views.rs @@ -6,14 +6,14 @@ use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{FromPyObject, IntoPyObjectExt, pyclass, pymethods}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ DestinationFact, defaulted_destination, object_key, relation_location, }; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_views::model_input_view::{ InputViewClasses, reference_tuple, view_classes, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; use crate::bindings::_helpers::graph::project_graph::ResourceRow; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/getters.rs new file mode 100644 index 0000000000..dda648c730 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/getters.rs @@ -0,0 +1,779 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::compiled_views::audit_views::{ + NativeAuditInput, NativeCompiledAudit, +}; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::function_views::{ + NativeCompiledFunction, NativeFunctionInput, +}; +use crate::bindings::_helpers::compiled_views::inputs_view::NativeInputsView; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; +use crate::bindings::_helpers::compiled_views::project_view::NativeProjectView; +use crate::bindings::_helpers::compiled_views::seed_views::{NativeCompiledSeed, NativeSeedInput}; +use crate::bindings::_helpers::compiled_views::source_views::{ + NativeCompiledSource, NativeSourceInput, +}; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_native_audit_input, + }, + GetterEntry { + class: class_of::, + read: read_native_compiled_audit, + }, + GetterEntry { + class: class_of::, + read: read_native_compiled_model, + }, + GetterEntry { + class: class_of::, + read: read_native_compiled_function, + }, + GetterEntry { + class: class_of::, + read: read_native_function_input, + }, + GetterEntry { + class: class_of::, + read: read_native_inputs_view, + }, + GetterEntry { + class: class_of::, + read: read_native_model_input, + }, + GetterEntry { + class: class_of::, + read: read_native_project_view, + }, + GetterEntry { + class: class_of::, + read: read_native_compiled_seed, + }, + GetterEntry { + class: class_of::, + read: read_native_seed_input, + }, + GetterEntry { + class: class_of::, + read: read_native_compiled_source, + }, + GetterEntry { + class: class_of::, + read: read_native_source_input, + }, +]; + +fn read_native_audit_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "meta" => this.meta(py).and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_audit<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "meta" => this.meta(py).and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "scope_deps" => this + .scope_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "definition_name" => this + .definition_name(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_model<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "key_row" => this + .key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "dep_rows" => this + .dep_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination_row" => this + .destination_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_rows" => this + .inferred_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_column_rows" => this + .schema_column_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "has_dynamic_columns" => this + .dynamic_columns_declared(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_count" => this + .output_column_count(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_columns" => this + .inferred_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_columns" => this + .fast_lineage_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_has_star" => this + .fast_lineage_has_star(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_star_resolved" => this + .fast_lineage_star_resolved(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_sql" => this + .authored_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_query_sql" => this + .authored_query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "extract_implicit_alias_columns" => this + .extract_implicit_alias_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_diagnostics" => this + .binding_diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_validated" => this + .binding_validated(py) + .and_then(|value| value.into_bound_py_any(py)), + "dynamic_column_contract" => this + .dynamic_column_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "unchecked_output_columns" => this + .unchecked_output_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_function<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file_path" => this + .source_file_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_destination" => this + .fingerprint_destination(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_function_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "function_file" => this + .function_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "database" => this + .database(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema" => this + .schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_database" => this + .logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_schema" => this + .logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_database" => this + .fingerprint_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_schema" => this + .fingerprint_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_database" => this + .fingerprint_logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_schema" => this + .fingerprint_logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_inputs_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "no_sql_validation" => this.is_sql_validation_skipped().into_bound_py_any(py), + "model_inputs" => this.model_inputs(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "project_config" => this.project_config(py).into_bound_py_any(py), + "local_config" => this.local_config(py).into_bound_py_any(py), + "discovered_inputs" => this.discovered_inputs(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "effective_target" => this.effective_target(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "macro_context" => this.macro_context(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "effective_settings" => this.effective_settings(py).into_bound_py_any(py), + "seed_inputs" => this.seed_inputs(py).into_bound_py_any(py), + "source_inputs" => this.source_inputs(py).into_bound_py_any(py), + "sql_function_inputs" => this.sql_function_inputs(py).into_bound_py_any(py), + "test_inputs" => this.test_inputs(py).into_bound_py_any(py), + "scenario_inputs" => this.scenario_inputs(py).into_bound_py_any(py), + "audit_inputs" => this.audit_inputs(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "declaration_scope" => this.declaration_scope(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_model_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_file" => this + .model_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_source_sql" => this + .macro_source_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_schema_name" => this + .attached_schema_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this.schema_file(py).into_bound_py_any(py), + "sql_validation_enabled" => this + .sql_validation_enabled(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_usages" => this + .macro_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_expansion" => this + .sql_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + "lint_expansion" => this + .lint_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_project_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "effective_target_database" => this.effective_target_database().into_bound_py_any(py), + "effective_target_schema" => this.effective_target_schema().into_bound_py_any(py), + "sql_analysis_dialect" => this.sql_analysis_dialect().into_bound_py_any(py), + "enforce_explicit_references" => { + this.is_explicit_reference_enforced().into_bound_py_any(py) + } + "models" => this.models(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "binding_catalog" => this.binding_catalog(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "loader_functions" => this.loader_functions(py).into_bound_py_any(py), + "hook_functions" => this.hook_functions(py).into_bound_py_any(py), + "sql_hook_files" => this.sql_hook_files(py).into_bound_py_any(py), + "materialization_files" => this.materialization_files(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "native_session" => this.native_session(py).into_bound_py_any(py), + "settings" => this.settings(py).into_bound_py_any(py), + "scenario" => this.scenario(py).into_bound_py_any(py), + "sources" => this.sources(py).into_bound_py_any(py), + "seeds" => this.seeds(py).into_bound_py_any(py), + "functions" => this.functions(py).into_bound_py_any(py), + "audits" => this.audits(py).into_bound_py_any(py), + "sql_tests" => this.sql_tests(py).into_bound_py_any(py), + "sql_scenarios" => this.sql_scenarios(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "unmatched_literal_sql_relations" => this + .unmatched_literal_sql_relations(py) + .into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "sql_expansions" => this + .sql_expansions(py) + .and_then(|value| value.into_bound_py_any(py)), + "lineage_graph" => this + .lineage_graph(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_seed<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "external" => this.is_external().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_seed_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_source<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_source_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/inputs_view.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/inputs_view.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/mod.rs new file mode 100644 index 0000000000..41cfd50614 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/mod.rs @@ -0,0 +1,15 @@ +//! Python views of the compiled project: model, input, resource and project views and their records. +pub(crate) mod audit_views; +pub(crate) mod compiled_model_analysis; +pub(crate) mod compiled_model_view; +pub(crate) mod function_views; +pub(crate) mod getters; +pub(crate) mod inputs_view; +pub(crate) mod model_input_view; +pub(crate) mod model_reads; +pub(crate) mod project_view; +pub(crate) mod records; +pub(crate) mod registration; +pub(crate) mod relation_keys; +pub(crate) mod seed_views; +pub(crate) mod source_views; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_input_view.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_input_view.rs index 9e37af932f..d0b6281702 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_input_view.rs @@ -8,17 +8,17 @@ use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; use pyo3::{FromPyObject, IntoPyObject, pyclass, pymethods}; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ - CompiledArguments, CompiledRecord, CompiledViewClasses, NativeCompiledModel, compiled_record, -}; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; use crate::bindings::_helpers::compiled_project::schema_facts::python_column_facts; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ + CompiledArguments, CompiledRecord, CompiledViewClasses, NativeCompiledModel, compiled_record, +}; +use crate::bindings::_helpers::compiled_views::relation_keys::{RelationKeyRow, relation_key_row}; use crate::bindings::_helpers::discovery::model_file_record::{NativeModelFile, projected_text}; use crate::bindings::_helpers::model_config::header_metadata::HeaderColumns; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::macro_call_rows::SpanRow; -use crate::bindings::_helpers::rules::relation_keys::{RelationKeyRow, relation_key_row}; const MODEL_RELATION_KIND: &str = "ref"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_reads.rs similarity index 99% rename from crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_reads.rs index 9c449309a4..e0eebf6b54 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_reads.rs @@ -2,7 +2,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ DeclaredRow, InferredRow, LineageInput, NativeCompiledModel, }; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/project_view.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/project_view.rs index 966d655754..ee166d5fb3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/project_view.rs @@ -7,16 +7,16 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple, PyTupleMethods}; use pyo3::{pyclass, pymethods}; use crate::bindings::_helpers::compile_driver::stage_work::{LINEAGE_GRAPH_BUILDS, count_stage}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ NativeCompiledModel, model_graph_row, }; -use crate::bindings::_helpers::compiled_project::function_views::NativeCompiledFunction; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_views::function_views::NativeCompiledFunction; +use crate::bindings::_helpers::compiled_views::model_input_view::{ InputViewClasses, authored_expansion, view_classes, }; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::seed_views::NativeCompiledSeed; -use crate::bindings::_helpers::compiled_project::source_views::NativeCompiledSource; +use crate::bindings::_helpers::compiled_views::seed_views::NativeCompiledSeed; +use crate::bindings::_helpers::compiled_views::source_views::NativeCompiledSource; use crate::bindings::_helpers::graph::project_graph::{ NativeProjectGraph, ResourceRow, project_graph, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/records.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/records.rs index 4d095ca181..ef77b24d30 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/records.rs @@ -9,15 +9,15 @@ use pyo3::types::{ use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; use sqlbuild_analysis::compiled_project::models::CompiledModelFacts; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::compiled_project::project::{ AnalysisPy, NativeCompiledProject, ProofPy, model_facts, }; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; use crate::bindings::_helpers::compiled_project::schema_facts::entry_schema_fact; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::inputs_view::NativeInputsView; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; +use crate::bindings::_helpers::compiled_views::project_view::NativeProjectView; use crate::bindings::_helpers::records::construct::{enum_member, new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::record_spec; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/registration.rs new file mode 100644 index 0000000000..348c352052 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/registration.rs @@ -0,0 +1,5 @@ +use pyo3::prelude::{Bound, PyModule, PyResult}; + +pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { + crate::bindings::_helpers::compiled_views::records::register(module) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/relation_keys.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/relation_keys.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/rules/relation_keys.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/relation_keys.rs index 70f684af2a..b388aee974 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/relation_keys.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/relation_keys.rs @@ -13,10 +13,13 @@ use sqlbuild_rules::sql_quality::main::declared_relation_keys::declared_relation use sqlbuild_rules::sql_quality::models::{DeclaredKeyColumn, DeclaredRelation}; use crate::bindings::_helpers::compiled_project::schema_facts::python_column_facts; -use crate::bindings::_helpers::compiled_project::source_views::{SourceKeyFacts, read_source_view}; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::model_input_view::{ + NativeModelInput, model_relation_key_row, +}; +use crate::bindings::_helpers::compiled_views::source_views::{SourceKeyFacts, read_source_view}; use crate::bindings::_helpers::discovery::project_facts::seed_csv_settings; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::rules::lint_inputs::model_key_row; const MATERIALIZED_CONFIG: &str = "materialized"; const INCREMENTAL_MODE_CONFIG: &str = "incremental_mode"; @@ -346,3 +349,17 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(declared_relation_keys, module)?)?; module.add_function(wrap_pyfunction!(compiled_relation_keys, module)?) } + +/// The declared key facts of a model input or compiled model. +pub(crate) fn model_key_row(model: &Bound<'_, PyAny>) -> PyResult { + let py: Python<'_> = model.py(); + if let Ok(input) = model.downcast::() { + return input.get().read_with_owner(py, |owner, record| { + model_relation_key_row(owner, record, py) + }); + } + if let Ok(compiled) = model.downcast::() { + return compiled.get().relation_key_row(py); + } + native_field(model, "relation_key_row")?.extract() +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/seed_views.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/seed_views.rs index 52486ab28b..9fe4958451 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/seed_views.rs @@ -7,13 +7,11 @@ use pyo3::types::PyTuple; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; use sqlbuild_attachments::seeds::main::pair_seed_declarations::pair_seed_declarations; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ DestinationFact, defaulted_destination, object_key, relation_location, }; -use crate::bindings::_helpers::compiled_project::model_input_view::{ - InputViewClasses, view_classes, -}; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_views::model_input_view::{InputViewClasses, view_classes}; use crate::bindings::_helpers::graph::project_graph::ResourceRow; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/source_views.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs rename to crates/sqlbuild-python/src/bindings/_helpers/compiled_views/source_views.rs index e3537d16b5..92b648c4cf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_views/source_views.rs @@ -7,16 +7,14 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; -use crate::bindings::_helpers::compiled_project::compiled_model_view::object_key; -use crate::bindings::_helpers::compiled_project::model_input_view::{ - InputViewClasses, view_classes, -}; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; use crate::bindings::_helpers::compiled_project::schema_facts::python_column_facts; +use crate::bindings::_helpers::compiled_views::compiled_model_view::object_key; +use crate::bindings::_helpers::compiled_views::model_input_view::{InputViewClasses, view_classes}; +use crate::bindings::_helpers::compiled_views::relation_keys::audit_key_rows; use crate::bindings::_helpers::graph::project_graph::ResourceRow; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; -use crate::bindings::_helpers::rules::relation_keys::audit_key_rows; const SOURCE_RESOURCE: &str = "source"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiler_records/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiler_records/constants.rs index 8303b8a13a..055a9891d2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiler_records/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiler_records/constants.rs @@ -1,6 +1,7 @@ //! Layouts of the compiler, lint and config value records hosted natively. -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use sqlbuild_host::entries::models::UserCodeHost; + use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::records::models::{FieldDefault, FieldSpec, RecordSpec}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs index 3ff64702d5..3dd374faac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs @@ -8,9 +8,9 @@ use sqlbuild_cli::compute_logs::errors::{ComputeLogError, ComputeLogErrorKind}; use sqlbuild_cli::compute_logs::models::{ CaptureCompletion, CaptureDocument, CaptureInstant, InventoryEntry, }; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/getters.rs new file mode 100644 index 0000000000..15b1025097 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/getters.rs @@ -0,0 +1,31 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::compute_logs::storage::LocalFilesystemComputeLogStorage; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_local_filesystem_compute_log_storage, +}]; + +fn read_local_filesystem_compute_log_storage<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "root" => this.root(py).and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/mod.rs index 380263eda1..93879e74b9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod conversion; +pub(crate) mod getters; pub(crate) mod registration; pub(crate) mod storage; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs index 40b859097c..72b1d28a9f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs @@ -27,16 +27,14 @@ use sqlbuild_cli::compute_logs::main::read_stream_chunk::read_stream_chunk; use sqlbuild_cli::compute_logs::main::stream_byte_counts::stream_byte_counts; use sqlbuild_cli::compute_logs::main::validate_capture_id::validate_capture_id; use sqlbuild_cli::compute_logs::models::CaptureDocument; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_recall::writer::models::RecallSession; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::compute_logs::conversion::{ capture_id, document, inventory_item, is_exact_int, metadata_model, rejection, storage_error, stream_index, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::recall::session::{forward_diagnostic, forward_output}; use crate::bindings::_helpers::recall::sinks::RecallLifecycleSink; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs index 56b69f6503..cfa2c58dfa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs @@ -18,14 +18,14 @@ use sqlbuild_core::contract_command::models::{ ContractFindingText, ContractProgress, ContractReport, ContractResourceText, }; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; use crate::bindings::_helpers::command_runtime::invocation::resolve_adapter_connection_context; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_project_graph_from_compiled_project; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::contract_command::write::{ContractWrite, write_contracts}; use crate::bindings::_helpers::native_host::connections::connection_failure; use crate::bindings::_helpers::planner_selection::selectors::select_project_graph; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs index 2aab03b0d2..ce1d459823 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs @@ -4,10 +4,10 @@ use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyTuple}; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::format_command::files::write_file_atomically; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs index f9b65d4618..21a1f8c95e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs @@ -10,7 +10,7 @@ use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; use sqlbuild_sqltext::compiler::main::model_output_columns::model_output_columns; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::records::compiled_project_facts; +use crate::bindings::_helpers::compiled_views::records::compiled_project_facts; use crate::bindings::_helpers::contracts::model_contracts::{ ConflictRow, DiagnosticRow, evaluate_project_model_contracts, project_promotion_conflicts, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/mod.rs index 2b178eeadc..9a0cd62366 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/mod.rs @@ -2,9 +2,7 @@ pub(crate) mod contract_diagnostics; pub(crate) mod effective_config; pub(crate) mod exception_types; pub(crate) mod model_contracts; -pub(crate) mod project_config; pub(crate) mod registration; pub(crate) mod resource_identities; pub(crate) mod spec_resolution; -pub(crate) mod sql_values; pub(crate) mod state_literals; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/registration.rs index c4774e6584..db24e3be65 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/registration.rs @@ -2,10 +2,12 @@ use pyo3::prelude::{Bound, PyModule, PyResult}; +use crate::bindings::_helpers::authored_values::sql_values; use crate::bindings::_helpers::contracts::{ - contract_diagnostics, effective_config, exception_types, project_config, resource_identities, - spec_resolution, sql_values, state_literals, + contract_diagnostics, effective_config, exception_types, resource_identities, spec_resolution, + state_literals, }; +use crate::bindings::_helpers::discovery::project_config; pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { contract_diagnostics::register(module)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs index 2a2b4e9d68..7685cc92b8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs @@ -13,7 +13,8 @@ use sqlbuild_state::freshness::constants::STRING_STATE_VALUE_TYPE as STRING_TYPE const INTEGER_TYPE: &str = "integer"; const BOOLEAN_TYPE: &str = "boolean"; const TIMESTAMP_TYPE: &str = "timestamp"; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use sqlbuild_state::freshness::constants::TEXT_TIMESTAMP_STATE_VALUE_TYPE as TEXT_TIMESTAMP_TYPE; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs index 1ce23b0463..083a22fbc9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs @@ -10,7 +10,7 @@ use sqlbuild_core::cost_command::constants::ISO_DATE_LENGTH; use sqlbuild_core::cost_command::errors::CostCommandError; use sqlbuild_core::cost_command::main::is_zero_cost_duration::is_zero_cost_duration; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cost_command::refusal::cost_error; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs index 5ccd9be6b6..b4b4cfdfe5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs @@ -12,7 +12,7 @@ use sqlbuild_core::cost_command::main::cost_history_limit::cost_history_limit; use sqlbuild_core::cost_command::main::select_cost_run::select_cost_run; use sqlbuild_core::cost_command::main::validate_cost_request::validate_cost_request; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cost_command::bounds::{parse_bound, parse_since}; use crate::bindings::_helpers::cost_command::refresh::refresh_pending_cost_run; use crate::bindings::_helpers::cost_command::refusal::cost_error; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs index 518b8f373c..8372c76c9e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs @@ -8,19 +8,19 @@ use sqlbuild_core::cost_command::constants::{ }; use sqlbuild_core::cost_command::main::accepts_cost_refresh::accepts_cost_refresh; use sqlbuild_core::cost_command::models::CostCoverage; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_target_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::cost_report::functions::read_cost_run; use crate::bindings::_helpers::cost_report::functions::resolve_cost_run; use crate::bindings::_helpers::cost_report::functions::write_cost_run; use crate::bindings::_helpers::cost_telemetry::values::cost_aware; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs index b4096e93fd..a6c9205b50 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs @@ -5,7 +5,7 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyCFunction, PyDict, PyDictMethods, PyInt, PyList, PyTuple, PyTupleMethods}; use sqlbuild_core::cost_command::constants::{HISTORY_METRIC_SORT_FIELDS, MISSING_METRIC_STATUSES}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::fields::field as native_field; type SortKey = fn(&Bound<'_, PyAny>, &str) -> PyResult>; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs index 754cfae34f..bdd4ba21ec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs @@ -10,12 +10,12 @@ use pyo3::types::{PyDict, PyDictMethods, PyString, PyTypeMethods}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::cost_report::main::format_cost_breakdown::format_cost_breakdown; use sqlbuild_core::cost_report::models::BreakdownOptions; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::cost_report::records::cost_run; use crate::bindings::_helpers::cost_report::store; use crate::bindings::_helpers::cost_telemetry::values::cost_aware; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs index f1288d7a3e..3253ebae0b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs @@ -13,7 +13,7 @@ use sqlbuild_core::cost_report::main::format_cost_history::format_cost_history a use sqlbuild_core::cost_report::main::select_cost_run::select_cost_run; use sqlbuild_core::cost_report::models::{BreakdownOptions, CostRun}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::cost_report::records::{ cost_run, cost_runs, record_object, record_tuple, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs index 407315978e..89f5cb4230 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs @@ -4,9 +4,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use sqlbuild_core::cost_report::errors::CostArtifactError; use sqlbuild_core::cost_report::models::{CostResource, CostRun, CostSummary}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs index a0162e96cd..db146809f6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs @@ -8,12 +8,12 @@ use sqlbuild_core::cost_allocation::main::allocate_run_cost::allocate_run_cost a use sqlbuild_core::cost_allocation::models::{ AllocationStatus, CostQuery, PyDecimal, ResourceAllocation, RunAllocation, WarehouseKey, }; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::cost_telemetry::values::{ instant_micros, native_decimal, python_decimal, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs index 0d80fbf9af..6b19137ffa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs @@ -4,12 +4,10 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyTuple}; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::cost_telemetry::values::process_object; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs index 6da921bd9b..697a3570d9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs @@ -15,7 +15,7 @@ use sqlbuild_cache::digest::main::sha256_hex::sha256_hex; use sqlbuild_core::json::main::dumps::dumps; use sqlbuild_core::json::models::{JsonDialect, JsonInteger, JsonValue, StdlibJsonOptions}; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported, within}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported, within}; use crate::bindings::_helpers::cost_telemetry::health::mark_ledger_failure; use crate::bindings::_helpers::cost_telemetry::values::process_object; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs index 96b5c7561b..80fbc37771 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs @@ -15,7 +15,7 @@ use sqlbuild_core::cost_allocation::constants::QUERY_HISTORY_RESULT_LIMIT; use sqlbuild_core::cost_allocation::main::query_history_sql::query_history_sql; use sqlbuild_core::cost_allocation::models::{QueryHistoryWindow, RunAllocation}; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::cost_telemetry::allocation::{ SummaryState, allocate_observations, priced, summary_object, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs index ab41216edd..4b47afb67f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs @@ -7,7 +7,7 @@ use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyTuple}; use sqlbuild_core::cost_allocation::models::PyDecimal; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::state_rows::timestamps::offset_aware; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs index a67df9d222..1d94516925 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs @@ -12,13 +12,13 @@ use sqlbuild_cursor::algebra::models::{ Grain, Interval, LocalDateTime, Scalar, ScalarValue, Timestamp, ZoneOffset, }; use sqlbuild_cursor::algebra::types::ZoneRules; +use sqlbuild_host::entries::models::FacadeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::cursor::values::{ DATETIME_MODULE, civil_date, local_date_time, naive_date_time, plain_date, replaced, timedelta_micros, }; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{ enum_from_value, new_record_with, record_class, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/durations.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/durations.rs index 748ca20656..fab9937096 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/durations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/durations.rs @@ -8,7 +8,7 @@ use sqlbuild_cursor::algebra::main::parse_duration::parse_duration; use sqlbuild_cursor::algebra::main::shift_by_duration::shift_by_duration; use sqlbuild_cursor::algebra::models::{DurationDigits, DurationSpan, Moment}; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::values::{ DATETIME_MODULE, civil_date, local_date_time, replaced, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs index a3d30b79ec..c3c10c6de4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs @@ -16,11 +16,11 @@ use sqlbuild_cursor::algebra::main::observed_partition::observed_partition; use sqlbuild_cursor::algebra::main::split_into_batches::split_into_batches; use sqlbuild_cursor::algebra::main::validate_interval::validate_interval; use sqlbuild_cursor::algebra::models::{Interval, Scalar}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::as_scalar; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs index 92b95542c1..8b82a1bf9e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs @@ -5,7 +5,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyInt, PyString, PyStringMethods}; use sqlbuild_cursor::algebra::main::parse_integer_text::parse_integer_text; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::conversion::algebra_error; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::records::construct::record_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs index 8595a0fa79..c75f175a30 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs @@ -23,11 +23,11 @@ use sqlbuild_cursor::algebra::main::normalize_timestamp_text::normalize_timestam use sqlbuild_cursor::algebra::main::parse_integer_text::parse_integer_text; use sqlbuild_cursor::algebra::main::render::render; use sqlbuild_cursor::algebra::models::{Extreme, Grain, Scalar, ScalarValue, SortKey, ZoneOffset}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::conversion::{CursorSession, algebra_error}; use crate::bindings::_helpers::cursor::values::{DATETIME_MODULE, naive_date_time}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs index 0724d362da..85a0cc4557 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs @@ -4,7 +4,7 @@ use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use sqlbuild_cursor::algebra::models::{CivilDate, LocalDateTime}; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::records::fields::field as native_field; pub(crate) const DATETIME_MODULE: &str = "datetime"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs index 2e8bc71041..4375c5a4c3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs @@ -13,10 +13,10 @@ use sqlbuild_analysis::dag_artifact::models::{ AssetNodePlan, AssetProjectionPolicy, AssetSpecKindPolicy, CheckKindFilter, CheckPlan, DagProjectionCheck, DagProjectionGraph, DagProjectionNode, }; +use sqlbuild_host::entries::models::ThirdPartyHost; use crate::bindings::_helpers::dag_artifact::selection::selected_node_ids; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs index ddc97decfb..1efb0e901c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs @@ -14,10 +14,10 @@ use sqlbuild_analysis::dag_artifact::models::{ DagSelectionCheck, DagSelectionGraph, DagSelectionNode, }; use sqlbuild_analysis::planner_selection::main::unit_test_selector_rejection::unit_test_selector_rejection; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::planner_selection::carrier::Carrier; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs index fde9347b4c..2c93d12ceb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs @@ -4,9 +4,9 @@ use std::collections::HashSet; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyTuple}; +use sqlbuild_host::entries::models::ThirdPartyHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs index f3a7722a4c..95fd304984 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs @@ -12,14 +12,14 @@ use sqlbuild_core::dagster_invocation::main::caller_json_output_path::caller_jso use sqlbuild_core::dagster_invocation::main::has_explicit_scenario_selector::has_explicit_scenario_selector; use sqlbuild_core::dagster_invocation::main::json_output_requested::json_output_requested; use sqlbuild_core::dagster_invocation::main::wrap_selectors::wrap_selectors; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::dagster_invocation::access::{ AssetPath, CheckKey, asset_path, asset_path_or_empty, check_enabled, check_key_set, constant, constant_contains, get, items, node_with_id, nodes_by_id, path_set, string_tuple, text_of, }; use crate::bindings::_helpers::dagster_invocation::results::{dagster_check_name, sorted_nodes}; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; const SELECT_FILE_FLAG: &str = "--select-file"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/failures.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/failures.rs index b4f7ed9dc4..f54f01aac6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/failures.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/failures.rs @@ -6,12 +6,12 @@ use pyo3::types::{PyDict, PyDictMethods, PyString}; use sqlbuild_core::dagster_invocation::main::asset_failure_text::asset_failure_text; use sqlbuild_core::dagster_invocation::main::diagnostic_tail::diagnostic_tail; use sqlbuild_core::dagster_invocation::models::AssetFailure; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::dagster_invocation::access::{ constant_contains, get, items, text_of, }; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; const LIVE_FAILURE_MESSAGE: &str = diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs index 3914bb5227..3668e3300e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs @@ -8,14 +8,14 @@ use pyo3::types::{PyBool, PyDict, PyDictMethods, PyList, PyString, PyTuple}; use pyo3::{IntoPyObject, pyfunction}; use sqlbuild_core::dagster_invocation::main::normalize_check_name::normalize_check_name; use sqlbuild_core::dagster_invocation::main::topological_order::topological_order; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::dagster_invocation::access::{ AssetPath, CheckKey, asset_enabled, asset_path, check_enabled, check_key_set, constant, constant_contains, get, items, merged, node_with_id, nodes_by_id, path_set, string_list, text_of, value_or, }; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs index c911d37cec..7468e995cb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs @@ -9,11 +9,11 @@ use sqlbuild_core::dagster_invocation::main::dagster_name_segment::dagster_name_ use sqlbuild_core::dagster_invocation::main::dagster_tag_key::dagster_tag_key; use sqlbuild_core::dagster_invocation::main::fallback_asset_description::fallback_asset_description; use sqlbuild_core::text::main::python_strip::python_strip; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::dagster_invocation::access::{get, value_or}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; const ABC_MODULE: &str = "collections.abc"; const BUILTINS_MODULE: &str = "builtins"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs index 7a9481f474..04a2e55501 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs @@ -11,7 +11,7 @@ use sqlbuild_core::dbt_command::main::forwarded_dbt_args::forwarded_dbt_args; use sqlbuild_core::dbt_command::main::render_dbt_auto_init::render_dbt_auto_init; use sqlbuild_core::dbt_command::models::ForwardedArg; -use crate::bindings::_helpers::cli::progress_reporters::DbtInitProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::DbtInitProgressReporter; use crate::bindings::_helpers::dbt_command::init_project::build_dbt_init_project; use crate::bindings::_helpers::dbt_command::support::{color_enabled, flag, path, stream}; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs index c015fa7d63..6b2bb3dd36 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs @@ -6,10 +6,8 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::dbt_command::main::dbt_output_options::dbt_output_options; use sqlbuild_core::dbt_command::models::DbtOutputOptions; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; use crate::bindings::_helpers::dbt_command::auto_init::{args_tuple, ensure_twin_project}; use crate::bindings::_helpers::dbt_command::debug::run_dbt_debug; use crate::bindings::_helpers::dbt_command::support::{color_enabled, effective_dir, flag, stream}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs index a3158e1ed4..007876b06f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs @@ -3,7 +3,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use sqlbuild_core::dbt_command::constants::NO_CONNECTION_OPTION; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::dbt_command::auto_init::args_tuple; use crate::bindings::_helpers::dbt_command::support::{color_enabled, flag, status, stream}; use crate::bindings::_helpers::dbt_interop::pipeline::debug_dbt_from_project; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs index 74822b5420..980492e532 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs @@ -11,8 +11,8 @@ use sqlbuild_core::dbt_command::main::render_dbt_init_preview::render_dbt_init_p use sqlbuild_core::dbt_command::main::render_dbt_init_summary::render_dbt_init_summary; use sqlbuild_core::dbt_command::models::DbtInitSummary; -use crate::bindings::_helpers::cli::progress_reporters::DbtInitProgressReporter; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::build_progress::progress_reporters::DbtInitProgressReporter; use crate::bindings::_helpers::dbt_command::init_project::build_dbt_init_project; use crate::bindings::_helpers::dbt_command::init_project::validate_dbt_init_project; use crate::bindings::_helpers::dbt_command::support::{color_enabled, flag, path, stream}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs index a9a72ee0d2..c9fd7c7501 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs @@ -12,7 +12,9 @@ use sqlbuild_core::dbt_process::main::run_dbt_process::run_dbt_process; use sqlbuild_core::dbt_process::models::DbtProcessOutput; use sqlbuild_core::text::main::python_strip::python_strip; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use sqlbuild_host::entries::models::ThirdPartyHost; + +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::dbt_interop::profile::build_dbt_init_project_toml; use crate::bindings::_helpers::dbt_interop::profile::normalize_dbt_profile_connection; use crate::bindings::_helpers::dbt_interop::profile_load::{ @@ -24,7 +26,6 @@ use crate::bindings::types::CompilerDetach; use sqlbuild_config::dbt_profile::models::DbtProjectMetadata; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME as PROJECT_FILE; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs index f92b519062..a2e00d4243 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs @@ -3,8 +3,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyBool; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; /// `sys.stdout` or `sys.stderr`, looked up when written. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/getters.rs new file mode 100644 index 0000000000..1f54a82289 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/getters.rs @@ -0,0 +1,34 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::dbt_events::stream::DbtEventStreamUpdate; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_dbt_event_stream_update, +}]; + +fn read_dbt_event_stream_update<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "status_message" => (&this.status_message).into_bound_py_any(py), + "result" => (&this.result).into_bound_py_any(py), + "row" => (&this.row).into_bound_py_any(py), + "finished" => (&this.finished).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/mod.rs index ffde820035..8124b7b4a9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/mod.rs @@ -1,4 +1,5 @@ pub(crate) mod event; +pub(crate) mod getters; pub(crate) mod registration; pub(crate) mod results; pub(crate) mod stream; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs index acd8854958..9252d97372 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs @@ -14,7 +14,7 @@ use sqlbuild_core::dbt_events::main::format_dbt_active_nodes::format_dbt_active_ use sqlbuild_core::dbt_events::main::render_dbt_node_row::render_dbt_node_row; use sqlbuild_core::dbt_events::models::{DbtRowPosition, DbtStreamState, DbtStreamUpdate}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::dbt_events::event::dbt_event; use crate::bindings::_helpers::dbt_events::results::{native_result, python_result}; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs index 979b588dbd..f768dc1b43 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs @@ -18,9 +18,7 @@ use sqlbuild_core::dbt_cli::models::{ use sqlbuild_core::text::main::python_splitlines::python_splitlines; use sqlbuild_core::text::main::python_strip::python_strip; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_from_value, new_record_with, record_class, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs index 3360637d7d..2b99be86c9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs @@ -22,8 +22,8 @@ use sqlbuild_core::dbt_process::main::spawn_dbt_json_process::spawn_dbt_json_pro use sqlbuild_core::dbt_process::main::stop_dbt_process::stop_dbt_process; use sqlbuild_core::dbt_process::models::DbtJsonProcess; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported, within}; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported, within}; use crate::bindings::_helpers::dbt_events::stream::DbtEventStream; use crate::bindings::_helpers::dbt_interop::runner::{ dbt_command_lifecycle, launch_failure, launch_os_error, report_exit, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs index e4151638b0..b9ea9b07c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs @@ -15,7 +15,7 @@ use sqlbuild_core::dbt_plan::main::merged_dbt_execution_args::merged_dbt_executi use sqlbuild_core::dbt_plan::main::render_dbt_execution_summary::render_dbt_execution_summary; use sqlbuild_core::dbt_plan::models::DbtExecutedNode; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::dbt_interop::cli::option_values; use crate::bindings::_helpers::dbt_interop::graph::{DbtCombinedGraph, texts}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/getters.rs new file mode 100644 index 0000000000..1013321adc --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/getters.rs @@ -0,0 +1,84 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::dbt_interop::graph::DbtCombinedGraph; +use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileReferenceResolver; +use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_dbt_combined_graph, + }, + GetterEntry { + class: class_of::, + read: read_dbt_compile_reference_resolver, + }, + GetterEntry { + class: class_of::, + read: read_dbt_runner, + }, +]; + +fn read_dbt_combined_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "nodes" => this.nodes(py).and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_dbt_compile_reference_resolver<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "_dbt_manifest" => this.dbt_manifest(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_dbt_runner<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "dbt_executable" => (&this.dbt_executable).into_bound_py_any(py), + "invoker" => (&this.invoker).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs index 83ded1c9f5..1ccfa4ced8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs @@ -19,7 +19,7 @@ use sqlbuild_core::dbt_graph::models::{ }; use sqlbuild_core::dbt_graph::types::DbtSelectorResolver; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::dbt_interop::manifest::resolve_sqlbuild_model_dbt_refs; use crate::bindings::_helpers::planner_selection::model_selectors::{ resolve_sqlbuild_model_selector_names, split_selector_expansion, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs index 957ff7cb24..cf0e76d253 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs @@ -19,7 +19,7 @@ use sqlbuild_config::dbt_manifest::models::{ ManifestNode, NodeChecksum, ParsedModel, ParsedSeed, ParsedSource, }; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/mod.rs index a6dc7f2cbd..7717f01b44 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod cli; pub(crate) mod constants; pub(crate) mod event_stream; pub(crate) mod execution; +pub(crate) mod getters; pub(crate) mod graph; pub(crate) mod manifest; pub(crate) mod orchestration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs index c901f5ca89..c0e004e052 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs @@ -13,9 +13,7 @@ use sqlbuild_core::dbt_plan::main::dbt_plan_argvs::dbt_plan_argvs; use sqlbuild_core::dbt_plan::main::dbt_required_selector_terms::dbt_required_selector_terms; use sqlbuild_core::dbt_plan::models::{DbtPlanArgvRequest, DbtPlanArgvs, DbtReferencedModel}; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; use crate::bindings::_helpers::dbt_interop::cli::{option_values, raised}; use crate::bindings::_helpers::dbt_interop::graph::{ PlannerResolver, planner_resolver, resolve_dbt_interop_sqlbuild_selection, texts, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs index 1ab8952417..f504580906 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs @@ -8,12 +8,12 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::dbt_cli::main::dbt_debug_args::dbt_debug_args; use std::time::Instant; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::build_command::support::{boolean, none, text}; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::pipeline_entries::plan_has_executable_work; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::dbt_interop::cli::resolve_dbt_config; use crate::bindings::_helpers::dbt_interop::execution::build_failed_sqlbuild_model_names; use crate::bindings::_helpers::dbt_interop::execution::build_merged_dbt_execution_argv; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs index 9a3746dd1c..93f4139cc8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs @@ -4,10 +4,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::PyDict; use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::build_command::support::{boolean, emit, none, text, tuple}; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::dbt_interop::execution::render_dbt_execution_summary_footer; use crate::bindings::_helpers::dbt_interop::pipeline_prologue::progress; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs index 59c7519e5f..582248ae0b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs @@ -1,9 +1,9 @@ //! Discover, compile and resolve the combined dbt pipeline through its existing boundaries. +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::dbt_interop::cli::resolve_dbt_executable; use crate::bindings::_helpers::dbt_interop::cli::route_dbt_interop_args; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs index 234250edc8..59b605b1f1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs @@ -8,7 +8,7 @@ use sqlbuild_core::cli_text::main::format_dbt_interop_plan::format_dbt_interop_p use sqlbuild_core::cli_text::main::format_dbt_interop_plan_json::format_dbt_interop_plan_json; use sqlbuild_core::cli_text::models::{DbtInteropPlanText, DbtLsNodeText, DisplayLimit}; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::plan_output::plan_text::format_plan; use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record, new_record_with, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs index 9a68ae4c3a..4b3fdea078 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs @@ -3,7 +3,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; use crate::bindings::_helpers::build_command::support::{boolean, keyword_relay, none}; use crate::bindings::_helpers::command_runtime::connection::{ anchor_local_database_path, with_dbt_profile, @@ -12,10 +14,6 @@ use crate::bindings::_helpers::command_runtime::warehouses::apply_command_wareho use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_connection_config; use crate::bindings::_helpers::compile_driver::deferral::resolve_model_deferral_inputs; use crate::bindings::_helpers::compile_driver::plan_result::connection_with_hooks; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::display_plan::build_display_only_sqlbuild_plan; use crate::bindings::_helpers::planner_entries::execution_plan::build_execution_plan; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs index fd9599abdf..724c26b268 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs @@ -11,10 +11,10 @@ use sqlbuild_config::dbt_profile::main::normalize_dbt_profile::normalize_dbt_pro use sqlbuild_config::dbt_profile::models::{ ConnectionKey, ConnectionSource, DbtInitConfig, NormalizedProfile, ProfileEntry, ProfileValue, }; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs index 7971187131..9f05ba0858 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs @@ -6,15 +6,15 @@ use pyo3::prelude::{ use pyo3::types::{PyDict, PyDictMethods, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::text::main::python_strip::python_strip; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::dbt_interop::cli::resolved_path; use crate::bindings::_helpers::dbt_interop::profile::normalize_dbt_profile_connection; use crate::bindings::_helpers::dbt_interop::profile_load::{ default_profiles_dir, load_dbt_project_metadata, load_selected_dbt_profile_output, }; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; const DBT_PROFILE_SOURCE: &str = "dbt_profile"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs index fd8e338baa..73370e23e8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs @@ -9,12 +9,12 @@ use sqlbuild_config::dbt_profile::main::select_dbt_profile_target::select_dbt_pr use sqlbuild_config::dbt_profile::models::{ DbtProfileOutputs, DbtProjectMetadata, DbtYamlValue, LoadedDbtProfile, }; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::dbt_interop::profile::raised; use crate::bindings::_helpers::dbt_interop::profile_connection::profile_error; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs index 85f2ccff50..f05541ffb7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs @@ -5,16 +5,16 @@ use pyo3::prelude::{ }; use pyo3::types::{PyDict, PySet, PySetMethods, PyString, PyTuple, PyTupleMethods}; use pyo3::{pyclass, pyfunction, pymethods, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; use std::collections::HashSet; -use crate::bindings::_helpers::compile_driver::python_calls::{ +use crate::bindings::_helpers::boundary::python_calls::{ KeywordArguments, call_with, imported, keywords, within, }; use crate::bindings::_helpers::dbt_interop::manifest::build_compile_dbt_manifest_index; use crate::bindings::_helpers::dbt_interop::manifest::resolve_dbt_reference_relation; use crate::bindings::_helpers::dbt_interop::manifest::validate_compile_dbt_model_names; use crate::bindings::_helpers::dbt_interop::manifest::validate_compile_dbt_model_reference; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs index 9f698755f9..12479d4845 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs @@ -15,12 +15,12 @@ use pyo3::{pyclass, pymethods}; use sqlbuild_core::dbt_cli::models::DbtArgvCommand; use sqlbuild_core::dbt_process::main::run_dbt_process::run_dbt_process; use sqlbuild_core::dbt_process::models::DbtProcessOutput; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, within}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, within}; use crate::bindings::_helpers::dbt_interop::cli::{ argv, ls_nodes, resolve_dbt_executable, sequence, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs index 8d2a041fa7..09300d8282 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs @@ -11,11 +11,11 @@ use sqlbuild_cli::argv::models::{ArgvSettings, DbtExecutionFailure, DbtExecution use sqlbuild_core::dbt_cli::errors::DbtCliError; use sqlbuild_core::dbt_cli::main::dbt_flag_value::dbt_flag_value; use sqlbuild_core::dbt_cli::models::DbtParsedFlags; +use sqlbuild_host::entries::models::AdapterHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; use crate::bindings::_helpers::dbt_interop::cli::resolve_dbt_config; use crate::bindings::_helpers::dbt_interop::cli::{raised, resolved_path}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs index ecca3e3a25..1eebc9e4f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs @@ -1,9 +1,7 @@ //! Execute dbt through the subprocess boundary and finalize results in artifact order. +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; use crate::bindings::_helpers::build_progress::transient_status::TransientStatusReporter; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; use crate::bindings::_helpers::dbt_events::stream::render_dbt_node_result; use crate::bindings::_helpers::dbt_interop::cli::parse_dbt_ls_json_lines; use crate::bindings::_helpers::dbt_interop::event_stream::execute_dbt_json_event_stream; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs index 64f90fa032..f4670bf157 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs @@ -1,6 +1,6 @@ //! Backfill streamed dbt results using Python's JSON and UTF-8 artifact contract. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs index 27ce82fdec..e6fe96555f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs @@ -7,20 +7,18 @@ use sqlbuild_core::build_command::constants::{ EXECUTION_LIMIT_DBT_NOTE, MISSING_ORIGIN_DBT_HELP, RETENTION_DECREASE_DBT_HELP, SNAPSHOT_FULL_REFRESH_DBT_HELP, TABLE_TYPE_DOWNGRADE_DBT_HELP, }; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; use crate::bindings::_helpers::build_command::policies::enforce_plan_safety_policies_binding; use crate::bindings::_helpers::build_command::support::{ boolean, emit, joined, keyword_relay, none, text, tuple, }; use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; use crate::bindings::_helpers::build_progress::footer::format_build_footer; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::format_execution_header; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::format_execution_header; use crate::bindings::_helpers::compile_outputs::runtime_target::write_runtime_target; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs b/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs index 88ed612454..e55c49a4c5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs @@ -21,6 +21,10 @@ use sqlbuild_core::debug_report::models::{ DebugReport, DebugRuntime, WarehouseCheck, }; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{ + KeywordArguments, call_with, imported, within, +}; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::project_connection_config; use crate::bindings::_helpers::command_runtime::runtime_errors::{ @@ -32,10 +36,6 @@ use crate::bindings::_helpers::command_runtime::warehouses::{ }; use crate::bindings::_helpers::compile_attachment::target::build_effective_target_namespace; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, within, -}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::record_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/getters.rs new file mode 100644 index 0000000000..ae7f06237a --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/getters.rs @@ -0,0 +1,38 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_build_phase_timing_tracker, +}]; + +fn read_build_phase_timing_tracker<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "compile_seconds" => (&this.compile_seconds).into_bound_py_any(py), + "planning_seconds" => (&this.planning_seconds).into_bound_py_any(py), + "connection_preparation_seconds" => { + (&this.connection_preparation_seconds).into_bound_py_any(py) + } + "schema_preparation_seconds" => (&this.schema_preparation_seconds).into_bound_py_any(py), + "execution_seconds" => (&this.execution_seconds).into_bound_py_any(py), + "cost_collection_seconds" => (&this.cost_collection_seconds).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs index f36f8fa2ac..f38cf364fe 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs @@ -20,11 +20,11 @@ use sqlbuild_core::diagnostic_routing::main::route_admits::route_admits; use sqlbuild_core::diagnostic_routing::main::sql_digest::sql_digest; use sqlbuild_core::diagnostic_routing::models::{RecordFacts, RouteOptions}; use sqlbuild_core::redaction::main::redact_text::redact_text; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::diagnostics::redaction::redacted_value; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/mod.rs index 52003770f1..fb03912c6b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/mod.rs @@ -1,4 +1,5 @@ pub(crate) mod console_records; +pub(crate) mod getters; pub(crate) mod log_records; pub(crate) mod redaction; pub(crate) mod registration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs index 3ad81fee78..f9c45e9419 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs @@ -9,7 +9,7 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::redaction::main::redact_text::redact_text; use sqlbuild_core::redaction::main::secret_field_name::secret_field_name; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::fields::mapping_items; const REDACTED: &str = "[REDACTED]"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs index 646afabf6c..e541d16b17 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs @@ -6,9 +6,9 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyTuple, PyType}; use pyo3::{pyclass, pymethods}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{context_variable, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{context_variable, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs index 4b0ff2b799..0c84319d67 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs @@ -16,29 +16,28 @@ use sqlbuild_cli::diff_report::models::{ use sqlbuild_cli::diff_report::types::QueryDiffPhase; use sqlbuild_core::json::main::dumps::dumps; use sqlbuild_core::json::models::{JsonDialect, StdlibJsonOptions}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::command_runtime::connection::resolve_target_connection_config; use crate::bindings::_helpers::compile_driver::diff::run_diff_pipeline; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::diff_report::facts::diff_facts; +use crate::bindings::_helpers::diff_report::output::publish_diff_output; use crate::bindings::_helpers::diff_report::query::{ execute_query_diff, execution_options, prepare_query_diff, project_adapter, }; -use crate::bindings::_helpers::diff_report::registration::publish_diff_output; use crate::bindings::_helpers::diff_report::support::{ call, caused, cli_error, error_text, is_exception, matches_class, matches_native, none, object, request_facts, user_error_parts, }; use crate::bindings::_helpers::discovery::configuration::discover_project_configuration; use crate::bindings::_helpers::frontier::encoder::emit_error; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::connections::connection_failure; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs index 11b2e71d79..1bbdb32301 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs @@ -13,7 +13,7 @@ use sqlbuild_cli::diff_report::types::DiffNamedValue; use sqlbuild_core::json::main::python_float_repr::python_float_repr; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::fields::field as native_field; fn text_of(value: &Bound<'_, PyAny>) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/mod.rs index d0a3f88ba1..89d1c7ae4e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod command; pub(crate) mod facts; +pub(crate) mod output; pub(crate) mod query; pub(crate) mod registration; pub(crate) mod support; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/output.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/output.rs new file mode 100644 index 0000000000..bed9d4d21d --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/output.rs @@ -0,0 +1,214 @@ +//! `sqb diff` output: the terminal summary, JSON documents, output publication and exit codes. + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; +use pyo3::types::{PyDict, PyDictMethods}; +use sqlbuild_cli::diff_report::main::render_diff_error_json::render_diff_error_json as error_document; +use sqlbuild_cli::diff_report::main::render_diff_json::render_diff_json; +use sqlbuild_cli::diff_report::main::render_diff_text::render_diff_text; +use sqlbuild_cli::diff_report::models::{ + DiffDocumentOptions, DiffErrorFacts, DiffExampleOptions, DiffModelFacts, DiffTextOptions, +}; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::diff_report::facts::{diff_facts, json_of}; +use crate::bindings::_helpers::frontier::encoder::emit_error; +use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::fields::field as native_field; +use sqlbuild_cli::diff_report::types::PhaseSeconds; + +const DEFAULT_MAX_VALUE_LENGTH: usize = 160; +const TEXT_OPTIONS: (&[&str], &[&str]) = ( + &[ + "result", + "from_label", + "to_label", + "mode_label", + "use_color", + "verbose", + "max_column_examples", + "max_row_only_examples", + ], + &["max_value_length", "suppress_example_values", "outcome"], +); +const ERROR_OPTIONS: (&[&str], &[&str]) = + (&["status", "code", "message"], &["help_text", "size_guard"]); + +fn optional_string(value: Bound<'_, PyAny>) -> PyResult> { + if value.is_none() { + return Ok(None); + } + value.extract().map(Some) +} + +fn phase_seconds(value: Bound<'_, PyAny>) -> PyResult>> { + if value.is_none() { + return Ok(None); + } + let mapping: Bound<'_, PyDict> = value.downcast_into()?; + let mut phases: Vec<(String, f64)> = Vec::new(); + for (phase, seconds) in mapping.iter() { + phases.push((phase.extract()?, seconds.extract()?)); + } + Ok(Some(phases)) +} + +/// The example options of explicit `max_value_length`/`suppress_example_values` arguments. +fn example_options(arguments: &KeywordArguments<'_>) -> PyResult { + Ok(DiffExampleOptions { + max_value_length: if arguments.passed("max_value_length")? { + { + let limit: Bound<'_, PyAny> = arguments.value("max_value_length")?; + if limit.is_none() { + None + } else { + Some(limit.extract()?) + } + } + } else { + Some(DEFAULT_MAX_VALUE_LENGTH) + }, + suppress_values: arguments.flag("suppress_example_values")?, + }) +} + +fn document_options( + arguments: &KeywordArguments<'_>, + examples: DiffExampleOptions, +) -> PyResult { + Ok(DiffDocumentOptions { + from_label: arguments.value("from_label")?.extract()?, + to_label: arguments.value("to_label")?.extract()?, + examples, + outcome: optional_string(arguments.value("outcome")?)?, + phase_seconds: phase_seconds(arguments.value("phase_seconds")?)?, + }) +} + +fn json_text(models: &[DiffModelFacts], options: &DiffDocumentOptions) -> PyResult { + render_diff_json(models, options).map_err(emit_error) +} + +/// Render the concise terminal summary of a diff result. +#[pyfunction] +#[pyo3(signature = (**options))] +pub(crate) fn render_diff_output( + py: Python<'_>, + options: Option>, +) -> PyResult { + let arguments: KeywordArguments<'_> = + KeywordArguments::read(py, "render_diff_output", options, TEXT_OPTIONS)?; + let models: Vec = diff_facts(&arguments.value("result")?)?; + let document: DiffDocumentOptions = document_options(&arguments, example_options(&arguments)?)?; + Ok(render_diff_text( + &models, + &document, + &DiffTextOptions { + mode_label: arguments.value("mode_label")?.extract()?, + use_color: arguments.flag("use_color")?, + verbose: arguments.flag("verbose")?, + max_column_examples: arguments.value("max_column_examples")?.extract()?, + max_row_only_examples: arguments.value("max_row_only_examples")?.extract()?, + }, + )) +} + +/// Render a machine-readable incomplete or execution-failure outcome. +#[pyfunction] +#[pyo3(signature = (**options))] +pub(crate) fn render_diff_error_json( + py: Python<'_>, + options: Option>, +) -> PyResult { + let arguments: KeywordArguments<'_> = + KeywordArguments::read(py, "render_diff_error_json", options, ERROR_OPTIONS)?; + let size_guard: Bound<'_, PyAny> = arguments.value("size_guard")?; + error_document(&DiffErrorFacts { + status: arguments.value("status")?.extract()?, + code: arguments.value("code")?.extract()?, + message: arguments.value("message")?.extract()?, + help: optional_string(arguments.value("help_text")?)?, + size_guard: if size_guard.is_none() { + None + } else { + Some(json_of(&size_guard)?) + }, + }) + .map_err(emit_error) +} + +fn mode_label(request: &Bound<'_, PyAny>) -> PyResult { + if native_field(request, "schema_only")?.is_truthy()? { + return Ok("schema-only".to_owned()); + } + let bounded: Bound<'_, PyAny> = native_field(request, "bounded")?; + if bounded.is_truthy()? { + return Ok(format!("bounded {}", bounded.str()?)); + } + Ok("full".to_owned()) +} + +fn write_stdout(py: Python<'_>, text: &str) -> PyResult<()> { + imported(py, "sys", "stdout")?.call_method1("write", (format!("{text}\n"),))?; + Ok(()) +} + +/// Write the requested JSON file, then print the JSON document or the terminal summary. +pub(crate) fn publish_diff_output( + request: &Bound<'_, PyAny>, + (from_label, to_label): (&str, &str), + (max_column_examples, max_row_only_examples): (i64, i64), + (models, phase_seconds, outcome): (&[DiffModelFacts], Option, Option), +) -> PyResult<()> { + let py: Python<'_> = request.py(); + let max_value_length: Bound<'_, PyAny> = native_field(request, "max_value_length")?; + let examples: DiffExampleOptions = DiffExampleOptions { + max_value_length: if native_field(request, "full_example_values")?.is_truthy()? { + None + } else if max_value_length.is_truthy()? { + Some(max_value_length.extract()?) + } else { + Some(DEFAULT_MAX_VALUE_LENGTH) + }, + suppress_values: native_field(request, "suppress_example_values")?.is_truthy()?, + }; + let document: DiffDocumentOptions = DiffDocumentOptions { + from_label: from_label.to_owned(), + to_label: to_label.to_owned(), + examples, + outcome, + phase_seconds, + }; + let path: Bound<'_, PyAny> = native_field(request, "json_output_path")?; + if !path.is_none() { + let keywords: Bound<'_, PyDict> = PyDict::new(py); + keywords.set_item("parents", true)?; + keywords.set_item("exist_ok", true)?; + native_field(&path, "parent")?.call_method("mkdir", (), Some(&keywords))?; + let encoding: Bound<'_, PyDict> = PyDict::new(py); + encoding.set_item("encoding", "utf-8")?; + path.call_method( + "write_text", + (format!("{}\n", json_text(models, &document)?),), + Some(&encoding), + )?; + } + if native_field(request, "json_output")?.is_truthy()? { + return write_stdout(py, &json_text(models, &document)?); + } + let use_color: bool = + !native_field(request, "no_color")?.is_truthy()? && stdout_supports_color(py)?; + write_stdout( + py, + &render_diff_text( + models, + &document, + &DiffTextOptions { + mode_label: mode_label(request)?, + use_color, + verbose: native_field(request, "verbose")?.is_truthy()?, + max_column_examples: usize::try_from(max_column_examples).unwrap_or_default(), + max_row_only_examples: usize::try_from(max_row_only_examples).unwrap_or_default(), + }, + ), + ) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs index bd8dd810b2..f9a27a370b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs @@ -12,19 +12,19 @@ use sqlbuild_cli::diff_report::main::read_only_query_problem::read_only_query_pr use sqlbuild_cli::diff_report::models::QueryShapeFacts; use sqlbuild_cli::diff_report::types::PhaseSeconds; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; + use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_runtime_config; use crate::bindings::_helpers::compile_attachment::target::build_effective_target_namespace; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::diff_report::support::{ call, cli_error, error_text, none, object, progress_line, }; use crate::bindings::_helpers::diff_report::tolerances::cli_tolerance_overrides; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs index af9c4d14b3..4357437f57 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs @@ -1,221 +1,13 @@ -//! `sqb diff` output: the terminal summary, JSON documents, output publication and exit codes. +//! Register the native `sqb diff` functions. -use pyo3::prelude::{ - Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python, pyfunction, - wrap_pyfunction, -}; -use pyo3::types::{PyDict, PyDictMethods}; -use sqlbuild_cli::diff_report::main::render_diff_error_json::render_diff_error_json as error_document; -use sqlbuild_cli::diff_report::main::render_diff_json::render_diff_json; -use sqlbuild_cli::diff_report::main::render_diff_text::render_diff_text; -use sqlbuild_cli::diff_report::models::{ - DiffDocumentOptions, DiffErrorFacts, DiffExampleOptions, DiffModelFacts, DiffTextOptions, -}; +use pyo3::prelude::{Bound, PyModule, PyModuleMethods, PyResult}; +use pyo3::wrap_pyfunction; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::diff_report::command::{ execute_prepared_query_diff, run_diff_command, }; -use crate::bindings::_helpers::diff_report::facts::{diff_facts, json_of}; +use crate::bindings::_helpers::diff_report::output::{render_diff_error_json, render_diff_output}; use crate::bindings::_helpers::diff_report::tolerances; -use crate::bindings::_helpers::frontier::encoder::emit_error; -use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; -use crate::bindings::_helpers::records::fields::field as native_field; -use sqlbuild_cli::diff_report::types::PhaseSeconds; - -const DEFAULT_MAX_VALUE_LENGTH: usize = 160; -const TEXT_OPTIONS: (&[&str], &[&str]) = ( - &[ - "result", - "from_label", - "to_label", - "mode_label", - "use_color", - "verbose", - "max_column_examples", - "max_row_only_examples", - ], - &["max_value_length", "suppress_example_values", "outcome"], -); -const ERROR_OPTIONS: (&[&str], &[&str]) = - (&["status", "code", "message"], &["help_text", "size_guard"]); - -fn optional_string(value: Bound<'_, PyAny>) -> PyResult> { - if value.is_none() { - return Ok(None); - } - value.extract().map(Some) -} - -fn phase_seconds(value: Bound<'_, PyAny>) -> PyResult>> { - if value.is_none() { - return Ok(None); - } - let mapping: Bound<'_, PyDict> = value.downcast_into()?; - let mut phases: Vec<(String, f64)> = Vec::new(); - for (phase, seconds) in mapping.iter() { - phases.push((phase.extract()?, seconds.extract()?)); - } - Ok(Some(phases)) -} - -/// The example options of explicit `max_value_length`/`suppress_example_values` arguments. -fn example_options(arguments: &KeywordArguments<'_>) -> PyResult { - Ok(DiffExampleOptions { - max_value_length: if arguments.passed("max_value_length")? { - { - let limit: Bound<'_, PyAny> = arguments.value("max_value_length")?; - if limit.is_none() { - None - } else { - Some(limit.extract()?) - } - } - } else { - Some(DEFAULT_MAX_VALUE_LENGTH) - }, - suppress_values: arguments.flag("suppress_example_values")?, - }) -} - -fn document_options( - arguments: &KeywordArguments<'_>, - examples: DiffExampleOptions, -) -> PyResult { - Ok(DiffDocumentOptions { - from_label: arguments.value("from_label")?.extract()?, - to_label: arguments.value("to_label")?.extract()?, - examples, - outcome: optional_string(arguments.value("outcome")?)?, - phase_seconds: phase_seconds(arguments.value("phase_seconds")?)?, - }) -} - -fn json_text(models: &[DiffModelFacts], options: &DiffDocumentOptions) -> PyResult { - render_diff_json(models, options).map_err(emit_error) -} - -/// Render the concise terminal summary of a diff result. -#[pyfunction] -#[pyo3(signature = (**options))] -fn render_diff_output(py: Python<'_>, options: Option>) -> PyResult { - let arguments: KeywordArguments<'_> = - KeywordArguments::read(py, "render_diff_output", options, TEXT_OPTIONS)?; - let models: Vec = diff_facts(&arguments.value("result")?)?; - let document: DiffDocumentOptions = document_options(&arguments, example_options(&arguments)?)?; - Ok(render_diff_text( - &models, - &document, - &DiffTextOptions { - mode_label: arguments.value("mode_label")?.extract()?, - use_color: arguments.flag("use_color")?, - verbose: arguments.flag("verbose")?, - max_column_examples: arguments.value("max_column_examples")?.extract()?, - max_row_only_examples: arguments.value("max_row_only_examples")?.extract()?, - }, - )) -} - -/// Render a machine-readable incomplete or execution-failure outcome. -#[pyfunction] -#[pyo3(signature = (**options))] -pub(crate) fn render_diff_error_json( - py: Python<'_>, - options: Option>, -) -> PyResult { - let arguments: KeywordArguments<'_> = - KeywordArguments::read(py, "render_diff_error_json", options, ERROR_OPTIONS)?; - let size_guard: Bound<'_, PyAny> = arguments.value("size_guard")?; - error_document(&DiffErrorFacts { - status: arguments.value("status")?.extract()?, - code: arguments.value("code")?.extract()?, - message: arguments.value("message")?.extract()?, - help: optional_string(arguments.value("help_text")?)?, - size_guard: if size_guard.is_none() { - None - } else { - Some(json_of(&size_guard)?) - }, - }) - .map_err(emit_error) -} - -fn mode_label(request: &Bound<'_, PyAny>) -> PyResult { - if native_field(request, "schema_only")?.is_truthy()? { - return Ok("schema-only".to_owned()); - } - let bounded: Bound<'_, PyAny> = native_field(request, "bounded")?; - if bounded.is_truthy()? { - return Ok(format!("bounded {}", bounded.str()?)); - } - Ok("full".to_owned()) -} - -fn write_stdout(py: Python<'_>, text: &str) -> PyResult<()> { - imported(py, "sys", "stdout")?.call_method1("write", (format!("{text}\n"),))?; - Ok(()) -} - -/// Write the requested JSON file, then print the JSON document or the terminal summary. -pub(crate) fn publish_diff_output( - request: &Bound<'_, PyAny>, - (from_label, to_label): (&str, &str), - (max_column_examples, max_row_only_examples): (i64, i64), - (models, phase_seconds, outcome): (&[DiffModelFacts], Option, Option), -) -> PyResult<()> { - let py: Python<'_> = request.py(); - let max_value_length: Bound<'_, PyAny> = native_field(request, "max_value_length")?; - let examples: DiffExampleOptions = DiffExampleOptions { - max_value_length: if native_field(request, "full_example_values")?.is_truthy()? { - None - } else if max_value_length.is_truthy()? { - Some(max_value_length.extract()?) - } else { - Some(DEFAULT_MAX_VALUE_LENGTH) - }, - suppress_values: native_field(request, "suppress_example_values")?.is_truthy()?, - }; - let document: DiffDocumentOptions = DiffDocumentOptions { - from_label: from_label.to_owned(), - to_label: to_label.to_owned(), - examples, - outcome, - phase_seconds, - }; - let path: Bound<'_, PyAny> = native_field(request, "json_output_path")?; - if !path.is_none() { - let keywords: Bound<'_, PyDict> = PyDict::new(py); - keywords.set_item("parents", true)?; - keywords.set_item("exist_ok", true)?; - native_field(&path, "parent")?.call_method("mkdir", (), Some(&keywords))?; - let encoding: Bound<'_, PyDict> = PyDict::new(py); - encoding.set_item("encoding", "utf-8")?; - path.call_method( - "write_text", - (format!("{}\n", json_text(models, &document)?),), - Some(&encoding), - )?; - } - if native_field(request, "json_output")?.is_truthy()? { - return write_stdout(py, &json_text(models, &document)?); - } - let use_color: bool = - !native_field(request, "no_color")?.is_truthy()? && stdout_supports_color(py)?; - write_stdout( - py, - &render_diff_text( - models, - &document, - &DiffTextOptions { - mode_label: mode_label(request)?, - use_color, - verbose: native_field(request, "verbose")?.is_truthy()?, - max_column_examples: usize::try_from(max_column_examples).unwrap_or_default(), - max_row_only_examples: usize::try_from(max_row_only_examples).unwrap_or_default(), - }, - ), - ) -} pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(render_diff_output, module)?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs index f7a1696932..8fdb349046 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs @@ -5,10 +5,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_cli::diff_report::errors::DiffUserError; use sqlbuild_cli::diff_report::models::DiffRequestFacts; +use sqlbuild_host::entries::models::HostId; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::models::HostId; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs index 2700d8b6dc..82f43ff952 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs @@ -5,11 +5,10 @@ use pyo3::prelude::{ }; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyFloat, PyInt, PyString}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/configuration.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/configuration.rs index d0b17cbd19..96c80164de 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/configuration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/configuration.rs @@ -2,15 +2,15 @@ use pyo3::prelude::{Bound, PyAny, PyResult, Python}; use pyo3::types::PyString; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; use crate::bindings::_helpers::compile_driver::config_validation::{ ProjectConfiguration, reject_invalid_connection_configuration, }; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; -use crate::bindings::_helpers::contracts::project_config::{ +use crate::bindings::_helpers::discovery::project_config::{ load_local_config_file, load_project_config_file, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs index 8c3c3aa0d3..c1415677ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs @@ -13,10 +13,11 @@ use sqlbuild_discovery::declaration_files::models::{ use sqlbuild_discovery::declaration_files::types::Collection; use sqlbuild_discovery::models::{FileOutcome, LineColumnSpan}; use sqlbuild_discovery::tree::models::ProjectTree; +use sqlbuild_host::entries::models::FacadeHost; use sqlbuild_sqltext::compiler::models::AuthoredValue; use std::sync::Arc; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; use crate::bindings::_helpers::discovery::constants; use crate::bindings::_helpers::discovery::faults::{FileFaults, record_tuple}; use crate::bindings::_helpers::discovery::header_declarations::typed_constant_record; @@ -27,7 +28,6 @@ use crate::bindings::_helpers::discovery::snapshot::{ }; use crate::bindings::_helpers::discovery::sorted_keys::sorted_keys; use crate::bindings::_helpers::model_config::header_columns::schema_columns; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/description_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/description_inputs.rs index eaf8f24422..71ede5131f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/description_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/description_inputs.rs @@ -4,11 +4,11 @@ use pyo3::prelude::{Bound, PyAny, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyCFunction, PyDict, PyFrozenSet}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::contracts::project_config::load_project_config_file; use crate::bindings::_helpers::discovery::declaration_records::discover_model_schema_files; use crate::bindings::_helpers::discovery::model_records::{ ModelFileSelection, discovered_model_files, }; +use crate::bindings::_helpers::discovery::project_config::load_project_config_file; use crate::bindings::_helpers::discovery::snapshot::in_snapshot; use crate::bindings::_helpers::model_config::described_models::externally_described_models as described_models; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/getters.rs new file mode 100644 index 0000000000..a137005c45 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/getters.rs @@ -0,0 +1,77 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; +use crate::bindings::models::NativeDirectorySnapshot; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_native_model_file, + }, + GetterEntry { + class: class_of::, + read: read_native_directory_snapshot, + }, +]; + +fn read_native_model_file<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "file_path" => this + .file_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "contents" => this.contents(py).into_bound_py_any(py), + "header_values" => this + .header_values(py) + .and_then(|value| value.into_bound_py_any(py)), + "header_column_locations" => this + .header_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this.query_sql(py).into_bound_py_any(py), + "enum_declarations" => this.enum_declarations(py).into_bound_py_any(py), + "constant_declarations" => this.constant_declarations(py).into_bound_py_any(py), + "extract_implicit_alias_columns" => { + this.extract_implicit_alias_columns().into_bound_py_any(py) + } + _ => return None, + }) +} + +fn read_native_directory_snapshot<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_dir" => this.project_dir(py).into_bound_py_any(py), + "memo" => this.memo(py).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs index 8f6763f297..a6bdf4d223 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs @@ -11,7 +11,7 @@ use sqlbuild_config::project::main::snippet_help_text::snippet_help_text; use sqlbuild_config::project::main::sql_analysis_off_guidance::sql_analysis_off_guidance as analysis_off; use sqlbuild_config::project::models::{SettingSite, SettingText}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; const SQL_ANALYSIS_KEY: &str = "sql_analysis"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs index 6ee384b9a7..a65df02681 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs @@ -15,7 +15,7 @@ use sqlbuild_model_config::declarations::models::{ use sqlbuild_model_config::sql_values::errors::SqlValueFailure; use sqlbuild_model_config::sql_values::models::RawSqlValue; -use crate::bindings::_helpers::contracts::sql_values::{ +use crate::bindings::_helpers::authored_values::sql_values::{ SqlValueClasses, raw_value, sql_value, sql_value_error, }; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/header_keys.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_keys.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compile_delta/header_keys.rs rename to crates/sqlbuild-python/src/bindings/_helpers/discovery/header_keys.rs index 9cc07cefd5..5abec8d9f4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_delta/header_keys.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_keys.rs @@ -10,12 +10,10 @@ use sqlbuild_sqltext::sql_references::main::extract_sql_references::extract_sql_ use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; -use crate::bindings::_helpers::compile_delta::context::{capture, capturing}; +use crate::bindings::_helpers::compile_context::delta::HeaderKeys; +use crate::bindings::_helpers::compile_context::delta::{capture, capturing}; use crate::bindings::_helpers::discovery::model_records::model_file_options; -/// One model's header keys with the digest of each authored value, sorted by key. -pub(crate) type HeaderKeys = Vec<(String, String)>; - /// Header keys a delta compile recompiles the model for; any other changed key falls back. const PATCHED_KEYS: [&str; 6] = [ "description", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs index 3c1e89c048..0a43dbd683 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs @@ -4,12 +4,13 @@ use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple, PyTupleMethods}; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use sqlbuild_host::entries::models::UserCodeHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::discovery::locations::project_relative_path; use crate::bindings::_helpers::discovery::python_module_files::discover_python_module_files; use crate::bindings::_helpers::event_exporting::scope::current_scope; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs index e6b381bc4d..d3eefb90c6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs @@ -2,20 +2,21 @@ use std::collections::HashSet; -use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; +use pyo3::exceptions::PyRuntimeError; +use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; -use pyo3::types::{PyDict, PyDictMethods}; +use pyo3::sync::PyOnceLock; +use pyo3::types::{PyDict, PyDictMethods, PyType}; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::input_reads::record_settings_class_read; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; +use crate::bindings::_helpers::compile_context::input_reads::record_settings_class_read; use crate::bindings::_helpers::contracts::resource_identities::validate_resource_identity; use crate::bindings::_helpers::discovery::imported_modules::{ ProjectDir, discovered, discovery_error, discovery_error_from, module_functions, provider_by_name, provider_usages, shim, tuple_of, }; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; -use crate::bindings::_helpers::recall::writer::RecallWriter; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; @@ -31,6 +32,9 @@ const ROOT_LOCATION: &str = ""; const DEFAULT_MESSAGE: &str = "invalid value"; const DEFAULT_ERROR_TYPE: &str = "validation_error"; const DEFAULT_SETTINGS_ERROR: &str = "invalid provider settings"; +const RECALL_WRITER_UNINSTALLED: &str = "the native module registered no RecallWriter class"; + +static RECALL_WRITER: PyOnceLock> = PyOnceLock::new(); fn reject_invalid_identity( name: &Bound<'_, PyAny>, @@ -281,19 +285,26 @@ pub(crate) fn discover_event_exporter_declarations<'py>( tuple_of(py, declarations) } +/// Install the `RecallWriter` class sink parameters are recognised by, once, at registration. +pub(crate) fn install_recall_writer(writer: &Bound<'_, PyType>) { + let _ = RECALL_WRITER.get_or_init(writer.py(), || writer.clone().unbind()); +} + /// Each parameter of `function` with its annotation, and whether that annotation is `RecallWriter`. fn annotated_parameters<'py>( function: &Bound<'py, PyAny>, ) -> PyResult, bool)>> { let py: Python<'py> = function.py(); - let writer = py.get_type::(); + let writer: &Py = RECALL_WRITER + .get(py) + .ok_or_else(|| PyRuntimeError::new_err(RECALL_WRITER_UNINSTALLED))?; let mut parameters: Vec<(String, Bound<'py, PyAny>, bool)> = Vec::new(); for pair in shim(py, UserCodeHost::ParameterAnnotations)? .call1((function,))? .try_iter()? { let (parameter, annotation): (String, Bound<'py, PyAny>) = pair?.extract()?; - let is_writer: bool = annotation.is(writer.as_any()); + let is_writer: bool = annotation.is(writer.bind(py).as_any()); parameters.push((parameter, annotation, is_writer)); } Ok(parameters) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs index 4f1ee4a910..529bc375d0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs @@ -4,24 +4,21 @@ use std::collections::HashMap; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyBytes, PyDict, PyDictMethods, PyList, PyString, PyTuple}; -use pyo3::{pyfunction, wrap_pyfunction}; +use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use sqlbuild_core::constants::PYTHON_NODE_ROOT; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::discovery::imported_modules::{ ProjectDir, definition, discovered, discovery_error, discovery_error_from, is_exception, module_functions, provider_by_name, provider_usages, shim, tuple_of, }; use crate::bindings::_helpers::discovery::imported_providers; -use crate::bindings::_helpers::records::construct::new_record; - use crate::bindings::_helpers::discovery::python_hook_files::discover_python_hook_files; -use crate::bindings::_helpers::graph::python_node_graph::node_identity; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use pyo3::IntoPyObjectExt; -use sqlbuild_core::constants::PYTHON_NODE_ROOT; const NODE_ERROR: ErrorId = ErrorId::PythonNodeDiscovery; const AUDIT_CASE: UserCodeHost = UserCodeHost::AuditCase; const READ_FACTORY: UserCodeHost = UserCodeHost::ReadFactoryDefinition; @@ -578,3 +575,67 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module )?) } + +fn optional_value<'py>(value: &Bound<'py, PyAny>) -> PyResult> { + if value.is_none() { + return Ok(value.clone()); + } + native_field(value, "value") +} + +/// The decorator configuration the identity of one node of `kind` hashes, read through `get`. +fn decorator_config<'py>( + py: Python<'py>, + (kind, documented): (&str, bool), + get: &dyn Fn(&str) -> PyResult>, +) -> PyResult> { + let config: Bound<'py, PyDict> = PyDict::new(py); + match kind { + "LOADER" => { + config.set_item("columns", get("columns")?)?; + config.set_item("contract", get("contract")?)?; + config.set_item("cursor_column", get("cursor_column")?)?; + config.set_item("destination", get("destination")?)?; + config.set_item("unique_key", get("unique_key")?)?; + config.set_item("write_strategy", optional_value(&get("write_strategy")?)?)?; + } + "ASSET" => { + config.set_item("columns", get("columns")?)?; + config.set_item("column_lineage", get("column_lineage")?)?; + } + "CHECK" => { + config.set_item("severity", get("severity")?.getattr("value")?)?; + } + _ => {} + } + if documented { + for field in ["description", "group", "meta", "tags"] { + config.set_item(field, get(field)?)?; + } + } + Ok(config) +} + +/// The identity of one discovered node of `(kind, documented)`, hashed once by the user-code host. +pub(crate) fn node_identity<'py>( + py: Python<'py>, + (kind, documented): (&str, bool), + get: &dyn Fn(&str) -> PyResult>, +) -> PyResult> { + let kind_value: Bound<'py, PyAny> = host::entry(py, UserCodeHost::PythonNodeKind)? + .getattr(kind)? + .getattr("value")?; + call_with( + &host::entry(py, UserCodeHost::PythonNodeIdentity)?, + &[ + ("kind", kind_value), + ("name", get("name")?), + ("function", get("function")?), + ("file_path", get("file_path")?), + ( + "decorator_config", + decorator_config(py, (kind, documented), get)?.into_any(), + ), + ], + ) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/mod.rs index 285db345a7..43c35fbb89 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/mod.rs @@ -4,8 +4,10 @@ pub(crate) mod declaration_files; pub(crate) mod declaration_records; pub(crate) mod description_inputs; pub(crate) mod faults; +pub(crate) mod getters; pub(crate) mod guidance; pub(crate) mod header_declarations; +pub(crate) mod header_keys; pub(crate) mod header_values; pub(crate) mod hook_entries; pub(crate) mod imported_modules; @@ -15,6 +17,7 @@ pub(crate) mod key_checks; pub(crate) mod locations; pub(crate) mod model_file_record; pub(crate) mod model_records; +pub(crate) mod project_config; pub(crate) mod project_facts; pub(crate) mod project_files; pub(crate) mod project_validation; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs index b42b199fd8..9975ca2f83 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs @@ -9,7 +9,7 @@ use sqlbuild_discovery::model_files::models::{DiscoveredModelFile, ModelFileOpti use sqlbuild_discovery::models::{DiscoveredFile, FileOutcome, StageFailure}; use std::path::Path; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::discovery::constants; use crate::bindings::_helpers::discovery::faults::{FileFaults, record_tuple}; use crate::bindings::_helpers::discovery::model_file_record::DiscoveredPaths; @@ -69,7 +69,7 @@ fn model_items<'py>( for file in files { let raw: bool = tree.get().inner.raw_relative(&file.relative_path).is_some(); if !raw && let FileOutcome::Parsed(model) = file.outcome { - crate::bindings::_helpers::compile_delta::header_keys::record_header_keys( + crate::bindings::_helpers::discovery::header_keys::record_header_keys( &file.relative_path, &model.header_values, ); @@ -130,7 +130,7 @@ pub(crate) fn discovered_model_files<'py>( removed_keys: sorted_keys(&constants::REMOVED_SQL_MODEL_HEADER_KEYS), extract_implicit_alias_columns, extract_output_column_locations, - path_filter: crate::bindings::_helpers::compile_delta::context::injection() + path_filter: crate::bindings::_helpers::compile_context::delta::injection() .map(|injection| std::sync::Arc::new(injection.model_paths.clone())), }; let items: Vec> = model_items(project_dir, &options)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_config.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs rename to crates/sqlbuild-python/src/bindings/_helpers/discovery/project_config.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs index 639f068c24..5bfcaeb0d1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs @@ -1,6 +1,6 @@ //! The facts cross-file validation reads, taken from Python's `DiscoveredProjectInputs`. -use crate::bindings::_helpers::compile_delta::context::injection; +use crate::bindings::_helpers::compile_context::delta::injection; use crate::bindings::_helpers::discovery::model_file_record::{ModelFileTexts, NativeModelFile}; use crate::bindings::_helpers::records::fields::{field as native_field, path_stem}; use pyo3::FromPyObject; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs index c73a2bfbae..2527fe47b6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs @@ -7,9 +7,6 @@ use pyo3::prelude::{ use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::contracts::project_config::{ - load_local_config_file, load_project_config_file, -}; use crate::bindings::_helpers::discovery::declaration_records::{ discover_audit_files, discover_constant_files, discover_enum_files, discover_macro_files, discover_model_schema_files, discover_sql_function_files, discover_sql_hook_files, path_class, @@ -17,6 +14,9 @@ use crate::bindings::_helpers::discovery::declaration_records::{ use crate::bindings::_helpers::discovery::model_records::{ ModelFileSelection, discovered_model_files, }; +use crate::bindings::_helpers::discovery::project_config::{ + load_local_config_file, load_project_config_file, +}; use crate::bindings::_helpers::discovery::snapshot::in_snapshot; use crate::bindings::_helpers::discovery::sql_test_records::{ discover_scenario_files, discover_test_files, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs index 6f636c6d51..c4fc8b523b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs @@ -8,13 +8,15 @@ use pyo3::exceptions::PyRuntimeError; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; +use sqlbuild_host::entries::models::FacadeHost; use sqlbuild_model_config::sql_tests::main::sql_test_block::sql_test_block; use sqlbuild_model_config::sql_tests::main::sql_test_names_failure::sql_test_names_failure; use sqlbuild_model_config::sql_tests::models::{SqlTestBlock, SqlTestCase}; use sqlbuild_model_config::sql_values::models::{RawKey, RawSqlValue}; -use crate::bindings::_helpers::contracts::sql_values::{SqlValueClasses, raw_value, sql_value}; -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use crate::bindings::_helpers::authored_values::sql_values::{ + SqlValueClasses, raw_value, sql_value, +}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs index 5ef3604e1f..5d2de99d53 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs @@ -16,7 +16,7 @@ use sqlbuild_discovery::sql_tests::models::{ use sqlbuild_discovery::tree::models::ProjectTree; use sqlbuild_model_config::execution_limits::main::parse_execution_limit::parse_execution_limit; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::discovery::constants; use crate::bindings::_helpers::discovery::faults::{FileFaults, record_tuple}; use crate::bindings::_helpers::discovery::project_files::path_object; @@ -57,7 +57,7 @@ fn options() -> PyResult { Ok(SqlTestFileOptions { test_keys: sorted_keys(&constants::SQL_TEST_HEADER_KEYS), scenario_keys: sorted_keys(&constants::SQL_SCENARIO_HEADER_KEYS), - path_filter: crate::bindings::_helpers::compile_delta::context::injection() + path_filter: crate::bindings::_helpers::compile_context::delta::injection() .map(|injection| std::sync::Arc::new(injection.test_paths.clone())), }) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs index 9734f1a56b..a408a909ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs @@ -349,9 +349,9 @@ pub(crate) fn parse_sources_document<'py>( parse_error(py, error, SOURCE_PARSE_ERROR).unwrap_or_else(|error| error) })?; let referenced: Option> = - crate::bindings::_helpers::compile_delta::context::injection() + crate::bindings::_helpers::compile_context::delta::injection() .and_then(|injection| injection.source_names.clone()); - crate::bindings::_helpers::compile_delta::context::record_source_reads( + crate::bindings::_helpers::compile_context::delta::record_source_reads( loaded_sources(&sources).iter().map(String::as_str), ); let mut built: Vec> = Vec::with_capacity(sources.len()); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs index 4fcf280d58..56c7b08861 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs @@ -17,7 +17,7 @@ use sqlbuild_discovery::yaml_files::models::{YamlFileOutcome, YamlPathFailure}; use std::path::PathBuf; use crate::bindings::_helpers::boundary::config_values::config_value_to_python; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::discovery::faults::{FileFaults, record_tuple}; use crate::bindings::_helpers::discovery::project_files::path_object; use crate::bindings::_helpers::discovery::raised::{ @@ -155,12 +155,13 @@ fn load_files<'py>( let py: Python<'py> = project_dir.py(); let tree: Bound<'py, NativeProjectTree> = project_tree(project_dir)?; let root: ProjectRoot = project_root(project_dir)?; - let mut documents: Option = - if matches!(kind, YamlKind::Source) { - crate::bindings::_helpers::compile_delta::yaml_cache::open_documents(py) - } else { - None - }; + let mut documents: Option< + crate::bindings::_helpers::compile_context::yaml_cache::DocumentStore, + > = if matches!(kind, YamlKind::Source) { + crate::bindings::_helpers::compile_context::yaml_cache::open_documents(py) + } else { + None + }; for batch in batches(&tree.get().inner, paths, YAML_BATCH_BYTES) { let named: Vec = batch .iter() @@ -184,7 +185,7 @@ fn load_files<'py>( let mut outcomes: Vec = outcomes.map_err(|failure| stage_error(&tree.get().inner, project_dir, failure))?; if matches!(kind, YamlKind::Source) { - crate::bindings::_helpers::compile_delta::report_hooks::retain_read_sources( + crate::bindings::_helpers::compile_context::yaml_cache::retain_read_sources( &mut outcomes, ); } @@ -211,7 +212,7 @@ fn load_files<'py>( } } if let Some(documents) = &documents { - crate::bindings::_helpers::compile_delta::yaml_cache::save_documents(py, documents); + crate::bindings::_helpers::compile_context::yaml_cache::save_documents(py, documents); } Ok(()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs index 9bdef06fc7..673e708842 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs @@ -24,10 +24,9 @@ use sqlbuild_core::event_export::models::{ EventQueue, ExportPolicy, ExportSeverity, ExportSnapshot, ExporterCounts, ExporterFilter, QueuedEvent, SnapshotInputs, }; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::event_exporting::constants::{ DISPATCHER_THREAD_NAME, EXIT_JOIN_SECONDS, HEALTH_THREAD_NAME, IDLE_WAIT_SECONDS, JOIN_GRACE_SECONDS, NO_SECONDS, NOTIFIER_THREAD_NAME, OUTPUT_SINK_THREAD_NAME, POLL_SECONDS, @@ -41,7 +40,6 @@ use crate::bindings::_helpers::event_exporting::values::{ }; use crate::bindings::_helpers::event_exporting::workers::{DispatcherWorker, Lane, WorkerRole}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::native_threads::constants::OUTPUT_SUPPRESSED_ATTRIBUTE; use crate::bindings::_helpers::native_threads::exit_signal::{ interpreter_exiting, signal_interpreter_exit, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/getters.rs new file mode 100644 index 0000000000..f4fec94b7a --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/getters.rs @@ -0,0 +1,209 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; +use crate::bindings::_helpers::event_exporting::models::{ + BoundEventExporter, EventExportSummary, EventExporterAccounting, EventExporterCounts, + EventExporterFailure, +}; +use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_event_exporter_dispatcher, + }, + GetterEntry { + class: class_of::, + read: read_bound_event_exporter, + }, + GetterEntry { + class: class_of::, + read: read_event_export_summary, + }, + GetterEntry { + class: class_of::, + read: read_event_exporter_accounting, + }, + GetterEntry { + class: class_of::, + read: read_event_exporter_counts, + }, + GetterEntry { + class: class_of::, + read: read_event_exporter_failure, + }, + GetterEntry { + class: class_of::, + read: read_event_exporter_command_scope, + }, +]; + +fn read_event_exporter_dispatcher<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "thread" => this.thread(py).into_bound_py_any(py), + "notification_thread" => this.notification_thread(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_bound_event_exporter<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name().into_bound_py_any(py), + "function" => this.function(py).into_bound_py_any(py), + "provider_arguments" => this.provider_arguments(py).into_bound_py_any(py), + "event_kinds" => this + .event_kinds(py) + .and_then(|value| value.into_bound_py_any(py)), + "min_severity" => this + .min_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_event_export_summary<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "aggregate" => this.aggregate().into_bound_py_any(py), + "per_exporter" => this + .per_exporter(py) + .and_then(|value| value.into_bound_py_any(py)), + "queue_depth" => this.queue_depth().into_bound_py_any(py), + "queue_capacity" => this.queue_capacity().into_bound_py_any(py), + "flush_complete" => this.flush_complete().into_bound_py_any(py), + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_accounting<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "counts" => this.counts().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_counts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_failure<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "error_type" => this.error_type().into_bound_py_any(py), + "event_kind" => this.event_kind().into_bound_py_any(py), + "event_severity" => this + .event_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_event_exporter_command_scope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "dispatcher" => this.dispatcher(py).into_bound_py_any(py), + "provider_session" => this + .provider_session(py) + .and_then(|value| value.into_bound_py_any(py)), + "project_dir" => this + .project_dir(py) + .and_then(|value| value.into_bound_py_any(py)), + "providers" => this + .providers(py) + .and_then(|value| value.into_bound_py_any(py)), + "event_exporters" => this + .event_exporters(py) + .and_then(|value| value.into_bound_py_any(py)), + "command_output_sinks" => this + .command_output_sinks(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/mod.rs index 1c089a997c..2425304a06 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod constants; pub(crate) mod dispatcher; +pub(crate) mod getters; pub(crate) mod models; pub(crate) mod policy; pub(crate) mod registration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs index 40d42b4598..84e9fee3b0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs @@ -2,7 +2,7 @@ use pyo3::prelude::{Bound, PyAnyMethods, PyModule, PyModuleMethods, PyResult, wrap_pyfunction}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::event_exporting::dispatcher::{ EventExporterDispatcher, stop_event_exporter_threads, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs index f3a5b2a94c..3c86c9b399 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs @@ -9,15 +9,14 @@ use pyo3::prelude::{ }; use pyo3::sync::PyOnceLock; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyTuple}; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; -use crate::bindings::_helpers::compile_driver::python_calls::{ +use crate::bindings::_helpers::boundary::python_calls::{ KeywordArguments, call_with, context_variable, }; use crate::bindings::_helpers::event_exporting::constants::SCOPE_CONTEXT_VARIABLE; use crate::bindings::_helpers::event_exporting::models::BoundEventExporter; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs index 80ee687a90..44920480a6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs @@ -11,9 +11,9 @@ use sqlbuild_core::event_export::main::sanitized_exception_type::sanitized_excep use sqlbuild_core::event_export::models::{ExportPolicy, ExportSeverity, ExporterCounts}; use sqlbuild_core::lifecycle_events::constants::CURRENT_LIFECYCLE_EVENT_SCHEMA_VERSION; use sqlbuild_core::lifecycle_events::main::catalog::catalog; +use sqlbuild_host::entries::models::UserCodeHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::enum_from_value; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs index ca07475d2c..8ed535cbd5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs @@ -13,8 +13,9 @@ use sqlbuild_core::event_export::main::take_lifecycle_event::take_lifecycle_even use sqlbuild_core::event_export::models::{ EventQueue, ExportSeverity, ExportSnapshot, QueuedEvent, }; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::event_exporting::constants::{ INVOCATION_THREAD_PREFIX, LANE_WINDOW, NO_SECONDS, POLL_SECONDS, }; @@ -24,7 +25,6 @@ use crate::bindings::_helpers::event_exporting::models::{ }; use crate::bindings::_helpers::event_exporting::values::error_type_of; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; /// Which long-lived dispatcher thread a worker runs. #[derive(Clone, Copy)] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs index 07f47a4ebe..9445d56a19 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs @@ -4,6 +4,7 @@ use pyo3::IntoPyObjectExt; use pyo3::exceptions::PyValueError; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyInt, PyList, PyString, PyStringMethods, PyTuple}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::execution_history::constants::ENVELOPE_TEXT_FIELDS; use sqlbuild_state::execution_history::errors::{HistoryError, HistoryErrorKind}; use sqlbuild_state::execution_history::models::{ @@ -12,9 +13,8 @@ use sqlbuild_state::execution_history::models::{ }; use sqlbuild_state::execution_history::types::UtcTime; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::cursor::values::{DATETIME_MODULE, local_date_time}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/getters.rs new file mode 100644 index 0000000000..83277a7b95 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/getters.rs @@ -0,0 +1,56 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHistory; +use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_postgres_execution_history, + }, + GetterEntry { + class: class_of::, + read: read_sqlite_execution_history, + }, +]; + +fn read_postgres_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_sqlite_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "path" => this.path(py).and_then(|value| value.into_bound_py_any(py)), + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/mod.rs index 10306a6285..164cfbcba9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/mod.rs @@ -1,6 +1,7 @@ pub(crate) mod appends; pub(crate) mod conversion; pub(crate) mod functions; +pub(crate) mod getters; pub(crate) mod postgres; pub(crate) mod registration; pub(crate) mod sqlite; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs index c597a017d6..f566f251ab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs @@ -7,6 +7,7 @@ use pyo3::IntoPyObjectExt; use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python, pyclass, pymethods}; use pyo3::types::{PyBool, PyDateTime, PyDict, PyTuple}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::execution_history::constants::{ DEFAULT_PAGE_LIMIT, POSTGRES_ADVISORY_LOCK, POSTGRES_ALL_EVENTS, POSTGRES_ALL_RUNS, POSTGRES_CONNECT_TIMEOUT_SECONDS, POSTGRES_DELETE_RUNS, POSTGRES_EVENT_BY_ID, @@ -37,7 +38,7 @@ use sqlbuild_state::execution_history::models::{ }; use sqlbuild_state::execution_history::types::UtcTime; -use crate::bindings::_helpers::compile_driver::python_calls::{ +use crate::bindings::_helpers::boundary::python_calls::{ KeywordArguments, call_with, imported, keywords, within, }; use crate::bindings::_helpers::execution_history::appends::prepared_batch; @@ -49,7 +50,6 @@ use crate::bindings::_helpers::execution_history::conversion::{ use crate::bindings::_helpers::execution_history::statements::{ column, execute, execute_plain, execute_query, fetch_all, fetch_one, tuple_of, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs index f978a20d2e..387a1cee99 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs @@ -9,6 +9,7 @@ use std::sync::atomic::{AtomicBool, AtomicI64, Ordering}; use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python, pyclass, pymethods}; use pyo3::types::{PyDict, PyTuple}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::execution_history::constants::{ DEFAULT_PAGE_LIMIT, MEMORY_PATH, RUN_CURSOR_TIMESTAMP, SCHEMA_VERSION, SQLITE_ALL_EVENTS, SQLITE_ALL_RUNS, SQLITE_BEGIN, SQLITE_BUSY_TIMEOUT_MS, SQLITE_COMMIT, SQLITE_DELETE_RUNS, @@ -39,8 +40,8 @@ use sqlbuild_state::execution_history::models::{ }; use sqlbuild_state::execution_history::types::UtcTime; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::execution_history::appends::prepared_batch; use crate::bindings::_helpers::execution_history::conversion::{ checked, event_filter_spec, exact_int, history_error_of_kind, new_namespace, now, @@ -51,7 +52,6 @@ use crate::bindings::_helpers::execution_history::conversion::{ use crate::bindings::_helpers::execution_history::statements::{ column, execute, execute_plain, execute_query, fetch_one, locked, tuple_of, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; @@ -634,7 +634,7 @@ impl SqliteExecutionHistory { Some(record) => native_field(record, "cursor")?, None => py.None().into_bound(py), }; - crate::bindings::_helpers::compile_driver::python_calls::call_with( + crate::bindings::_helpers::boundary::python_calls::call_with( &host::entry(py, ExecutorHost::EventPage)?, &[ ("records", tuple_of(py, records)?.into_any()), @@ -703,7 +703,7 @@ impl SqliteExecutionHistory { } None => py.None().into_bound(py), }; - crate::bindings::_helpers::compile_driver::python_calls::call_with( + crate::bindings::_helpers::boundary::python_calls::call_with( &host::entry(py, ExecutorHost::RunPage)?, &[ ("records", run_records(py, &runs)?.into_any()), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/exported_constants/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/exported_constants/constants.rs index 044bc2611c..7e4ed5ab92 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/exported_constants/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/exported_constants/constants.rs @@ -29,6 +29,7 @@ use sqlbuild_core::constants::{ use sqlbuild_core::diagnostic_routing::constants::{ SQL_DIGEST_FIELD, SQL_PRIVATE_RECORD_FIELD, SQL_TEXT_FIELD, }; +use sqlbuild_host::entries::constants::CUSTOM_HOST_LAUNCH_MODULE; use sqlbuild_rules::constants::MIN_CUSTOM_RULE_TEST_CASES_KEY; use sqlbuild_rules::custom_host_pool::constants::CUSTOM_RULE_PROJECT_SUBJECT; use sqlbuild_state::execution_history::constants::{ @@ -45,7 +46,6 @@ use crate::bindings::_helpers::compile_delta::driver::{ DELTA_DISABLE_ENV_VAR, DELTA_VERIFY_ENV_VAR, }; use crate::bindings::_helpers::frontier::stage_capture::CAPTURE_DIR_ENV_VAR; -use crate::bindings::_helpers::native_host::constants::CUSTOM_HOST_LAUNCH_MODULE; use crate::bindings::_helpers::result_output::event_writer::RESULT_PATH_ENV; use crate::bindings::_helpers::rules::constants::CUSTOM_HOST_RUNTIME_VERSION; use crate::bindings::_helpers::semantic_shapes::shapes::{VALID_FROM_DEFAULT, VALID_TO_DEFAULT}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs index d2beed1e6a..7f99a3849c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs @@ -12,6 +12,8 @@ use sqlbuild_analysis::fingerprint_storage::main::read_latest_sql::read_latest_s use sqlbuild_analysis::fingerprint_storage::main::relevant_read_sql::relevant_read_sql; use sqlbuild_analysis::fingerprint_storage::models::RelevantRead; +use sqlbuild_host::entries::models::AdapterHost; + use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::fingerprints::latest_rows::{ fingerprint_input_error, fingerprint_set_from_rows, @@ -21,7 +23,6 @@ use crate::bindings::_helpers::fingerprints::storage_sql::{ }; use crate::bindings::_helpers::records::construct::new_record; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs index 008ca5e3f7..46a9cc1923 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs @@ -15,12 +15,10 @@ use sqlbuild_core::format_command::models::LintReport; use sqlbuild_rules::lint_text::main::scan_fixture_null_candidates::scan_fixture_null_candidates; use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; use crate::bindings::_helpers::format_command::config::{FormatConfig, format_config, lint_config}; use crate::bindings::_helpers::format_command::files::FormatChange; use crate::bindings::_helpers::format_command::report::lint_report; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs index bd12368073..75c4fc9947 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs @@ -8,7 +8,7 @@ use pyo3::types::{PyBool, PyDict, PyDictMethods, PyList, PyListMethods}; use sqlbuild_core::format_command::main::collect_lint_files::collect_lint_files; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::stage_work::{ FORMAT_LINT_BATCHES, FORMAT_LINT_FILES, count_stage, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs index ad01a1efae..9680a9592a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs @@ -14,16 +14,16 @@ use sqlbuild_core::format_command::main::resolve_lint_paths::resolve_lint_paths; use sqlbuild_rules::lint_text::main::scan_fixture_null_candidates::scan_fixture_null_candidates; use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::within; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::project::build_project_graph; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::within; -use crate::bindings::_helpers::contracts::project_config::load_local_config_file; -use crate::bindings::_helpers::contracts::project_config::load_project_config_file; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::discovery::declaration_records::discover_model_schema_files; use crate::bindings::_helpers::discovery::model_records::discover_model_files; +use crate::bindings::_helpers::discovery::project_config::load_local_config_file; +use crate::bindings::_helpers::discovery::project_config::load_project_config_file; use crate::bindings::_helpers::discovery::snapshot::directory_snapshot_scope; use crate::bindings::_helpers::discovery::sql_test_records::discover_test_files; use crate::bindings::_helpers::discovery::yaml_records::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs index a26b38c856..8dda1953ed 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs @@ -14,6 +14,8 @@ use sqlbuild_core::freshness_text::main::freshness_json::freshness_json; use sqlbuild_core::freshness_text::main::render_freshness_text::render_freshness_text; use sqlbuild_core::freshness_text::models::FreshnessSourceResult; +use sqlbuild_host::entries::models::AdapterHost; + use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; @@ -32,7 +34,6 @@ use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::result_output::documents::write_execution_json_output; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs index 16ba60e71c..25de2f1f46 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs @@ -10,12 +10,13 @@ use pyo3::types::{PyDict, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::freshness_text::main::freshness_json::freshness_json; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::freshness::observation::{ Observer, observation_record, observation_source, observe_adapter_batch, observe_configured, strategy, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs index 5f12c69fac..86b94ed5e2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs @@ -3,16 +3,15 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyBool, PyDateTime, PyDict, PyDictMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; use sqlbuild_state::freshness::main::single_value_problem::single_value_problem; use sqlbuild_state::freshness::models::QueryShape; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; use crate::bindings::_helpers::freshness::support::{ OBSERVATION_ERROR, exception_text, freshness_error, presumed_utc_datetime, presumed_utc_value, text, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::constants::{DATA_VERSION_FIELD, OBSERVED_AT_FIELD}; use crate::bindings::_helpers::records::construct::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs index fad04155ac..02de3f71e1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs @@ -5,9 +5,10 @@ use pyo3::prelude::{ }; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PySet, PySetMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_state::freshness::main::configuration_error::configuration_error; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::freshness::exception_types::SourceFreshnessObservationError; use crate::bindings::_helpers::freshness::observation::{ Observer, observation_record, observation_source, observe_adapter_batch, observe_configured, @@ -15,7 +16,6 @@ use crate::bindings::_helpers::freshness::observation::{ }; use crate::bindings::_helpers::freshness::state_io::{StateRead, read_latest}; use crate::bindings::_helpers::freshness::support::text; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_identity::graph::build_downstream_model_name_closure; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs index 0baeb79bd9..25361a5242 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs @@ -3,14 +3,14 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{ +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{ KeywordArguments, call_with, imported, within, }; use crate::bindings::_helpers::cost_telemetry::context::CostContext; use crate::bindings::_helpers::freshness::state_io::write_source_freshness_records; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs index df9f1f03fd..292bada80f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs @@ -8,9 +8,7 @@ use sqlbuild_state::freshness::constants::{REQUIRED_STATE_COLUMNS, SOURCE_FRESHN use sqlbuild_state::freshness::main::read_latest_sql::read_latest_sql; use sqlbuild_state::freshness::main::relevant_sources_sql::relevant_sources_sql; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::freshness::support::{ INPUT_ERROR, exception_text, freshness_error, optional_str, presumed_utc_datetime, text, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs index 2450e4e5c1..fcd82526c3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs @@ -4,7 +4,7 @@ use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyString}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::freshness::exception_types::{ SourceFreshnessInputError, SourceFreshnessObservationError, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs b/crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs index 9be48b4ae4..d93bf3bc40 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs @@ -3,11 +3,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::PyDict; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::frontier::stage_capture::write_stage_capture; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs b/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs index 3a915ef3a8..6fcee26eaf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs @@ -21,7 +21,7 @@ use sqlbuild_cache::stage_capture::models::CaptureDocument; use sqlbuild_core::json::errors::JsonEmitError; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::frontier::python_types::PythonTypes; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs b/crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs index 9f2f2cb712..d626cba4c0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs @@ -5,7 +5,7 @@ use pyo3::types::{PyBytes, PyBytesMethods, PyStringMethods, PyTuple}; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::frontier::encoder::qualified_name; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs b/crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs index 1ca54501a7..caa0e5e1c5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs @@ -8,9 +8,7 @@ use sqlbuild_cache::stage_capture::constants::OMITTED_ATTRIBUTES; use sqlbuild_cache::stage_capture::main::mask_capture_noise::mask_capture_noise as masked; use sqlbuild_cache::stage_capture::main::next_capture_number::next_capture_number; -use crate::bindings::_helpers::compile_driver::python_calls::{ - call_with, imported, keywords, within, -}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords, within}; use crate::bindings::_helpers::frontier::encoder::{CaptureEncoder, emit_error}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs index ac8620b4b1..124c11f231 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs @@ -4,14 +4,14 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods, PyList, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::analysis::explicit_references::{ - GateRow, HookRow, native_execution_gate_edges, -}; use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::references::explicit_references::{ + GateRow, HookRow, native_execution_gate_edges, +}; const PATHLIB_MODULE: &str = "pathlib"; /// The model config keys whose entries are hooks, in lifecycle order. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/getters.rs new file mode 100644 index 0000000000..379524f11b --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/getters.rs @@ -0,0 +1,50 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_compiled_project_graph, +}]; + +fn read_compiled_project_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project" => this.project_attribute(py).into_bound_py_any(py), + "native" => this.native_attribute(py).into_bound_py_any(py), + "lineage_views" => this + .lineage_views(py) + .and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "tag_index" => this + .tag_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "path_index" => this + .path_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "all_keys" => this + .all_keys(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/mod.rs index e0d28601d0..0db6458b40 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod algorithms; pub(crate) mod execution_gates; +pub(crate) mod getters; pub(crate) mod keys; pub(crate) mod node_set; pub(crate) mod project_graph; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs index b049c49cf7..91b7c08c18 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs @@ -5,14 +5,15 @@ use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_analysis::python_selection::main::python_node_graph_indexes::python_node_graph_indexes as graph_indexes; use sqlbuild_analysis::python_selection::models::{InventoryIndexes, InventoryNode}; +use sqlbuild_host::entries::models::UserCodeHost; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::discovery::imported_modules::provider_usages; +use crate::bindings::_helpers::discovery::imported_python_nodes::node_identity; use crate::bindings::_helpers::graph::python_selection::resolve_python_sql_run_selection; use crate::bindings::_helpers::graph::views::compiled_graph_keys; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; @@ -39,70 +40,6 @@ fn attribute_value<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult(value: &Bound<'py, PyAny>) -> PyResult> { - if value.is_none() { - return Ok(value.clone()); - } - native_field(value, "value") -} - -/// The decorator configuration the identity of one node of `kind` hashes, read through `get`. -fn decorator_config<'py>( - py: Python<'py>, - (kind, documented): (&str, bool), - get: &dyn Fn(&str) -> PyResult>, -) -> PyResult> { - let config: Bound<'py, PyDict> = PyDict::new(py); - match kind { - "LOADER" => { - config.set_item("columns", get("columns")?)?; - config.set_item("contract", get("contract")?)?; - config.set_item("cursor_column", get("cursor_column")?)?; - config.set_item("destination", get("destination")?)?; - config.set_item("unique_key", get("unique_key")?)?; - config.set_item("write_strategy", optional_value(&get("write_strategy")?)?)?; - } - "ASSET" => { - config.set_item("columns", get("columns")?)?; - config.set_item("column_lineage", get("column_lineage")?)?; - } - "CHECK" => { - config.set_item("severity", get("severity")?.getattr("value")?)?; - } - _ => {} - } - if documented { - for field in ["description", "group", "meta", "tags"] { - config.set_item(field, get(field)?)?; - } - } - Ok(config) -} - -/// The identity of one discovered node of `(kind, documented)`, hashed once by the user-code host. -pub(crate) fn node_identity<'py>( - py: Python<'py>, - (kind, documented): (&str, bool), - get: &dyn Fn(&str) -> PyResult>, -) -> PyResult> { - let kind_value: Bound<'py, PyAny> = host::entry(py, UserCodeHost::PythonNodeKind)? - .getattr(kind)? - .getattr("value")?; - call_with( - &host::entry(py, UserCodeHost::PythonNodeIdentity)?, - &[ - ("kind", kind_value), - ("name", get("name")?), - ("function", get("function")?), - ("file_path", get("file_path")?), - ( - "decorator_config", - decorator_config(py, (kind, documented), get)?.into_any(), - ), - ], - ) -} - /// The kind's metadata field and record of one discovered function. fn kind_metadata<'py>( py: Python<'py>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs index 9ca684d2eb..6461a285cd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs @@ -13,7 +13,7 @@ use sqlbuild_core::init_command::main::init_project_name::init_project_name; use sqlbuild_core::init_command::main::init_project_toml::init_project_toml; use sqlbuild_core::init_command::main::render_init_summary::render_init_summary; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; use crate::bindings::_helpers::init_command::scaffold::scaffold_blank_project; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/attachment.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/attachment.rs index ea17c67eb1..d34298388a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/attachment.rs @@ -1,31 +1,32 @@ //! Seeds, functions, sources, SQL tests, scenarios and audits attached from discovered inputs. +use std::collections::HashMap; + use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyCFunction, PyDict, PyDictMethods, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; -use std::collections::HashMap; - use sqlbuild_attachments::audits::constants::BUILTIN_AUDITS; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; +use sqlbuild_host::entries::models::{ExecutorHost, FacadeHost, UserCodeHost}; -use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_timing; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; -use crate::bindings::_helpers::compiled_project::audit_loop::{AuditBlockRow, AuditFileRow}; -use crate::bindings::_helpers::compiled_project::function_loop::{FunctionRow, FunctionSettings}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditBlockRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditFileRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::DiagnosticSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::LoaderRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::ScenarioRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SourceRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::TestBlockRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::TestCaseRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::TestFileRow; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::resource_diagnostics::{ - DiagnosticSettings, LoaderRow, resource_diagnostics, -}; -use crate::bindings::_helpers::compiled_project::scenario_loop::ScenarioRow; -use crate::bindings::_helpers::compiled_project::source_loop::SourceRow; -use crate::bindings::_helpers::compiled_project::sql_test_loop::{ - TestBlockRow, TestCaseRow, TestFileRow, +use crate::bindings::_helpers::input_loops::resource_attachment::{ + attach_audits, attach_functions, attach_sources, attach_sql_tests, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use crate::bindings::_helpers::input_loops::resource_diagnostics::resource_diagnostics; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; @@ -177,7 +178,7 @@ pub(crate) fn attach_resources<'py>( let defaults: Bound<'py, PyAny> = native_field(discovered_inputs, "project_config")?.getattr("defaults")?; let function_kind: Bound<'py, PyAny> = enum_member(py, RecordId::ResourceKind, "FUNCTION")?; - let functions = NativeCompiledProject::attach_functions( + let functions = attach_functions( native_project, ( function_rows(discovered_inputs, ("sql_function_files", "body_sql"), false)?, @@ -210,7 +211,7 @@ pub(crate) fn attach_resources<'py>( )); } } - let sources = NativeCompiledProject::attach_sources( + let sources = attach_sources( native_project, source_rows, ( @@ -608,8 +609,8 @@ pub(crate) fn attach_checks<'py>( ) = arguments.value("settings")?.extract()?; let scan_cache: &Bound<'py, PyAny> = &arguments.value("scan_cache")?; let source_inputs: &Bound<'py, PyAny> = &arguments.value("source_inputs")?; - let (tests, scenarios) = record_compile_timing(TEST_TIMING_KEY, || { - let attached = NativeCompiledProject::attach_sql_tests( + let (tests, scenarios) = record_compile_timing(TEST_TIMING_KEY, || -> PyResult<_> { + let attached = attach_sql_tests( native_project, items(discovered_inputs, "test_files")? .into_iter() @@ -624,7 +625,7 @@ pub(crate) fn attach_checks<'py>( scan_cache.call_method0("save")?; Ok(attached) })?; - let (audits, audit_diagnostics) = NativeCompiledProject::attach_audits( + let (audits, audit_diagnostics) = attach_audits( native_project, items(discovered_inputs, "audit_files")? .into_iter() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/audit_loop.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/audit_loop.rs index 22a82e9e5b..bee6d46f46 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/audit_loop.rs @@ -1,11 +1,8 @@ //! `build_project_audit_inputs`: singular and attached generic audits attached natively. -use crate::bindings::_helpers::compile_delta::context::record_source_reads; use std::collections::{BTreeMap, HashMap}; -use crate::bindings::_helpers::model_config::header_metadata::HeaderColumns; -use pyo3::FromPyObject; -use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyString, PyTuple, PyTupleMethods}; use sqlbuild_analysis::compiled_project::main::merge_call_site_references::merge_call_site_references; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; @@ -20,30 +17,35 @@ use sqlbuild_attachments::audits::models::{ use sqlbuild_attachments::cursor_intrinsics::main::intrinsic_free::intrinsic_free; use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicCheck; use sqlbuild_attachments::functions::models::KnownResources; +use sqlbuild_core::json::models::JsonValue; +use sqlbuild_model_config::errors::ConfigError; +use sqlbuild_model_config::header_metadata::main::parse_measurement_policy::parse_measurement_policy; use sqlbuild_sqltext::sql_references::models::SqlReference; use crate::bindings::_helpers::attachments::argument_values::argument_pairs; -use crate::bindings::_helpers::compiled_project::audit_views::{AttachedAudit, AttachedTarget}; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compile_context::delta::record_source_reads; +use crate::bindings::_helpers::compiled_project::attachment_inputs::{ + AuditBlockRow, AuditFileRow, AuditSettings, +}; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::audit_views::{AttachedAudit, AttachedTarget}; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, compile_error, helped_compile_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_calls::origin_references; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::reference_row; -use crate::bindings::_helpers::compiled_project::model_loop_named::{ +use crate::bindings::_helpers::input_loops::model_loop_calls::origin_references; +use crate::bindings::_helpers::input_loops::model_loop_inputs::reference_row; +use crate::bindings::_helpers::input_loops::model_loop_named::{ AUDIT_DECLARATION, resource_named_usages, }; -use crate::bindings::_helpers::compiled_project::source_loop::{ +use crate::bindings::_helpers::input_loops::source_loop::{ AuthoredExpansion, expanded_authored_sql, file_declarations, }; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; +use crate::bindings::_helpers::model_config::header_metadata::HeaderColumns; use crate::bindings::_helpers::model_config::header_metadata::thresholds; use crate::bindings::_helpers::model_config::model_validator::NativeModelValidator; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::result_output::integration_values::json_value; -use sqlbuild_core::json::models::JsonValue; -use sqlbuild_model_config::errors::ConfigError; -use sqlbuild_model_config::header_metadata::main::parse_measurement_policy::parse_measurement_policy; const THRESHOLDS_KEY: &str = "thresholds"; const MINIMUM_SAMPLES_KEY: &str = "minimum_samples"; @@ -61,49 +63,6 @@ const MODEL_TARGET: &str = "model"; const SOURCE_TARGET: &str = "source"; const SEED_TARGET: &str = "seed"; -positional_record! { - extract, into; - /// An audit block, its name, SQL body, evidence SQL, measurement flag and header values. - pub(crate) struct AuditBlockRow { - pub(crate) block: Py, - pub(crate) name: Option, - pub(crate) sql_body: String, - pub(crate) evidence_sql: Option, - pub(crate) measurement: bool, - pub(crate) header: Py, - } -} - -positional_record! { - extract, into; - /// An audit file's paths, stem, discovered file, generic flag, contents and blocks. - pub(crate) struct AuditFileRow { - pub(crate) file_path: String, - pub(crate) relative_path: String, - pub(crate) stem: String, - pub(crate) file: Py, - pub(crate) generic: bool, - pub(crate) contents: String, - pub(crate) blocks: Vec, - } -} - -/// What every audit in one compile resolves against, and the Python values it builds with. -#[derive(FromPyObject)] -#[pyo3(from_item_all)] -pub(crate) struct AuditSettings { - default_severity: Option, - default_run_scope: Option, - /// Built-in generic definitions as audit file rows, overridden by project definitions. - builtins: Vec, - /// `DeclarationIdentity`, and the singular and generic audit `DeclarationKind`s. - declaration_identity: Py, - singular_kind: Py, - audit_kind: Py, - /// `ResourceKind` by value, for the resources singular audits read and attach to. - resource_kinds: Py, -} - /// Generic definitions by name, and the warnings for project ones overriding built-ins. type Definitions<'a, 'py> = (HashMap>, Vec>); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/expanded_offsets.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/expanded_offsets.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/expanded_offsets.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/expanded_offsets.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/function_loop.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/function_loop.rs index 31748115b7..74c413a4c3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/function_loop.rs @@ -1,10 +1,9 @@ //! `build_sql_function_inputs`: every SQL and Python function attached natively. -use crate::bindings::_helpers::compile_delta::context::record_source_reads; use std::collections::{HashMap, HashSet}; use pyo3::exceptions::PyValueError; -use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods, PyTuple}; use sqlbuild_analysis::assembly::analysis_session::main::query_columns::query_columns; use sqlbuild_analysis::assembly::analysis_session::models::{ @@ -31,19 +30,21 @@ use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; use crate::bindings::_helpers::analysis_session::query_columns::query_columns_error; use crate::bindings::_helpers::attachments::function_headers::parsed_header; -use crate::bindings::_helpers::compiled_project::compiled_model_view::DestinationFact; -use crate::bindings::_helpers::compiled_project::function_views::{ +use crate::bindings::_helpers::compile_context::delta::record_source_reads; +use crate::bindings::_helpers::compiled_project::attachment_inputs::{ + FunctionRow, FunctionSettings, +}; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::compiled_model_view::DestinationFact; +use crate::bindings::_helpers::compiled_views::function_views::{ AttachedFunction, NamedTypeRow, PythonRuntime, }; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, compile_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_calls::{ - CallOrigin, report_invalid_calls, -}; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::reference_row; -use crate::bindings::_helpers::compiled_project::source_loop::{ +use crate::bindings::_helpers::input_loops::model_loop_calls::{CallOrigin, report_invalid_calls}; +use crate::bindings::_helpers::input_loops::model_loop_inputs::reference_row; +use crate::bindings::_helpers::input_loops::source_loop::{ AuthoredExpansion, expanded_authored_sql, expanded_template, parse_checked, scoped_declarations, }; use crate::bindings::_helpers::model_config::model_validator::NativeModelValidator; @@ -57,33 +58,6 @@ const SCHEMA_KEY: &str = "schema"; /// The reference kind of a source. const SOURCE_KIND: &str = "source"; -positional_record! { - extract; - /// A function's paths, stem, discovered file, header values, body and SQL file contents. - pub(crate) struct FunctionRow { - pub(crate) file_path: String, - pub(crate) relative_path: String, - pub(crate) name: String, - pub(crate) function_file: Py, - pub(crate) header_values: Py, - pub(crate) body: String, - pub(crate) contents: Option, - } -} - -positional_record! { - extract; - /// Adapter, validation, raw default and target namespaces, inheritance and resource kind. - pub(crate) struct FunctionSettings { - pub(crate) adapter_name: String, - pub(crate) validate: bool, - pub(crate) defaults: (Option, Option), - pub(crate) target: Option<(Option, Option)>, - pub(crate) inherit: bool, - pub(crate) kind: Py, - } -} - /// What every function in one compile resolves against. struct FunctionScope<'a, 'py> { model_loop: &'a NativeModelLoop, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/loop_classes.rs similarity index 96% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/loop_classes.rs index 3660b9432b..21a9dee2fe 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/loop_classes.rs @@ -3,12 +3,13 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyList, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::FacadeHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; +use crate::bindings::_helpers::records::fields::by_attribute; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; @@ -341,19 +342,6 @@ fn input_view_classes<'py>(py: Python<'py>) -> PyResult> { ) } -/// `{item.: item for item in items}`. -pub(crate) fn by_attribute<'py>( - items: &Bound<'py, PyAny>, - attribute: &str, -) -> PyResult> { - let keyed: Bound<'py, PyDict> = PyDict::new(items.py()); - for item in items.try_iter()? { - let item: Bound<'py, PyAny> = item?; - keyed.set_item(native_field(&item, attribute)?, item)?; - } - Ok(keyed) -} - /// The classes, error factories and project declarations the model loop reads. pub(crate) fn model_loop_classes<'py>( audit_factories: &Bound<'py, PyAny>, @@ -392,7 +380,7 @@ pub(crate) fn model_loop_classes<'py>( vec![( "declaration_rows", pyo3::wrap_pyfunction!( - crate::bindings::_helpers::compiled_project::records::declaration_rows, + crate::bindings::_helpers::compiled_views::records::declaration_rows, py )? .into_any(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/input_loops/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/mod.rs new file mode 100644 index 0000000000..c871160e3f --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/mod.rs @@ -0,0 +1,28 @@ +//! The native model loop and the loops that attach the project's other resources to it. +pub(crate) mod attachment; +pub(crate) mod audit_loop; +pub(crate) mod expanded_offsets; +pub(crate) mod function_loop; +pub(crate) mod loop_classes; +pub(crate) mod model_loop; +pub(crate) mod model_loop_calls; +pub(crate) mod model_loop_config; +pub(crate) mod model_loop_contracts; +pub(crate) mod model_loop_external; +pub(crate) mod model_loop_header; +pub(crate) mod model_loop_hooks; +pub(crate) mod model_loop_host; +pub(crate) mod model_loop_inputs; +pub(crate) mod model_loop_macros; +pub(crate) mod model_loop_named; +pub(crate) mod model_loop_opt_out; +pub(crate) mod model_loop_prepass; +pub(crate) mod model_loop_python_hooks; +pub(crate) mod model_loop_schema; +pub(crate) mod model_loop_visibility; +pub(crate) mod registration; +pub(crate) mod resource_attachment; +pub(crate) mod resource_diagnostics; +pub(crate) mod scenario_loop; +pub(crate) mod source_loop; +pub(crate) mod sql_test_loop; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs similarity index 92% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs index e6d8cd6bb8..f67dd3dbe8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs @@ -1,65 +1,90 @@ //! The compile-input model loop: each model's steps run in the attachment's order, natively. -use crate::bindings::_helpers::compiled_project::audit_loop::{ - AttachmentOwner, AuditFileRow, AuditSettings, attached_audits, +use std::collections::{HashMap, HashSet}; + +use pyo3::prelude::{ + Bound, Py, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, +}; +use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods, PyTuple}; +use pyo3::{FromPyObject, pyclass, pymethods}; +use sqlbuild_analysis::compiled_project::main::analysis_gate::analysis_gate; +use sqlbuild_analysis::compiled_project::main::calls_macros::calls_macros; +use sqlbuild_analysis::compiled_project::main::located_scan_error::located_scan_error; +use sqlbuild_analysis::compiled_project::main::merge_call_site_references::merge_call_site_references; +use sqlbuild_analysis::compiled_project::models::{ + AnalysisGate, ModelLoopSettings, ScanFaultOrigin, SplicedSpan, }; -use crate::bindings::_helpers::compiled_project::audit_views::AttachedAudit; -use crate::bindings::_helpers::compiled_project::function_loop::{ - FunctionRow, FunctionSettings, attached_functions, checked_table_function_arities, +use sqlbuild_attachments::cursor_intrinsics::main::validated_model_intrinsics::validated_model_intrinsics; +use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicModel; +use sqlbuild_attachments::functions::models::KnownResources; +use sqlbuild_attachments::test_targets::models::TargetCatalog; +use sqlbuild_discovery::model_files::models::HeaderFacts; +use sqlbuild_sqltext::sql_references::main::extract_sql_references::extract_sql_references; +use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; +use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; + +use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AttachedSqlTests; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditFileRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::AuditSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::FunctionSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::ScenarioRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SourceRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SourceSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::SqlTestSettings; +use crate::bindings::_helpers::compiled_project::attachment_inputs::TestFileRow; +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::audit_views::AttachedAudit; +use crate::bindings::_helpers::compiled_views::function_views::AttachedFunction; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; +use crate::bindings::_helpers::compiled_views::source_views::{ + AttachedSource, NativeSourceInput, retain_sources, }; -use crate::bindings::_helpers::compiled_project::function_views::AttachedFunction; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; -use crate::bindings::_helpers::compiled_project::model_loop_calls::{ - CallOrigin, report_invalid_calls, +use crate::bindings::_helpers::discovery::model_file_record::{ModelFileTexts, NativeModelFile}; +use crate::bindings::_helpers::input_loops::audit_loop::{AttachmentOwner, attached_audits}; +use crate::bindings::_helpers::input_loops::function_loop::{ + attached_functions, checked_table_function_arities, }; -use crate::bindings::_helpers::compiled_project::model_loop_config::{ConfigClasses, ModelConfigs}; -use crate::bindings::_helpers::compiled_project::model_loop_external::external_errors; -use crate::bindings::_helpers::compiled_project::model_loop_header::{ +use crate::bindings::_helpers::input_loops::model_loop_calls::{CallOrigin, report_invalid_calls}; +use crate::bindings::_helpers::input_loops::model_loop_config::ModelConfigs; +use crate::bindings::_helpers::input_loops::model_loop_external::external_errors; +use crate::bindings::_helpers::input_loops::model_loop_header::{ AttachedHeader, HeaderSource, header_schema, }; -use crate::bindings::_helpers::compiled_project::model_loop_hooks::{ +use crate::bindings::_helpers::input_loops::model_loop_hooks::{ ExpandedHooks, HookModel, SqlHookClasses, expanded_hooks, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::{ +use crate::bindings::_helpers::input_loops::model_loop_host::{ DeclarationScan, FinishedModel, InterpolationRow, ModelLoopRow, RecordClasses, RecordInputs, - ReferenceRow, finished_record, + finished_record, }; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::{ +use crate::bindings::_helpers::input_loops::model_loop_inputs::{ analysis_override, hook_presence, reference_row, }; -use crate::bindings::_helpers::compiled_project::model_loop_macros::{ +use crate::bindings::_helpers::input_loops::model_loop_macros::{ ExpandedMacros, MacroClasses, MacroModel, expanded_macros, }; -use crate::bindings::_helpers::compiled_project::model_loop_named::{ - SCHEMA_DECLARATION, named_usages, -}; -use crate::bindings::_helpers::compiled_project::model_loop_opt_out::{ +use crate::bindings::_helpers::input_loops::model_loop_named::{SCHEMA_DECLARATION, named_usages}; +use crate::bindings::_helpers::input_loops::model_loop_opt_out::{ OptOut, OptOutModel, reject_unparseable_query, rejected_opt_out, }; -use crate::bindings::_helpers::compiled_project::model_loop_prepass::{ +use crate::bindings::_helpers::input_loops::model_loop_prepass::{ NativeHeader, all_header_facts, native_header, }; -use crate::bindings::_helpers::compiled_project::model_loop_python_hooks::{ +use crate::bindings::_helpers::input_loops::model_loop_python_hooks::{ HookClasses, HookSignatures, }; -use crate::bindings::_helpers::compiled_project::model_loop_schema::{ +use crate::bindings::_helpers::input_loops::model_loop_schema::{ ModelSchema, model_schema, schema_column_names, }; -use crate::bindings::_helpers::compiled_project::model_loop_visibility::{ +use crate::bindings::_helpers::input_loops::model_loop_visibility::{ ModelVisibility, VisibilityClasses, VisibilityModel, }; -use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::scenario_loop::ScenarioRow; -use crate::bindings::_helpers::compiled_project::source_loop::{ - SourceRow, SourceSettings, attached_sources, -}; -use crate::bindings::_helpers::compiled_project::source_views::{ - AttachedSource, NativeSourceInput, retain_sources, -}; -use crate::bindings::_helpers::compiled_project::sql_test_loop::{ - AttachedSqlTests, SqlTestSettings, TestFileRow, TestScope, -}; -use crate::bindings::_helpers::discovery::model_file_record::{ModelFileTexts, NativeModelFile}; +use crate::bindings::_helpers::input_loops::source_loop::attached_sources; +use crate::bindings::_helpers::input_loops::sql_test_loop::TestScope; +use crate::bindings::_helpers::model_config::config_classes::ConfigClasses; use crate::bindings::_helpers::model_config::config_errors::raised_config_exception; use crate::bindings::_helpers::model_config::header_metadata::ContractClasses; use crate::bindings::_helpers::model_config::model_validator::NativeModelValidator; @@ -76,29 +101,6 @@ use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; use crate::bindings::_helpers::sqltext::static_sql::{ InterpolationRow as SqlInterpolationRow, InterpolationSources, interpolation_batch, }; -use pyo3::prelude::{ - Bound, Py, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, -}; -use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods, PyTuple}; -use pyo3::{FromPyObject, pyclass, pymethods}; -use sqlbuild_analysis::compiled_project::main::analysis_gate::analysis_gate; -use sqlbuild_analysis::compiled_project::main::calls_macros::calls_macros; -use sqlbuild_analysis::compiled_project::main::located_scan_error::located_scan_error; -use sqlbuild_analysis::compiled_project::main::merge_call_site_references::merge_call_site_references; -use sqlbuild_analysis::compiled_project::models::{ - AnalysisGate, ModelLoopSettings, ScanFaultOrigin, SplicedSpan, -}; -use sqlbuild_attachments::cursor_intrinsics::main::validated_model_intrinsics::validated_model_intrinsics; -use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicModel; -use sqlbuild_attachments::functions::models::KnownResources; -use sqlbuild_attachments::test_targets::models::TargetCatalog; -use sqlbuild_discovery::model_files::models::HeaderFacts; -use sqlbuild_sqltext::sql_references::main::extract_sql_references::extract_sql_references; -use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; -use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; -use std::collections::{HashMap, HashSet}; - -use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::types::CompilerDetach; const MATERIALIZED_KEY: &str = "materialized"; @@ -430,7 +432,7 @@ impl NativeModelLoop { } project .borrow_mut() - .keep_attachment_loop(slf.clone().unbind(), host.clone().unbind()); + .keep_attachment_loop(slf.clone().unbind().into_any(), host.clone().unbind()); slf.get().run_models(py, project, host, models) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_calls.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_calls.rs index 0403d11316..80467fdb25 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_calls.rs @@ -14,7 +14,7 @@ use sqlbuild_sqltext::sql_references::models::{ }; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, compile_error}; +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, compile_error}; const REFERENCE_CALL_SYNTAX_CODE: &str = "P012"; const MODEL_RESOURCE: &str = "model"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_config.rs similarity index 55% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_config.rs index a5d1223038..332e531c49 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_config.rs @@ -5,45 +5,21 @@ use std::collections::HashMap; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods, PyTuple}; -use pyo3::{FromPyObject, IntoPyObject}; +use sqlbuild_discovery::model_files::models::HeaderFacts; use sqlbuild_model_config::config_presence::main::blocks_config_reuse::blocks_config_reuse; use sqlbuild_model_config::config_presence::main::contains_template::contains_template; use sqlbuild_model_config::config_presence::main::mutable_config_value::mutable_config_value; -use sqlbuild_model_config::model_validation::models::{RetentionOverride, TableTypeOverride}; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, config_error}; +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, config_error}; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; +use crate::bindings::_helpers::model_config::config_classes::{ConfigClasses, config_fields, view}; use crate::bindings::_helpers::model_config::model_config_builder::{ BuiltConfig, ConfigBuild, NativeModelConfigBuilder, }; -use sqlbuild_discovery::model_files::models::HeaderFacts; const COLUMNS_KEY: &str = "columns"; const DESCRIPTION_KEY: &str = "description"; -const MATERIALIZED_KEY: &str = "materialized"; -const VALUES_FIELD: &str = "values"; const HOOK_KEYS: [&str; 2] = ["pre_hooks", "post_hooks"]; -const PERMANENT_TABLE_TYPE: &str = "permanent"; -const TRANSIENT_TABLE_TYPE: &str = "transient"; - -/// The builder, storage defaults and Python classes a model's `CompileModelConfig` is made of. -#[derive(FromPyObject)] -#[pyo3(from_item_all)] -pub(crate) struct ConfigClasses<'py> { - pub(crate) builder: Bound<'py, NativeModelConfigBuilder>, - /// Inherited `(retention, table type)` by table-backed materialization, or `None`. - inherited_storage: Bound<'py, PyDict>, - table_backed: Vec, - compile_model_config: Bound<'py, PyAny>, - resolved_retention: Bound<'py, PyAny>, - retention_source: Bound<'py, PyAny>, - resolved_table_type: Bound<'py, PyAny>, - table_type: Bound<'py, PyAny>, - table_type_source: Bound<'py, PyAny>, - /// `record_template_reads`, the compile-reuse sink of template reads. - pub(crate) record_template_reads: Bound<'py, PyAny>, -} - /// What a path default's models inherit, and whether a model may reuse another's config. struct InheritedLayer<'py> { reusable: bool, @@ -202,116 +178,3 @@ fn reusable_metadata<'py>( } Ok(Some(header.clone())) } - -/// The model's `CompileModelConfig`, once its template reads are recorded. -pub(crate) fn built_config<'py>( - classes: &ConfigClasses<'py>, - built: &BuiltConfig<'py>, - matched: Option<&str>, -) -> PyResult> { - let fields: Bound<'py, PyDict> = config_fields(classes, built, matched)?; - view(classes, &built.values, &fields) -} - -/// Every `CompileModelConfig` field but `values`, recording the build's template reads first. -fn config_fields<'py>( - classes: &ConfigClasses<'py>, - built: &BuiltConfig<'py>, - matched: Option<&str>, -) -> PyResult> { - let py: Python<'py> = built.values.py(); - if !built.reads.is_empty() { - classes - .record_template_reads - .call1((PyTuple::new(py, &built.reads)?,))?; - } - let none: Bound<'py, PyAny> = py.None().into_bound(py); - let (inherited_retention, inherited_table_type): (Bound<'py, PyAny>, Bound<'py, PyAny>) = - classes - .inherited_storage - .as_any() - .get_item(storage_key(classes, &built.values)?)? - .extract()?; - let retention: Bound<'py, PyAny> = match built.retention { - RetentionOverride::Inherit => inherited_retention, - RetentionOverride::Unmanaged => resolved_retention(classes, none.clone(), true)?, - RetentionOverride::Days(days) => { - resolved_retention(classes, days.into_pyobject(py)?.into_any(), false)? - } - }; - let table_type: Bound<'py, PyAny> = match built.table_type { - TableTypeOverride::Inherit => inherited_table_type, - TableTypeOverride::Permanent => resolved_table_type(classes, PERMANENT_TABLE_TYPE)?, - TableTypeOverride::Transient => resolved_table_type(classes, TRANSIENT_TABLE_TYPE)?, - }; - let logical_schema: Bound<'py, PyAny> = built.logical_schema.clone().unwrap_or(none.clone()); - let fields: Bound<'py, PyDict> = PyDict::new(py); - fields.set_item("model_header_keys", PyTuple::new(py, &built.header_keys)?)?; - fields.set_item("matched_path_default", matched)?; - fields.set_item("logical_schema", &logical_schema)?; - fields.set_item( - "layer_schema", - if built.layer_schema_configured { - logical_schema - } else { - none.clone() - }, - )?; - fields.set_item( - "logical_database", - built.logical_database.clone().unwrap_or(none), - )?; - fields.set_item("time_travel_retention", retention)?; - fields.set_item("table_type", table_type)?; - Ok(fields) -} - -/// The materialization whose inherited storage policy applies, or `None` when not table-backed. -fn storage_key<'py>( - classes: &ConfigClasses<'py>, - values: &Bound<'py, PyDict>, -) -> PyResult> { - let py: Python<'py> = values.py(); - if let Some(materialized) = values.get_item(MATERIALIZED_KEY)? - && let Ok(text) = materialized.downcast::() - && let Ok(text) = text.to_str() - && classes.table_backed.iter().any(|name| name == text) - { - return Ok(materialized); - } - Ok(py.None().into_bound(py)) -} - -fn resolved_retention<'py>( - classes: &ConfigClasses<'py>, - desired_days: Bound<'py, PyAny>, - unmanaged: bool, -) -> PyResult> { - let fields: Bound<'py, PyDict> = PyDict::new(desired_days.py()); - fields.set_item("desired_days", desired_days)?; - fields.set_item("unmanaged", unmanaged)?; - fields.set_item("source", &classes.retention_source)?; - classes.resolved_retention.call((), Some(&fields)) -} - -fn resolved_table_type<'py>( - classes: &ConfigClasses<'py>, - value: &str, -) -> PyResult> { - let fields: Bound<'py, PyDict> = PyDict::new(classes.table_type.py()); - fields.set_item("value", classes.table_type.call1((value,))?)?; - fields.set_item("source", &classes.table_type_source)?; - fields.set_item("declared", true)?; - classes.resolved_table_type.call((), Some(&fields)) -} - -/// A `CompileModelConfig` of `values` and the other `fields`. -fn view<'py>( - classes: &ConfigClasses<'py>, - values: &Bound<'py, PyDict>, - fields: &Bound<'py, PyDict>, -) -> PyResult> { - let arguments: Bound<'py, PyDict> = fields.copy()?; - arguments.set_item(VALUES_FIELD, values)?; - classes.compile_model_config.call((), Some(&arguments)) -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_contracts.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_contracts.rs index 009cc5c581..b9a8d2c3fb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_contracts.rs @@ -8,8 +8,8 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; use sqlbuild_model_config::header_metadata::models::DynamicFamily; -use crate::bindings::_helpers::compiled_project::model_loop::LoopContext; -use crate::bindings::_helpers::compiled_project::model_loop_schema::DeclaredColumns; +use crate::bindings::_helpers::input_loops::model_loop::LoopContext; +use crate::bindings::_helpers::input_loops::model_loop_schema::DeclaredColumns; use crate::bindings::_helpers::model_config::header_metadata::{HeaderColumn, HeaderColumns}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_external.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_external.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_external.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_external.rs index e6b96c419c..5ec1658ae3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_external.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_external.rs @@ -3,8 +3,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::PyDict; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, compile_error}; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, compile_error}; const DBT_REF_KIND: &str = "dbt_ref"; const VALIDATE_METHOD: &str = "validate_reference"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_header.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_header.rs index bc6456e4a9..c7a8584120 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_header.rs @@ -15,18 +15,18 @@ use sqlbuild_model_config::header_metadata::main::parse_header_metadata::parse_h use sqlbuild_model_config::header_metadata::models::{DynamicFamily, ParsedColumn}; use sqlbuild_model_config::model_validation::models::ColumnMigration; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compiled_project::schema_facts::family_fact; +use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, compile_error, config_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_contracts::{ +use crate::bindings::_helpers::input_loops::model_loop_contracts::{ EnumColumns, dynamic_family_objects, enum_columns, factory_audits, }; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::present; -use crate::bindings::_helpers::compiled_project::model_loop_schema::{ +use crate::bindings::_helpers::input_loops::model_loop_inputs::present; +use crate::bindings::_helpers::input_loops::model_loop_schema::{ DeclaredColumns, ModelSchema, merged_columns, schema_enums, }; -use crate::bindings::_helpers::compiled_project::schema_facts::family_fact; -use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; use crate::bindings::_helpers::model_config::column_migrations::column_migration_error; use crate::bindings::_helpers::model_config::config_errors::native_config_error; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_hooks.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_hooks.rs index eb86febd9a..74931699bc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_hooks.rs @@ -19,25 +19,23 @@ use sqlbuild_sqltext::sql_references::main::extract_sql_references::extract_sql_ use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; use crate::bindings::_helpers::attachments::argument_values::argument_pairs; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, VisibleDeclarations, compile_error, record_reads, validation_outcome, }; -use crate::bindings::_helpers::compiled_project::model_loop_calls::{ - CallOrigin, report_invalid_calls, -}; -use crate::bindings::_helpers::compiled_project::model_loop_external::external_errors; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::{ +use crate::bindings::_helpers::input_loops::model_loop_calls::{CallOrigin, report_invalid_calls}; +use crate::bindings::_helpers::input_loops::model_loop_external::external_errors; +use crate::bindings::_helpers::input_loops::model_loop_inputs::{ HOOK_KEYS, present, reference_row, }; -use crate::bindings::_helpers::compiled_project::model_loop_macros::{ +use crate::bindings::_helpers::input_loops::model_loop_macros::{ argument_references, expanded_with, }; -use crate::bindings::_helpers::compiled_project::model_loop_named::{ +use crate::bindings::_helpers::input_loops::model_loop_named::{ SQL_HOOK_DECLARATION, named_usages, }; -use crate::bindings::_helpers::compiled_project::model_loop_visibility::ModelVisibility; +use crate::bindings::_helpers::input_loops::model_loop_visibility::ModelVisibility; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::declaration_expansion::{ DeclarationExpansion, ExpandedDeclarations, ExpansionClasses, ExpansionConsumer, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_host.rs similarity index 95% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_host.rs index 85574127c6..fe1d13a1b3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_host.rs @@ -9,27 +9,26 @@ use sqlbuild_analysis::compiled_project::main::plain_model_facts::plain_model_fa use sqlbuild_analysis::compiled_project::models::{ CompiledModelFacts, ModelConfigFacts, PlainModel, }; +use sqlbuild_discovery::model_files::models::HeaderFacts; -use crate::bindings::_helpers::compiled_project::model_input_view::{ - ExpansionRecord, InputProjections, ModelInputRecord, SchemaRecord, -}; -use crate::bindings::_helpers::compiled_project::model_loop_header::AttachedHeader; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::{ - reference_fact, stripped_values, -}; use crate::bindings::_helpers::compiled_project::project::{ CONTRACT_KEY, INCREMENTAL_MODE_KEY, materialization, text_value, }; use crate::bindings::_helpers::compiled_project::project::{ DeclarationPy, config_values, declarations, }; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::model_input_view::{ + ExpansionRecord, InputProjections, ModelInputRecord, SchemaRecord, +}; use crate::bindings::_helpers::discovery::model_file_record::{ModelFileTexts, NativeModelFile}; +use crate::bindings::_helpers::input_loops::model_loop_header::AttachedHeader; +use crate::bindings::_helpers::input_loops::model_loop_inputs::{reference_fact, stripped_values}; use crate::bindings::_helpers::records::fields::{field as native_field, replaced_keywords}; use crate::bindings::_helpers::render::declaration_expansion::{ExpandedDeclarations, span_rows}; use crate::bindings::_helpers::render::macro_call_rows::{SpanRow, span_row}; use crate::bindings::_helpers::render::macro_expansion::ExpansionOutput; use crate::bindings::_helpers::sqltext::declaration_references::ScannedReference; -use sqlbuild_discovery::model_files::models::HeaderFacts; const HEADER_KEYS_ATTRIBUTE: &str = "model_header_keys"; const LAYER_SCHEMA_ATTRIBUTE: &str = "layer_schema"; @@ -84,17 +83,6 @@ pub(crate) struct InterpolationRow { /// The substitution spans. pub(crate) spans: Vec, } -positional_record! { - extract, into; - /// `(kind, name, package, call argument count)`. - #[derive(Clone, Debug, PartialEq, Eq)] - pub(crate) struct ReferenceRow { - pub(crate) kind: String, - pub(crate) name: String, - pub(crate) package: Option, - pub(crate) call_argument_count: Option, - } -} /// One model the native loop finished, before the host builds its Python view. pub(crate) struct FinishedModel<'py> { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_inputs.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_inputs.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_inputs.rs index 82a3173139..bf8ba2d2e2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_inputs.rs @@ -6,7 +6,7 @@ use sqlbuild_analysis::compiled_project::main::header_metadata_keys::is_header_m use sqlbuild_analysis::compiled_project::models::{AnalysisOverride, ModelReferenceFact}; use sqlbuild_sqltext::sql_references::models::SqlReference; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; const SQL_ANALYSIS_KEY: &str = "sql_analysis"; const SQL_VALIDATION_KEY: &str = "sql_validation"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs index 56eef6ba1d..29dd88c6a0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs @@ -10,11 +10,11 @@ use sqlbuild_sqltext::sql_references::main::extract_sql_references::extract_sql_ use sqlbuild_sqltext::sql_references::models::ReferenceExtraction; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, VisibleDeclarations, compile_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::reference_row; +use crate::bindings::_helpers::input_loops::model_loop_inputs::reference_row; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::macro_expansion::{ ExpansionOutput, NativeMacroExpansion, StateInput, expanded, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_named.rs similarity index 86% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_named.rs index 88fdb63008..f1312f45ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_named.rs @@ -4,13 +4,12 @@ use std::path::Path; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; -use sqlbuild_scopes::scope_index::main::normalize_scope_path::normalize_scope_path; use sqlbuild_scopes::scope_index::main::path_visible::path_visible; use sqlbuild_scopes::scope_index::models::{ - DeclaredScope, ResourceIdentity, ResourceKind, ScopeKind, ScopePathFailure, + DeclaredScope, ResourceIdentity, ResourceKind, ScopeKind, }; -use crate::bindings::_helpers::compiled_project::model_loop::LoopContext; +use crate::bindings::_helpers::input_loops::model_loop::LoopContext; use crate::bindings::_helpers::records::fields::field as native_field; const NAME_FIELD: &str = "name"; @@ -24,7 +23,6 @@ const OWNING_PATH_FIELD: &str = "owning_path"; const OWNERSHIP_ROOT_FIELD: &str = "ownership_root"; const CONSUMER_FIELD: &str = "consumer"; const DECLARATION_FIELD: &str = "declaration"; -const CURRENT_FOLDER: &str = "."; const INACCESSIBLE_CODE: &str = "S006"; const MODEL_RESOURCE: &str = "model"; @@ -60,6 +58,7 @@ pub(crate) const AUDIT_DECLARATION: NamedKind = NamedKind { label: "Generic audit", role: "audits/generic", }; +use crate::bindings::_helpers::scopes::compile_usages::{CURRENT_FOLDER, scope_path_message}; /// The usage of the indexed declaration `name`, if any, reporting S006 when it is hidden. pub(crate) fn named_usages<'py>( @@ -122,28 +121,6 @@ fn path_error(context: &LoopContext<'_, '_>, declared: &DeclaredScope, label: &s } } -/// The `InvalidScopePathError` message of the first path Python's visibility check rejects. -pub(crate) fn scope_path_message(declared: &DeclaredScope, label: &str) -> String { - let owner: &str = declared - .owning_path - .as_deref() - .filter(|path| !path.is_empty()) - .unwrap_or(CURRENT_FOLDER); - let (path, failure) = match normalize_scope_path(label) { - Err(failure) => (label, failure), - Ok(_) => match normalize_scope_path(owner) { - Err(failure) => (owner, failure), - Ok(_) => (label, ScopePathFailure::NotProjectRelative), - }, - }; - match failure { - ScopePathFailure::NotProjectRelative => { - format!("Scope path must be project-relative: {path}") - } - ScopePathFailure::EscapesProject => format!("Scope path escapes the project: {path}"), - } -} - /// The scope facts of a Python `DeclarationRecord`. fn declared_scope(record: &Bound<'_, PyAny>) -> PyResult { let scope: String = diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_opt_out.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_opt_out.rs index afde98b0d6..435682527c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_opt_out.rs @@ -9,10 +9,10 @@ use sqlbuild_analysis::compiled_project::main::opt_out_position::opt_out_positio use sqlbuild_analysis::compiled_project::models::TextPosition; use sqlbuild_attachments::cursor_intrinsics::main::replace_intrinsics::replace_intrinsics; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, compile_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::{HOOK_KEYS, present}; +use crate::bindings::_helpers::input_loops::model_loop_inputs::{HOOK_KEYS, present}; use crate::bindings::_helpers::project_assembly::resources::{syntax_error_message, syntax_valid}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_prepass.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_prepass.rs similarity index 69% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_prepass.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_prepass.rs index 8c707a6ceb..cab15b8d9a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_prepass.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_prepass.rs @@ -2,15 +2,13 @@ use std::sync::{Arc, OnceLock}; -use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; -use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods}; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use rayon::{ThreadPool, ThreadPoolBuildError, ThreadPoolBuilder}; use sqlbuild_discovery::model_files::main::header_facts::header_facts; -use sqlbuild_discovery::model_files::models::{EntryFacts, HeaderFacts}; +use sqlbuild_discovery::model_files::models::HeaderFacts; use sqlbuild_sqltext::compiler::models::AuthoredValue; -use crate::bindings::_helpers::compiled_project::model_loop_host::ModelLoopRow; +use crate::bindings::_helpers::input_loops::model_loop_host::ModelLoopRow; /// The compile pools' fixed worker count. const PREPASS_WORKERS: usize = 4; @@ -21,27 +19,6 @@ static POOL: OnceLock> = OnceLock::new( /// A model's native header values and the relative path parse messages name. pub(crate) type NativeHeader = (Arc<[(String, AuthoredValue)]>, String); -/// An entry's facts only when its value is the header's own, so replaced values read from Python. -pub(crate) fn own_entry<'a, 'py>( - facts: &'a HeaderFacts, - header: &Bound<'py, PyDict>, - (key, value): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), -) -> PyResult> { - let Ok(name) = key.downcast::() else { - return Ok(None); - }; - let Ok(name) = name.to_str() else { - return Ok(None); - }; - let Some(entry) = facts.entry(name) else { - return Ok(None); - }; - Ok(header - .get_item(name)? - .filter(|own| own.is(value)) - .map(|_| entry)) -} - /// Each model's header facts on the compile pool, or in turn when the pool cannot start. pub(crate) fn all_header_facts(headers: &[Option]) -> Vec> { pooled(headers, facts_of) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_python_hooks.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_python_hooks.rs index d0fa86a4c2..14b71db82a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_python_hooks.rs @@ -7,8 +7,8 @@ use pyo3::FromPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyTuple}; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, compile_error}; -use crate::bindings::_helpers::compiled_project::model_loop_named::{ +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, compile_error}; +use crate::bindings::_helpers::input_loops::model_loop_named::{ PYTHON_HOOK_DECLARATION, named_usages, }; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_schema.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_schema.rs index 8931d52454..ff8eec9203 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_schema.rs @@ -5,9 +5,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, compile_error}; -use crate::bindings::_helpers::compiled_project::model_loop_inputs::present; use crate::bindings::_helpers::compiled_project::schema_facts::python_column_fact; +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, compile_error}; +use crate::bindings::_helpers::input_loops::model_loop_inputs::present; use crate::bindings::_helpers::model_config::header_metadata::HeaderColumn; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_visibility.rs similarity index 99% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_visibility.rs index 3042c27beb..a4403468ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_visibility.rs @@ -8,7 +8,7 @@ use pyo3::FromPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; -use crate::bindings::_helpers::compiled_project::model_loop::{LoopContext, VisibleDeclarations}; +use crate::bindings::_helpers::input_loops::model_loop::{LoopContext, VisibleDeclarations}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::scopes::declaration_contexts::NativeDeclarationContexts; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/input_loops/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/registration.rs new file mode 100644 index 0000000000..b18d7efcaa --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/registration.rs @@ -0,0 +1,11 @@ +use pyo3::prelude::{Bound, PyModule, PyResult}; + +use crate::bindings::_helpers::compiled_project::attachment_inputs; +use crate::bindings::_helpers::input_loops::resource_attachment::RESOURCE_ATTACHMENT; + +pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { + attachment_inputs::install(RESOURCE_ATTACHMENT); + crate::bindings::_helpers::input_loops::model_loop::register(module)?; + crate::bindings::_helpers::input_loops::attachment::register(module)?; + crate::bindings::_helpers::input_loops::expanded_offsets::register(module) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_attachment.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_attachment.rs new file mode 100644 index 0000000000..baea73a399 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_attachment.rs @@ -0,0 +1,198 @@ +//! The model loop's attachment of the project's sources, functions, SQL tests and audits. + +use std::collections::HashMap; + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; + +use crate::bindings::_helpers::compiled_project::attachment_inputs::{ + AttachedSqlTests, AuditFileRow, AuditSettings, FunctionRow, FunctionSettings, + ResourceAttachment, ScenarioRow, SourceRow, SourceSettings, SqlTestSettings, TestFileRow, +}; +use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::audit_views::NativeAuditInput; +use crate::bindings::_helpers::compiled_views::function_views::{ + AttachedFunction, NativeFunctionInput, +}; +use crate::bindings::_helpers::compiled_views::seed_views::SeedParts; +use crate::bindings::_helpers::compiled_views::source_views::{AttachedSource, NativeSourceInput}; +use crate::bindings::_helpers::input_loops::audit_loop::{ + AttachmentOwner, model_owner, resource_owner, +}; +use crate::bindings::_helpers::input_loops::model_loop::NativeModelLoop; +use crate::bindings::_helpers::input_loops::resource_diagnostics::resource_diagnostics; +use crate::bindings::_helpers::records::fields::field as native_field; + +const RELATIVE_PATH_ATTRIBUTE: &str = "relative_path"; +const SOURCE_OWNER: &str = "source"; +const SEED_OWNER: &str = "seed"; + +/// The attachment runs the project's Python methods dispatch to, installed at registration. +pub(crate) const RESOURCE_ATTACHMENT: ResourceAttachment = ResourceAttachment { + sources: attach_sources, + functions: attach_functions, + diagnostics: resource_diagnostics, + sql_tests: attach_sql_tests, + audits: attach_audits, +}; + +/// Attach every discovered source in order with the kept loop; return each source's view. +pub(crate) fn attach_sources( + project: &Bound<'_, NativeCompiledProject>, + rows: Vec, + settings: SourceSettings, +) -> PyResult> { + if rows.is_empty() { + return Ok(Vec::new()); + } + let py: Python<'_> = project.py(); + let (model_loop, host) = project.borrow().attachment_loop(py)?; + let model_loop: &Bound<'_, NativeModelLoop> = model_loop.bind(py).cast()?; + model_loop + .get() + .run_sources(project, host.bind(py), rows, settings) +} + +/// Attach every SQL, then Python, function with the kept loop; return each one's view. +pub(crate) fn attach_functions( + project: &Bound<'_, NativeCompiledProject>, + rows: (Vec, Vec), + settings: FunctionSettings, +) -> PyResult> { + let py: Python<'_> = project.py(); + let (model_loop, host) = project.borrow().attachment_loop(py)?; + let model_loop: &Bound<'_, NativeModelLoop> = model_loop.bind(py).cast()?; + let models: Vec<(String, Vec)> = project + .borrow() + .inputs() + .iter() + .map(|record| { + Ok(( + record.model_file.get().relative_text(py)?, + record.references.clone(), + )) + }) + .collect::>()?; + let attached: Vec = + model_loop + .get() + .run_functions(host.bind(py), rows, settings, &models)?; + let count: usize = attached.len(); + let first: usize = project.borrow_mut().extend_functions(attached); + Ok((first..first + count) + .map(|index| NativeFunctionInput::new(project.clone().unbind(), index)) + .collect()) +} + +/// Attach every SQL test case, then every scenario, with the kept loop. +pub(crate) fn attach_sql_tests( + project: &Bound<'_, NativeCompiledProject>, + files: Vec, + scenarios: Vec, + settings: SqlTestSettings, +) -> PyResult { + let py: Python<'_> = project.py(); + let (model_loop, host) = project.borrow().attachment_loop(py)?; + let model_loop: &Bound<'_, NativeModelLoop> = model_loop.bind(py).cast()?; + let arities: HashMap = project + .borrow() + .functions() + .iter() + .filter(|record| !record.attached.return_columns.is_empty()) + .map(|record| { + ( + record.attached.name.clone(), + record.attached.arguments.len(), + ) + }) + .collect(); + model_loop + .get() + .run_sql_tests(host.bind(py), (&files, &scenarios), &settings, arities) +} + +/// Attach singular, then resource-attached, audits; return views and override warnings. +pub(crate) fn attach_audits<'py>( + project: &Bound<'py, NativeCompiledProject>, + files: Vec, + settings: AuditSettings, +) -> PyResult<(Vec, Vec>)> { + let py: Python<'py> = project.py(); + let (model_loop, host) = project.borrow().attachment_loop(py)?; + let model_loop: &Bound<'_, NativeModelLoop> = model_loop.bind(py).cast()?; + let owners: Vec> = attachment_owners(&project.borrow(), py)?; + let (attached, shadows) = + model_loop + .get() + .run_audits(host.bind(py), &files, owners, &settings)?; + let count: usize = attached.len(); + let first: usize = project.borrow_mut().extend_audits(attached); + Ok(( + (first..first + count) + .map(|index| NativeAuditInput::new(project.clone().unbind(), index)) + .collect(), + shadows, + )) +} + +/// Each schema-attached model, then each source and seed, with the audits attached to it. +fn attachment_owners<'py>( + project: &NativeCompiledProject, + py: Python<'py>, +) -> PyResult>> { + let mut owners: Vec> = Vec::new(); + for record in project.inputs() { + let (Some(schema), Some(fact)) = (&record.schema, project.input_schema_fact(record)) else { + continue; + }; + owners.push(model_owner( + record.name.clone(), + record.model_file.get().relative_text(py)?, + ( + schema.audits.bind(py), + (schema.columns.as_ref(), &fact.columns), + ), + )?); + } + for source in project.sources() { + let attached: &AttachedSource = source.attached(); + let path: String = native_field(attached.source_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? + .str()? + .to_string(); + owners.push(resource_owner( + SOURCE_OWNER, + attached.name.clone(), + (path.clone(), path), + ( + attached.audits.bind(py).as_any(), + attached.columns.bind(py).as_any(), + ), + )?); + } + for seed in project.seeds() { + let SeedParts { + name, + seed_file, + schema_entry, + schema_file, + } = seed.parts(); + let schema_entry: &Bound<'py, PyAny> = schema_entry.bind(py); + owners.push(resource_owner( + SEED_OWNER, + name.to_owned(), + ( + native_field(seed_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? + .str()? + .to_string(), + native_field(schema_file.bind(py), RELATIVE_PATH_ATTRIBUTE)? + .str()? + .to_string(), + ), + ( + &native_field(schema_entry, "audits")?, + &native_field(schema_entry, "columns")?, + ), + )?); + } + Ok(owners) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_diagnostics.rs similarity index 87% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_diagnostics.rs index 9dd9ba24b1..f4c86683fb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_diagnostics.rs @@ -1,14 +1,10 @@ //! Compile-input diagnostics of the project's resources, read from the native owner. -use pyo3::exceptions::PyValueError; -use sqlbuild_discovery::yaml_files::main::yaml_entry_lines::yaml_entry_lines; -use sqlbuild_pysource::definition_locations::main::decorator_location::decorator_location; -use sqlbuild_sqltext::compiler::main::model_header_entry_span::model_header_entry_span; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; -use pyo3::FromPyObject; -use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; +use pyo3::exceptions::PyValueError; +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString, PyStringMethods}; use sqlbuild_analysis::compiled_project::main::text_position::text_position; use sqlbuild_analysis::compiled_project::models::TextPosition; @@ -20,10 +16,17 @@ use sqlbuild_analysis::resource_diagnostics::main::header_help::header_help; use sqlbuild_analysis::resource_diagnostics::main::missing_description::missing_description; use sqlbuild_analysis::resource_diagnostics::main::yaml_help::yaml_help; use sqlbuild_analysis::resource_diagnostics::models::{CursorModel, HeaderHelp}; +use sqlbuild_discovery::yaml_files::main::yaml_entry_lines::yaml_entry_lines; +use sqlbuild_pysource::definition_locations::main::decorator_location::decorator_location; +use sqlbuild_sqltext::compiler::main::model_header_entry_span::model_header_entry_span; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::attachment_inputs::{ + DiagnosticSettings, HookDescriptionRow, LoaderRow, PythonResourceRow, ResourceDiagnostics, + ScenarioDescriptionRow, +}; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::seed_views::SeedParts; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::seed_views::SeedParts; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; use crate::bindings::_helpers::records::fields::field as native_field; @@ -35,73 +38,6 @@ const CURSOR_KEY: &str = "cursor"; const CURSOR_INPUTS_KEY: &str = "cursor_inputs"; const PYTHON_UDF_DECORATOR: &str = "udf"; -/// A loader's description, relative path and whether that path is a YAML file. -pub(crate) type LoaderRow = (Option, String, bool); - -positional_record! { - extract; - /// A Python resource's kind, name, description (a `str` that may hold surrogates), location, help. - struct PythonResourceRow { - kind: String, - name: String, - description: Option>, - location: Py, - help: String, - } -} - -positional_record! { - extract; - /// A scenario's name, relative path, contents and authored header description. - struct ScenarioDescriptionRow { - name: String, - path: String, - contents: String, - raw: Py, - } -} - -positional_record! { - extract; - /// A SQL hook file's name, relative path, contents and description. - struct HookDescriptionRow { - name: String, - path: String, - contents: String, - description: Option, - } -} - -/// What the resource diagnostics read beyond the owner, and the Python values they build. -#[derive(FromPyObject)] -#[pyo3(from_item_all)] -pub(crate) struct DiagnosticSettings { - /// `CompilerDiagnostic`, `SourceLocation`, `Path` and `CompileInputError`. - compiler_diagnostic: Py, - compile_error: Py, - source_location: Py, - path_class: Py, - /// Every discovered model file, whose headers attach audit factories. - model_files: Vec>, - /// Each discovered audit factory's name, relative path and line. - audit_factories: Vec<(String, String, usize)>, - /// Each scenario's name, relative path, contents and authored header description. - scenarios: Vec, - /// Each SQL hook file's name, relative path, contents and description. - sql_hooks: Vec, - /// Each loader by name. - loaders: HashMap, - /// Python-defined resources: kind, name, description, location and help, read by Python. - python_resources: Vec, -} - -/// The orphaned audit factory warnings, then the missing descriptions, then the cursor errors. -pub(crate) type ResourceDiagnostics<'py> = ( - Vec>, - Vec>, - Vec>, -); - struct Diagnostics<'a, 'py> { py: Python<'py>, settings: &'a DiagnosticSettings, @@ -419,7 +355,7 @@ fn docstring_text(description: &Bound<'_, PyString>) -> String { /// A source's P010, falling back to its loader's description and naming the loader in help. fn source_description<'py>( diagnostics: &Diagnostics<'_, 'py>, - source: &crate::bindings::_helpers::compiled_project::source_views::SourceRecord, + source: &crate::bindings::_helpers::compiled_views::source_views::SourceRecord, ) -> PyResult>> { let py: Python<'py> = diagnostics.py; let attached = source.attached(); @@ -465,7 +401,7 @@ fn source_description<'py>( /// A SQL or Python function's P010, located at its header or `@udf` decorator. fn function_description<'py>( diagnostics: &Diagnostics<'_, 'py>, - function: &crate::bindings::_helpers::compiled_project::function_views::FunctionRecord, + function: &crate::bindings::_helpers::compiled_views::function_views::FunctionRecord, ) -> PyResult>> { let py: Python<'py> = diagnostics.py; let attached = &function.attached; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/scenario_loop.rs similarity index 91% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/scenario_loop.rs index 2e8c4f2db4..e4e9142274 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/scenario_loop.rs @@ -1,6 +1,5 @@ //! `build_scenario_inputs`: SQL scenarios expanded, classified and checked natively. -use crate::bindings::_helpers::compile_delta::context::record_test_source_reads; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use sqlbuild_analysis::compiler::main::scenario_helper_scope::scenario_helper_scope; @@ -13,28 +12,17 @@ use sqlbuild_attachments::test_targets::main::scenario_source_violation::scenari use sqlbuild_attachments::test_targets::models::ScenarioCteSources; use sqlbuild_sqltext::sql_references::models::SqlReference; -use crate::bindings::_helpers::compiled_project::model_loop::compile_error; -use crate::bindings::_helpers::compiled_project::model_loop_calls::origin_references; -use crate::bindings::_helpers::compiled_project::source_loop::{ +use crate::bindings::_helpers::compile_context::delta::record_test_source_reads; +use crate::bindings::_helpers::compiled_project::attachment_inputs::ScenarioRow; +use crate::bindings::_helpers::input_loops::model_loop::compile_error; +use crate::bindings::_helpers::input_loops::model_loop_calls::origin_references; +use crate::bindings::_helpers::input_loops::source_loop::{ AuthoredExpansion, expanded_authored_sql, scoped_declarations, }; -use crate::bindings::_helpers::compiled_project::sql_test_loop::{ +use crate::bindings::_helpers::input_loops::sql_test_loop::{ FileOrigin, TestScope, assertion_targets, checked_body, source_names, unique, }; -positional_record! { - extract; - /// A scenario file's paths, discovered file, contents, SQL body and name. - pub(crate) struct ScenarioRow { - pub(crate) file_path: String, - pub(crate) relative_path: String, - pub(crate) scenario_file: Py, - pub(crate) contents: String, - pub(crate) sql_body: String, - pub(crate) name: String, - } -} - impl<'py> TestScope<'_, 'py> { /// Every scenario expanded, classified and checked, in discovery order. pub(crate) fn attached_scenarios(&self, rows: &[ScenarioRow]) -> PyResult>> { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/source_loop.rs similarity index 97% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/source_loop.rs index 4f3e3d1204..06a53815b2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/source_loop.rs @@ -7,14 +7,15 @@ use sqlbuild_attachments::cursor_intrinsics::main::intrinsic_free::intrinsic_fre use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicCheck; use sqlbuild_model_config::templates::models::TemplateOptions; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compiled_project::attachment_inputs::{SourceRow, SourceSettings}; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::source_views::{AttachedSource, replaced}; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, compile_error, record_reads, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::compiled_project::model_loop_macros::{ +use crate::bindings::_helpers::input_loops::model_loop_macros::{ argument_references as macro_argument_references, expanded_with, }; -use crate::bindings::_helpers::compiled_project::source_views::{AttachedSource, replaced}; use crate::bindings::_helpers::model_config::config_errors::native_config_error; use crate::bindings::_helpers::model_config::config_errors::raised_config_exception; use crate::bindings::_helpers::model_config::config_templates::{ @@ -40,12 +41,6 @@ const EXPRESSION_STATEMENTS: [&str; 3] = ["select", "with", "values"]; /// The SQL parsed for an authored source expression and its syntax error message. type ParsedExpression = (String, PyResult>); -/// One discovered source: its file's path, the discovered file and the entry. -pub(crate) type SourceRow = (String, Py, Py); - -/// `(default contract, whether expressions are syntax-checked, source kind)`. -pub(crate) type SourceSettings = (Option, bool, Py); - /// Attach every source in order, as `build_source_inputs` does. pub(crate) fn attached_sources<'py>( model_loop: &NativeModelLoop, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/sql_test_loop.rs similarity index 93% rename from crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs rename to crates/sqlbuild-python/src/bindings/_helpers/input_loops/sql_test_loop.rs index 40aa64302a..0b8b6c0e19 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/input_loops/sql_test_loop.rs @@ -1,10 +1,8 @@ //! `build_test_inputs`: SQL test blocks expanded, classified and checked natively. -use crate::bindings::_helpers::compile_delta::context::record_test_source_reads; use std::collections::{HashMap, HashSet}; use std::convert::Infallible; -use pyo3::FromPyObject; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use sqlbuild_analysis::compiled_project::main::text_position::text_position; @@ -38,16 +36,20 @@ use sqlbuild_sqltext::sql_references::models::{ReferenceExtraction, SqlReference use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; use crate::bindings::_helpers::cache::sql_test_scan_store::SqlTestScanStore; -use crate::bindings::_helpers::compiled_project::model_loop::{ +use crate::bindings::_helpers::compile_context::delta::record_test_source_reads; +use crate::bindings::_helpers::compiled_project::attachment_inputs::{ + SqlTestSettings, TestBlockRow, TestCaseRow, TestFileRow, +}; +use crate::bindings::_helpers::compiled_views::source_views::replaced; +use crate::bindings::_helpers::input_loops::model_loop::{ LoopContext, NativeModelLoop, compile_error, helped_compile_error, }; -use crate::bindings::_helpers::compiled_project::model_loop_calls::{ +use crate::bindings::_helpers::input_loops::model_loop_calls::{ CallOrigin, origin_references, report_invalid_call, }; -use crate::bindings::_helpers::compiled_project::source_loop::{ +use crate::bindings::_helpers::input_loops::source_loop::{ AuthoredExpansion, expanded_authored_sql, scoped_declarations, }; -use crate::bindings::_helpers::compiled_project::source_views::replaced; use crate::bindings::_helpers::records::fields::field as native_field; const MODEL_MODE: &str = "model"; @@ -67,64 +69,6 @@ const CONSTANT_VISIBILITY: &str = "constant_visibility"; const MACRO_RECORDS: &str = "macro_records"; const MACRO_VISIBILITY: &str = "macro_visibility"; -/// A test case's discovered case, name and parameter values in authored order. -pub(crate) type TestCaseRow = (Py, String, Vec<(String, Py)>); - -positional_record! { - extract; - /// A test block, its name, SQL, mode, declared parameter names, cases and authored SQL span. - pub(crate) struct TestBlockRow { - pub(crate) block: Py, - pub(crate) name: Option, - pub(crate) sql_body: String, - pub(crate) mode: String, - pub(crate) parameters: Vec, - pub(crate) cases: Vec, - pub(crate) sql_body_span: Option<(usize, usize)>, - } -} - -positional_record! { - extract; - /// A test file's paths, stem, discovered file, contents and blocks. - pub(crate) struct TestFileRow { - pub(crate) file_path: String, - pub(crate) relative_path: String, - pub(crate) stem: String, - pub(crate) file: Py, - pub(crate) contents: String, - pub(crate) blocks: Vec, - } -} - -/// What every SQL test and scenario of one compile resolves and records with. -#[derive(FromPyObject)] -#[pyo3(from_item_all)] -pub(crate) struct SqlTestSettings { - /// `CompileSqlTestInput`, its model and direct payloads, and `CompileSqlTestCte`. - pub(crate) test_input: Py, - pub(crate) model_payload: Py, - pub(crate) direct_payload: Py, - pub(crate) test_cte: Py, - /// `CompileSqlScenarioInput` and `CompileSqlScenarioCte`. - pub(crate) scenario_input: Py, - pub(crate) scenario_cte: Py, - /// `SqlTestMode` by value. - pub(crate) modes: Py, - /// The `ResourceKind`s of tests and scenarios, and the runtime `UsageKind`. - pub(crate) test_kind: Py, - pub(crate) scenario_kind: Py, - pub(crate) runtime_usage: Py, - /// The adapter's typed scalar renderer, returning `(text, None)` or `(None, error)`. - pub(crate) render_parameter: Py, - pub(crate) adapter_name: String, - /// `SourceLocation`, for helper problems located natively. - pub(crate) source_location: Py, - /// The shared scan store with the scan algorithm and lexical rules keying it, if any. - pub(crate) scan_store: Option>, - pub(crate) scan_key: (String, String), -} - /// The loop, its context, the settings and the project names every test resolves against. pub(crate) struct TestScope<'a, 'py> { pub(crate) model_loop: &'a NativeModelLoop, @@ -145,9 +89,6 @@ struct ExpandedTest<'a, 'py> { usages: Bound<'py, PyTuple>, } -/// The attached SQL test inputs, then scenario inputs. -pub(crate) type AttachedSqlTests = (Vec>, Vec>); - /// `(file path, relative path, contents)` of an authored test or scenario file. pub(crate) type FileOrigin<'a> = (&'a str, &'a str, &'a str); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs index 9308ed6926..3c66339c05 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs @@ -16,6 +16,7 @@ use sqlbuild_analysis::janitor_planning::main::matching_exclude_pattern::matchin use sqlbuild_analysis::janitor_planning::main::parse_archive_name::parse_archive_name; use sqlbuild_analysis::janitor_planning::main::query_diff_artifact_parts::query_diff_artifact_parts; use sqlbuild_analysis::janitor_planning::main::unaddressable_relation_reason::unaddressable_relation_reason; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::janitor::janitor_facts::{ Warehouse, WarehouseFacts, skipped_relation, @@ -24,7 +25,6 @@ use crate::bindings::_helpers::janitor::janitor_keys::{ Folded, Key, SchemaKey, archive_timestamp, days, folded_schema, optional, record, relation_age_timestamp, sorted_schemas, text, timestamp_fields, tuple, utc_datetime, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::planner_scenario::artifacts::is_scenario_artifact_physical_name; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::relation_naming::fitting::shared_error; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs index cd9266e6de..9ff0f2b19e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs @@ -7,7 +7,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyBool; use sqlbuild_analysis::janitor_planning::constants::UNTRACKED_QUERY_DIFF_REASON; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; + +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::fingerprints::storage_io::read_latest_fingerprints; use crate::bindings::_helpers::janitor::janitor_keys::{ Folded, Key, SchemaKey, dedupe_schema_keys, folded_schema, integer, optional, record, @@ -19,8 +21,6 @@ const QUERY_ARTIFACT_LIFECYCLE: ExecutorHost = ExecutorHost::QueryDiffArtifactLi const RELATION_LOOKUP: AdapterHost = AdapterHost::BuildRelationLookup; const LOG_DEBUG_EVENT: ExecutorHost = ExecutorHost::LogDebugEvent; const EXECUTION_LOGGER: &str = "sqlbuild.execution"; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use sqlbuild_core::constants::FINGERPRINT_TABLE_NAME; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs index 0f582cee79..277e089ef9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs @@ -5,9 +5,9 @@ use std::collections::HashSet; use pyo3::prelude::{Bound, IntoPyObject, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyString, PyTuple}; use sqlbuild_analysis::janitor_planning::models::ArchiveTimestamp; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs index daa6ce2f1f..e6a3ba599b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs @@ -7,9 +7,11 @@ use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_analysis::janitor_planning::main::migration_origin_keys::migration_origin_keys; use sqlbuild_analysis::janitor_planning::main::old_name_request_matches::old_name_request_matches; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::janitor::janitor_facts::{ SchemaRelations, Warehouse, model_destinations, }; @@ -22,7 +24,6 @@ use crate::bindings::_helpers::state_rows::migration_io::{ }; const IS_COMPATIBILITY_VIEW: ExecutorHost = ExecutorHost::IsCompatibilityView; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs index 5fc363b8da..9141d10afc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs @@ -1,24 +1,25 @@ //! `sqb janitor` phases: compile, connect, inspect and plan, clean up and close. +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::native_host::connections::connection_failure; use std::time::Instant; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods}; -use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::cli::progress_reporters::{ +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; +use crate::bindings::_helpers::build_progress::progress_reporters::{ ConnectionProgressReporter, PlanningProgressReporter, }; +use crate::bindings::_helpers::build_progress::transient_status::status_reporter; use crate::bindings::_helpers::command_runtime::invocation::resolve_adapter_connection_context; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; use crate::bindings::_helpers::janitor::janitor_facts::Warehouse; use crate::bindings::_helpers::janitor::janitor_planning::{ JanitorSettings, RelationScope, build_plan, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs index 7a45eee6b8..82165954cf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs @@ -9,8 +9,9 @@ use sqlbuild_analysis::janitor_planning::constants::OLD_NAME_VIEW_REASON; use sqlbuild_analysis::janitor_planning::main::build_archive_name::build_archive_name; use sqlbuild_analysis::janitor_planning::main::query_diff_artifact_name::query_diff_artifact_name; use sqlbuild_analysis::janitor_planning::main::query_diff_artifact_parts::query_diff_artifact_parts; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, within}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, within}; use crate::bindings::_helpers::janitor::janitor_classification::{ Candidate, Policy, Protection, SchemaClassification, classify_target_schemas, plan_archives, }; @@ -25,7 +26,6 @@ use crate::bindings::_helpers::janitor::janitor_keys::{ use crate::bindings::_helpers::janitor::janitor_old_names::{ OldNamePlanning, pending_migration_origins, plan_old_name_views, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs index 26d38685c9..601f4f5013 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs @@ -17,7 +17,7 @@ use sqlbuild_core::lifecycle_events::main::publishable_hook_name::publishable_ho use sqlbuild_core::lifecycle_events::main::run_bounds_problem::run_bounds_problem; use sqlbuild_core::lifecycle_events::models::{HookFacts, SequenceFact}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::lifecycle_events::payloads::validation_error; use crate::bindings::_helpers::lifecycle_events::validation::{ frozen_json, known_event_check, optional_text_check, required_text_check, schema_version_check, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs index 0288adf8b9..b517d5fec0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs @@ -3,9 +3,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyFloat, PyInt, PyList, PyString, PyTuple}; use sqlbuild_core::lifecycle_events::models::PayloadValue; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs index 53f9c1f9ad..a6c9d8abde 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs @@ -6,7 +6,7 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::lifecycle_events::main::validate_known_event::validate_known_event; use sqlbuild_core::lifecycle_events::models::KnownEventFacts; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::lifecycle_events::payloads::{ PathSegment, frozen, object_entries, validation_error, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs index e588c0c463..75e3d8fc95 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs @@ -10,10 +10,8 @@ use pyo3::{pyclass, pymethods}; use sqlbuild_analysis::lineage_graph::main::edge_index::edge_index; use sqlbuild_analysis::lineage_graph::models::{EdgeIndex, EdgeKey}; +use crate::bindings::_helpers::lineage::lineage_facts::{confidence_member, transform_kind_member}; use crate::bindings::_helpers::lineage::lineage_objects::LineageClasses; -use crate::bindings::_helpers::record_behaviours::lineage_facts::{ - confidence_member, transform_kind_member, -}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_facts.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs rename to crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_facts.rs index 32f93faf4f..5824d85d34 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_facts.rs @@ -5,7 +5,7 @@ use pyo3::exceptions::PyIndexError; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PySlice, PyTuple, PyTupleMethods}; -use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; +use crate::bindings::_helpers::boundary::call_arguments::call_argument; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs index bb45d5359d..aca500345b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs @@ -1,6 +1,7 @@ //! The Python lineage models and enums native lineage builds. -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/mod.rs index 26032298d2..5f73ca5eb7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/mod.rs @@ -1,6 +1,7 @@ pub(crate) mod column_lineage_graph; pub(crate) mod lineage_cache; pub(crate) mod lineage_command; +pub(crate) mod lineage_facts; pub(crate) mod lineage_index; pub(crate) mod lineage_objects; pub(crate) mod project_lineage; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs index a5fca8538c..7920ac0b77 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs @@ -18,9 +18,9 @@ use sqlbuild_analysis::lineage_graph::main::analysis_dialect::analysis_dialect; use sqlbuild_analysis::lineage_graph::models::AnalysisDialect; use sqlbuild_analysis::semantic_validation::models as validation; -use crate::bindings::_helpers::analysis::model_reads::star_flags; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::model_reads::star_flags; use crate::bindings::_helpers::lineage::column_lineage_graph::{ CompactColumns, CompactModel, ProjectColumnLineage, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_schema.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_schema.rs index 9cb3beeafd..0652036246 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_schema.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_schema.rs @@ -5,7 +5,7 @@ use sqlbuild_analysis::lineage::models::{ LineageResourceType, LineageSchemaResource, RichSchemaResource, }; -use crate::bindings::_helpers::analysis::model_reads::{declared_rows, inferred_rows}; +use crate::bindings::_helpers::compiled_views::model_reads::{declared_rows, inferred_rows}; use crate::bindings::_helpers::records::fields::field as native_field; type TypedColumns = Vec<(String, Option)>; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs index 0255c9390e..13dc11a79e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs @@ -11,11 +11,11 @@ use sqlbuild_core::dlt_destination::models::{ DltDataset, DltDatasetName, DltDestinationPlan, DltDestinationRequest, DltValue, }; use sqlbuild_core::loader_connection::models::LoaderConnection; +use sqlbuild_host::entries::models::ThirdPartyHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::load::ingestr_command::connection; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::mapping_get_or; const DLT_ERROR: ThirdPartyHost = ThirdPartyHost::DltIntegrationError; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs index fd8825e1c3..35b5cd292a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs @@ -13,12 +13,12 @@ use sqlbuild_core::ingestr_command::main::ingestr_destination_table::ingestr_des use sqlbuild_core::ingestr_command::main::ingestr_destination_uri::ingestr_destination_uri; use sqlbuild_core::ingestr_command::models::{IngestrDestination, IngestrSource}; use sqlbuild_core::loader_connection::models::LoaderConnection; +use sqlbuild_host::entries::models::ThirdPartyHost; use sqlbuild_model_config::templates::models::TemplateOptions; use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::model_config::template_data::expanded_template_data; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; const INGESTR_ERROR: ThirdPartyHost = ThirdPartyHost::IngestrIntegrationError; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs index 8007be6dac..3e4284bff7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs @@ -15,17 +15,18 @@ use sqlbuild_core::load_command::main::render_load_footer::render_load_footer; use sqlbuild_core::load_command::main::render_load_plan::render_load_plan; use sqlbuild_core::load_command::main::render_load_ready::render_load_ready; use sqlbuild_core::load_command::models::{LoadCounts, LoadResultText}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost, UserCodeHost}; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_runtime_config; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_target_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::cursor::overrides::{cursor_integer, cursor_timestamp}; use crate::bindings::_helpers::load::load_progress::{ @@ -34,11 +35,8 @@ use crate::bindings::_helpers::load::load_progress::{ use crate::bindings::_helpers::load::load_selection::{ LoadProject, LoaderDefaults, loader_defaults, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::connections::connection_failure; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_resolution::cursor_overrides::type_cursor_overrides; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs index aa1e1e3877..a09d0164ea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs @@ -10,12 +10,12 @@ use sqlbuild_core::cli_text::models::CliStyle; use sqlbuild_core::load_command::main::render_load_result::render_load_result; use sqlbuild_core::load_command::main::render_load_spinner_line::render_load_spinner_line; use sqlbuild_core::load_command::models::{LoadResultText, LoadSpinnerRow, LoadStatus}; +use sqlbuild_host::entries::models::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, within}; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; use crate::bindings::_helpers::build_progress::terminal::start_spinner; use crate::bindings::_helpers::build_progress::transient_lines::shared_transient_line_coordinator; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, within}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs index 1f8d7f1e04..9ee1fcb3d2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs @@ -11,12 +11,12 @@ use sqlbuild_core::load_command::errors::UnknownLoadSelector; use sqlbuild_core::load_command::main::load_reference_loaders::load_reference_loaders; use sqlbuild_core::load_command::main::select_load_entries::select_load_entries as select_entries; use sqlbuild_core::load_command::models::{LoadEntry, LoadGraph}; +use sqlbuild_host::entries::models::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_connection_config; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::contracts::spec_resolution::loader_destination_parts; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/first_compile.rs b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/first_compile.rs index 69314bf43e..d47ea31186 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/first_compile.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/first_compile.rs @@ -5,7 +5,7 @@ use std::sync::{Mutex, MutexGuard, PoisonError}; use pyo3::prelude::{Bound, PyModule, PyModuleMethods, PyResult}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::compile_delta::context::injection; +use crate::bindings::_helpers::compile_context::delta::injection; /// Whether a compile claimed the first-compile slot, and whether a delta compile only borrowed it. #[derive(Debug)] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs index dd5b9d407a..2a815a9166 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs @@ -10,8 +10,8 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_cache::module_digests::main::module_digests_metadata::module_digests_metadata as metadata_text; use sqlbuild_core::json::models::JsonValue; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cache::native_store::digest_files; -use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::frontier::encoder::emit_error; use crate::bindings::_helpers::macro_bridge::store_keys::text; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs index f13306459b..170265aab4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs @@ -15,7 +15,7 @@ use sqlbuild_cache::macro_store_keys::main::context_store_token::context_store_t use sqlbuild_cache::macro_store_keys::main::macro_store_token::macro_store_token as macro_key; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::frontier::encoder::emit_error; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs b/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs index db04cdb028..b329b960e6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs @@ -11,6 +11,7 @@ use sqlbuild_analysis::manifest::errors::{ManifestEncodeError, ManifestError}; use sqlbuild_analysis::manifest::main::build_manifest_json::build_manifest_json; use sqlbuild_analysis::manifest::models::ManifestInput; use sqlbuild_core::json::errors::JsonEmitError; +use sqlbuild_host::entries::models::UserCodeHost; use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::boundary::panics::compiler_guard; @@ -20,7 +21,6 @@ use crate::bindings::_helpers::manifest::rows::{ ProjectRows, plan_input, project_rows, python_hooks, }; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs index b8dfa3816d..4475559bbc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs @@ -6,11 +6,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::PyString; use sqlbuild_cursor::algebra::main::cursor_sort_key::cursor_sort_key; use sqlbuild_cursor::algebra::models::{Scalar, SortKey}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::microbatches::models::{BoundInterval, CursorBound}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::as_scalar; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs index 1e904e48dd..d11f523f55 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs @@ -3,6 +3,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyString, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::microbatches::main::latest_requirement::latest_requirement; use sqlbuild_state::microbatches::main::project_coverage::project_coverage; use sqlbuild_state::microbatches::main::project_replay::project_replay; @@ -12,11 +13,10 @@ use sqlbuild_state::microbatches::models::{ }; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::microbatches::conversion::{ BoundParser, enum_text, optional_text, timestamp, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs index 2619ade2c4..5b93d44494 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs @@ -3,6 +3,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; use sqlbuild_state::events::main::microbatch_event_id::microbatch_event_id; use sqlbuild_state::microbatches::main::create_index_sqls::create_index_sqls; use sqlbuild_state::microbatches::main::existing_event_ids_sql::existing_event_ids_sql; @@ -13,12 +14,10 @@ use sqlbuild_state::state_tables::main::create_table_sql::create_table_sql; use sqlbuild_state::state_tables::models::TableColumn; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::contracts::state_literals::render_state_sql_literal; use crate::bindings::_helpers::frontier::encoder::emit_error; use crate::bindings::_helpers::microbatches::conversion::{optional_text, state_error}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/mod.rs index 06dd803e7b..3f78468b90 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/mod.rs @@ -16,11 +16,13 @@ pub(crate) mod clone; pub(crate) mod command_runtime; pub(crate) mod compile_attachment; pub(crate) mod compile_command; +pub(crate) mod compile_context; pub(crate) mod compile_delta; pub(crate) mod compile_driver; pub(crate) mod compile_outputs; pub(crate) mod compile_records; pub(crate) mod compiled_project; +pub(crate) mod compiled_views; pub(crate) mod compiler_enums; pub(crate) mod compiler_errors; pub(crate) mod compiler_records; @@ -51,6 +53,7 @@ pub(crate) mod frontier; pub(crate) mod graph; pub(crate) mod hand_built; pub(crate) mod init_command; +pub(crate) mod input_loops; pub(crate) mod janitor; pub(crate) mod lifecycle_events; pub(crate) mod lineage; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_classes.rs new file mode 100644 index 0000000000..a46722f80c --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_classes.rs @@ -0,0 +1,146 @@ +//! The Python classes a model's `CompileModelConfig` is built from, and building one from a native build. + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; +use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods, PyTuple}; +use pyo3::{FromPyObject, IntoPyObject}; +use sqlbuild_model_config::model_validation::models::{RetentionOverride, TableTypeOverride}; + +use crate::bindings::_helpers::model_config::model_config_builder::{ + BuiltConfig, NativeModelConfigBuilder, +}; + +const MATERIALIZED_KEY: &str = "materialized"; +const VALUES_FIELD: &str = "values"; +const PERMANENT_TABLE_TYPE: &str = "permanent"; +const TRANSIENT_TABLE_TYPE: &str = "transient"; + +/// The builder, storage defaults and Python classes a model's `CompileModelConfig` is made of. +#[derive(FromPyObject)] +#[pyo3(from_item_all)] +pub(crate) struct ConfigClasses<'py> { + pub(crate) builder: Bound<'py, NativeModelConfigBuilder>, + /// Inherited `(retention, table type)` by table-backed materialization, or `None`. + pub(crate) inherited_storage: Bound<'py, PyDict>, + pub(crate) table_backed: Vec, + pub(crate) compile_model_config: Bound<'py, PyAny>, + pub(crate) resolved_retention: Bound<'py, PyAny>, + pub(crate) retention_source: Bound<'py, PyAny>, + pub(crate) resolved_table_type: Bound<'py, PyAny>, + pub(crate) table_type: Bound<'py, PyAny>, + pub(crate) table_type_source: Bound<'py, PyAny>, + /// `record_template_reads`, the compile-reuse sink of template reads. + pub(crate) record_template_reads: Bound<'py, PyAny>, +} + +/// The model's `CompileModelConfig`, once its template reads are recorded. +pub(crate) fn built_config<'py>( + classes: &ConfigClasses<'py>, + built: &BuiltConfig<'py>, + matched: Option<&str>, +) -> PyResult> { + let fields: Bound<'py, PyDict> = config_fields(classes, built, matched)?; + view(classes, &built.values, &fields) +} + +/// Every `CompileModelConfig` field but `values`, recording the build's template reads first. +pub(crate) fn config_fields<'py>( + classes: &ConfigClasses<'py>, + built: &BuiltConfig<'py>, + matched: Option<&str>, +) -> PyResult> { + let py: Python<'py> = built.values.py(); + if !built.reads.is_empty() { + classes + .record_template_reads + .call1((PyTuple::new(py, &built.reads)?,))?; + } + let none: Bound<'py, PyAny> = py.None().into_bound(py); + let (inherited_retention, inherited_table_type): (Bound<'py, PyAny>, Bound<'py, PyAny>) = + classes + .inherited_storage + .as_any() + .get_item(storage_key(classes, &built.values)?)? + .extract()?; + let retention: Bound<'py, PyAny> = match built.retention { + RetentionOverride::Inherit => inherited_retention, + RetentionOverride::Unmanaged => resolved_retention(classes, none.clone(), true)?, + RetentionOverride::Days(days) => { + resolved_retention(classes, days.into_pyobject(py)?.into_any(), false)? + } + }; + let table_type: Bound<'py, PyAny> = match built.table_type { + TableTypeOverride::Inherit => inherited_table_type, + TableTypeOverride::Permanent => resolved_table_type(classes, PERMANENT_TABLE_TYPE)?, + TableTypeOverride::Transient => resolved_table_type(classes, TRANSIENT_TABLE_TYPE)?, + }; + let logical_schema: Bound<'py, PyAny> = built.logical_schema.clone().unwrap_or(none.clone()); + let fields: Bound<'py, PyDict> = PyDict::new(py); + fields.set_item("model_header_keys", PyTuple::new(py, &built.header_keys)?)?; + fields.set_item("matched_path_default", matched)?; + fields.set_item("logical_schema", &logical_schema)?; + fields.set_item( + "layer_schema", + if built.layer_schema_configured { + logical_schema + } else { + none.clone() + }, + )?; + fields.set_item( + "logical_database", + built.logical_database.clone().unwrap_or(none), + )?; + fields.set_item("time_travel_retention", retention)?; + fields.set_item("table_type", table_type)?; + Ok(fields) +} + +/// The materialization whose inherited storage policy applies, or `None` when not table-backed. +fn storage_key<'py>( + classes: &ConfigClasses<'py>, + values: &Bound<'py, PyDict>, +) -> PyResult> { + let py: Python<'py> = values.py(); + if let Some(materialized) = values.get_item(MATERIALIZED_KEY)? + && let Ok(text) = materialized.downcast::() + && let Ok(text) = text.to_str() + && classes.table_backed.iter().any(|name| name == text) + { + return Ok(materialized); + } + Ok(py.None().into_bound(py)) +} + +fn resolved_retention<'py>( + classes: &ConfigClasses<'py>, + desired_days: Bound<'py, PyAny>, + unmanaged: bool, +) -> PyResult> { + let fields: Bound<'py, PyDict> = PyDict::new(desired_days.py()); + fields.set_item("desired_days", desired_days)?; + fields.set_item("unmanaged", unmanaged)?; + fields.set_item("source", &classes.retention_source)?; + classes.resolved_retention.call((), Some(&fields)) +} + +fn resolved_table_type<'py>( + classes: &ConfigClasses<'py>, + value: &str, +) -> PyResult> { + let fields: Bound<'py, PyDict> = PyDict::new(classes.table_type.py()); + fields.set_item("value", classes.table_type.call1((value,))?)?; + fields.set_item("source", &classes.table_type_source)?; + fields.set_item("declared", true)?; + classes.resolved_table_type.call((), Some(&fields)) +} + +/// A `CompileModelConfig` of `values` and the other `fields`. +pub(crate) fn view<'py>( + classes: &ConfigClasses<'py>, + values: &Bound<'py, PyDict>, + fields: &Bound<'py, PyDict>, +) -> PyResult> { + let arguments: Bound<'py, PyDict> = fields.copy()?; + arguments.set_item(VALUES_FIELD, values)?; + classes.compile_model_config.call((), Some(&arguments)) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs index 200dec579f..2bc2ff7200 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs @@ -4,7 +4,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods use pyo3::types::{PyBool, PyInt, PyList, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/contract_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/contract_classes.rs index c43f5a614a..f0c02effe8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/contract_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/contract_classes.rs @@ -3,10 +3,9 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods}; +use sqlbuild_host::entries::models::{FacadeHost, ThirdPartyHost}; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/getters.rs new file mode 100644 index 0000000000..a06dd173ed --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/getters.rs @@ -0,0 +1,35 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::model_config::errors::NativeConfigError; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_native_config_error, +}]; + +fn read_native_config_error<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "class_name" => (&this.class_name).into_bound_py_any(py), + "message" => (&this.message).into_bound_py_any(py), + "code" => (&this.code).into_bound_py_any(py), + "help" => (&this.help).into_bound_py_any(py), + "key" => (&this.key).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/mod.rs index 0d0f9cbb49..e428f56314 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/mod.rs @@ -1,11 +1,13 @@ pub(crate) mod authored_nodes; pub(crate) mod column_migrations; +pub(crate) mod config_classes; pub(crate) mod config_errors; pub(crate) mod config_templates; pub(crate) mod config_values; pub(crate) mod contract_classes; pub(crate) mod described_models; pub(crate) mod errors; +pub(crate) mod getters; pub(crate) mod header_columns; pub(crate) mod header_metadata; pub(crate) mod model_config_builder; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs index cd1b534582..6846442d16 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs @@ -7,6 +7,7 @@ use pyo3::types::{ PyTupleMethods, }; use pyo3::{PyErr, pyclass, pymethods}; +use sqlbuild_discovery::model_files::models::{EntryFacts, HeaderFacts}; use sqlbuild_model_config::config_presence::main::contains_template::contains_template; use sqlbuild_model_config::config_presence::main::entry_macro_path::entry_macro_path; use sqlbuild_model_config::config_presence::models::MacroPath; @@ -20,9 +21,8 @@ use sqlbuild_model_config::templates::models::TemplateOptions; use sqlbuild_model_config::types::AuthoredNode; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compiled_project::model_loop_config::{ConfigClasses, built_config}; -use crate::bindings::_helpers::compiled_project::model_loop_prepass::own_entry; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; +use crate::bindings::_helpers::model_config::config_classes::{ConfigClasses, built_config}; use crate::bindings::_helpers::model_config::config_errors::config_exception; use crate::bindings::_helpers::model_config::config_errors::native_config_error; use crate::bindings::_helpers::model_config::config_templates::{ @@ -30,7 +30,6 @@ use crate::bindings::_helpers::model_config::config_templates::{ }; use crate::bindings::_helpers::model_config::errors::NativeConfigError; use crate::bindings::_helpers::model_config::project_defaults::project_defaults_mapping; -use sqlbuild_discovery::model_files::models::{EntryFacts, HeaderFacts}; const HOOK_KEYS: [&str; 2] = ["pre_hooks", "post_hooks"]; /// Hook keys in the sorted order `validate_model_hook_config` checks them. @@ -842,3 +841,24 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_class::()?; Ok(()) } + +/// An entry's facts only when its value is the header's own, so replaced values read from Python. +pub(crate) fn own_entry<'a, 'py>( + facts: &'a HeaderFacts, + header: &Bound<'py, PyDict>, + (key, value): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), +) -> PyResult> { + let Ok(name) = key.downcast::() else { + return Ok(None); + }; + let Ok(name) = name.to_str() else { + return Ok(None); + }; + let Some(entry) = facts.entry(name) else { + return Ok(None); + }; + Ok(header + .get_item(name)? + .filter(|own| own.is(value)) + .map(|_| entry)) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs index 2e4d8740f9..4f48fb0d60 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs @@ -72,7 +72,7 @@ fn discovered_names(inputs: &Bound<'_, PyAny>) -> PyResult { let mut models: HashSet = each(inputs, "model_files", model_stem)? .into_iter() .collect(); - if let Some(injection) = crate::bindings::_helpers::compile_delta::context::injection() { + if let Some(injection) = crate::bindings::_helpers::compile_context::delta::injection() { models.extend(injection.model_names.iter().cloned()); } let mut seeds: HashSet = HashSet::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs index 984795e66c..5ab12302d9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs @@ -11,8 +11,8 @@ use sqlbuild_core::scenario_command::main::format_captured_at::format_captured_a use sqlbuild_model_config::templates::models::TemplateOptions; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::input_reads::{context_read, environment_read}; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; +use crate::bindings::_helpers::compile_context::input_reads::{context_read, environment_read}; use crate::bindings::_helpers::model_config::config_errors::config_exception; use crate::bindings::_helpers::model_config::config_templates::{ TemplateOutcome, TemplateSources, expand_config_templates, lone_surrogate_site, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs index 39a2480d3f..27341964c0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs @@ -6,7 +6,7 @@ use pyo3::prelude::{ use pyo3::types::{PyBytes, PyBytesMethods, PyDict, PyDictMethods, PyString}; use pyo3::{pyclass, pymethods}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/connections.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_host/connections.rs index 447ddf442d..e1a80def32 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/connections.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/native_host/connections.rs @@ -2,8 +2,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, Python}; use pyo3::types::{PyDict, PyDictMethods}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; /// The coded error to raise for a failed `adapter.connect`, or the failure itself when coded. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/host.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_host/host.rs index 29b9e8ec96..5ed20ed5e2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/host.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/native_host/host.rs @@ -1,14 +1,13 @@ //! Resolve host entries: targets read once from `sqlbuild._native_host`, attributes read live. +use pyo3::PyErr; use pyo3::exceptions::PyImportError; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple, PyTupleMethods}; - -use crate::bindings::_helpers::native_host::constants::{ - HOST_ENTRIES, HOST_MODULE, HOST_TARGETS_FUNCTION, -}; -use crate::bindings::_helpers::native_host::models::HostId; +use sqlbuild_host::entries::constants::{HOST_ENTRIES, HOST_MODULE, HOST_TARGETS_FUNCTION}; +use sqlbuild_host::entries::models::HostId; +use sqlbuild_host::entries::types::HostEntries; /// One entry's target module path and attribute name. type Target = (Py, Py); @@ -16,7 +15,7 @@ type Target = (Py, Py); /// Every entry's target, grouped and ordered as `HOST_ENTRIES`. static TARGETS: PyOnceLock>> = PyOnceLock::new(); -fn missing(name: &str) -> pyo3::PyErr { +fn missing(name: &str) -> PyErr { PyImportError::new_err(format!("{HOST_MODULE} does not define host entry '{name}'")) } @@ -45,10 +44,23 @@ fn host_targets(py: Python<'_>) -> PyResult>> { Ok(groups) } +/// The host entries of one interpreter, read through `sqlbuild._native_host`. +#[derive(Clone, Copy)] +pub(crate) struct PythonHost<'py>(pub(crate) Python<'py>); + +impl<'py> HostEntries for PythonHost<'py> { + type Entry = Bound<'py, PyAny>; + type Error = PyErr; + + fn entry(&self, id: HostId) -> PyResult> { + let py: Python<'py> = self.0; + let targets: &Vec> = TARGETS.get_or_try_init(py, || host_targets(py))?; + let (module, attribute): &Target = &targets[id.edge as usize][id.index]; + py.import(module.bind(py))?.getattr(attribute.bind(py)) + } +} + /// The host entry `id`: its target module imported and the attribute read on every call. pub(crate) fn entry<'py>(py: Python<'py>, id: impl Into) -> PyResult> { - let id: HostId = id.into(); - let targets: &Vec> = TARGETS.get_or_try_init(py, || host_targets(py))?; - let (module, attribute): &Target = &targets[id.edge as usize][id.index]; - py.import(module.bind(py))?.getattr(attribute.bind(py)) + PythonHost(py).entry(id.into()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_host/mod.rs index 3efbda9aea..514ff42697 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/native_host/mod.rs @@ -1,12 +1,5 @@ //! The one Python module native code imports by path, and the staying-Python entries it names. -pub(crate) mod adapter; pub(crate) mod connections; -pub(crate) mod constants; -pub(crate) mod executor; -pub(crate) mod facade; pub(crate) mod host; -pub(crate) mod models; pub(crate) mod registration; -pub(crate) mod third_party; -pub(crate) mod user_code; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/models.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_host/models.rs deleted file mode 100644 index a8bc406038..0000000000 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/models.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Host entries: the staying-Python names native code reaches through `sqlbuild._native_host`. - -/// What a host entry resolves to. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum HostKind { - Function, - Class, - Exception, - Value, -} - -impl HostKind { - /// The kind as the import test and `_native.HOST_ENTRIES` spell it. - pub(crate) const fn label(self) -> &'static str { - match self { - Self::Function => "function", - Self::Class => "class", - Self::Exception => "exception", - Self::Value => "value", - } - } -} - -/// Which boundary a host entry crosses; also its group in `HOST_ENTRIES`. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum HostEdge { - Adapter, - UserCode, - Executor, - ThirdParty, - Facade, -} - -impl HostEdge { - /// The edge as `_native.HOST_ENTRIES` spells it. - pub(crate) const fn label(self) -> &'static str { - match self { - Self::Adapter => "adapter", - Self::UserCode => "user_code", - Self::Executor => "executor", - Self::ThirdParty => "third_party", - Self::Facade => "facade", - } - } -} - -/// One host entry: its `sqlbuild._native_host` name, kind and edge. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) struct HostEntry { - pub(crate) name: &'static str, - pub(crate) kind: HostKind, - pub(crate) edge: HostEdge, -} - -/// A host entry by edge and position, from any edge's entry enum. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) struct HostId { - pub(crate) edge: HostEdge, - pub(crate) index: usize, -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_host/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_host/registration.rs index d6ae0baed6..71da763363 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_host/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/native_host/registration.rs @@ -2,14 +2,11 @@ use pyo3::prelude::{Bound, PyModule, PyModuleMethods, PyResult}; use pyo3::types::PyTuple; - -use crate::bindings::_helpers::native_host::constants::HOST_ENTRIES; +use sqlbuild_host::entries::main::host_entry_labels::host_entry_labels; pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { - let entries: Vec<(&str, &str, &str)> = HOST_ENTRIES - .iter() - .flat_map(|group| group.iter()) - .map(|entry| (entry.name, entry.kind.label(), entry.edge.label())) - .collect(); - module.add("HOST_ENTRIES", PyTuple::new(module.py(), entries)?) + module.add( + "HOST_ENTRIES", + PyTuple::new(module.py(), host_entry_labels())?, + ) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs b/crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs index dbe63d9e8c..6f127b26a5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs @@ -3,7 +3,7 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; static EXIT_SIGNAL: PyOnceLock> = PyOnceLock::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs index 2334c9d65f..9948f44406 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs @@ -9,11 +9,9 @@ use pyo3::prelude::{ }; use pyo3::sync::PyOnceLock; use pyo3::types::PyTuple; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{ - call_with, context_variable, imported, -}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, context_variable, imported}; use crate::bindings::_helpers::native_host::host; const CONTEXT_VARIABLE: &str = "sqlbuild_output_capture_context"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs index 523a936c90..7f276d3f12 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs @@ -21,9 +21,9 @@ use sqlbuild_core::command_output::main::queue_output_record::queue_output_recor use sqlbuild_core::command_output::models::{ BufferOutcome, IdleStep, OutputBuffer, OutputQueue, OutputStream, RecordDraft, RecordPriority, }; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_threads::constants::OUTPUT_SUPPRESSED_ATTRIBUTE; use crate::bindings::_helpers::native_threads::exit_signal::signal_interpreter_exit; @@ -354,25 +354,24 @@ impl OutputCaptureDispatcher { #[new] #[pyo3(signature = (**options))] fn new(py: Python<'_>, options: Option>) -> PyResult { - let options = - crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments::read( - py, - "OutputCaptureDispatcher", - options, - ( - &["exporter", "invocation_id"], - &[ - "run_id", - "external_context", - "queue_capacity", - "batch_size", - "max_record_bytes", - "shutdown_timeout_seconds", - "clock", - "failure_callback", - ], - ), - )?; + let options = crate::bindings::_helpers::boundary::python_calls::KeywordArguments::read( + py, + "OutputCaptureDispatcher", + options, + ( + &["exporter", "invocation_id"], + &[ + "run_id", + "external_context", + "queue_capacity", + "batch_size", + "max_record_bytes", + "shutdown_timeout_seconds", + "clock", + "failure_callback", + ], + ), + )?; let number = |name: &str, default: i64| -> PyResult { let value = options.value(name)?; if value.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs index 5f902b9587..be1ea2bbea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs @@ -14,9 +14,9 @@ use sqlbuild_core::command_output::main::validate_output_record::validate_output use sqlbuild_core::command_output::models::RecordShape; use sqlbuild_core::json::main::dumps::dumps; use sqlbuild_core::json::models::{JsonDialect, JsonValue, StdlibJsonOptions}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::output_capture::values::{ freeze, json_value, object, output_error, plain_int, validation_error, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs index 5a7ae85049..3e710b140e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs @@ -10,10 +10,10 @@ use pyo3::types::{ use sqlbuild_core::command_output::errors::UnencodableText; use sqlbuild_core::command_output::types::PassText; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::macro_bridge::store_keys::text; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs index ddf569199b..9ca83a6dce 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs @@ -5,21 +5,21 @@ use pyo3::prelude::{ }; use pyo3::types::{PyBool, PyDict, PyDictMethods}; use pyo3::wrap_pyfunction; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::build_command::support::keyword_relay; -use crate::bindings::_helpers::cli::progress_reporters::{ +use crate::bindings::_helpers::build_progress::progress_reporters::{ ConnectionProgressReporter, PlanningProgressReporter, }; -use crate::bindings::_helpers::cli::progress_text::with_verbose_inspection; +use crate::bindings::_helpers::build_progress::progress_text::with_verbose_inspection; use crate::bindings::_helpers::command_runtime::invocation::resolve_adapter_connection_context; use crate::bindings::_helpers::command_runtime::preview_target::validate_preview_target; use crate::bindings::_helpers::compile_attachment::effective_config::build_effective_settings_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::pipeline::run_compile_pipeline; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::compile_driver::plan_pipeline::run_compile_pipeline; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::plan_json::format_plan_json; use crate::bindings::_helpers::plan_output::plan_text::format_plan; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs index 9fcc0ef2bf..19fc6051ec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs @@ -8,11 +8,11 @@ use pyo3::wrap_pyfunction; use sqlbuild_rules::rule_catalogue::main::render_rule_list::render_rule_list; use sqlbuild_rules::rule_catalogue::models::RuleListing; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::project::build_project_graph; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::planner_selection::selectors::select_project_graph; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs index e66e8d319b..d446b3f23a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs @@ -1,9 +1,9 @@ //! One planned model's requested, resolved and deferred cursor state, for text and JSON plans. use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::cursor::conversion::GRAIN_NAMES; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::display::{ aligned_timestamp_bounds, resolve_effective_microbatch_batch_size, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs index d6cccac33f..5ca5664651 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs @@ -18,7 +18,7 @@ use sqlbuild_core::plan_display::main::model_materialization_label::model_materi use sqlbuild_core::plan_display::main::model_resource_type::model_resource_type as resource_type; use sqlbuild_core::plan_display::models::{ModelLabelFacts, ParsedBound}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::scalars::{ render_value, to_exclusive, to_inclusive, try_parse, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs index f3d60591e4..a9755d48f3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs @@ -4,7 +4,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::compile_outputs::json_report::indented_json; use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::plan_output::cursor_details::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs index b7f51bc97e..e53da1d79b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs @@ -12,7 +12,7 @@ use sqlbuild_core::cli_text::models::{ }; use sqlbuild_core::plan_display::main::format_query_diff::format_query_diff; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::plan_output::cursor_details::{ CursorDetails, DEFERRED, RESOLVED, cursor_details, runtime_inputs_clause, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs index 45f40afa35..0fa98dc16f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs @@ -1,6 +1,8 @@ //! Detect how each selected model and function changed since its recorded build. -use crate::bindings::_helpers::analysis::model_reads; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; + +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::contracts::spec_resolution::matching_dynamic_families; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_changes::results::native_enum; @@ -25,14 +27,10 @@ use sqlbuild_analysis::planner_changes::models::{ SchemaFindingRow, }; -use crate::bindings::_helpers::analysis::model_reads::{inferred_rows, star_flags}; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::InferredRow; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; +use crate::bindings::_helpers::compiled_views::compiled_model_view::InferredRow; +use crate::bindings::_helpers::compiled_views::model_reads::{inferred_rows, star_flags}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_changes::renames::origin_names; use crate::bindings::_helpers::planner_changes::results::{ backfill_result, change_kind, planner_enum, replay_policy_error, schema_findings, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs index 2320bd9193..eb24df0b17 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs @@ -8,7 +8,7 @@ use sqlbuild_analysis::planner_changes::main::with_declared_columns_hash::with_d use sqlbuild_analysis::planner_changes::main::without_declared_columns_hash::without_declared_columns_hash as without_hash; use sqlbuild_analysis::planner_changes::models::IdentityPayload; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; /// The decoded metadata that participates in version identity, the raw text when it is not JSON, or `None`. #[pyfunction] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs index b20359e228..df127086a8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs @@ -12,11 +12,9 @@ use sqlbuild_analysis::planner_changes::main::origin_reference_names::origin_ref use sqlbuild_analysis::planner_changes::models::{NameSpan, RenameCandidate}; use sqlbuild_rules::lint_text::main::neutralize_interpolation::neutralize_interpolation; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_identity::hashing::model_query_hash; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs index 5b54c2c886..4648abb8c7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs @@ -1,8 +1,8 @@ //! Clone planning: destination and origin entries, and deferred-clone graph traversal. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::graph::project_graph::NativeProjectGraph; use crate::bindings::_helpers::planner_entries::models::ModelPlanContext; use crate::bindings::_helpers::planner_entries::values::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs index 284d458d3b..6de0009d69 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs @@ -1,8 +1,8 @@ //! Static plans for commands that do not build models, and direct seed identity reads. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::fingerprints::storage_io::read_latest_fingerprints; use crate::bindings::_helpers::planner_entries::models::RelationsRequest; use crate::bindings::_helpers::planner_entries::plan_output::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/contexts.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/contexts.rs index 58595655e7..5c0ac73afd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/contexts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/contexts.rs @@ -4,7 +4,7 @@ use pyo3::prelude::{Bound, Py, PyAny, PyResult, Python}; use pyo3::pymethods; use pyo3::types::{PyDict, PyFrozenSet}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_entries::models::{ ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/display_plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/display_plan.rs index 2caf473c20..8c91a000be 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/display_plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/display_plan.rs @@ -1,6 +1,6 @@ //! Display-only plans for external plan surfaces when warehouse planning cannot resolve. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_entries::values::{ boolean, native, none, planner_model, planner_type, string, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs index d2e2734323..aeb70b2f53 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs @@ -1,10 +1,9 @@ //! Top-level planner orchestration producing an execution plan. +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, within}; use crate::bindings::_helpers::build_command::support::utc_now; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, within, -}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_changes::actions::resolve_model_actions; use crate::bindings::_helpers::planner_changes::detect::detect_changes; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/getters.rs new file mode 100644 index 0000000000..49ca8f0864 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/getters.rs @@ -0,0 +1,113 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::planner_entries::models::{ + ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, +}; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_model_plan_context, + }, + GetterEntry { + class: class_of::, + read: read_plan_entry_build_inputs, + }, + GetterEntry { + class: class_of::, + read: read_planner_relations_context, + }, +]; + +fn read_model_plan_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_locations" => (&this.model_locations).into_bound_py_any(py), + "models_by_name" => (&this.models_by_name).into_bound_py_any(py), + "seed_locations" => (&this.seed_locations).into_bound_py_any(py), + "function_locations" => (&this.function_locations).into_bound_py_any(py), + "source_map" => (&this.source_map).into_bound_py_any(py), + "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), + "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), + "functions_by_name" => (&this.functions_by_name).into_bound_py_any(py), + "runtime_cursor_producer_names" => { + (&this.runtime_cursor_producer_names).into_bound_py_any(py) + } + "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), + "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_plan_entry_build_inputs<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "source_freshness_blocked_model_names" => { + (&this.source_freshness_blocked_model_names).into_bound_py_any(py) + } + "external_blocked_model_names" => { + (&this.external_blocked_model_names).into_bound_py_any(py) + } + "start_cursor_override" => (&this.start_cursor_override).into_bound_py_any(py), + "end_cursor_override" => (&this.end_cursor_override).into_bound_py_any(py), + "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), + "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + "max_microbatches" => (&this.max_microbatches).into_bound_py_any(py), + "max_microbatches_is_override" => { + (&this.max_microbatches_is_override).into_bound_py_any(py) + } + "microbatch_limit_action" => (&this.microbatch_limit_action).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_planner_relations_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_locations" => (&this.model_locations).into_bound_py_any(py), + "seed_locations" => (&this.seed_locations).into_bound_py_any(py), + "function_locations" => (&this.function_locations).into_bound_py_any(py), + "source_map" => (&this.source_map).into_bound_py_any(py), + "source_read_map" => (&this.source_read_map).into_bound_py_any(py), + "python_source_read_map" => (&this.python_source_read_map).into_bound_py_any(py), + "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), + "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), + "listed_source_names" => (&this.listed_source_names).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/mod.rs index 145ad2dc23..584c84460b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod command_plans; pub(crate) mod contexts; pub(crate) mod display_plan; pub(crate) mod execution_plan; +pub(crate) mod getters; pub(crate) mod model_entries; pub(crate) mod models; pub(crate) mod plan_output; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs index bf5a563cdf..ae9d789bc0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs @@ -1,8 +1,8 @@ //! Per-model plan entries from resolved change results and warehouse snapshot facts. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::discovery::guidance::microbatch_guidance; use crate::bindings::_helpers::planner_changes::actions::replaces_incremental_relation; use crate::bindings::_helpers::planner_changes::detect::detect_model_changes; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs index 2782efa869..afbf586a68 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs @@ -1,7 +1,7 @@ //! `PlanOutput` assembly from planned model entries, seeds, sources, functions, audits and tests. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_entries::model_entries::scope_overlaps; use crate::bindings::_helpers::planner_entries::models::PlanOutputInputs; use crate::bindings::_helpers::planner_entries::values::{ @@ -20,7 +20,7 @@ use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::sql_test_glue::models::SqlTestAssembly; use crate::bindings::_helpers::sql_test_glue::plan_assembly::assemble_sql_test_plans; -use crate::bindings::_helpers::sql_test_glue::plan_driver::resolve_sql_test_model_chains; +use crate::bindings::_helpers::sql_test_glue::plan_driver::sql_test_model_chain_names_by_key; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyList, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; @@ -738,22 +738,6 @@ pub(crate) fn plan_selected_sql_tests<'py>( planned_sql_tests(project, adapter, selected_keys, sql_test_selection) } -/// Return model closures resolved natively in one project batch, keyed by SQL test key. -#[pyfunction] -#[pyo3(signature = (*, project, tests))] -pub(crate) fn sql_test_model_chain_names_by_key<'py>( - project: &Bound<'py, PyAny>, - tests: &Bound<'py, PyAny>, -) -> PyResult> { - let py = project.py(); - let chains = resolve_sql_test_model_chains(project, tests)?; - let by_key = PyDict::new(py); - for (test, chain) in tests.try_iter()?.zip(chains.try_iter()?) { - by_key.set_item(native_field(&test?, "key")?, chain?)?; - } - Ok(by_key) -} - /// Whether a test is named by the selection or covers a selected resource, and not excluded. #[pyfunction] #[pyo3(signature = (*, test, selected_keys, sql_test_selection))] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs index d784d97814..b04b65bc6c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs @@ -1,7 +1,7 @@ //! Relation locations and source metadata for plan entry construction. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_entries::models::{ PlannerRelationsContext, RelationsRequest, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs index 26487ca4f9..755b87bfd5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs @@ -14,7 +14,7 @@ use pyo3::types::PyDict; use pyo3::{pyclass, pyfunction, pymethods, wrap_pyfunction}; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::native_threads::exit_signal::signal_interpreter_exit; use crate::bindings::_helpers::planner_entries::plan_output::plan_selected_sql_tests; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs index 3d7a4f9dda..9fc062023a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs @@ -1,6 +1,6 @@ //! Python boundary values shared by plan entry and plan output assembly. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::replaced_keywords; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs index 35ebf4b34e..3130f2b735 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs @@ -19,10 +19,7 @@ use sqlbuild_analysis::planner_identity::main::missing_upstreams::missing_upstre use sqlbuild_analysis::planner_identity::main::topological_order::topological_order; use sqlbuild_analysis::planner_identity::models::{AvailableUpstreams, GraphKey, MissingUpstream}; -use crate::bindings::_helpers::analysis::explicit_references::{ - GateRow, HookRow, native_execution_gate_edges, -}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::graph::algorithms::{closure, inverted}; use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::planner_identity::hashing::graph_key; @@ -32,6 +29,9 @@ use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::references::explicit_references::{ + GateRow, HookRow, native_execution_gate_edges, +}; const TABLE_FN_TEST_MODE: &str = "table_fn"; const INLINE_SQL_HOOK: &str = "inline SQL"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs index b053c04bd5..9886e8acb7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs @@ -13,7 +13,7 @@ use sqlbuild_analysis::sql_tokens::main::definition_fingerprint::definition_fing use sqlbuild_core::panics::main::is_compiler_panic::is_compiler_panic; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs index f8e834f09c..0f59644b3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs @@ -13,11 +13,11 @@ use sqlbuild_analysis::planner_identity::main::expected_graph_identity_hashes::e use sqlbuild_analysis::planner_identity::main::graph_write_identity_hashes::graph_write_identity_hashes; use sqlbuild_analysis::planner_identity::main::model_local_identity_hash::model_local_identity_hash; use sqlbuild_analysis::planner_identity::models::{GraphKey, IdentityGraph, IdentityNode}; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_identity::hashing::{graph_key, model_query_hash}; use crate::bindings::_helpers::planner_identity::metadata::{ function_local_hashes, model_version_identity_metadata_json, seed_identity, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs index 7a9250c696..9f3fbbd822 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs @@ -14,8 +14,8 @@ use sqlbuild_analysis::planner_identity::main::function_fingerprint_sql::functio use sqlbuild_analysis::planner_identity::main::stable_identity_hash::stable_identity_hash; use sqlbuild_analysis::planner_identity::models::FunctionFingerprintFields; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords, within}; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords, within}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::discovery::hook_entries::hook_entries; use crate::bindings::_helpers::planner_identity::hashing::function_definition_hash; use crate::bindings::_helpers::planner_identity::json_values::{COMPACT, SPACED, sorted_dumps}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs index fd417d7dc1..7af8fb8aff 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs @@ -17,7 +17,7 @@ use sqlbuild_analysis::planner_identity::models::{ GraphKey, StaleWarning, StalenessGraph, StalenessNames, }; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_changes::detect::{ModelPass, model_change}; use crate::bindings::_helpers::planner_identity::hashing::graph_key; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs index 73f6fa81c0..beb4f4ff94 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs @@ -1,6 +1,6 @@ //! Gather live candidate evidence without changing adapter inspection ownership. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_migrations::column_objects::{ config, definition_hash, lower, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs index 3a165d5625..106959861a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs @@ -1,10 +1,11 @@ //! Materialize column decisions from native proofs and live evidence. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::analysis::model_reads::inferred_rows; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads::inferred_rows; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::column_candidates::declared_names; use crate::bindings::_helpers::planner_migrations::column_objects::{lower, model, replace}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs index 78a498dc4f..58f2542027 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs @@ -1,6 +1,6 @@ //! Boundary conversions for the column migration planner. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_identity::hashing::model_definition_hash; use crate::bindings::_helpers::planner_phases::objects::object; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs index 41f26b4732..6e1fd8aa45 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs @@ -1,8 +1,8 @@ //! Project column renames onto the existing snapshot and redirect cursor reads. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_migrations::column_objects::{ config, definition_hash, lower, native, replace, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs index 7a6b5f7765..c44224d308 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs @@ -1,7 +1,7 @@ //! Host column migration planning while Python owns warehouse inspection. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_migrations::column_objects::replace; use crate::bindings::_helpers::planner_migrations::known_input_columns::KnownInputColumns; use crate::bindings::_helpers::planner_migrations::models::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs index 91a92f9499..e6f1acda80 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs @@ -11,7 +11,7 @@ use sqlbuild_analysis::planner_migrations::main::{ }; use sqlbuild_analysis::planner_migrations::models::Projection; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs index df77c45227..4a0d766153 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs @@ -1,9 +1,9 @@ //! Convert existing planner contracts for origin compatibility checks. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::analysis::model_reads::inferred_rows; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads::inferred_rows; use crate::bindings::_helpers::planner_changes::detect::detect_model_changes; use crate::bindings::_helpers::planner_migrations::models::{ CompatibilityCheck, MigrationCompatibilityResult, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/constants.rs index 7dbe08a7b3..09e5891b19 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/constants.rs @@ -1,4 +1,4 @@ -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; pub(super) const AUTOMATIC: &str = "automatic"; pub(super) const DONE: &str = "done"; pub(super) const PENDING_ARCHIVE: &str = "pending_archive"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs index b23a6cb872..2cab5a269b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs @@ -1,6 +1,6 @@ //! Native migration discovery over existing inspection and fingerprint cache boundaries. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::planner_migrations::matching::{ match_migration_fingerprints, migration_destination_fingerprints, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs index 6732bc6c9e..9bec76268f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs @@ -1,7 +1,8 @@ //! Preserve event and declared-origin precedence at the inspection boundary. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::column_objects::config; use crate::bindings::_helpers::planner_migrations::models::ModelMigrationDeclaration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs index fa88beb13e..861a44763d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs @@ -1,8 +1,9 @@ //! Model ordering, selection and metadata at the migration discovery boundary. +use sqlbuild_host::entries::models::UserCodeHost; + use crate::bindings::_helpers::graph::node_set::PyNodeSet; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_identity::metadata::build_function_local_hashes; use crate::bindings::_helpers::planner_identity::metadata::build_model_version_identity_metadata_json; use crate::bindings::_helpers::planner_phases::objects::object; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs index 8bc39a0c08..a8bde508ea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs @@ -1,6 +1,6 @@ //! Live candidate inspection and automatic request materialization. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::planner_migrations::column_objects::config; use crate::bindings::_helpers::planner_migrations::column_objects::native; use crate::bindings::_helpers::planner_migrations::discovery_events::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs index 31e4eea1b3..4a7a6d461c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs @@ -1,7 +1,7 @@ //! Migration identity binding with unchanged metadata and hash format. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use pyo3::exceptions::PyValueError; @@ -91,7 +91,7 @@ pub(crate) fn with_migration_fingerprints<'py>( py: Python<'py>, options: Option>, ) -> PyResult> { - use crate::bindings::_helpers::compile_driver::python_calls::call_with; + use crate::bindings::_helpers::boundary::python_calls::call_with; let arguments = KeywordArguments::read( py, "with_migration_fingerprints", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/getters.rs new file mode 100644 index 0000000000..9a2883efa9 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/getters.rs @@ -0,0 +1,40 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_migration_state_inspection, +}]; + +fn read_migration_state_inspection<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "database" => this.database(py).into_bound_py_any(py), + "events" => this + .events(py) + .and_then(|value| value.into_bound_py_any(py)), + "column_events" => this + .column_events(py) + .and_then(|value| value.into_bound_py_any(py)), + "old_name_histories" => this + .old_name_histories(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs index 138d33d354..de7593ec79 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs @@ -1,7 +1,7 @@ //! Fingerprint cache callbacks around native one-to-one migration matching. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_migrations::models::{ FingerprintInputs, ModelMigrationRequest, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs index 9d72a99976..b5361f630c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs @@ -13,6 +13,7 @@ mod discovery_models; mod discovery_requests; mod errors; pub(crate) mod fingerprint; +pub(crate) mod getters; mod known_input_columns; mod matching; mod model_entries; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs index ddcd356b04..344d3ab855 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs @@ -1,7 +1,8 @@ //! Assemble model migration decisions from inspected warehouse facts. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::column_objects::{lower, model, replace, text}; use crate::bindings::_helpers::planner_migrations::compatibility::check_migration_compatibility; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs index 9f6f6ac829..ff688d70b1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs @@ -1,7 +1,7 @@ //! Adapt immutable migration fingerprints without changing their persisted representation. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::fingerprints::query_hashes::compute_query_hash; use crate::bindings::_helpers::planner_migrations::column_objects::{replace, text}; use crate::bindings::_helpers::planner_migrations::constants::MIGRATION_MODEL_NAME_METADATA_KEY; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs index 6e3bb3b5ba..1ad521d07d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs @@ -1,7 +1,7 @@ //! Model migration orchestration over Python-owned live inspection. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_changes::renames::plan_reference_renames; use crate::bindings::_helpers::planner_migrations::column_objects::{config, replace}; use crate::bindings::_helpers::planner_migrations::discovery::discover_model_migrations; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs index c6c867664d..33e58dcdfe 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs @@ -1,7 +1,7 @@ //! Assemble new and resumed old-name view steps from recorded facts. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::planner_migrations::column_objects::{model, text}; use crate::bindings::_helpers::planner_migrations::constants::{PENDING_ARCHIVE, PENDING_VIEW}; use crate::bindings::_helpers::planner_migrations::models::OldNamePlanner; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs index 52b8e9dcca..840ef0b8ab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs @@ -1,7 +1,8 @@ //! Old-name planner object conversions and existing native helper calls. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::column_objects::{config, model}; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs index e7967e5971..16654086ab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs @@ -1,8 +1,9 @@ //! Old-name planning orchestration over existing live state inspection. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::models::{MigrationPhase, OldNameViewPlanning}; use crate::bindings::_helpers::planner_migrations::old_name_objects::recorded_view; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs index 73660a9ae4..e45a21a704 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs @@ -1,15 +1,16 @@ //! Diagnose literal references to compatibility-only old names. -use crate::bindings::_helpers::analysis::explicit_references::hard_coded_relation_remedy; -use crate::bindings::_helpers::analysis::explicit_references::old_name_reference_message; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use sqlbuild_host::entries::models::UserCodeHost; + +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_migrations::column_objects::{native, text}; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::references::explicit_references::hard_coded_relation_remedy; +use crate::bindings::_helpers::references::explicit_references::old_name_reference_message; use crate::bindings::_helpers::references::relations::match_project_relation; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyStringMethods, PyTuple}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs index 111e2ddea5..09fabbd24d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs @@ -1,8 +1,9 @@ //! Existing old-name planner models at the native decision boundary. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::old_name_objects::relation; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_boundary.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_boundary.rs index b3e1d78400..08121b79e8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_boundary.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_boundary.rs @@ -1,6 +1,6 @@ //! Assemble migration policy and redirected live cursor inspection requests. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_migrations::column_objects::native; use crate::bindings::_helpers::planner_migrations::models::MigrationPhase; use crate::bindings::_helpers::planner_phases::full_refresh::effectively_full_refreshed_model_names; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs index d6ccd21cd0..c6ba2f9d3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs @@ -1,7 +1,8 @@ //! Preserve adapter overrides when describing migration execution. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::column_objects::replace; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs index 7328e691be..8ae3f96ed6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs @@ -1,6 +1,6 @@ //! Resolve authored migration origins at the adapter and inspection boundaries. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::planner_migrations::constants::QUALIFIED_RELATION_MAX_PARTS; use crate::bindings::_helpers::planner_migrations::models::ModelMigrationRequest; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs index 877ada6de2..eb272f1aae 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs @@ -1,6 +1,6 @@ //! Adapt existing Python query shape models to pure migration proofs. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_migrations::errors::ProofError; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs index 5565ce3709..9fd64202eb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs @@ -1,6 +1,6 @@ //! Read-only warehouse evidence gathered once for all model migrations in one plan. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::fingerprints::storage_io::read_latest_fingerprints; use std::collections::{HashMap, HashSet}; @@ -14,7 +14,7 @@ use sqlbuild_core::constants::OLD_NAME_VIEW_TABLE_NAME; use sqlbuild_state::events::main::newest_fingerprint::newest_fingerprint; use sqlbuild_state::events::models::{EventRelation, FingerprintKey, FingerprintOrder}; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_migrations::constants::{ GET_COLUMNS_FOR_INSPECTION, LIST_RELATIONS_FOR_INSPECTION, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/buildability.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/buildability.rs index c4e0320e7f..7f5241fcb3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/buildability.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/buildability.rs @@ -1,6 +1,6 @@ //! Selected-scope buildability validation before change planning. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_identity::graph::build_execution_edge_origins; use crate::bindings::_helpers::planner_identity::graph::check_buildability; use crate::bindings::_helpers::planner_identity::graph::missing_upstream_message; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs index dae677b9a5..8ae9620301 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs @@ -1,7 +1,7 @@ //! Write-hash reconciliation and plan entry construction. +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::command_runtime::concurrency::resolve_configured_concurrency; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::planner_entries::contexts::default_microbatch_limit_action; use crate::bindings::_helpers::planner_entries::model_entries::plan_entries; use crate::bindings::_helpers::planner_entries::models::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs index 7fca1039bc..c29651a9ae 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs @@ -1,6 +1,6 @@ //! Per-model full-refresh resolution and full-rebuild refusals. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_phases::constants::FULL_REFRESH_DISABLED_REBUILD_CODE; use crate::bindings::_helpers::planner_phases::objects::{frozenset, planner_error, strings}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/getters.rs new file mode 100644 index 0000000000..a5ec1af29e --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/getters.rs @@ -0,0 +1,115 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::planner_phases::models::{ + PlannerIdentityContext, PlannerRuntime, PlannerScopeResolution, PlannerWarehouseState, +}; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_planner_identity_context, + }, + GetterEntry { + class: class_of::, + read: read_planner_runtime, + }, + GetterEntry { + class: class_of::, + read: read_planner_scope_resolution, + }, + GetterEntry { + class: class_of::, + read: read_planner_warehouse_state, + }, +]; + +fn read_planner_identity_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "version_identities" => (&this.version_identities).into_bound_py_any(py), + "stale_warning_identities" => (&this.stale_warning_identities).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_planner_runtime<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project" => (&this.project).into_bound_py_any(py), + "adapter" => (&this.adapter).into_bound_py_any(py), + "connection" => (&this.connection).into_bound_py_any(py), + "project_config" => (&this.project_config).into_bound_py_any(py), + "local_config" => (&this.local_config).into_bound_py_any(py), + "on_progress" => (&this.on_progress).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_planner_scope_resolution<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "selected_scope" => (&this.selected_scope).into_bound_py_any(py), + "stale_warning_scope" => (&this.stale_warning_scope).into_bound_py_any(py), + "inspection_scope" => (&this.inspection_scope).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_planner_warehouse_state<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "snapshot" => (&this.snapshot).into_bound_py_any(py), + "inspection_relations" => (&this.inspection_relations).into_bound_py_any(py), + "migration_entries" => (&this.migration_entries).into_bound_py_any(py), + "migration_warnings" => (&this.migration_warnings).into_bound_py_any(py), + "column_migration_entries" => (&this.column_migration_entries).into_bound_py_any(py), + "column_rename_hints" => (&this.column_rename_hints).into_bound_py_any(py), + "old_name_view_entries" => (&this.old_name_view_entries).into_bound_py_any(py), + "old_name_views" => (&this.old_name_views).into_bound_py_any(py), + "migration_fingerprints" => (&this.migration_fingerprints).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs index 53e8c181bd..a869e16d2a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs @@ -1,6 +1,6 @@ //! Expected version identities and stale-warning change detection. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_changes::detect::scope_model_changes; use crate::bindings::_helpers::planner_identity::identities::direct_model_version_identities; use crate::bindings::_helpers::planner_phases::contexts::class_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/mod.rs index 79bb897f9e..ec478e3ab3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod constants; pub(crate) mod contexts; pub(crate) mod execution_changes; pub(crate) mod full_refresh; +pub(crate) mod getters; pub(crate) mod identities; pub(crate) mod models; pub(crate) mod objects; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs index 8a25585108..cf6f809bba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs @@ -1,9 +1,10 @@ //! Boundary helpers shared by the native planner phases. -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keywords}; +use sqlbuild_host::entries::models::HostId; + +use crate::bindings::_helpers::boundary::python_calls::{call_with, keywords}; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::models::HostId; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs index 71e3e09c26..7259f08623 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs @@ -1,7 +1,7 @@ //! Plan output assembly: storage policies, warnings and direct-mode metadata. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_entries::models::PlanOutputInputs; use crate::bindings::_helpers::planner_entries::plan_output::plan_output_fields; use crate::bindings::_helpers::planner_identity::staleness::build_stale_out_of_selection_warnings; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs index ae5321a3ed..86d36cd3ee 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs @@ -1,9 +1,10 @@ //! Warehouse-aware time-travel retention and Snowflake table-type planning. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_phases::constants::{ BIGQUERY_ADAPTER, DECREASE_WARNING, DOWNGRADE_HISTORY_DAYS, PERMANENT_TABLE_TYPE, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/runtime.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/runtime.rs index 6259243ca5..66e9888874 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/runtime.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/runtime.rs @@ -5,8 +5,8 @@ use pyo3::prelude::{Bound, Py, PyAny, PyResult, Python}; use pyo3::pymethods; use pyo3::types::{PyDict, PyTuple}; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::build_command::support::utc_now; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_phases::models::{PlannerRuntime, PlannerWarehouseState}; #[pymethods] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/scopes.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/scopes.rs index 179955248f..3e6c586595 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/scopes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/scopes.rs @@ -1,7 +1,7 @@ //! Resolve the selected, stale-warning and inspection scopes of one plan. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::graph::algorithms::transitive_closure_many; use crate::bindings::_helpers::planner_phases::models::PlannerScopeResolution; use crate::bindings::_helpers::planner_phases::objects::object; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs index d201e7b24d..6982428912 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs @@ -1,7 +1,8 @@ //! Layouts of the planner, migration, cursor and fingerprint value records hosted natively. -use crate::bindings::_helpers::native_host::executor::ExecutorHost; -use crate::bindings::_helpers::record_behaviours::planner::forward_only_backfill; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::planner_records::defaults::forward_only_backfill; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::records::models::{EnumSpec, FieldDefault, FieldSpec, RecordSpec}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_records/defaults.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/defaults.rs new file mode 100644 index 0000000000..da81e05b9c --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/defaults.rs @@ -0,0 +1,17 @@ +//! Factories for planner record field defaults. + +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; +use pyo3::types::{PyDict, PyDictMethods}; + +use crate::bindings::_helpers::records::construct::{enum_member, new_record}; +use crate::bindings::_helpers::records::ids::RecordId; + +/// `ModelPlanEntry.backfill`'s default: a forward-only backfill. +pub(crate) fn forward_only_backfill(py: Python<'_>) -> PyResult> { + let keywords: Bound<'_, PyDict> = PyDict::new(py); + keywords.set_item( + "action", + enum_member(py, RecordId::BackfillAction, "FORWARD_ONLY")?, + )?; + new_record(py, RecordId::BackfillResult, (), Some(&keywords)) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_records/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/mod.rs index 61d449b063..4f7b302924 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_records/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_records/mod.rs @@ -1 +1,2 @@ pub(crate) mod constants; +pub(crate) mod defaults; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs index b340482346..0e69eb5a47 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs @@ -1,10 +1,11 @@ //! Snapshot conversion and cursor window policy boundary. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::cursor::conversion::{CursorSession, algebra_error}; use crate::bindings::_helpers::cursor::scalars::try_parse; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_resolution::maximum_safety::apply_maximum_start_policy; use crate::bindings::_helpers::planner_resolution::values::string; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs index 7108b75d93..5adc03600f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs @@ -1,14 +1,14 @@ //! Model cursor orchestration over live warehouse snapshot facts. -use crate::bindings::_helpers::analysis::model_reads; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; + +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_attachment::cursor_roles::resolve_cursor_input_roles; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::model_config::config_values::{ config_cursor_bound, config_str as authored_config_str, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::display::resolve_bounded_cursor_override; use crate::bindings::_helpers::planner_entries::models::ModelPlanContext; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs index 6757d9996c..47acfc8e63 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs @@ -1,7 +1,7 @@ //! Selected-model inspection and untyped override conversion. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_resolution::values::{method, string}; use crate::bindings::_helpers::records::construct::enum_from_value; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs index 8f5ac2ff0f..a33e740b2c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs @@ -1,6 +1,6 @@ //! Model-level cursor safety policy overrides over project configuration. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs index ce480daf28..d1dafb1736 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs @@ -1,16 +1,15 @@ //! Plan-entry cursor windows: overrides, planner-owned bounds and microbatch ranges. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use sqlbuild_host::entries::models::ExecutorHost; + +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::{parse_value, sentinel_to_token}; use crate::bindings::_helpers::cursor::values::{local_date_time, replaced}; use crate::bindings::_helpers::model_config::config_values::config_cursor_bound; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::display::resolve_bounded_cursor_override; use crate::bindings::_helpers::planner_entries::models::ModelPlanContext; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs index 2222e558a9..3f99802e58 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs @@ -1,6 +1,6 @@ //! Shared safety horizon conversion and Python evidence construction. -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::planner_resolution::cursor_bounds::duration; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs index 3d2061bdd9..19d2d70f89 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs @@ -1,6 +1,6 @@ //! Empty-window decisions and snapshot grain conversion. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::parse_value; use crate::bindings::_helpers::planner_resolution::values::string; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/future_safety.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/future_safety.rs index 56c1be8f6d..33e04c438a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/future_safety.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/future_safety.rs @@ -1,6 +1,6 @@ //! Future cursor safety evidence and exception boundary. -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::planner_resolution::cursor_safety::{ horizon, replace, safety_duration, safety_error, timestamp_bound, utc_clock, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs index 4289e3a46e..c5d6cd8c3e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs @@ -1,7 +1,7 @@ //! Maximum automatic-start recovery and evidence boundary. -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::render_value; use crate::bindings::_helpers::planner_phases::objects::object; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs index 1214afb4d3..ce6f4cb9c4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs @@ -1,10 +1,10 @@ //! Model, function and SQL-hook orchestration through adapter-owned rendering. -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::attachments::cursor_intrinsics::resolve_cursor_intrinsics; use crate::bindings::_helpers::attachments::reference_markers::assert_no_unresolved_sql_markers; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::compile_attachment::cursor_roles::resolve_cursor_input_roles; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_entries::models::ModelPlanContext; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs index d2cfdbe819..a0e533808b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs @@ -1,7 +1,8 @@ //! Reference lookup and adapter callbacks for planner SQL. -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_resolution::models::CursorFiltering; use crate::bindings::_helpers::planner_resolution::values::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs index aa2bbb39de..44e0752476 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs @@ -1,6 +1,6 @@ //! Source contract validation and adapter-controlled projection rendering. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_resolution::models::CursorFiltering; use crate::bindings::_helpers::planner_resolution::values::{ cursor_wrap, filtering_of, method, string, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs index 8c085ec34e..c60c97eb66 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs @@ -1,6 +1,6 @@ //! Boundary calls shared by reference and source resolution. -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::planner_resolution::models::CursorFiltering; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs index dc13c15357..6a34c76ea4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs @@ -1,6 +1,6 @@ //! Scenario artifact dataclasses and adapter identifier callbacks. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_scenario::constants::{ SCENARIO_PLAN_HASH_COLLISION, SCENARIO_PLAN_INVALID_HASH_PREFIX, SCENARIO_PLAN_RELATION_COLLISION, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs index a7344e0805..39b573ed81 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs @@ -1,8 +1,8 @@ //! Assemble CLI scenario plans while retaining adapter and executor boundaries. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_scenario::artifacts::build_scenario_hash_index; use crate::bindings::_helpers::planner_scenario::artifacts::build_scenario_relation_map; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs index 5febab502a..e506f21877 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs @@ -1,8 +1,7 @@ //! Existing seed and function plan dataclass construction. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compiled_project::loop_classes::by_attribute; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::planner_identity::metadata::build_compiled_function_fingerprint_sql; use crate::bindings::_helpers::planner_resolution::orchestration::resolve_function_sql; use crate::bindings::_helpers::planner_scenario::constants::SCENARIO_PLAN_UNKNOWN_SEED; @@ -11,6 +10,7 @@ use crate::bindings::_helpers::planner_scenario::{ }; use crate::bindings::_helpers::planner_strategy::model_entries::extract_seed_columns; use crate::bindings::_helpers::records::construct::new_record_with; +use crate::bindings::_helpers::records::fields::by_attribute; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs index 6405d5f179..8f58f43a4b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs @@ -1,10 +1,9 @@ //! Assemble scenario execution plans through existing planner and adapter APIs. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compiled_project::loop_classes::by_attribute; -use crate::bindings::_helpers::compiled_project::records::compiled_model_record; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; +use crate::bindings::_helpers::compiled_views::records::compiled_model_record; use crate::bindings::_helpers::discovery::constants::{ SCENARIO_EXPECTED_COLUMNS_ALL, SCENARIO_EXPECTED_COLUMNS_KEY, }; @@ -28,6 +27,7 @@ use crate::bindings::_helpers::planner_scenario::{ use crate::bindings::_helpers::planner_strategy::fixture_completion::complete_fixtures as complete_relation_fixtures; use crate::bindings::_helpers::planner_strategy::fixture_context::planning_context; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; +use crate::bindings::_helpers::records::fields::by_attribute; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced_keywords; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs index 6ab30be6f1..d4342bc52e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs @@ -1,6 +1,6 @@ //! Materialize fixture SQL plans while preserving adapter and completion boundaries. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_scenario::constants::SCENARIO_PLAN_MISSING_FIXTURE_SQL; use crate::bindings::_helpers::planner_scenario::helper_scope::scenario_helper_scope; use crate::bindings::_helpers::planner_scenario::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/graph.rs index 7adf670153..525142eac8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/graph.rs @@ -1,6 +1,6 @@ //! Convert project views into pure scenario dependency facts. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::graph::keys::{KeyCache, native_key}; use crate::bindings::_helpers::planner_scenario::constants::SCENARIO_PLAN_GRAPH_VALIDATION; use crate::bindings::_helpers::planner_scenario::values::string; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/relations.rs index 2e75f9a3f8..42d92879bf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/relations.rs @@ -1,6 +1,6 @@ //! Build scenario relation locations through adapter qualification callbacks. -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::planner_scenario::constants::{REF, SOURCE}; use crate::bindings::_helpers::planner_scenario::constants::{ SCENARIO_PLAN_INTERNAL, SCENARIO_PLAN_MISSING_RELATION_TARGET, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs index 333ab54185..50bc28d3fa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs @@ -1,6 +1,6 @@ //! Resolve scenario SQL through the shared native scanner and adapter callbacks. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_scenario::constants::{ SCENARIO_PLAN_MISSING_RELATION_TARGET, SCENARIO_PLAN_UNRESOLVED_RELATION_MARKER, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs index 3c431e35cf..725619a262 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs @@ -1,6 +1,6 @@ //! Existing Python model constructors and scenario diagnostics. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; use pyo3::prelude::{Bound, PyAny, PyErr, PyResult, Python}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs index 5d42b34d18..30ae9b2874 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs @@ -1,6 +1,6 @@ //! Planner scope assembly using native graph and selector operations. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::graph::project_graph::NativeProjectGraph; use crate::bindings::_helpers::graph::views::lineage_graph_names; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs index 5aca0fa350..eb354739b7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs @@ -1,7 +1,8 @@ //! Existing source and load plan models materialised at the Python boundary. +use sqlbuild_host::entries::models::ExecutorHost; + use crate::bindings::_helpers::graph::algorithms::closure; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_scope::loaders::intermediate_map; use crate::bindings::_helpers::records::construct::new_record; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs index 3b706511a8..9dae06b6c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs @@ -12,7 +12,7 @@ use sqlbuild_analysis::planner_selection::models::{ ModelSelectorNames, SelectableModel, SelectorExpansion, }; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::planner_selection::carrier::Carrier; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/selectors.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/selectors.rs index efe7476d2b..15a0988d55 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/selectors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/selectors.rs @@ -14,7 +14,7 @@ use sqlbuild_analysis::graph::main::resolve_selectors::resolve_selectors; use sqlbuild_analysis::graph::models::{ParsedSelector, ProjectGraph}; use sqlbuild_analysis::planner_selection::main::unit_test_selector_rejection::unit_test_selector_rejection; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::graph::algorithms::closure; use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::graph::project_graph::{CompiledProjectGraph, NativeProjectGraph}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs index 5a6cd73896..189e4be386 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs @@ -2,7 +2,7 @@ use crate::bindings::_helpers::attachments::reference_markers::assert_no_unresolved_sql_markers; use crate::bindings::_helpers::auditing::render::render_audit_sql; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::graph::views::project_lineage_views; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_strategy::audits::{ @@ -16,7 +16,7 @@ use pyo3::types::{ }; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::planner_strategy::constants::{ AUDIT_TYPES_MODULE, COMPILE_TYPES_MODULE, MODEL_ATTACHMENT, SOURCE_ATTACHMENT, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs index b862f48152..c5aa2da64b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs @@ -9,7 +9,7 @@ use sqlbuild_analysis::planner_strategy::main::effective_run_scope::effective_ru use sqlbuild_analysis::planner_strategy::main::singular_attachment::singular_attachment; use sqlbuild_analysis::planner_strategy::models::{AuditAttachmentKind, AuditRunScope}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::graph::algorithms::closure; use crate::bindings::_helpers::planner_strategy::values::{input_error, optional_string, text}; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record_with}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs index dfb6cfb45b..c6b56458ed 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs @@ -7,9 +7,9 @@ use pyo3::types::{PyBool, PyDict, PyFrozenSet, PyString, PyTuple}; use sqlbuild_analysis::planner_strategy::main::cursor_input_column::cursor_input_column_failure; use sqlbuild_analysis::planner_strategy::models::{CursorInputColumnCheck, CursorInputColumnOwner}; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::compile_attachment::cursor_roles::resolve_cursor_input_roles; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::scalars::parse_value; use crate::bindings::_helpers::model_config::config_values::{config_cursor_bound, config_str}; use crate::bindings::_helpers::planner_identity::metadata::or_empty; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs index ab4b6e400a..f0a28a6bc5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs @@ -8,11 +8,9 @@ use sqlbuild_analysis::planner_strategy::errors::TypeParseFailure; use sqlbuild_analysis::planner_strategy::main::classify_cursor_sql_type::classify_cursor_sql_type as classify; use sqlbuild_analysis::planner_strategy::main::cursor_type_warning::cursor_type_warning; use sqlbuild_analysis::planner_strategy::models::{CursorType, CursorTypeCheck}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_changes::results::planner_enum; use crate::bindings::_helpers::planner_strategy::values::{optional_string, plan_warning, text}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_context.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_context.rs index f291797db3..7f9fb73a19 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_context.rs @@ -11,8 +11,8 @@ use sqlbuild_analysis::planner_fixtures::main::fixture_schema::fixture_schema; use sqlbuild_analysis::planner_fixtures::models::FixtureColumn; use sqlbuild_core::text::main::python_casefold::python_casefold; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::analysis_session::fixture_inferences::FixtureColumnInferences; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_strategy::constants::{ MODEL_REFERENCE_KIND, SEED_REFERENCE_KIND, SOURCE_REFERENCE_KIND, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs index 7034907f5e..1ebfb3713c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs @@ -5,8 +5,8 @@ use sqlbuild_analysis::planner_fixtures::main::merge_metadata::merge_metadata; use sqlbuild_analysis::planner_fixtures::models::FixtureColumn; use sqlbuild_core::text::main::python_casefold::python_casefold; -use crate::bindings::_helpers::analysis::model_reads::{inferred_rows, star_flags}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::InferredRow; +use crate::bindings::_helpers::compiled_views::compiled_model_view::InferredRow; +use crate::bindings::_helpers::compiled_views::model_reads::{inferred_rows, star_flags}; use crate::bindings::_helpers::planner_strategy::fixture_values::columns; use crate::bindings::_helpers::planner_strategy::models::FixtureRelation; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs index bd33f206d1..20f5bdbd1f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs @@ -13,11 +13,11 @@ use sqlbuild_analysis::required_columns::models::ColumnRead; use sqlbuild_core::panics::main::catch_compiler_panic::catch_compiler_panic; use std::collections::{HashMap, HashSet}; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::analysis::model_reads::{ +use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::compiled_views::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads::{ LineageFactRow, lineage_facts, proven_inputs, star_flags, }; -use crate::bindings::_helpers::boundary::panics::value_error; use crate::bindings::_helpers::planner_strategy::constants::HIGH_CONFIDENCE; use crate::bindings::_helpers::planner_strategy::fixture_context::work_counts; use crate::bindings::_helpers::planner_strategy::models::RelationFixturePlanningContext; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_types.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_types.rs index 1fe436cfdf..17109ed3ce 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_types.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_types.rs @@ -9,7 +9,7 @@ use sqlbuild_analysis::planner_fixtures::models::{ use sqlbuild_core::text::main::python_casefold::python_casefold; -use crate::bindings::_helpers::analysis::model_reads::{LineageFactRow, lineage_facts}; +use crate::bindings::_helpers::compiled_views::model_reads::{LineageFactRow, lineage_facts}; use crate::bindings::_helpers::planner_strategy::constants::{ DIRECT_TRANSFORM, MODEL_REFERENCE_KIND, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs index 6d4752166b..9976607ea7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs @@ -12,8 +12,8 @@ use sqlbuild_analysis::planner_strategy::main::lineage_reference::lineage_refere use sqlbuild_analysis::planner_strategy::models::{ProducerFacts, ReferenceIdentity}; use sqlbuild_analysis::planner_strategy::types::ReferenceGraph; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::compile_attachment::cursor_roles::resolve_cursor_input_roles; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::model_config::config_values::config_str; use crate::bindings::_helpers::planner_strategy::microbatches::{ CAP_ACTIONS, microbatch_limit_config, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs index 38ebd8a91b..2bdf521c3e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs @@ -12,7 +12,7 @@ use sqlbuild_core::plan_display::errors::UnknownCursorGrain; use sqlbuild_core::plan_display::main::effective_timestamp_grain::effective_timestamp_grain; use sqlbuild_core::plan_display::models::TimestampGrainFacts; -use crate::bindings::_helpers::compiled_project::records::replace; +use crate::bindings::_helpers::compiled_views::records::replace; use crate::bindings::_helpers::plan_output::display::resolve_effective_microbatch_batch_size; use crate::bindings::_helpers::planner_strategy::microbatches::{ CAP_ACTIONS, capped_microbatch_bounds, count_microbatches, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs index a775cca9c9..41409e94d4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs @@ -10,19 +10,18 @@ use sqlbuild_analysis::planner_strategy::main::microbatch_lookback::microbatch_l use sqlbuild_analysis::planner_strategy::main::physical_layout_warning::physical_layout_warning; use sqlbuild_analysis::planner_strategy::main::table_type_ddl::table_type_ddl; use sqlbuild_analysis::planner_strategy::models::{CursorTypeCheck, LookbackConfig}; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; use sqlbuild_model_config::execution_limits::constants::MODEL_MAX_DURATION_KEY; use sqlbuild_model_config::execution_limits::main::parse_execution_limit::parse_execution_limit; use sqlbuild_model_config::execution_limits::models::ExecutionLimit; use sqlbuild_model_config::model_validation::constants::PHYSICAL_STORAGE_KEYS; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::model_config::config_values::{ config_bool, config_cursor_bound, config_int, config_str, config_string_tuple, }; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_strategy::constants::{ CUSTOM_MATERIALIZATION, DDL_SEPARATOR, ENFORCED_CONTRACT, MICROBATCH_MODE, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/strategy.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/strategy.rs index da08459f8e..9980ea16dd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/strategy.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/strategy.rs @@ -1,6 +1,6 @@ //! Per-model plan actions, schema actions and plan warnings. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_changes::results::native_enum; use crate::bindings::_helpers::records::construct::new_record_with; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; @@ -15,7 +15,7 @@ use sqlbuild_analysis::planner_strategy::models::{ ModelStrategy, PlanAction, PlanReason, SchemaActionKind, WarningInputs, }; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_changes::results::planner_enum; use crate::bindings::_helpers::planner_strategy::values::{ change_facts, config_value, finding_rows, input_error, materialization_value, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs index 562eb830b0..ecdaeae4d5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs @@ -1,7 +1,7 @@ //! Python modules and fixed names of warehouse inspection for planning. -use crate::bindings::_helpers::native_host::adapter::AdapterHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use sqlbuild_host::entries::models::{AdapterHost, ExecutorHost}; + use crate::bindings::_helpers::records::ids::RecordId; pub(crate) const RELATIONS_MAIN_LIST: AdapterHost = AdapterHost::ListRelationsForInspection; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs index b5570f2f18..d4eb1f0050 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs @@ -1,8 +1,8 @@ //! Cursor MIN/MAX inspection of selected incremental models and their watermark inputs. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::compile_attachment::cursor_roles::resolve_cursor_input_roles; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::intervals::partition; use crate::bindings::_helpers::cursor::scalars; use crate::bindings::_helpers::cursor::scalars::compare_values; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs index 16afa8f495..45affa644d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs @@ -1,8 +1,6 @@ //! Migration fingerprints computed at most once per model definition and reused across runs. -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, imported, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, imported}; use crate::bindings::_helpers::planner_changes::metadata::without_declared_columns_hash; use crate::bindings::_helpers::planner_migrations::fingerprint::fingerprint; use crate::bindings::_helpers::planner_migrations::fingerprint::migration_fingerprint_ref_names; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs index c5005d1172..cd5d4baacd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs @@ -1,8 +1,8 @@ //! Complete missing source metadata in bounded, database-grouped batches. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_phases::objects::{text, tuple}; use crate::bindings::_helpers::planner_warehouse::constants::ACTIVE_CATALOG; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs index c4e1e72bf1..ee0642bf54 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs @@ -1,9 +1,9 @@ //! Gather a frozen point-in-time warehouse snapshot for planning. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::fingerprints::latest_rows::select_latest_fingerprints; use crate::bindings::_helpers::fingerprints::storage_io::read_latest_fingerprints; use crate::bindings::_helpers::graph::algorithms::transitive_closure_many; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs index 05b91ac2b3..7c63930fa3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs @@ -1,6 +1,6 @@ //! Warehouse source relation listing and column gathering for planning. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_phases::objects::{frozenset, text, tuple}; use crate::bindings::_helpers::planner_warehouse::constants::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs index 149c692a8f..1ad188cc4c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs @@ -1,11 +1,12 @@ //! Source read deferral for managed source loaders. -use crate::bindings::_helpers::analysis::model_reads; +use sqlbuild_host::entries::models::UserCodeHost; + use crate::bindings::_helpers::authored_values::project_vars::render_project_var_text; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_phases::objects::{ optional_text, planner_error, replace, text, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs index 1761c99d29..9d51a7f735 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs @@ -1,8 +1,8 @@ //! Direct planner source freshness observation and the warnings for unknown freshness. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, within}; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, within}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::freshness::planning::{ build_direct_source_freshness_planning_result, build_direct_source_freshness_propagation_result, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs index b126d465d0..aacf69c846 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs @@ -1,7 +1,7 @@ //! Selected-scope validation that external source tables exist in the warehouse. -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::discovery::locations::yaml_entry_line; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_phases::objects::{planner_error, tuple}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs index cbc12dd0e4..cb21ee5eda 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs @@ -1,6 +1,6 @@ //! Validate reliable watermark column contracts before warehouse inspection. -use crate::bindings::_helpers::analysis::model_reads; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_phases::objects::{config_str, planner_error, text}; use crate::bindings::_helpers::planner_strategy::cursor_types::classify_cursor_sql_type; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs index 7cdd6a24f4..db2e066a99 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs @@ -13,7 +13,7 @@ use sqlbuild_core::cli_text::main::resolve_name_column_width::resolve_name_colum use sqlbuild_core::cli_text::main::split_count_header::split_count_header; use sqlbuild_core::cli_text::models::{AlignedRow, CliStyle, CompletionState, SummaryCount}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; const ALIGNED_OPTIONS: (&[&str], &[&str]) = ( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/getters.rs new file mode 100644 index 0000000000..3722bb98f6 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/getters.rs @@ -0,0 +1,31 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_python_cli_style, +}]; + +fn read_python_cli_style<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "use_color" => (&this.use_color).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/mod.rs index a3c118adf5..352c9c7d9e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod document; pub(crate) mod functions; +pub(crate) mod getters; pub(crate) mod registration; pub(crate) mod style; pub(crate) mod terminal; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs index f308830cb4..e905651bf2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs @@ -8,11 +8,11 @@ use pyo3::types::{PyDict, PyDictMethods, PyString}; use sqlbuild_analysis::assembly::analysis_session::types::{Pairs, Shapes}; use sqlbuild_analysis::compiled_project::models::SchemaColumnFact; -use crate::bindings::_helpers::compiled_project::model_input_view::{ +use crate::bindings::_helpers::compiled_project::schema_facts::python_column_facts; +use crate::bindings::_helpers::compiled_views::model_input_view::{ attached_columns, attached_schema, }; -use crate::bindings::_helpers::compiled_project::schema_facts::python_column_facts; -use crate::bindings::_helpers::compiled_project::source_views::{AttachedSource, read_source_view}; +use crate::bindings::_helpers::compiled_views::source_views::{AttachedSource, read_source_view}; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::{enum_member_value, field as native_field}; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/getters.rs new file mode 100644 index 0000000000..b4c80b4747 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/getters.rs @@ -0,0 +1,109 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::project_assembly::models::{ + NativeModelFacts, NativeProjectFacts, NativeProjectResources, NativeResourceFailure, +}; +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_native_model_facts, + }, + GetterEntry { + class: class_of::, + read: read_native_project_facts, + }, + GetterEntry { + class: class_of::, + read: read_native_project_resources, + }, + GetterEntry { + class: class_of::, + read: read_native_resource_failure, + }, +]; + +fn read_native_model_facts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "deps" => (&this.deps).into_bound_py_any(py), + "dynamic_contract" => (&this.dynamic_contract).into_bound_py_any(py), + "syntax_valid" => (&this.syntax_valid).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_project_facts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "models" => (&this.models).into_bound_py_any(py), + "resources" => (&this.resources).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_project_resources<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_deps" => (&this.model_deps).into_bound_py_any(py), + "model_syntax_valid" => (&this.model_syntax_valid).into_bound_py_any(py), + "source_namespaces" => (&this.source_namespaces).into_bound_py_any(py), + "seed_namespaces" => (&this.seed_namespaces).into_bound_py_any(py), + "function_deps" => (&this.function_deps).into_bound_py_any(py), + "audit_scope_deps" => (&this.audit_scope_deps).into_bound_py_any(py), + "failure" => (&this.failure).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_resource_failure<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "slot" => (&this.slot).into_bound_py_any(py), + "index" => (&this.index).into_bound_py_any(py), + "error" => (&this.error).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/mod.rs index f672104c84..8873e278f1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/mod.rs @@ -1,4 +1,5 @@ pub(crate) mod declared_relations; +pub(crate) mod getters; pub(crate) mod models; pub(crate) mod native_resources; pub(crate) mod registration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs index 0fceed1307..3619725387 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs @@ -18,9 +18,9 @@ use sqlbuild_model_config::templates::models::Scalar; use crate::bindings::_helpers::authored_values::project_vars::project_var_text; use crate::bindings::_helpers::boundary::panics::{NativeCompilerError, compiler_error}; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; -use crate::bindings::_helpers::compiled_project::model_input_view::input_reference_rows; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::model_input_view::input_reference_rows; use crate::bindings::_helpers::model_config::template_data::record_reads; use crate::bindings::_helpers::project_assembly::models::{ NativeProjectResources, NativeResourceFailure, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/resources.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/resources.rs index 1359df28d5..515ad9806d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/resources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/resources.rs @@ -13,7 +13,7 @@ use sqlbuild_core::panics::main::catch_compiler_panic::catch_compiler_panic; use sqlbuild_core::panics::main::native_failure::native_failure; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::model_loop_prepass::pooled; +use crate::bindings::_helpers::input_loops::model_loop_prepass::pooled; use crate::bindings::types::CompilerDetach; const SYNTAX_CHECK_CONTEXT: &str = "native SQL syntax check"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs index cd5f88fbe5..7d87753fd1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs @@ -6,7 +6,7 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_sqltext::compiler::main::placeholder_defaults::placeholder_defaults; use crate::bindings::_helpers::attachments::cursor_intrinsics::analysis_cursor_sql; -use crate::bindings::_helpers::compiled_project::model_input_view::attached_schema; +use crate::bindings::_helpers::compiled_views::model_input_view::attached_schema; use crate::bindings::_helpers::project_assembly::syntax_validation::hook_sql_statements; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs b/crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs index 49dfea7d02..fd72197825 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs @@ -6,9 +6,9 @@ use pyo3::types::{PyBool, PyDict}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::query_command::main::render_dag_summary::render_dag_summary; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::project::build_project_graph; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::dag_artifact::artifact::build_dag_json; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs b/crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs index 9973b9619a..fbbeb3b012 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs @@ -2,10 +2,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::discovery::configuration::discover_connection_configuration; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs index 4d3f947a2e..a77de9d6a1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs @@ -12,11 +12,11 @@ use sqlbuild_core::query_command::main::render_query_json::render_query_json; use sqlbuild_core::query_command::main::render_query_long::render_query_long; use sqlbuild_core::query_command::main::render_query_table::render_query_table; use sqlbuild_core::query_command::models::QueryDisplay; +use sqlbuild_host::entries::models::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::connections::connection_failure; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::query_command::project::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs index 5bde968c4c..65f0682dc9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs @@ -9,7 +9,7 @@ use pyo3::types::{ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; const NULL_TEXT: &str = "NULL"; const FIXED_POINT_FORMAT: &str = "f"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/clickhouse_calls.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/clickhouse_calls.rs index 4918ddf991..a8a190f140 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/clickhouse_calls.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/clickhouse_calls.rs @@ -3,14 +3,14 @@ use pyo3::prelude::{Bound, FromPyObject, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBytes, PyDict, PyDictMethods, PyInt, PyList, PyString}; use sqlbuild_config::models::ConfigValue; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_recall::clickhouse::main::error_kind::error_kind; use sqlbuild_recall::records::models::RecallValue; use sqlbuild_recall::store::errors::{StoreError, StoreErrorKind}; use sqlbuild_recall::store::models::QueryResult; use crate::bindings::_helpers::boundary::config_values::config_value_to_python; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_threads::constants::OUTPUT_SUPPRESSED_ATTRIBUTE; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/command.rs index e21ed8aaac..bd62a458f4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/command.rs @@ -17,7 +17,7 @@ use sqlbuild_recall::store::main::read_output_transcript::read_output_transcript use sqlbuild_recall::store::main::resolve_invocation::resolve_invocation; use sqlbuild_recall::store::models::{OpenMode, SqliteStore}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::query_command::query::run_query_command; use crate::bindings::_helpers::recall::clickhouse_store::{ClickHouseLocation, ClickHouseReader}; use crate::bindings::_helpers::recall::console::{write_stderr, write_stdout_bytes}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/events.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/events.rs index fb3cfd60fb..dcd7115d59 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/events.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/events.rs @@ -6,9 +6,9 @@ use pyo3::types::{ PyStringMethods, PyTuple, }; use serde_json::{Map, Number, Value}; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::discovery::snapshot::escaped; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::recall::constants::{ EVENT_OPTIONAL_TEXT_FIELDS, EVENT_TEXT_FIELDS, INVOCATION_METADATA_SCHEMA_VERSION, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/registration.rs index fc10453d94..b703553e5f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/registration.rs @@ -2,10 +2,12 @@ use pyo3::prelude::{Bound, PyModule, PyModuleMethods, PyResult}; +use crate::bindings::_helpers::discovery::imported_providers::install_recall_writer; use crate::bindings::_helpers::recall::sinks::RecallLifecycleSink; use crate::bindings::_helpers::recall::writer::RecallWriter; pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_class::()?; + install_recall_writer(&module.py().get_type::()); module.add_class::() } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/replacements.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/replacements.rs index 275143aa8a..01ec368784 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/replacements.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/replacements.rs @@ -10,18 +10,17 @@ use sqlbuild_core::command_output::constants::RECALL_REPLACEMENT_SCHEMA_VERSION; use sqlbuild_core::command_output::main::ansi_free_text::ansi_free_text; use sqlbuild_core::event_export::main::route_lifecycle_event::route_lifecycle_event; use sqlbuild_core::event_export::models::{ExporterCounts, ExporterFilter}; +use sqlbuild_host::entries::models::{ExecutorHost, UserCodeHost}; use sqlbuild_recall::records::models::{OutputChunk, OutputStream}; use sqlbuild_recall::writer::models::{ DeliveryStream, RecallSession, ReplacedEvents, ReplacedOutput, }; use sqlbuild_recall::writer::types::{OutputReplacement, PendingLifecycleEvent}; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::event_exporting::models::BoundEventExporter; use crate::bindings::_helpers::event_exporting::values::export_policy; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::native_threads::constants::OUTPUT_SUPPRESSED_ATTRIBUTE; use crate::bindings::_helpers::output_capture::records::invocation_context; use crate::bindings::_helpers::recall::constants::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/session.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/session.rs index 013617a07d..fa67fe81fa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/session.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/session.rs @@ -8,6 +8,7 @@ use std::time::{Duration, Instant, SystemTime}; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use sqlbuild_cli::dispatch::main::closing_status::closing_status; use sqlbuild_cli::dispatch::models::CommandFacts; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_recall::records::main::format_timestamp::format_timestamp; use sqlbuild_recall::records::main::sha256_hex::sha256_hex; use sqlbuild_recall::records::models::{InvocationContext, OutputStream, RowEnvelope}; @@ -25,7 +26,6 @@ use sqlbuild_recall::writer::models::{ DeliverySummary, RecallSession, SessionConfig, SessionStore, SetupOutcome, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::output_capture::records::invocation_context; use crate::bindings::_helpers::recall::clickhouse_store::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/sinks.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/sinks.rs index 84e62531ba..21d3360b94 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/sinks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/sinks.rs @@ -6,10 +6,10 @@ use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyclass, pymethods}; use pyo3::types::PyString; use serde_json::{Map, Value}; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_recall::records::main::parse_event::parse_event; use sqlbuild_recall::writer::models::RecallSession; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::recall::events::{escaped_text, event_object}; use crate::bindings::_helpers::recall::replacements::RecallReplacements; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/recall/writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/recall/writer.rs index 484f24cd82..58636e88f8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/recall/writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/recall/writer.rs @@ -7,8 +7,8 @@ use pyo3::exceptions::{PyTypeError, PyValueError}; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyclass, pymethods}; use pyo3::types::{PyBytes, PyBytesMethods}; use serde_json::{Map, Value}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::recall::sinks::lifecycle_event_object; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs index c3ee9d27eb..3458911fd3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs @@ -4,11 +4,11 @@ use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyTuple}; +use crate::bindings::_helpers::compiled_views::relation_keys::entry_relation_key_row; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::rules::relation_keys::entry_relation_key_row; /// `CompilerDiagnostic` positions. const DIAGNOSTIC_PHASE_FIELD: usize = 0; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/constants.rs index cfc3cf2d89..6448a8f0a1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/constants.rs @@ -1,5 +1,9 @@ //! Native behaviour of the hosted shapes: computed attributes, methods, ordering and validation. +use crate::bindings::_helpers::freshness::observation::normalize_observation; +use crate::bindings::_helpers::lineage::lineage_facts::{ + facts_eq, facts_getitem, facts_iter, facts_len, facts_projected, facts_resource_name, +}; use crate::bindings::_helpers::record_behaviours::auditing::{ finish_measurement_contract, finish_threshold_bound, finish_thresholds, }; @@ -34,9 +38,6 @@ use crate::bindings::_helpers::record_behaviours::freshness::{ use crate::bindings::_helpers::record_behaviours::lexical::{ finish_lexical_syntax, lexical_cache_key, lexical_native_mapping, lexical_reads_differently, }; -use crate::bindings::_helpers::record_behaviours::lineage_facts::{ - facts_eq, facts_getitem, facts_iter, facts_len, facts_projected, facts_resource_name, -}; use crate::bindings::_helpers::record_behaviours::macros::{ context_render_constant, context_render_enum_member, macro_injects_context, project_lineage_graph, @@ -71,6 +72,7 @@ use crate::bindings::_helpers::record_behaviours::scopes::{ use crate::bindings::_helpers::record_behaviours::values::{ finish_fingerprint_set, logical_type_display_name, sql_value_kind, }; +use crate::bindings::_helpers::records::models::RecordBehaviours; use crate::bindings::_helpers::records::types::{ClassMethod, ClassProperty, RecordFinish}; /// Compiler records whose bound values are normalized or validated natively. @@ -342,3 +344,16 @@ pub(crate) const BEHAVIOUR_ORDERED: &[&str] = &[ "OwnershipRoot", "ProjectPath", ]; + +/// Every record behaviour, installed into `records::behaviours` at registration. +pub(crate) const RECORD_BEHAVIOURS: RecordBehaviours = RecordBehaviours { + finishers: &[ + &[("SourceFreshnessObservation", normalize_observation)], + BEHAVIOUR_FINISHERS, + ], + properties: &[BEHAVIOUR_PROPERTIES], + cached_properties: &[BEHAVIOUR_CACHED_PROPERTIES], + methods: &[BEHAVIOUR_METHODS], + ordered: &[BEHAVIOUR_ORDERED], + sequences: &[BEHAVIOUR_SEQUENCES], +}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs index e98819a728..a0a50ec0fc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs @@ -2,10 +2,10 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyString, PyTuple}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::scalars::parse_value; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs index 5bba071938..21e674caec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs @@ -3,7 +3,7 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; -use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; +use crate::bindings::_helpers::boundary::call_arguments::call_argument; use crate::bindings::_helpers::records::fields::field as native_field; const HELP_FIELD: &str = "help"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs index a2fe347ae6..7e767df23b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs @@ -4,8 +4,8 @@ use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyList, PyTuple, PyTupleMethods}; +use crate::bindings::_helpers::boundary::call_arguments::call_argument; use crate::bindings::_helpers::graph::project_graph::{ResourceRow, project_graph}; -use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; use crate::bindings::_helpers::record_behaviours::compiled::compile_input_error; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::declaration_values::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs index 019a336fb0..f1c0f3853f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs @@ -9,7 +9,7 @@ use sqlbuild_core::migration_values::main::migration_decision_traits::migration_ use sqlbuild_core::migration_values::main::plan_label::plan_label; use sqlbuild_core::migration_values::models::{ColumnDecisionTraits, DecisionTraits}; -use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; +use crate::bindings::_helpers::boundary::call_arguments::call_argument; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/mod.rs index 76a8bf272e..e3bc530352 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/mod.rs @@ -1,5 +1,4 @@ pub(crate) mod auditing; -pub(crate) mod call_arguments; pub(crate) mod compiled; pub(crate) mod config; pub(crate) mod constants; @@ -9,7 +8,6 @@ pub(crate) mod durations; pub(crate) mod error_inits; pub(crate) mod freshness; pub(crate) mod lexical; -pub(crate) mod lineage_facts; pub(crate) mod macros; pub(crate) mod migrations; pub(crate) mod planner; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs index 423bfd3e90..22b7ace820 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs @@ -9,13 +9,11 @@ use sqlbuild_core::migration_values::main::model_migration_blocks_build::model_m use sqlbuild_core::migration_values::main::storage_transition::storage_transition; use sqlbuild_core::migration_values::models::{DecisionTraits, ModelMigrationFacts}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::call_arguments::call_argument; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::scalars::parse_value; -use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; use crate::bindings::_helpers::records::construct::error_class; -use crate::bindings::_helpers::records::construct::{ - enum_from_value, enum_member, new_record, record_class, -}; +use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; @@ -303,16 +301,6 @@ pub(crate) fn overrides_typed_as( Ok(instance.get_type().call((), Some(&keywords))?.unbind()) } -/// `ModelPlanEntry.backfill`'s default: a forward-only backfill. -pub(crate) fn forward_only_backfill(py: Python<'_>) -> PyResult> { - let keywords: Bound<'_, PyDict> = PyDict::new(py); - keywords.set_item( - "action", - enum_member(py, RecordId::BackfillAction, "FORWARD_ONLY")?, - )?; - new_record(py, RecordId::BackfillResult, (), Some(&keywords)) -} - /// `ScenarioArtifactIdentity.kind` coerced to `ScenarioArtifactKind`. pub(crate) fn finish_scenario_artifact_kind( py: Python<'_>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs index 3610ff760b..19a236a8bb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs @@ -5,7 +5,7 @@ use pyo3::exceptions::PyTypeError; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple, PyTupleMethods}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::{enum_member, new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/behaviours.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/behaviours.rs new file mode 100644 index 0000000000..2c066186f1 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/behaviours.rs @@ -0,0 +1,18 @@ +//! The record behaviours installed at registration: finishers, computed attributes and methods. + +use std::sync::OnceLock; + +use crate::bindings::_helpers::records::constants::NO_RECORD_BEHAVIOURS; +use crate::bindings::_helpers::records::models::RecordBehaviours; + +static INSTALLED: OnceLock<&'static RecordBehaviours> = OnceLock::new(); + +/// Install the record behaviours; later calls keep the first behaviours. +pub(crate) fn install(behaviours: &'static RecordBehaviours) { + let _ = INSTALLED.get_or_init(|| behaviours); +} + +/// The installed record behaviours, or none before registration. +pub(crate) fn behaviours() -> &'static RecordBehaviours { + INSTALLED.get().copied().unwrap_or(&NO_RECORD_BEHAVIOURS) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs index da4f43df58..6bb05612f8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs @@ -1,24 +1,19 @@ //! The layouts of every native record class. +use sqlbuild_host::entries::models::ExecutorHost; + use crate::bindings::_helpers::compile_records::constants::COMPILE_VALUE_RECORDS; use crate::bindings::_helpers::compiler_enums::constants::COMPILER_ENUMS; use crate::bindings::_helpers::compiler_errors::constants::COMPILER_ERRORS; use crate::bindings::_helpers::compiler_records::constants::COMPILER_RECORDS; use crate::bindings::_helpers::contract_records::constants::CONTRACT_RECORDS; -use crate::bindings::_helpers::freshness::observation::normalize_observation; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::planner_records::constants::{ PLANNER_ENUMS, PLANNER_RECORDS, PLANNER_VALUE_RECORDS, }; -use crate::bindings::_helpers::record_behaviours::constants::{ - BEHAVIOUR_CACHED_PROPERTIES, BEHAVIOUR_FINISHERS, BEHAVIOUR_METHODS, BEHAVIOUR_ORDERED, - BEHAVIOUR_PROPERTIES, BEHAVIOUR_SEQUENCES, -}; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::records::models::{ - ClassValue, EnumSpec, ErrorSpec, FieldDefault, FieldSpec, RecordSpec, + ClassValue, EnumSpec, ErrorSpec, FieldDefault, FieldSpec, RecordBehaviours, RecordSpec, }; -use crate::bindings::_helpers::records::types::{ClassMethod, ClassProperty, RecordFinish}; use crate::bindings::_helpers::rule_records::constants::RULE_RECORDS; use crate::bindings::_helpers::scope_records::constants::SCOPE_RECORDS; @@ -167,22 +162,15 @@ pub(crate) const RECORDS: &[&[RecordSpec]] = &[ /// `str(PurePath("."))`, the path whose name and stem are empty. pub(crate) const CURRENT_DIRECTORY_PATH: &str = "."; -/// Records whose bound values are normalized or validated before the record is created. -pub(crate) const RECORD_FINISHERS: &[&[(&str, RecordFinish)]] = &[ - &[("SourceFreshnessObservation", normalize_observation)], - BEHAVIOUR_FINISHERS, -]; -/// `(class, attribute, getter)` computed attributes set on native classes after registration. -pub(crate) const CLASS_PROPERTIES: &[&[(&str, &str, ClassProperty)]] = &[BEHAVIOUR_PROPERTIES]; -/// `(class, attribute, getter)` computed attributes a record computes once and keeps. -pub(crate) const CACHED_PROPERTIES: &[&[(&str, &str, ClassProperty)]] = - &[BEHAVIOUR_CACHED_PROPERTIES]; -/// `(class, attribute, method)` methods set on native classes after registration. -pub(crate) const CLASS_METHODS: &[&[(&str, &str, ClassMethod)]] = &[BEHAVIOUR_METHODS]; -/// Records ordered by their compared fields, as `order=True` dataclasses are. -pub(crate) const ORDERED_RECORDS: &[&[&str]] = &[BEHAVIOUR_ORDERED]; -/// Native records registered as `collections.abc.Sequence` virtual subclasses. -pub(crate) const SEQUENCE_RECORDS: &[&[&str]] = &[BEHAVIOUR_SEQUENCES]; +/// The behaviours before registration installs them: none. +pub(crate) const NO_RECORD_BEHAVIOURS: RecordBehaviours = RecordBehaviours { + finishers: &[], + properties: &[], + cached_properties: &[], + methods: &[], + ordered: &[], + sequences: &[], +}; /// `SourceFreshnessObservation` field positions. pub(crate) const DATA_VERSION_FIELD: usize = 2; pub(crate) const OBSERVED_AT_FIELD: usize = 4; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs index d70b479ce1..d78ced3473 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs @@ -7,7 +7,7 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyModule, PyResult, P use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods}; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; /// Each `RecordId`'s class, captured when the extension module is initialised. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index f1f5086168..ef08628416 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -16,11 +16,11 @@ use pyo3::types::{ use sqlbuild_discovery::model_files::main::model_file_stem::model_file_stem; use sqlbuild_rules::project_tree::main::pure_path_posix::pure_path_posix; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::behaviours::behaviours; use crate::bindings::_helpers::records::constants::{ - CACHED_PROPERTIES, CLASS_METHODS, CLASS_PROPERTIES, CURRENT_DIRECTORY_PATH, ENUMS, - FROZEN_INSTANCE_ERROR, NATIVE_MODULE, ORDERED_RECORDS, RECORD_FINISHERS, RECORD_SPEC_ATTRIBUTE, + CURRENT_DIRECTORY_PATH, ENUMS, FROZEN_INSTANCE_ERROR, NATIVE_MODULE, RECORD_SPEC_ATTRIBUTE, RECORDS, }; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; @@ -130,7 +130,8 @@ pub(crate) fn record_attribute_opt<'py>( property_value(cell, property, cached_name) .map(|found| Some(found.into_bound(value.py()))), ), - None if CLASS_METHODS + None if behaviours() + .methods .iter() .flat_map(|group| group.iter()) .any(|(class, method, _)| *class == record.spec.name && *method == name) => @@ -230,10 +231,18 @@ fn record_properties() -> &'static PropertyTable { static TABLE: OnceLock = OnceLock::new(); TABLE.get_or_init(|| { let mut table: PropertyTable = HashMap::new(); - for &(class, name, property) in CLASS_PROPERTIES.iter().flat_map(|group| group.iter()) { + for &(class, name, property) in behaviours() + .properties + .iter() + .flat_map(|group| group.iter()) + { let _ = table.insert((class, name), (property, None)); } - for &(class, name, property) in CACHED_PROPERTIES.iter().flat_map(|group| group.iter()) { + for &(class, name, property) in behaviours() + .cached_properties + .iter() + .flat_map(|group| group.iter()) + { let _ = table.insert((class, name), (property, Some(name))); } table @@ -440,7 +449,8 @@ pub(crate) fn build_values( fn record_finishers() -> &'static HashMap<&'static str, RecordFinish> { static FINISHERS: OnceLock> = OnceLock::new(); FINISHERS.get_or_init(|| { - RECORD_FINISHERS + behaviours() + .finishers .iter() .flat_map(|group| group.iter()) .map(|&(record, finish)| (record, finish)) @@ -526,7 +536,10 @@ pub(crate) fn ordered_comparison( ) -> PyResult> { let py: Python<'_> = slf.py(); let name: &str = slf.get().spec.name; - let ordered: bool = ORDERED_RECORDS.iter().any(|group| group.contains(&name)); + let ordered: bool = behaviours() + .ordered + .iter() + .any(|group| group.contains(&name)); if !ordered || !other.get_type().is(slf.get_type()) { return Ok(py.NotImplemented()); } @@ -604,3 +617,16 @@ pub(crate) fn path_posix_text(path: &Bound<'_, PyAny>) -> PyResult { let text: Bound<'_, PyString> = path.str()?; Ok(text.to_str()?.replace(std::path::MAIN_SEPARATOR, "/")) } + +/// `{item.: item for item in items}`. +pub(crate) fn by_attribute<'py>( + items: &Bound<'py, PyAny>, + attribute: &str, +) -> PyResult> { + let keyed: Bound<'py, PyDict> = PyDict::new(items.py()); + for item in items.try_iter()? { + let item: Bound<'py, PyAny> = item?; + keyed.set_item(field(&item, attribute)?, item)?; + } + Ok(keyed) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs deleted file mode 100644 index 0af5b3562f..0000000000 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs +++ /dev/null @@ -1,1804 +0,0 @@ -//! The per-class readers behind `getters::getter_field`, one per native pyclass. - -use pyo3::IntoPyObjectExt; -use pyo3::prelude::{Bound, PyAny, PyResult, Python}; - -use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; -use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; -use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; -use crate::bindings::_helpers::build_progress::transient_lines::TransientLineCoordinator; -use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; -use crate::bindings::_helpers::compile_command::prepared_artifacts::PreparedCompileArtifacts; -use crate::bindings::_helpers::compile_command::reuse_recording::{ - CompileArtifactWrites, RecordedCompileOutput, -}; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::CollectedCompileDiagnostics; -use crate::bindings::_helpers::compile_driver::input_reads::CompileInputReads; -use crate::bindings::_helpers::compiled_project::audit_views::{ - NativeAuditInput, NativeCompiledAudit, -}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::function_views::{ - NativeCompiledFunction, NativeFunctionInput, -}; -use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; -use crate::bindings::_helpers::compiled_project::seed_views::{ - NativeCompiledSeed, NativeSeedInput, -}; -use crate::bindings::_helpers::compiled_project::source_views::{ - NativeCompiledSource, NativeSourceInput, -}; -use crate::bindings::_helpers::compute_logs::storage::LocalFilesystemComputeLogStorage; -use crate::bindings::_helpers::dbt_events::stream::DbtEventStreamUpdate; -use crate::bindings::_helpers::dbt_interop::graph::DbtCombinedGraph; -use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileReferenceResolver; -use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; -use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; -use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; -use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; -use crate::bindings::_helpers::event_exporting::models::{ - BoundEventExporter, EventExportSummary, EventExporterAccounting, EventExporterCounts, - EventExporterFailure, -}; -use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope; -use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHistory; -use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; -use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; -use crate::bindings::_helpers::model_config::errors::NativeConfigError; -use crate::bindings::_helpers::planner_entries::models::{ - ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, -}; -use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; -use crate::bindings::_helpers::planner_phases::models::{ - PlannerIdentityContext, PlannerRuntime, PlannerScopeResolution, PlannerWarehouseState, -}; -use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; -use crate::bindings::_helpers::project_assembly::models::{ - NativeModelFacts, NativeProjectFacts, NativeProjectResources, NativeResourceFailure, -}; -use crate::bindings::_helpers::result_output::integration_envelope::{ - IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, -}; -use crate::bindings::_helpers::result_output::terminal_index::TerminalEventClaim; -use crate::bindings::_helpers::rules::early_sql_lint::EarlySqlLint; -use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; -use crate::bindings::models::NativeDirectorySnapshot; - -pub(crate) fn read_binding_catalog<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "schemas" => (&this.schemas).into_bound_py_any(py), - "dialect" => (&this.dialect).into_bound_py_any(py), - "quoted_ignore_case" => (&this.quoted_ignore_case).into_bound_py_any(py), - "analysis_shapes" => (&this.analysis_shapes).into_bound_py_any(py), - "expression_shapes" => (&this.expression_shapes).into_bound_py_any(py), - "native" => (&this.native).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_model_analysis_session<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "fact_models" => this.fact_models().into_bound_py_any(py), - "cache_stats" => this.cache_stats().into_bound_py_any(py), - "sharing" => this.sharing().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_build_progress_callbacks<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "elapsed" => this.elapsed().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_transient_line_coordinator<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "lock" => (&this.lock).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_compile_reuse_attempt<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "outcome" => (&this.outcome).into_bound_py_any(py), - "project_dir" => (&this.project_dir).into_bound_py_any(py), - "started" => (&this.started).into_bound_py_any(py), - "check_ms" => (&this.check_ms).into_bound_py_any(py), - "exit_code" => (&this.exit_code).into_bound_py_any(py), - "entry_path" => (&this.entry_path).into_bound_py_any(py), - "native" => (&this.native).into_bound_py_any(py), - "selected_target" => (&this.selected_target).into_bound_py_any(py), - "json_output" => (&this.json_output).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_prepared_compile_artifacts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "enabled" => this.enabled().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_compile_artifact_writes<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "artifacts" => this - .artifacts(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_recorded_compile_output<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "stderr_lines" => this.stderr_lines(py).into_bound_py_any(py), - "stdout" => this.stdout(py).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_collected_compile_diagnostics<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "diagnostics" => this - .diagnostics(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_compile_input_reads<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "environment_names" => this - .environment_names(py) - .and_then(|value| value.into_bound_py_any(py)), - "settings_classes" => this - .settings_classes(py) - .and_then(|value| value.into_bound_py_any(py)), - "read_run_id" => this.read_run_id().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_audit_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "audit_file" => this - .audit_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "audit_block" => this - .audit_block(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_body" => this - .sql_body(py) - .and_then(|value| value.into_bound_py_any(py)), - "evaluation_mode" => this - .evaluation_mode(py) - .and_then(|value| value.into_bound_py_any(py)), - "measurement_contract" => this - .measurement_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "thresholds" => this - .thresholds(py) - .and_then(|value| value.into_bound_py_any(py)), - "minimum_samples" => this - .minimum_samples(py) - .and_then(|value| value.into_bound_py_any(py)), - "measure_sql" => this - .measure_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_sql" => this - .evidence_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_limit" => this - .evidence_limit(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_kind" => this - .attached_target_kind(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_name" => this - .attached_target_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_column_name" => this - .attached_column_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "severity" => this - .severity(py) - .and_then(|value| value.into_bound_py_any(py)), - "run_scope" => this - .run_scope(py) - .and_then(|value| value.into_bound_py_any(py)), - "always_run" => this - .always_run(py) - .and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "meta" => this.meta(py).and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_compiled_audit<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "audit_file" => this - .audit_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "audit_block" => this - .audit_block(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_body" => this - .sql_body(py) - .and_then(|value| value.into_bound_py_any(py)), - "evaluation_mode" => this - .evaluation_mode(py) - .and_then(|value| value.into_bound_py_any(py)), - "measurement_contract" => this - .measurement_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "thresholds" => this - .thresholds(py) - .and_then(|value| value.into_bound_py_any(py)), - "minimum_samples" => this - .minimum_samples(py) - .and_then(|value| value.into_bound_py_any(py)), - "measure_sql" => this - .measure_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_sql" => this - .evidence_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_limit" => this - .evidence_limit(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_kind" => this - .attached_target_kind(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_name" => this - .attached_target_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_column_name" => this - .attached_column_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "severity" => this - .severity(py) - .and_then(|value| value.into_bound_py_any(py)), - "run_scope" => this - .run_scope(py) - .and_then(|value| value.into_bound_py_any(py)), - "always_run" => this - .always_run(py) - .and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "meta" => this.meta(py).and_then(|value| value.into_bound_py_any(py)), - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "scope_deps" => this - .scope_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "definition_name" => this - .definition_name(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_compiled_model<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "relative_path" => this - .relative_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this - .query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "config" => this - .config(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "reference_rows" => this - .reference_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "relation_key_row" => this - .relation_key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "key_row" => this - .key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "dep_rows" => this - .dep_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination_row" => this - .destination_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "inferred_rows" => this - .inferred_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_column_rows" => this - .schema_column_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "has_dynamic_columns" => this - .dynamic_columns_declared(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_count" => this - .output_column_count(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "inferred_columns" => this - .inferred_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_columns" => this - .fast_lineage_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_has_star" => this - .fast_lineage_has_star(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_star_resolved" => this - .fast_lineage_star_resolved(py) - .and_then(|value| value.into_bound_py_any(py)), - "authored_sql" => this - .authored_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "authored_query_sql" => this - .authored_query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_locations" => this - .output_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "extract_implicit_alias_columns" => this - .extract_implicit_alias_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_deps" => this - .macro_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_declarations" => this - .enum_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "constant_declarations" => this - .constant_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_columns" => this - .enum_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "binding_diagnostics" => this - .binding_diagnostics(py) - .and_then(|value| value.into_bound_py_any(py)), - "binding_validated" => this - .binding_validated(py) - .and_then(|value| value.into_bound_py_any(py)), - "dynamic_column_contract" => this - .dynamic_column_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "unchecked_output_columns" => this - .unchecked_output_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "rejected_sql_analysis_opt_out" => this - .rejected_sql_analysis_opt_out(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_compiled_function<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "arguments" => this - .arguments(py) - .and_then(|value| value.into_bound_py_any(py)), - "returns" => this - .returns(py) - .and_then(|value| value.into_bound_py_any(py)), - "body_sql" => this - .body_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "return_columns" => this - .return_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "language" => this - .language(py) - .and_then(|value| value.into_bound_py_any(py)), - "runtime_version" => this - .runtime_version(py) - .and_then(|value| value.into_bound_py_any(py)), - "entry_point" => this - .entry_point(py) - .and_then(|value| value.into_bound_py_any(py)), - "packages" => this - .packages(py) - .and_then(|value| value.into_bound_py_any(py)), - "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), - "relative_path" => this - .relative_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file_path" => this - .source_file_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_destination" => this - .fingerprint_destination(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_function_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "arguments" => this - .arguments(py) - .and_then(|value| value.into_bound_py_any(py)), - "returns" => this - .returns(py) - .and_then(|value| value.into_bound_py_any(py)), - "body_sql" => this - .body_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "return_columns" => this - .return_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "language" => this - .language(py) - .and_then(|value| value.into_bound_py_any(py)), - "runtime_version" => this - .runtime_version(py) - .and_then(|value| value.into_bound_py_any(py)), - "entry_point" => this - .entry_point(py) - .and_then(|value| value.into_bound_py_any(py)), - "packages" => this - .packages(py) - .and_then(|value| value.into_bound_py_any(py)), - "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "function_file" => this - .function_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "database" => this - .database(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema" => this - .schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "logical_database" => this - .logical_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "logical_schema" => this - .logical_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_database" => this - .fingerprint_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_schema" => this - .fingerprint_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_logical_database" => this - .fingerprint_logical_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_logical_schema" => this - .fingerprint_logical_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_inputs_view<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "run_id" => this.run_id().into_bound_py_any(py), - "effective_target_name" => this.effective_target_name().into_bound_py_any(py), - "no_sql_validation" => this.is_sql_validation_skipped().into_bound_py_any(py), - "model_inputs" => this.model_inputs(py).into_bound_py_any(py), - "native_project" => this.native_project(py).into_bound_py_any(py), - "project_config" => this.project_config(py).into_bound_py_any(py), - "local_config" => this.local_config(py).into_bound_py_any(py), - "discovered_inputs" => this.discovered_inputs(py).into_bound_py_any(py), - "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), - "effective_target" => this.effective_target(py).into_bound_py_any(py), - "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), - "effective_connection" => this.effective_connection(py).into_bound_py_any(py), - "effective_vars" => this.effective_vars(py).into_bound_py_any(py), - "macro_context" => this.macro_context(py).into_bound_py_any(py), - "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), - "public_enums" => this.public_enums(py).into_bound_py_any(py), - "public_constants" => this.public_constants(py).into_bound_py_any(py), - "external_sql_reference_resolver" => this - .external_sql_reference_resolver(py) - .into_bound_py_any(py), - "effective_settings" => this.effective_settings(py).into_bound_py_any(py), - "seed_inputs" => this.seed_inputs(py).into_bound_py_any(py), - "source_inputs" => this.source_inputs(py).into_bound_py_any(py), - "sql_function_inputs" => this.sql_function_inputs(py).into_bound_py_any(py), - "test_inputs" => this.test_inputs(py).into_bound_py_any(py), - "scenario_inputs" => this.scenario_inputs(py).into_bound_py_any(py), - "audit_inputs" => this.audit_inputs(py).into_bound_py_any(py), - "diagnostics" => this.diagnostics(py).into_bound_py_any(py), - "scope_index" => this.scope_index(py).into_bound_py_any(py), - "declaration_scope" => this.declaration_scope(py).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_model_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "model_file" => this - .model_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "config" => this - .config(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this - .query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_source_sql" => this - .macro_source_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "reference_rows" => this - .reference_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "relation_key_row" => this - .relation_key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_schema_name" => this - .attached_schema_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this.schema_file(py).into_bound_py_any(py), - "sql_validation_enabled" => this - .sql_validation_enabled(py) - .and_then(|value| value.into_bound_py_any(py)), - "rejected_sql_analysis_opt_out" => this - .rejected_sql_analysis_opt_out(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_declarations" => this - .enum_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "constant_declarations" => this - .constant_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_columns" => this - .enum_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_deps" => this - .macro_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_usages" => this - .macro_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_expansion" => this - .sql_expansion(py) - .and_then(|value| value.into_bound_py_any(py)), - "lint_expansion" => this - .lint_expansion(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_project_view<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "run_id" => this.run_id().into_bound_py_any(py), - "effective_target_name" => this.effective_target_name().into_bound_py_any(py), - "effective_target_database" => this.effective_target_database().into_bound_py_any(py), - "effective_target_schema" => this.effective_target_schema().into_bound_py_any(py), - "sql_analysis_dialect" => this.sql_analysis_dialect().into_bound_py_any(py), - "enforce_explicit_references" => { - this.is_explicit_reference_enforced().into_bound_py_any(py) - } - "models" => this.models(py).into_bound_py_any(py), - "native_project" => this.native_project(py).into_bound_py_any(py), - "effective_connection" => this.effective_connection(py).into_bound_py_any(py), - "effective_vars" => this.effective_vars(py).into_bound_py_any(py), - "binding_catalog" => this.binding_catalog(py).into_bound_py_any(py), - "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), - "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), - "loader_functions" => this.loader_functions(py).into_bound_py_any(py), - "hook_functions" => this.hook_functions(py).into_bound_py_any(py), - "sql_hook_files" => this.sql_hook_files(py).into_bound_py_any(py), - "materialization_files" => this.materialization_files(py).into_bound_py_any(py), - "public_enums" => this.public_enums(py).into_bound_py_any(py), - "public_constants" => this.public_constants(py).into_bound_py_any(py), - "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), - "external_sql_reference_resolver" => this - .external_sql_reference_resolver(py) - .into_bound_py_any(py), - "native_session" => this.native_session(py).into_bound_py_any(py), - "settings" => this.settings(py).into_bound_py_any(py), - "scenario" => this.scenario(py).into_bound_py_any(py), - "sources" => this.sources(py).into_bound_py_any(py), - "seeds" => this.seeds(py).into_bound_py_any(py), - "functions" => this.functions(py).into_bound_py_any(py), - "audits" => this.audits(py).into_bound_py_any(py), - "sql_tests" => this.sql_tests(py).into_bound_py_any(py), - "sql_scenarios" => this.sql_scenarios(py).into_bound_py_any(py), - "diagnostics" => this.diagnostics(py).into_bound_py_any(py), - "unmatched_literal_sql_relations" => this - .unmatched_literal_sql_relations(py) - .into_bound_py_any(py), - "scope_index" => this.scope_index(py).into_bound_py_any(py), - "sql_expansions" => this - .sql_expansions(py) - .and_then(|value| value.into_bound_py_any(py)), - "lineage_graph" => this - .lineage_graph(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_compiled_seed<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).into_bound_py_any(py), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "seed_file" => this - .seed_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this - .schema_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "external" => this.is_external().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_seed_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "seed_file" => this - .seed_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this - .schema_file(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_compiled_source<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).into_bound_py_any(py), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "source_entry" => this - .source_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file" => this - .source_file(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_source_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "source_entry" => this - .source_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file" => this - .source_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_local_filesystem_compute_log_storage<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "root" => this.root(py).and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_dbt_event_stream_update<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "status_message" => (&this.status_message).into_bound_py_any(py), - "result" => (&this.result).into_bound_py_any(py), - "row" => (&this.row).into_bound_py_any(py), - "finished" => (&this.finished).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_dbt_combined_graph<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "nodes" => this.nodes(py).and_then(|value| value.into_bound_py_any(py)), - "upstream_deps" => this - .upstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "downstream_deps" => this - .downstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_dbt_compile_reference_resolver<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "_dbt_manifest" => this.dbt_manifest(py).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_dbt_runner<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "dbt_executable" => (&this.dbt_executable).into_bound_py_any(py), - "invoker" => (&this.invoker).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_build_phase_timing_tracker<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "compile_seconds" => (&this.compile_seconds).into_bound_py_any(py), - "planning_seconds" => (&this.planning_seconds).into_bound_py_any(py), - "connection_preparation_seconds" => { - (&this.connection_preparation_seconds).into_bound_py_any(py) - } - "schema_preparation_seconds" => (&this.schema_preparation_seconds).into_bound_py_any(py), - "execution_seconds" => (&this.execution_seconds).into_bound_py_any(py), - "cost_collection_seconds" => (&this.cost_collection_seconds).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_model_file<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "file_path" => this - .file_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "relative_path" => this - .relative_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "contents" => this.contents(py).into_bound_py_any(py), - "header_values" => this - .header_values(py) - .and_then(|value| value.into_bound_py_any(py)), - "header_column_locations" => this - .header_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_locations" => this - .output_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this.query_sql(py).into_bound_py_any(py), - "enum_declarations" => this.enum_declarations(py).into_bound_py_any(py), - "constant_declarations" => this.constant_declarations(py).into_bound_py_any(py), - "extract_implicit_alias_columns" => { - this.extract_implicit_alias_columns().into_bound_py_any(py) - } - _ => return None, - }) -} - -pub(crate) fn read_native_directory_snapshot<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project_dir" => this.project_dir(py).into_bound_py_any(py), - "memo" => this.memo(py).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_event_exporter_dispatcher<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "thread" => this.thread(py).into_bound_py_any(py), - "notification_thread" => this.notification_thread(py).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_bound_event_exporter<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name().into_bound_py_any(py), - "function" => this.function(py).into_bound_py_any(py), - "provider_arguments" => this.provider_arguments(py).into_bound_py_any(py), - "event_kinds" => this - .event_kinds(py) - .and_then(|value| value.into_bound_py_any(py)), - "min_severity" => this - .min_severity(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_event_export_summary<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "aggregate" => this.aggregate().into_bound_py_any(py), - "per_exporter" => this - .per_exporter(py) - .and_then(|value| value.into_bound_py_any(py)), - "queue_depth" => this.queue_depth().into_bound_py_any(py), - "queue_capacity" => this.queue_capacity().into_bound_py_any(py), - "flush_complete" => this.flush_complete().into_bound_py_any(py), - "accepted" => this.accepted().into_bound_py_any(py), - "filtered" => this.filtered().into_bound_py_any(py), - "delivered" => this.delivered().into_bound_py_any(py), - "failed" => this.failed().into_bound_py_any(py), - "dropped" => this.dropped().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_event_exporter_accounting<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "exporter_name" => this.exporter_name().into_bound_py_any(py), - "counts" => this.counts().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_event_exporter_counts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "accepted" => this.accepted().into_bound_py_any(py), - "filtered" => this.filtered().into_bound_py_any(py), - "delivered" => this.delivered().into_bound_py_any(py), - "failed" => this.failed().into_bound_py_any(py), - "dropped" => this.dropped().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_event_exporter_failure<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "exporter_name" => this.exporter_name().into_bound_py_any(py), - "error_type" => this.error_type().into_bound_py_any(py), - "event_kind" => this.event_kind().into_bound_py_any(py), - "event_severity" => this - .event_severity(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_event_exporter_command_scope<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "dispatcher" => this.dispatcher(py).into_bound_py_any(py), - "provider_session" => this - .provider_session(py) - .and_then(|value| value.into_bound_py_any(py)), - "project_dir" => this - .project_dir(py) - .and_then(|value| value.into_bound_py_any(py)), - "providers" => this - .providers(py) - .and_then(|value| value.into_bound_py_any(py)), - "event_exporters" => this - .event_exporters(py) - .and_then(|value| value.into_bound_py_any(py)), - "command_output_sinks" => this - .command_output_sinks(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_postgres_execution_history<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project_calls" => this.project_calls().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_sqlite_execution_history<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "path" => this.path(py).and_then(|value| value.into_bound_py_any(py)), - "project_calls" => this.project_calls().into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_compiled_project_graph<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project" => this.project_attribute(py).into_bound_py_any(py), - "native" => this.native_attribute(py).into_bound_py_any(py), - "lineage_views" => this - .lineage_views(py) - .and_then(|value| value.into_bound_py_any(py)), - "upstream_deps" => this - .upstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "downstream_deps" => this - .downstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "tag_index" => this - .tag_index(py) - .and_then(|value| value.into_bound_py_any(py)), - "path_index" => this - .path_index(py) - .and_then(|value| value.into_bound_py_any(py)), - "all_keys" => this - .all_keys(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_native_config_error<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "class_name" => (&this.class_name).into_bound_py_any(py), - "message" => (&this.message).into_bound_py_any(py), - "code" => (&this.code).into_bound_py_any(py), - "help" => (&this.help).into_bound_py_any(py), - "key" => (&this.key).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_model_plan_context<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "model_locations" => (&this.model_locations).into_bound_py_any(py), - "models_by_name" => (&this.models_by_name).into_bound_py_any(py), - "seed_locations" => (&this.seed_locations).into_bound_py_any(py), - "function_locations" => (&this.function_locations).into_bound_py_any(py), - "source_map" => (&this.source_map).into_bound_py_any(py), - "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), - "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), - "functions_by_name" => (&this.functions_by_name).into_bound_py_any(py), - "runtime_cursor_producer_names" => { - (&this.runtime_cursor_producer_names).into_bound_py_any(py) - } - "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), - "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), - "invocation_time" => (&this.invocation_time).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_plan_entry_build_inputs<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "source_freshness_blocked_model_names" => { - (&this.source_freshness_blocked_model_names).into_bound_py_any(py) - } - "external_blocked_model_names" => { - (&this.external_blocked_model_names).into_bound_py_any(py) - } - "start_cursor_override" => (&this.start_cursor_override).into_bound_py_any(py), - "end_cursor_override" => (&this.end_cursor_override).into_bound_py_any(py), - "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), - "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), - "invocation_time" => (&this.invocation_time).into_bound_py_any(py), - "max_microbatches" => (&this.max_microbatches).into_bound_py_any(py), - "max_microbatches_is_override" => { - (&this.max_microbatches_is_override).into_bound_py_any(py) - } - "microbatch_limit_action" => (&this.microbatch_limit_action).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_planner_relations_context<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "model_locations" => (&this.model_locations).into_bound_py_any(py), - "seed_locations" => (&this.seed_locations).into_bound_py_any(py), - "function_locations" => (&this.function_locations).into_bound_py_any(py), - "source_map" => (&this.source_map).into_bound_py_any(py), - "source_read_map" => (&this.source_read_map).into_bound_py_any(py), - "python_source_read_map" => (&this.python_source_read_map).into_bound_py_any(py), - "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), - "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), - "listed_source_names" => (&this.listed_source_names).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_migration_state_inspection<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "database" => this.database(py).into_bound_py_any(py), - "events" => this - .events(py) - .and_then(|value| value.into_bound_py_any(py)), - "column_events" => this - .column_events(py) - .and_then(|value| value.into_bound_py_any(py)), - "old_name_histories" => this - .old_name_histories(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -pub(crate) fn read_planner_identity_context<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "version_identities" => (&this.version_identities).into_bound_py_any(py), - "stale_warning_identities" => (&this.stale_warning_identities).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_planner_runtime<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project" => (&this.project).into_bound_py_any(py), - "adapter" => (&this.adapter).into_bound_py_any(py), - "connection" => (&this.connection).into_bound_py_any(py), - "project_config" => (&this.project_config).into_bound_py_any(py), - "local_config" => (&this.local_config).into_bound_py_any(py), - "on_progress" => (&this.on_progress).into_bound_py_any(py), - "invocation_time" => (&this.invocation_time).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_planner_scope_resolution<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "selected_scope" => (&this.selected_scope).into_bound_py_any(py), - "stale_warning_scope" => (&this.stale_warning_scope).into_bound_py_any(py), - "inspection_scope" => (&this.inspection_scope).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_planner_warehouse_state<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "snapshot" => (&this.snapshot).into_bound_py_any(py), - "inspection_relations" => (&this.inspection_relations).into_bound_py_any(py), - "migration_entries" => (&this.migration_entries).into_bound_py_any(py), - "migration_warnings" => (&this.migration_warnings).into_bound_py_any(py), - "column_migration_entries" => (&this.column_migration_entries).into_bound_py_any(py), - "column_rename_hints" => (&this.column_rename_hints).into_bound_py_any(py), - "old_name_view_entries" => (&this.old_name_view_entries).into_bound_py_any(py), - "old_name_views" => (&this.old_name_views).into_bound_py_any(py), - "migration_fingerprints" => (&this.migration_fingerprints).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_python_cli_style<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "use_color" => (&this.use_color).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_model_facts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "deps" => (&this.deps).into_bound_py_any(py), - "dynamic_contract" => (&this.dynamic_contract).into_bound_py_any(py), - "syntax_valid" => (&this.syntax_valid).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_project_facts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "models" => (&this.models).into_bound_py_any(py), - "resources" => (&this.resources).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_project_resources<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "model_deps" => (&this.model_deps).into_bound_py_any(py), - "model_syntax_valid" => (&this.model_syntax_valid).into_bound_py_any(py), - "source_namespaces" => (&this.source_namespaces).into_bound_py_any(py), - "seed_namespaces" => (&this.seed_namespaces).into_bound_py_any(py), - "function_deps" => (&this.function_deps).into_bound_py_any(py), - "audit_scope_deps" => (&this.audit_scope_deps).into_bound_py_any(py), - "failure" => (&this.failure).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_resource_failure<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "slot" => (&this.slot).into_bound_py_any(py), - "index" => (&this.index).into_bound_py_any(py), - "error" => (&this.error).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_integration_asset_result<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "as_dict" => return None, - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -pub(crate) fn read_integration_check_result<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "as_dict" | "decoded" | "parsed" => return None, - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -pub(crate) fn read_integration_result_envelope<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "asset" => this.asset(py).into_bound_py_any(py), - "checks" => this.checks(py).into_bound_py_any(py), - "from_json" | "from_json_without_optional_enrichment" | "register" | "to_json" => { - return None; - } - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -pub(crate) fn read_terminal_event_claim<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "terminal" => (&this.terminal).into_bound_py_any(py), - "event_sequence" => (&this.event_sequence).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_early_sql_lint<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "enabled" => (&this.enabled).into_bound_py_any(py), - _ => return None, - }) -} - -pub(crate) fn read_native_scope_index<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "index" => this.index(py).into_bound_py_any(py), - "has_scoped_relationship_declarations" => this - .has_scoped_relationship_declarations() - .into_bound_py_any(py), - _ => return None, - }) -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs index 62205596c6..43c36fbcb4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs @@ -1,350 +1,45 @@ -//! Direct reads of native pyclass `#[getter]` attributes by name; anything absent falls back to `getattr`. +//! Direct reads of native pyclass `#[getter]` attributes from installed per-module tables. use std::collections::HashMap; +use std::sync::OnceLock; +use pyo3::PyTypeInfo; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; +use pyo3::types::PyType; -use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; -use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; -use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; -use crate::bindings::_helpers::build_progress::transient_lines::TransientLineCoordinator; -use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; -use crate::bindings::_helpers::compile_command::prepared_artifacts::PreparedCompileArtifacts; -use crate::bindings::_helpers::compile_command::reuse_recording::{ - CompileArtifactWrites, RecordedCompileOutput, -}; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::CollectedCompileDiagnostics; -use crate::bindings::_helpers::compile_driver::input_reads::CompileInputReads; -use crate::bindings::_helpers::compiled_project::audit_views::{ - NativeAuditInput, NativeCompiledAudit, -}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::function_views::{ - NativeCompiledFunction, NativeFunctionInput, -}; -use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; -use crate::bindings::_helpers::compiled_project::seed_views::{ - NativeCompiledSeed, NativeSeedInput, -}; -use crate::bindings::_helpers::compiled_project::source_views::{ - NativeCompiledSource, NativeSourceInput, -}; -use crate::bindings::_helpers::compute_logs::storage::LocalFilesystemComputeLogStorage; -use crate::bindings::_helpers::dbt_events::stream::DbtEventStreamUpdate; -use crate::bindings::_helpers::dbt_interop::graph::DbtCombinedGraph; -use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileReferenceResolver; -use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; -use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; -use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; -use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; -use crate::bindings::_helpers::event_exporting::models::{ - BoundEventExporter, EventExportSummary, EventExporterAccounting, EventExporterCounts, - EventExporterFailure, -}; -use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope; -use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHistory; -use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; -use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; -use crate::bindings::_helpers::model_config::errors::NativeConfigError; -use crate::bindings::_helpers::planner_entries::models::{ - ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, -}; -use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; -use crate::bindings::_helpers::planner_phases::models::{ - PlannerIdentityContext, PlannerRuntime, PlannerScopeResolution, PlannerWarehouseState, -}; -use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; -use crate::bindings::_helpers::project_assembly::models::{ - NativeModelFacts, NativeProjectFacts, NativeProjectResources, NativeResourceFailure, -}; -use crate::bindings::_helpers::records::getter_readers::{ - read_binding_catalog, read_bound_event_exporter, read_build_phase_timing_tracker, - read_build_progress_callbacks, read_collected_compile_diagnostics, - read_compile_artifact_writes, read_compile_input_reads, read_compile_reuse_attempt, - read_compiled_project_graph, read_dbt_combined_graph, read_dbt_compile_reference_resolver, - read_dbt_event_stream_update, read_dbt_runner, read_early_sql_lint, read_event_export_summary, - read_event_exporter_accounting, read_event_exporter_command_scope, read_event_exporter_counts, - read_event_exporter_dispatcher, read_event_exporter_failure, read_integration_asset_result, - read_integration_check_result, read_integration_result_envelope, - read_local_filesystem_compute_log_storage, read_migration_state_inspection, - read_model_plan_context, read_native_audit_input, read_native_compiled_audit, - read_native_compiled_function, read_native_compiled_model, read_native_compiled_seed, - read_native_compiled_source, read_native_config_error, read_native_directory_snapshot, - read_native_function_input, read_native_inputs_view, read_native_model_analysis_session, - read_native_model_facts, read_native_model_file, read_native_model_input, - read_native_project_facts, read_native_project_resources, read_native_project_view, - read_native_resource_failure, read_native_scope_index, read_native_seed_input, - read_native_source_input, read_plan_entry_build_inputs, read_planner_identity_context, - read_planner_relations_context, read_planner_runtime, read_planner_scope_resolution, - read_planner_warehouse_state, read_postgres_execution_history, read_prepared_compile_artifacts, - read_python_cli_style, read_recorded_compile_output, read_sqlite_execution_history, - read_terminal_event_claim, read_transient_line_coordinator, -}; -use crate::bindings::_helpers::result_output::integration_envelope::{ - IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, -}; -use crate::bindings::_helpers::result_output::terminal_index::TerminalEventClaim; -use crate::bindings::_helpers::rules::early_sql_lint::EarlySqlLint; -use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; -use crate::bindings::models::NativeDirectorySnapshot; +use crate::bindings::_helpers::records::models::GetterEntry; +use crate::bindings::_helpers::records::types::GetterRead; -type Dispatch = for<'py> fn(&Bound<'py, PyAny>, &str) -> Option>>; +static TABLES: OnceLock<&'static [&'static [GetterEntry]]> = OnceLock::new(); +static DISPATCH: PyOnceLock> = PyOnceLock::new(); -static DISPATCH: PyOnceLock> = PyOnceLock::new(); +/// The type object of the native pyclass `T`, as a getter table entry names it. +pub(crate) fn class_of<'py, T: PyTypeInfo>(py: Python<'py>) -> Bound<'py, PyType> { + py.get_type::() +} + +/// Install every module's `getters::GETTERS` table once, before any record field is read. +pub(crate) fn install(tables: &'static [&'static [GetterEntry]]) { + let _ = TABLES.get_or_init(|| tables); +} /// The `#[getter]` `name` of a native pyclass instance read in Rust, or `None` when not generated here. pub(crate) fn getter_field<'py>( value: &Bound<'py, PyAny>, name: &str, ) -> Option>> { + let tables: &'static [&'static [GetterEntry]] = TABLES.get().copied()?; let py: Python<'py> = value.py(); - let table: &HashMap = DISPATCH.get_or_init(py, || { - let mut table: HashMap = HashMap::new(); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_binding_catalog, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_model_analysis_session, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_build_progress_callbacks, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_transient_line_coordinator, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_compile_reuse_attempt, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_prepared_compile_artifacts, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_compile_artifact_writes, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_recorded_compile_output, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_collected_compile_diagnostics, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_compile_input_reads, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_audit_input, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_compiled_audit, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_compiled_model, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_compiled_function, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_function_input, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_inputs_view, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_model_input, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_project_view, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_compiled_seed, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_seed_input, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_compiled_source, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_source_input, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_local_filesystem_compute_log_storage, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_dbt_event_stream_update, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_dbt_combined_graph, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_dbt_compile_reference_resolver, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_dbt_runner, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_build_phase_timing_tracker, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_model_file, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_directory_snapshot, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_exporter_dispatcher, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_bound_event_exporter, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_export_summary, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_exporter_accounting, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_exporter_counts, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_exporter_failure, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_event_exporter_command_scope, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_postgres_execution_history, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_sqlite_execution_history, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_compiled_project_graph, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_config_error, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_model_plan_context, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_plan_entry_build_inputs, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_planner_relations_context, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_migration_state_inspection, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_planner_identity_context, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_planner_runtime, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_planner_scope_resolution, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_planner_warehouse_state, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_python_cli_style, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_model_facts, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_project_facts, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_project_resources, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_resource_failure, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_integration_asset_result, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_integration_check_result, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_integration_result_envelope, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_terminal_event_claim, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_early_sql_lint, - ); - let _ = table.insert( - py.get_type::().as_ptr() as usize, - read_native_scope_index, - ); + let table: &HashMap = DISPATCH.get_or_init(py, || { + let mut table: HashMap = HashMap::new(); + for entries in tables { + for entry in entries.iter() { + let _ = table.insert((entry.class)(py).as_ptr() as usize, entry.read); + } + } table }); - let dispatch: &Dispatch = table.get(&(value.get_type().as_ptr() as usize))?; - dispatch(value, name) + let read: &GetterRead = table.get(&(value.get_type().as_ptr() as usize))?; + read(value, name) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs index ad8ff59f78..dc9157842e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs @@ -1,8 +1,8 @@ +pub(crate) mod behaviours; pub(crate) mod constants; pub(crate) mod construct; pub(crate) mod error_classes; pub(crate) mod fields; -pub(crate) mod getter_readers; pub(crate) mod getters; pub(crate) mod ids; pub(crate) mod models; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/models.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/models.rs index d7b6db29d4..5006a0fdd7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/models.rs @@ -7,14 +7,16 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyclass::CompareOp; use pyo3::types::{PyDict, PyTuple, PyType}; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; +use sqlbuild_host::entries::models::HostId; -use crate::bindings::_helpers::native_host::models::HostId; use crate::bindings::_helpers::records::fields::{ build_values, cached_value, compared_values, frozen_error, ordered_comparison, record_spec, repr_text, store_cached, }; use crate::bindings::_helpers::records::ids::RecordId; -use crate::bindings::_helpers::records::types::{ClassMethod, ClassProperty, RecordFactory}; +use crate::bindings::_helpers::records::types::{ + ClassMethod, ClassProperty, GetterClass, GetterRead, RecordFactory, RecordFinish, +}; /// How a record field is filled when the caller does not pass it. #[derive(Debug, Clone, Copy)] @@ -314,3 +316,28 @@ impl FieldSpec { } } } + +/// One native pyclass and the reader of its `#[getter]` attributes. +#[derive(Clone, Copy, Debug)] +pub(crate) struct GetterEntry { + pub(crate) class: GetterClass, + pub(crate) read: GetterRead, +} + +/// The record behaviours registration installs, each as groups searched in order. +#[derive(Clone, Copy, Debug)] +pub(crate) struct RecordBehaviours { + /// Records whose bound values are normalized or validated before the record is created. + pub(crate) finishers: &'static [&'static [(&'static str, RecordFinish)]], + /// `(class, attribute, getter)` computed attributes set on native classes after registration. + pub(crate) properties: &'static [&'static [(&'static str, &'static str, ClassProperty)]], + /// `(class, attribute, getter)` computed attributes a record computes once and keeps. + pub(crate) cached_properties: + &'static [&'static [(&'static str, &'static str, ClassProperty)]], + /// `(class, attribute, method)` methods set on native classes after registration. + pub(crate) methods: &'static [&'static [(&'static str, &'static str, ClassMethod)]], + /// Records ordered by their compared fields, as `order=True` dataclasses are. + pub(crate) ordered: &'static [&'static [&'static str]], + /// Native records registered as `collections.abc.Sequence` virtual subclasses. + pub(crate) sequences: &'static [&'static [&'static str]], +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs index 7fcecb19ff..dd8b3acb33 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs @@ -5,24 +5,62 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; use crate::bindings::_helpers::records::constants::{ - BUILTIN_PARENT_PREFIX, BUILTINS_MODULE, CACHED_PROPERTIES, CLASS_METHODS, CLASS_PROPERTIES, - DATACLASS_FIELD_KIND, DATACLASS_FIELDS_ATTRIBUTE, DATACLASSES_MODULE, ENUM_MODULE, ENUMS, - ERROR_SPEC_ATTRIBUTE, ERRORS, EXCEPTION_PARENT, NATIVE_MODULE, RECORD_SPEC_ATTRIBUTE, - SEQUENCE_RECORDS, STR_ENUM, VALUE_ERROR_PARENT, + BUILTIN_PARENT_PREFIX, BUILTINS_MODULE, DATACLASS_FIELD_KIND, DATACLASS_FIELDS_ATTRIBUTE, + DATACLASSES_MODULE, ENUM_MODULE, ENUMS, ERROR_SPEC_ATTRIBUTE, ERRORS, EXCEPTION_PARENT, + NATIVE_MODULE, RECORD_SPEC_ATTRIBUTE, STR_ENUM, VALUE_ERROR_PARENT, }; use crate::bindings::_helpers::records::error_classes::{ BoundErrorInitializer, ErrorInitializer, class_value, }; use std::collections::HashMap; +use crate::bindings::_helpers::record_behaviours::constants::RECORD_BEHAVIOURS; +use crate::bindings::_helpers::records::behaviours::{self, behaviours}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::{all_specs, register_specs}; +use crate::bindings::_helpers::records::getters; +use crate::bindings::_helpers::records::models::GetterEntry; use crate::bindings::_helpers::records::models::{ BoundNativeMethod, EnumSpec, ErrorSpec, NativeMethod, NativeProperty, NativeRecord, RecordAttribute, RecordSpec, }; +use crate::bindings::_helpers::{ + analysis, analysis_session, build_progress, compile_command, compile_context, compiled_views, + compute_logs, dbt_events, dbt_interop, diagnostics, discovery, event_exporting, + execution_history, graph, model_config, planner_entries, planner_migrations, planner_phases, + presentation_text, project_assembly, result_output, rules, scopes, +}; + +/// The getter tables of every module that defines native pyclasses. +static GETTER_TABLES: &[&[GetterEntry]] = &[ + analysis::getters::GETTERS, + analysis_session::getters::GETTERS, + build_progress::getters::GETTERS, + compile_command::getters::GETTERS, + compile_context::getters::GETTERS, + compiled_views::getters::GETTERS, + compute_logs::getters::GETTERS, + dbt_events::getters::GETTERS, + dbt_interop::getters::GETTERS, + diagnostics::getters::GETTERS, + discovery::getters::GETTERS, + event_exporting::getters::GETTERS, + execution_history::getters::GETTERS, + graph::getters::GETTERS, + model_config::getters::GETTERS, + planner_entries::getters::GETTERS, + planner_migrations::getters::GETTERS, + planner_phases::getters::GETTERS, + presentation_text::getters::GETTERS, + project_assembly::getters::GETTERS, + result_output::getters::GETTERS, + rules::getters::GETTERS, + scopes::getters::GETTERS, +]; pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { + getters::install(GETTER_TABLES); + behaviours::install(&RECORD_BEHAVIOURS); let py: Python<'_> = module.py(); module.add_class::()?; module.add_class::()?; @@ -60,7 +98,11 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add(spec.name, class)?; } register_specs(py, registered)?; - for (class, name, property) in CLASS_PROPERTIES.iter().flat_map(|group| group.iter()) { + for (class, name, property) in behaviours() + .properties + .iter() + .flat_map(|group| group.iter()) + { let descriptor: Py = Py::new( py, NativeProperty { @@ -71,7 +113,11 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { )?; module.getattr(*class)?.setattr(*name, descriptor)?; } - for (class, name, property) in CACHED_PROPERTIES.iter().flat_map(|group| group.iter()) { + for (class, name, property) in behaviours() + .cached_properties + .iter() + .flat_map(|group| group.iter()) + { let descriptor: Py = Py::new( py, NativeProperty { @@ -82,12 +128,12 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { )?; module.getattr(*class)?.setattr(*name, descriptor)?; } - for (class, name, method) in CLASS_METHODS.iter().flat_map(|group| group.iter()) { + for (class, name, method) in behaviours().methods.iter().flat_map(|group| group.iter()) { let descriptor: Py = Py::new(py, NativeMethod { method: *method })?; module.getattr(*class)?.setattr(*name, descriptor)?; } let sequence: Bound<'_, PyAny> = py.import("collections.abc")?.getattr("Sequence")?; - for class in SEQUENCE_RECORDS.iter().flat_map(|group| group.iter()) { + for class in behaviours().sequences.iter().flat_map(|group| group.iter()) { sequence.call_method1("register", (module.getattr(*class)?,))?; } Ok(()) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/types.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/types.rs index 6bd40b1bda..55bf747d2a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/types.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/types.rs @@ -1,7 +1,7 @@ //! Hooks applied while building native records. use pyo3::prelude::{Bound, Py, PyAny, PyResult, Python}; -use pyo3::types::{PyDict, PyTuple}; +use pyo3::types::{PyDict, PyTuple, PyType}; /// Normalizes the bound field values of one record before it is created. pub(crate) type RecordFinish = fn(Python<'_>, Vec>) -> PyResult>>; @@ -15,3 +15,10 @@ pub(crate) type ClassMethod = /// Builds the default value of one record field. pub(crate) type RecordFactory = fn(Python<'_>) -> PyResult>; + +/// Reads one `#[getter]` of a native pyclass instance by name, or `None` when the class has no such getter. +pub(crate) type GetterRead = + for<'py> fn(&Bound<'py, PyAny>, &str) -> Option>>; + +/// The type object of one native pyclass. +pub(crate) type GetterClass = for<'py> fn(Python<'py>) -> Bound<'py, PyType>; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs index 54a12a4d12..648e1410c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs @@ -5,10 +5,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::text::main::python_casefold::python_casefold; +use sqlbuild_host::entries::models::AdapterHost; use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::contracts::spec_resolution::matching_dynamic_families; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs index 0f031959a8..81a1fc8644 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs @@ -7,9 +7,9 @@ use pyo3::exceptions::PyValueError; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyBool, PyString, PyTuple}; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_command::target_writer::static_sql_test_planning_diagnostics; use crate::bindings::_helpers::compile_driver::analysis::analyze_compile_project; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/explicit_references.rs similarity index 98% rename from crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs rename to crates/sqlbuild-python/src/bindings/_helpers/references/explicit_references.rs index 221a27d6de..60a01dbf20 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/references/explicit_references.rs @@ -20,20 +20,20 @@ use sqlbuild_analysis::explicit_references::models::{ use sqlbuild_analysis::explicit_references::types::ResourceKey; use sqlbuild_config::project::main::explicit_references_help::explicit_references_help as references_help; use sqlbuild_core::panics::main::native_failure::native_failure; +use sqlbuild_host::entries::models::UserCodeHost; use sqlbuild_pysource::literal_sql::main::literal_sql_calls::literal_sql_calls; use sqlbuild_pysource::literal_sql::models::FunctionSource; -use crate::bindings::_helpers::analysis::reference_facts::{ProjectFacts, project_facts}; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::graph::execution_gates::model_python_hook_names; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::references::reference_facts::{ProjectFacts, project_facts}; use crate::bindings::types::CompilerDetach; const EXPLICIT_REFERENCES_CONTEXT: &str = "native explicit-reference checks"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/references/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/mod.rs index a46a8dc240..f183f2d284 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/references/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/references/mod.rs @@ -1,3 +1,5 @@ +pub(crate) mod explicit_references; +pub(crate) mod reference_facts; pub(crate) mod registration; pub(crate) mod relations; pub(crate) mod source_relations; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/reference_facts.rs similarity index 100% rename from crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs rename to crates/sqlbuild-python/src/bindings/_helpers/references/reference_facts.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs index 7231c263d7..620a2da1bf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs @@ -4,11 +4,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::text::main::python_casefold::python_casefold; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::analysis::relation_names::{ RelationRow, extract_sql_relation_names, }; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs index 9b7fccfde0..fd752ebcc9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs @@ -1,7 +1,8 @@ //! A declared source rendered as the SQL table factor that reads it. -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use pyo3::prelude::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs b/crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs index fe0ba7ee75..093cca6ee0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs @@ -5,9 +5,9 @@ use pyo3::types::PyDict; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_analysis::identifier_fitting::main::fit_artifact_logical_name::fit_artifact_logical_name as fit_logical; use sqlbuild_analysis::identifier_fitting::main::fit_auxiliary_relation_name::fit_auxiliary_relation_name as fit_auxiliary; +use sqlbuild_host::entries::models::FacadeHost; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; pub(crate) fn shared_error(py: Python<'_>, message: String) -> PyErr { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs index 2f52c18305..ad947ea062 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs @@ -1,5 +1,6 @@ //! Authored SQL expanded through project vars, declarations and macros, with each pass's spans. +use pyo3::prelude::Py; use pyo3::prelude::{ Bound, IntoPyObject, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; @@ -7,13 +8,14 @@ use pyo3::types::{PyDict, PyDictMethods, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; use crate::bindings::_helpers::model_config::template_data::record_reads; use crate::bindings::_helpers::model_config::unicode_environment::unicode_environment; use crate::bindings::_helpers::records::construct::error_class; -use crate::bindings::_helpers::records::construct::{new_record, new_record_with, record_class}; +use crate::bindings::_helpers::records::construct::new_record_with; +use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; +use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr}; use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::render::declaration_expansion::{ DeclarationExpansion, ExpandedDeclarations, ExpansionClasses, ExpansionConsumer, @@ -370,3 +372,66 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(substitute_sql_vars_with_spans, module)?)?; Ok(()) } + +/// The inputs authored SQL is expanded with outside a compile; the handles carry user values. +pub(crate) struct SqlExpansionInputs { + pub(crate) effective_vars: Py, + pub(crate) loaded_macros: Py, + pub(crate) macro_context: Py, + pub(crate) enums: Py, + pub(crate) constants: Py, + pub(crate) value_renderer: Py, + pub(crate) collection_rendering: Py, + /// Each model file's own declarations, by file path. + pub(crate) local_declarations: Py, + pub(crate) declaration_resolver: Py, +} + +impl SqlExpansionInputs { + /// The inputs a `SqlExpansionContext` record holds. + pub(crate) fn from_record(record: &Bound<'_, PyAny>) -> PyResult { + let field = + |name: &str| -> PyResult> { Ok(native_field(record, name)?.unbind()) }; + Ok(Self { + effective_vars: field("effective_vars")?, + loaded_macros: field("loaded_macros")?, + macro_context: field("macro_context")?, + enums: field("enums")?, + constants: field("constants")?, + value_renderer: field("value_renderer")?, + collection_rendering: field("collection_rendering")?, + local_declarations: native_field(record, "local_declarations")? + .downcast_into::()? + .unbind(), + declaration_resolver: field("declaration_resolver")?, + }) + } + + /// These inputs as a `SqlExpansionContext` record. + pub(crate) fn record<'py>(&self, py: Python<'py>) -> PyResult> { + new_record_with( + py, + RecordId::SqlExpansionContext, + &[ + ("effective_vars", self.effective_vars.bind(py).clone()), + ("loaded_macros", self.loaded_macros.bind(py).clone()), + ("macro_context", self.macro_context.bind(py).clone()), + ("enums", self.enums.bind(py).clone()), + ("constants", self.constants.bind(py).clone()), + ("value_renderer", self.value_renderer.bind(py).clone()), + ( + "collection_rendering", + self.collection_rendering.bind(py).clone(), + ), + ( + "local_declarations", + self.local_declarations.bind(py).clone().into_any(), + ), + ( + "declaration_resolver", + self.declaration_resolver.bind(py).clone(), + ), + ], + ) + } +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs index 7f83991dc6..1ab68788e4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs @@ -5,9 +5,9 @@ use pyo3::prelude::{ }; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyInt, PyList, PyString, PyTuple}; use pyo3::{IntoPyObject, pyclass, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs index 33c0d0fcb7..8ed14ac069 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs @@ -62,7 +62,7 @@ impl MacroCallMemo { path: PathBuf, environment: &str, ) -> PyResult<(Vec, usize)> { - if crate::bindings::_helpers::compile_delta::context::injection().is_some() { + if crate::bindings::_helpers::compile_context::delta::injection().is_some() { return Err(pyo3::exceptions::PyRuntimeError::new_err( "a delta compile leaves the macro call store to full compiles", )); @@ -83,7 +83,7 @@ impl MacroCallMemo { /// Whether this compile may use the call store; a delta compile leaves it to full compiles. fn store_allowed(&self) -> bool { - crate::bindings::_helpers::compile_delta::context::injection().is_none() + crate::bindings::_helpers::compile_context::delta::injection().is_none() } /// Whether this compile recorded calls the attached store does not hold yet. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs index 56347e672a..2b032702bf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs @@ -5,13 +5,11 @@ use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, P use pyo3::sync::PyOnceLock; use pyo3::types::{PyDict, PyDictMethods, PyList, PyString, PyStringMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, imported, keywords, -}; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported, keywords}; use crate::bindings::_helpers::discovery::guidance::explicit_references_help; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_member, new_record, new_record_with, record_class, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs index 87fa73b089..7dfe6b0298 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs @@ -11,7 +11,7 @@ use sqlbuild_sqltext::sql_references::models::{ }; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; +use crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs index 77c916c459..76a5730fec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs @@ -5,10 +5,10 @@ use pyo3::types::{PyDict, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; use sqlbuild_core::build_aggregate::main::aggregate_build_counts::aggregate_build_counts; use sqlbuild_core::build_aggregate::models::{BuildCounts, BuildResultFacts, ModelResultFacts}; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs index 52ef4e8003..a3ccfbe313 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs @@ -3,10 +3,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::compile_outputs::json_report::indented_json; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::values::{any, dict, items, text}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs index c0cabbca1c..783fbbb233 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs @@ -9,7 +9,7 @@ use pyo3::{pyclass, pymethods}; use sqlbuild_core::integration_results::errors::IntegrationRecordError; use sqlbuild_core::terminal_events::models::TerminalRequest; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::result_output::integration_records::{ clone_record, degraded_record, degraded_warning, execution_succeeded, integration_record, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/getters.rs new file mode 100644 index 0000000000..ae2daa943b --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/getters.rs @@ -0,0 +1,104 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; +use crate::bindings::_helpers::result_output::integration_envelope::{ + IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, +}; +use crate::bindings::_helpers::result_output::terminal_index::TerminalEventClaim; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[ + GetterEntry { + class: class_of::, + read: read_integration_asset_result, + }, + GetterEntry { + class: class_of::, + read: read_integration_check_result, + }, + GetterEntry { + class: class_of::, + read: read_integration_result_envelope, + }, + GetterEntry { + class: class_of::, + read: read_terminal_event_claim, + }, +]; + +fn read_integration_asset_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +fn read_integration_check_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" | "decoded" | "parsed" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +fn read_integration_result_envelope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "asset" => this.asset(py).into_bound_py_any(py), + "checks" => this.checks(py).into_bound_py_any(py), + "from_json" | "from_json_without_optional_enrichment" | "register" | "to_json" => { + return None; + } + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +fn read_terminal_event_claim<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "terminal" => (&this.terminal).into_bound_py_any(py), + "event_sequence" => (&this.event_sequence).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs index 5ad6ed5ace..ecfc177dc2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs @@ -8,8 +8,8 @@ use pyo3::types::{ use sqlbuild_core::integration_results::errors::IntegrationRecordError; use sqlbuild_core::integration_results::main::encode_integration_value::encode_integration_value; use sqlbuild_core::json::models::{JsonInteger, JsonValue}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; /// A contract failure, or a Python failure while reading the values. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/mod.rs index ac7be681a2..e68e0fd101 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/mod.rs @@ -3,6 +3,7 @@ pub(crate) mod assets; pub(crate) mod checks; pub(crate) mod documents; pub(crate) mod event_writer; +pub(crate) mod getters; pub(crate) mod integration_envelope; pub(crate) mod integration_records; pub(crate) mod integration_values; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs index 32dfecc1e6..61ee4d6220 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs @@ -2,8 +2,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyRef, PyResult, Python}; use pyo3::types::{PyFloat, PyInt}; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::plan_output::values::text; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs index 1981991cba..31a7b13635 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs @@ -10,7 +10,7 @@ use pyo3::types::{PyDict, PyInt, PyString, PyTuple}; use pyo3::{pyclass, pyfunction, pymethods, wrap_pyfunction}; use sqlbuild_core::terminal_events::main::claim_resource_terminal::claim_resource_terminal; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::NativeAttr; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs index 955823e09e..02b51f667e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs @@ -8,14 +8,14 @@ use pyo3::types::{ PyBool, PyCFunction, PyDict, PyDictMethods, PyInt, PyString, PyTuple, PyTupleMethods, }; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; use sqlbuild_rules::models::RulesConfig; use sqlbuild_rules::rule_catalogue::main::sorted_catalogue_order::sorted_catalogue_order; use sqlbuild_rules::rule_catalogue::models::{CatalogueRule, OptionKind, OptionSpec, OptionValue}; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_scope::scope::build_planner_scope; use crate::bindings::_helpers::records::fields::{field as record_field, path_posix, replaced}; use crate::bindings::_helpers::rules::builtin_catalogue::builtin_rules; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs index 06199b4ab1..b137b22c4d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs @@ -15,9 +15,9 @@ use sqlbuild_rules::custom_host_pool::types::{FactKey, HostPlan}; use sqlbuild_rules::custom_rule_cache::models::CustomEvaluation; use sqlbuild_rules::custom_rule_cache::types::ReadSet; +use crate::bindings::_helpers::boundary::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::cache::native_store::current_code_identity; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; @@ -98,11 +98,11 @@ pub(crate) fn evaluate_custom_rules_cached<'py>( let project_dir: PathBuf = run.project_dir.extract()?; let mut digests: FactDigests<'py> = FactDigests::new(run.project, &project_dir)?; let models: Vec<(String, String, Option)> = - match crate::bindings::_helpers::compile_delta::context::injection() { + match crate::bindings::_helpers::compile_context::delta::injection() { Some(injection) => { let Some(mut rows) = injection.model_subjects.clone() else { return Err( - crate::bindings::_helpers::compile_delta::context::delta_unsupported( + crate::bindings::_helpers::compile_context::delta::delta_unsupported( "the custom rules' subjects were not recorded", ), ); @@ -117,7 +117,7 @@ pub(crate) fn evaluate_custom_rules_cached<'py>( } None => { let rows: Vec<(String, String, Option)> = digests.replay.model_rows()?; - crate::bindings::_helpers::compile_delta::context::capture(|capture| { + crate::bindings::_helpers::compile_context::delta::capture(|capture| { capture.model_subjects = Some(rows.clone()); }); rows @@ -137,10 +137,10 @@ pub(crate) fn evaluate_custom_rules_cached<'py>( readset_digests.push(reproducible(digests.combined(readset))?); } let plan: HostPlan = cache.plan(readset_digests); - if !plan.is_empty() && crate::bindings::_helpers::compile_delta::context::injection().is_some() + if !plan.is_empty() && crate::bindings::_helpers::compile_context::delta::injection().is_some() { return Err( - crate::bindings::_helpers::compile_delta::context::delta_unsupported( + crate::bindings::_helpers::compile_context::delta::delta_unsupported( "a custom rule must run again", ), ); @@ -168,7 +168,7 @@ pub(crate) fn evaluate_custom_rules_cached<'py>( let evaluations: Vec = evaluations(host_run, &mut digests, enabled)?; cache.record(py, evaluations)?; } - crate::bindings::_helpers::compile_delta::context::capture(|capture| { + crate::bindings::_helpers::compile_context::delta::capture(|capture| { capture.fact_digests.extend( digests .digests @@ -275,7 +275,7 @@ impl<'py> FactDigests<'py> { return Ok(cached.clone()); } if let Some(injected) = - crate::bindings::_helpers::compile_delta::context::injected_fact_digest(key) + crate::bindings::_helpers::compile_context::delta::injected_fact_digest(key) { self.digests.insert(key.clone(), injected.clone()); return Ok(injected); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_payload.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_payload.rs index e18d3fda33..fc3a56479c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_payload.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_payload.rs @@ -11,8 +11,8 @@ use pyo3::types::{ use serde_json::{Map, Value, json}; use sqlbuild_discovery::models::LineColumnSpan; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::records::{ +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_views::records::{ compiled_audit_record, compiled_function_record, compiled_seed_record, compiled_source_record, }; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs index 7cabe5d7d5..15770e2b81 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs @@ -13,6 +13,7 @@ use pyo3::exceptions::PyKeyboardInterrupt; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::PyBytes; use serde_json::{Map, Value, json}; +use sqlbuild_host::entries::constants::CUSTOM_HOST_LAUNCH_MODULE; use sqlbuild_rules::custom_host_pool::constants::{ CGROUP_ROOT, HOST_TIMEOUT_MILLIS, MIN_INVOCATIONS_PER_HOST, PROC_CGROUP, }; @@ -27,8 +28,7 @@ use sqlbuild_rules::custom_host_pool::models::{HostRuleSubject, HostRun, HostSli use sqlbuild_rules::custom_host_pool::types::{HostInvocation, HostPlan}; use sqlbuild_rules::engine::main::custom_host::run_custom_host_json; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::native_host::constants::CUSTOM_HOST_LAUNCH_MODULE; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::rules::constants::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs index d3a30786e6..03c8537acd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs @@ -16,7 +16,7 @@ use sqlbuild_pysource::rule_evidence::models::{ DisallowedImport, RuleTestEvidence, UnparsedSource, }; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_builtin_rules.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_builtin_rules.rs index ad7205070d..7baeba25dd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_builtin_rules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_builtin_rules.rs @@ -8,6 +8,9 @@ use std::time::Instant; use pyo3::exceptions::PyException; use pyo3::prelude::{Bound, IntoPyObject, PyAny, PyAnyMethods, PyResult, Python}; +use sqlbuild_host::compile_context::main::add_compile_timing::add_compile_timing; +use sqlbuild_host::compile_context::main::record_compile_metric::record_compile_metric; +use sqlbuild_host::compile_context::main::record_compile_timing::record_compile_timing; use sqlbuild_rules::engine::main::answer_speculative_rows::answer_speculative_rows; use sqlbuild_rules::engine::main::discard_speculative_rows::discard_speculative_rows; use sqlbuild_rules::engine::main::start_speculative_rows::start_speculative_rows; @@ -15,11 +18,8 @@ use sqlbuild_rules::errors::RowsError; use sqlbuild_rules::models::{RowsEvaluation, RowsRequest, SpeculativeAnswer, SpeculativeRows}; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compile_driver::compile_timings::{ - add_compile_timing, record_compile_metric, record_compile_timing, -}; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::records::{ +use crate::bindings::_helpers::compiled_views::records::{ compiled_project_facts, record_model_analyses, }; use crate::bindings::_helpers::records::fields::field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs index 61fad4cdb1..5781e5abd8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs @@ -21,21 +21,21 @@ use sqlbuild_rules::rule_cache::main::rules_bulk_cache_path::rules_bulk_cache_pa use sqlbuild_rules::rules::main::selected_sql_codes::selected_sql_codes; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::{ - SqlExpansionInputs, present, +use crate::bindings::_helpers::compile_attachment::sql_expansion_context::present; +use crate::bindings::_helpers::compiled_views::relation_keys::model_key_row; +use crate::bindings::_helpers::compiled_views::relation_keys::{ + RelationKeyRow, RelationKeys, one_row_seed_names, relation_keys, source_key_input, }; use crate::bindings::_helpers::native_threads::interruptible_join::{Joined, join_interruptibly}; use crate::bindings::_helpers::records::fields::field as record_field; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::rules::lint_expansion::{ LintExpansionSources, lint_expansion_inputs, }; -use crate::bindings::_helpers::rules::lint_inputs::{model_key_row, model_lint_expansion}; +use crate::bindings::_helpers::rules::lint_inputs::model_lint_expansion; use crate::bindings::_helpers::rules::lint_pipeline::{ CompiledSource, LintFile, LintOutcome, LintRequest, LintSettings, lint, lint_sources, }; -use crate::bindings::_helpers::rules::relation_keys::{ - RelationKeyRow, RelationKeys, one_row_seed_names, relation_keys, source_key_input, -}; use crate::bindings::_helpers::rules::rule_cache::stored_entries; use crate::bindings::_helpers::rules::rules_config::rules_config_of; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs index ff7e5d1568..8fce4a2148 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs @@ -18,7 +18,7 @@ use sqlbuild_cache::digest::main::sha256_hex::sha256_hex; use sqlbuild_core::json::main::dumps::dumps; use sqlbuild_core::json::models::{JsonDialect, JsonValue, OrjsonOptions}; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::record_spec; use crate::bindings::_helpers::records::models::NativeRecord; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs index 1fae745e26..b79144b27a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs @@ -13,14 +13,14 @@ use sqlbuild_rules::project_tree::main::resolve_project_path::resolve_project_pa use sqlbuild_rules::project_tree::main::tracked_text_path::tracked_text_path; use sqlbuild_rules::project_tree::models::ProjectTreeEntry; -use crate::bindings::_helpers::compiled_project::audit_views::NativeCompiledAudit; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_views::audit_views::NativeCompiledAudit; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ InferredRow, NativeCompiledModel, }; -use crate::bindings::_helpers::compiled_project::function_views::NativeCompiledFunction; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; -use crate::bindings::_helpers::compiled_project::seed_views::NativeCompiledSeed; -use crate::bindings::_helpers::compiled_project::source_views::NativeCompiledSource; +use crate::bindings::_helpers::compiled_views::function_views::NativeCompiledFunction; +use crate::bindings::_helpers::compiled_views::project_view::NativeProjectView; +use crate::bindings::_helpers::compiled_views::seed_views::NativeCompiledSeed; +use crate::bindings::_helpers::compiled_views::source_views::NativeCompiledSource; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as record_field_or_attribute; use crate::bindings::_helpers::records::fields::record_spec; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs index 932c2a997c..98cfc3b12c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs @@ -10,21 +10,24 @@ use pyo3::types::{ PyDict, PyDictMethods, PyFrozenSet, PyList, PyListMethods, PyString, PyStringMethods, PyTuple, }; use sqlbuild_core::text::main::python_strip::python_strip; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_rules::fix_verification::main::refusal::refusal; use sqlbuild_rules::fix_verification::main::with_edits::with_edits; use sqlbuild_rules::fix_verification::models::{FixEdit, FixEligibility}; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::compile_driver::project::build_compiled_project; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; +use crate::bindings::_helpers::compiled_views::relation_keys::{ + RelationKeys, project_relation_keys, +}; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::{field, replaced}; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::rules::constants::SAFE_RULE_FIX_CODES; use crate::bindings::_helpers::rules::fix_facts::compile_facts; use crate::bindings::_helpers::rules::fix_verdict::fix_verdict; @@ -34,7 +37,6 @@ use crate::bindings::_helpers::rules::lint_expansion::{ use crate::bindings::_helpers::rules::lint_pipeline::{ LintFile, LintOutcome, LintRequest, LintSettings, ViolationClasses, lint, lint_sources, }; -use crate::bindings::_helpers::rules::relation_keys::{RelationKeys, project_relation_keys}; use crate::bindings::_helpers::rules::run_lint::given_files; const VERIFICATION_FAILURE: &str = diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/getters.rs new file mode 100644 index 0000000000..a5aa801090 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/getters.rs @@ -0,0 +1,31 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; +use crate::bindings::_helpers::rules::early_sql_lint::EarlySqlLint; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_early_sql_lint, +}]; + +fn read_early_sql_lint<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "enabled" => (&this.enabled).into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs index 9e31779378..a56fcdb084 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs @@ -19,7 +19,7 @@ use sqlbuild_rules::rule_catalogue::main::skill_lock_name::skill_lock_name; use sqlbuild_rules::rule_catalogue::models::{FingerprintRule, OptionText, RuleText, SkillTarget}; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::fields::field as record_field; use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::rules::catalogue::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint.rs index c28d595f73..17a656ed28 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint.rs @@ -6,7 +6,7 @@ use sqlbuild_rules::lint_text::models::InterpolationSite; use sqlbuild_rules::sql_lint::types::PreparedSql; use crate::bindings::_helpers::boundary::panics::{compiler_guard, value_error}; -use crate::bindings::_helpers::rules::relation_keys; +use crate::bindings::_helpers::compiled_views::relation_keys; use crate::bindings::models::Positional; use crate::bindings::types::CompilerDetach; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs index fe0fc58faa..d84b4a5c3b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs @@ -5,19 +5,20 @@ use pyo3::prelude::{ }; use pyo3::types::{PyBool, PyDict}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::compile_attachment::sql_expansion_context::{ - ExpansionSources, SqlExpansionInputs, present, sql_expansion_inputs, + ExpansionSources, present, sql_expansion_inputs, }; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; const COMPILE_FIRST_MESSAGE: &str = "compiler-integrated Rules check the SQL your project \ actually produces, so the project must compile first"; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs index 164895dc88..6cc4c01404 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs @@ -6,34 +6,18 @@ use std::sync::Arc; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::model_input_view::{ - ExpansionRecord, ModelInputRecord, NativeModelInput, model_relation_key_row, +use crate::bindings::_helpers::compiled_views::model_input_view::{ + ExpansionRecord, ModelInputRecord, NativeModelInput, }; -use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; +use crate::bindings::_helpers::compiled_views::project_view::NativeProjectView; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::render::macro_call_rows::SpanRow; use crate::bindings::_helpers::rules::lint_pipeline::{ CompiledExpansion, CompiledSource, span_pass, }; -use crate::bindings::_helpers::rules::relation_keys::RelationKeyRow; const FILE_PATH_ATTRIBUTE: &str = "file_path"; -/// The declared key facts of a model input or compiled model. -pub(crate) fn model_key_row(model: &Bound<'_, PyAny>) -> PyResult { - let py: Python<'_> = model.py(); - if let Ok(input) = model.downcast::() { - return input.get().read_with_owner(py, |owner, record| { - model_relation_key_row(owner, record, py) - }); - } - if let Ok(compiled) = model.downcast::() { - return compiled.get().relation_key_row(py); - } - native_field(model, "relation_key_row")?.extract() -} - /// The model file path of a native input record. fn record_path(record: &ModelInputRecord) -> PathBuf { record.model_file.get().file_path_buf() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs index 3349c48537..c6b4431710 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs @@ -37,12 +37,12 @@ use sqlbuild_rules::sql_lint::main::preparation::prepare; use sqlbuild_rules::sql_lint::types::PreparedSql; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as record_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::render::authored_sql::{AuthoredExpansion, expand_with_inputs}; use crate::bindings::_helpers::render::macro_call_rows::SpanRow; use crate::bindings::_helpers::rules::dsl_headers::header_violations; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs index 155fe9f742..0c16e70692 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs @@ -5,11 +5,11 @@ use pyo3::pyfunction; use pyo3::types::{PyBool, PyDict, PyTuple}; use sqlbuild_rules::lint_text::models::{ExpansionSpan, LintSqlBody}; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::rules::lint_pipeline::{ BodyRole, SingleBody, SingleBodyRequest, prepare_single_body, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/mod.rs index 677f355f6e..ed6a942378 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/mod.rs @@ -22,6 +22,7 @@ pub(crate) mod fix_session; pub(crate) mod fix_verdict; pub(crate) mod fixture_formatting; pub(crate) mod fixture_schemas; +pub(crate) mod getters; pub(crate) mod guidance; pub(crate) mod lint; pub(crate) mod lint_expansion; @@ -34,7 +35,6 @@ pub(crate) mod lint_text; pub(crate) mod native_header_parser; pub(crate) mod project_tree_queries; pub(crate) mod registration; -pub(crate) mod relation_keys; pub(crate) mod results; pub(crate) mod rows; pub(crate) mod rule_api; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs index 7cd3411a79..2e6dbeb1fc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs @@ -21,7 +21,7 @@ use sqlbuild_rules::project_tree::main::project_tree_glob::project_tree_glob; use sqlbuild_rules::project_tree::main::read_project_text::read_project_text; use sqlbuild_rules::project_tree::main::resolve_project_path::resolve_project_path; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs index f4e41c3b2b..d64b31bc13 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs @@ -13,7 +13,7 @@ use sqlbuild_rules::rule_results::main::format_rules_progress::format_rules_prog use sqlbuild_rules::rule_results::main::format_skipped_rules::format_skipped_rules; use sqlbuild_rules::rule_results::models::{ResultCounts, RuleFinding}; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::{field, path_posix, replaced}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs index e90de02503..d069c5a342 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs @@ -28,13 +28,13 @@ use sqlbuild_rules::rule_cache::main::rules_bulk_cache_path::rules_bulk_cache_pa use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::boundary::panics::{compiler_guard, value_error}; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cache::native_store::current_code_identity; -use crate::bindings::_helpers::compile_driver::python_calls::imported; -use crate::bindings::_helpers::compiled_project::audit_views::NativeCompiledAudit; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; -use crate::bindings::_helpers::compiled_project::records::compiled_project_facts; -use crate::bindings::_helpers::compiled_project::records::declaration_rows; use crate::bindings::_helpers::compiled_project::values::plain_value; +use crate::bindings::_helpers::compiled_views::audit_views::NativeCompiledAudit; +use crate::bindings::_helpers::compiled_views::records::compiled_project_facts; +use crate::bindings::_helpers::compiled_views::records::declaration_rows; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field; use crate::bindings::_helpers::records::ids::RecordId; @@ -306,7 +306,7 @@ fn built_request( request.models = built_models(&rows, &request, model_rows)?; let request: EvaluateRequest = crate::bindings::_helpers::compile_delta::rules_rows::whole_project_request(request)?; - let delta: bool = crate::bindings::_helpers::compile_delta::context::injection().is_some(); + let delta: bool = crate::bindings::_helpers::compile_context::delta::injection().is_some(); let memo: Option<(String, PathBuf)> = rows .memo .take() @@ -315,7 +315,7 @@ fn built_request( Ok(RowsRequest { request, memo, - retain: crate::bindings::_helpers::compile_delta::context::capturing(), + retain: crate::bindings::_helpers::compile_context::delta::capturing(), }) }) } @@ -356,9 +356,9 @@ fn evaluated<'py>( RowsError::Io(error) => PyOSError::new_err(error.to_string()), })?; if let Some(retained) = evaluation.retained.take() { - crate::bindings::_helpers::compile_delta::context::capture(|capture| { + crate::bindings::_helpers::compile_context::delta::capture(|capture| { capture.rules = - Some(crate::bindings::_helpers::compile_delta::context::CapturedRules { retained }); + Some(crate::bindings::_helpers::compile_context::delta::CapturedRules { retained }); }); } let classes = FindingClasses::new(py)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs index fba9d659fa..0da4df7dd6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs @@ -16,7 +16,7 @@ use sqlbuild_rules::project_tree::main::project_path_escapes::project_path_escap use sqlbuild_rules::project_tree::main::project_tree_entries::project_tree_entries; use sqlbuild_rules::project_tree::models::ProjectTreeEntry; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs index 3d30794f32..1681736db9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs @@ -14,14 +14,13 @@ use pyo3::prelude::{ use pyo3::types::{PyDict, PyTuple}; use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with, keywords}; use crate::bindings::_helpers::cache::native_store::current_code_identity; -use crate::bindings::_helpers::compile_driver::python_calls::{ - KeywordArguments, call_with, keywords, -}; use crate::bindings::_helpers::compile_driver::stage_work::count_stage; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs index 5d2745fb88..abce3d3f30 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs @@ -3,15 +3,15 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyFrozenSet, PySet, PySetMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::UserCodeHost; use sqlbuild_rules::project_tree::main::pure_path_posix::pure_path_posix; use std::path::Path; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compiled_project::records::project_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::compiled_views::records::project_with; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::{field, replaced}; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs index 56f766520f..3050ceeae5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs @@ -12,7 +12,7 @@ use sqlbuild_rules::rule_results::main::group_unevaluated::group_unevaluated; use sqlbuild_rules::rule_results::models::RuleFinding; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as record_field; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/run_lint.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/run_lint.rs index 9885fb6da7..0eddfda678 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/run_lint.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/run_lint.rs @@ -7,10 +7,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyDict, PyDictMethods}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::compile_attachment::sql_expansion_context::{ - SqlExpansionInputs, present, -}; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compile_attachment::sql_expansion_context::present; +use crate::bindings::_helpers::render::authored_sql::SqlExpansionInputs; use crate::bindings::_helpers::rules::lint_expansion::{ LintExpansionSources, lint_expansion_inputs, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs index 66ea5cdef2..eb0982207b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs @@ -17,12 +17,13 @@ use sqlbuild_rules::rule_cache::main::file_rule_key::file_rule_key; use sqlbuild_rules::rule_results::main::duplicate_literal_hints::duplicate_literal_hints; use sqlbuild_rules::rule_results::models::RuleFinding; -use crate::bindings::_helpers::analysis::model_reads::output_proven; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::boundary::python_calls::{imported, keywords}; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ NativeCompiledModel, SqlRuleInputs, SqlRuleKey, }; +use crate::bindings::_helpers::compiled_views::model_reads::output_proven; +use crate::bindings::_helpers::compiled_views::relation_keys::project_relation_keys; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field; @@ -41,7 +42,6 @@ use crate::bindings::_helpers::rules::lint_pipeline::{ CompiledSource, LintFile, LintOutcome, LintRequest, LintSettings, LintViolationRow, lint, lint_sources, outside_project, resolved, }; -use crate::bindings::_helpers::rules::relation_keys::project_relation_keys; use crate::bindings::_helpers::rules::rule_cache::{ ModelRuleRow, StoredEntries, cached_rule_findings, encoded_findings, model_rule_keys, settings_lint_key, stored_entries, write_rule_cache, @@ -148,7 +148,7 @@ pub(crate) fn run_planned_sql_rules<'py>( let project_files: Option> = if !identities.is_empty() && run.prepared().is_none() && !run.model_selection - && crate::bindings::_helpers::compile_delta::context::injection().is_none() + && crate::bindings::_helpers::compile_context::delta::injection().is_none() { Some(lint_sources(&run.project_dir, None, None)?) } else { @@ -356,7 +356,7 @@ fn linted_files( let py: Python<'_> = run.project.py(); let project_dir: &Path = &run.project_dir; let prepared = prepared_result(run, py); - if crate::bindings::_helpers::compile_delta::context::injection().is_some() { + if crate::bindings::_helpers::compile_context::delta::injection().is_some() { return crate::bindings::_helpers::compile_delta::lint_hooks::changed_files(project_dir); } Ok(match prepared { @@ -613,9 +613,7 @@ fn path_rows(outcome: LintOutcome) -> Vec<(PathBuf, LintViolationRow)> { /// Build lint expansion, reusing the compiler's scope only for the same discovery. fn lint_expansion_context( run: &SqlRun<'_, '_>, -) -> PyResult< - crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs, -> { +) -> PyResult { let py: Python<'_> = run.project.py(); let declaration_scope: Option> = run .early_lint diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs index 963703505b..9a9f3ff91a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs @@ -11,8 +11,8 @@ use sqlbuild_rules::models::{ }; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compiled_project::records::plain_typed_value; use crate::bindings::_helpers::compiled_project::values::plain_value; +use crate::bindings::_helpers::compiled_views::records::plain_typed_value; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs index 470ab6f736..098af3218c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs @@ -8,9 +8,9 @@ use sqlbuild_core::cli_text::models::{CliStyle, SummaryCount}; use sqlbuild_core::scenario_command::main::snapshot_capture_warning::snapshot_capture_warning; use sqlbuild_core::scenario_command::main::sql_analysis_required_error::sql_analysis_required_error; use sqlbuild_core::scenario_command::models::SqlAnalysisCommand; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::scenario_command::conversions::succeeded; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs index 6041f97185..d73bd9d710 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs @@ -14,9 +14,9 @@ use sqlbuild_core::scenario_command::models::{ FixtureStatements, FunctionStatements, LoadedRelation, LocalRuntimeInputs, ModelArtifactEntry, NamedStatements, RetainedInputs, RetainedRelation, ScenarioResultRow, WarehouseRuntimeInputs, }; +use sqlbuild_host::entries::models::AdapterHost; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_from_value; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs index 0762d7b65e..1de783b86a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs @@ -11,12 +11,12 @@ use sqlbuild_core::scenario_command::main::render_scenario_result::render_scenar use sqlbuild_core::scenario_command::main::render_snapshot_sync_result::render_snapshot_sync_result; use sqlbuild_core::scenario_command::main::scenario_activity_message::scenario_activity_message; use sqlbuild_core::scenario_command::models::ScenarioNamespace; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::scenario_command::conversions::{ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs index 2c128fe959..f24d9e5d66 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs @@ -19,20 +19,20 @@ use sqlbuild_core::scenario_command::models::{ NamespaceCandidates, ScenarioFile, ScenarioNamespace, ScenarioSelection, SnapshotLimitConfig, SnapshotLimitInputs, SnapshotLimits, SqlAnalysisCommand, }; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{call_with, within}; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::command_runtime::adapters::resolve_cli_adapter; use crate::bindings::_helpers::command_runtime::connection::resolve_project_connection_config; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::pipeline_entries::run_compile_only_pipeline; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, within}; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_scenario_config; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; use crate::bindings::_helpers::discovery::guidance::sql_analysis_guidance; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs index d125ca59c2..3b64b7d7e4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs @@ -6,11 +6,11 @@ use sqlbuild_core::cli_text::main::format_summary_footer::format_summary_footer; use sqlbuild_core::cli_text::models::SummaryCount; use sqlbuild_core::scenario_command::main::snapshot_capture_warning::snapshot_capture_warning; use sqlbuild_core::scenario_command::models::ScenarioNamespace; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::cli::progress_reporters::PlanningProgressReporter; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::build_progress::progress_reporters::PlanningProgressReporter; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::result_output::documents::format_scenario_snapshot_execution_json; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs index 8ee77168f2..dc9607e854 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs @@ -12,11 +12,11 @@ use sqlbuild_core::scenario_command::main::validate_scenario_test_flags::validat use sqlbuild_core::scenario_command::models::{ ScenarioNamespace, ScenarioTestFlags, SqlAnalysisCommand, }; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::result_output::documents::format_scenario_execution_json; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs index 58e7eddeb9..bd93222659 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs @@ -14,18 +14,20 @@ use sqlbuild_scopes::compile_usages::main::schema_scope_usages::schema_scope_usa use sqlbuild_scopes::compile_usages::models::{ DependencySource, InaccessibleDiagnostic, NamedRecord, SchemaDeclaration, SchemaUsages, }; +use sqlbuild_scopes::scope_index::main::normalize_scope_path::normalize_scope_path; use sqlbuild_scopes::scope_index::models::{ - DeclarationKind, DeclaredScope, ResourceIdentity, ResourceKind, ScopeKind, + DeclarationKind, DeclaredScope, ResourceIdentity, ResourceKind, ScopeKind, ScopePathFailure, }; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; -use crate::bindings::_helpers::compiled_project::model_loop_named::scope_path_message; +use crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +/// The folder a scope path is relative to when its owner names none. +pub(crate) const CURRENT_FOLDER: &str = "."; const INACCESSIBLE_DECLARATION_CODE: &str = "S006"; const SCHEMA_USAGE_KINDS: [&str; 2] = ["schema", "enum"]; @@ -298,3 +300,25 @@ pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> { module.add_function(wrap_pyfunction!(model_schema_scope_usages, module)?)?; Ok(()) } + +/// The `InvalidScopePathError` message of the first path Python's visibility check rejects. +pub(crate) fn scope_path_message(declared: &DeclaredScope, label: &str) -> String { + let owner: &str = declared + .owning_path + .as_deref() + .filter(|path| !path.is_empty()) + .unwrap_or(CURRENT_FOLDER); + let (path, failure) = match normalize_scope_path(label) { + Err(failure) => (label, failure), + Ok(_) => match normalize_scope_path(owner) { + Err(failure) => (owner, failure), + Ok(_) => (label, ScopePathFailure::NotProjectRelative), + }, + }; + match failure { + ScopePathFailure::NotProjectRelative => { + format!("Scope path must be project-relative: {path}") + } + ScopePathFailure::EscapesProject => format!("Scope path escapes the project: {path}"), + } +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/getters.rs new file mode 100644 index 0000000000..6f9008f8ba --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/getters.rs @@ -0,0 +1,34 @@ +//! Direct `#[getter]` reads of this module's native pyclasses, installed into `records::getters`. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::records::getters::class_of; +use crate::bindings::_helpers::records::models::GetterEntry; +use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; + +/// The getter readers of this module's native pyclasses. +pub(crate) const GETTERS: &[GetterEntry] = &[GetterEntry { + class: class_of::, + read: read_native_scope_index, +}]; + +fn read_native_scope_index<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "index" => this.index(py).into_bound_py_any(py), + "has_scoped_relationship_declarations" => this + .has_scoped_relationship_declarations() + .into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/mod.rs index d5d93cd1f1..5c1b242f57 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/mod.rs @@ -1,6 +1,7 @@ pub(crate) mod compile_usages; pub(crate) mod declaration_contexts; pub(crate) mod declaration_resolution; +pub(crate) mod getters; pub(crate) mod placement; pub(crate) mod registration; pub(crate) mod relationship_names; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs index df43d56320..274f7329b6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs @@ -1,6 +1,6 @@ //! Report a scope index's error findings as individual compile diagnostics. -use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; +use crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs index 80cdf70d97..5259110f2a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs @@ -9,17 +9,17 @@ use pyo3::prelude::{ use pyo3::types::{PyBool, PyCFunction, PyDict, PyDictMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::{AdapterHost, UserCodeHost}; + +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::compile_driver::discovery::discover_project_inputs; use crate::bindings::_helpers::compile_driver::inputs::{InputsRequest, attached_inputs}; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_collection_rendering; use crate::bindings::_helpers::discovery::scope_snapshot::discover_scope_snapshot; use crate::bindings::_helpers::frontier::cache_directory::cache_directory; use crate::bindings::_helpers::frontier::compile_frontier::{FrontierStage, bridged, produced}; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; -use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs index bb699daa8c..a532e253a1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs @@ -20,7 +20,7 @@ use sqlbuild_scopes::scope_report::models::{ ScopeResult, }; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs index 8ddc2ef87f..bd5caf53ff 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs @@ -355,7 +355,7 @@ pub(crate) fn scope_index_with_compile_usages<'py>( usages.extend(usage_records( model_schema_scope_usages(&schema_files, &resolver)?.as_any(), )?); - let digests: bool = crate::bindings::_helpers::compile_delta::context::capturing(); + let digests: bool = crate::bindings::_helpers::compile_context::delta::capturing(); for model in native_field(inputs, "model_inputs")?.try_iter()? { let model: Bound<'py, PyAny> = model?; let macro_usages: Vec> = @@ -363,7 +363,7 @@ pub(crate) fn scope_index_with_compile_usages<'py>( let declaration_usages: Vec> = usage_records(&native_field(&model, "declaration_usages")?)?; if digests { - crate::bindings::_helpers::compile_delta::image_facts::record_model_usages( + crate::bindings::_helpers::compile_context::image_facts::record_model_usages( &model, (¯o_usages, &declaration_usages), )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs index 80fc6e43fe..c5938f72c1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs @@ -13,19 +13,19 @@ use sqlbuild_core::seed_command::main::render_seed_ready::render_seed_ready; use sqlbuild_core::seed_command::main::render_seed_row::render_seed_row; use sqlbuild_core::seed_command::main::seed_exit_code::seed_exit_code; use sqlbuild_core::seed_command::models::SeedRow; +use sqlbuild_host::entries::models::ExecutorHost; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::write_execution_header; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::write_execution_header; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; use crate::bindings::_helpers::command_runtime::invocation::resolve_command_invocation; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_static_pipeline_result; use crate::bindings::_helpers::compile_driver::plan_result::connection_with_hooks; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::selection_phases::compile_static_command_context; +use crate::bindings::_helpers::compile_driver::static_context::compile_static_command_context; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::command_plans::build_seed_command_plan; use crate::bindings::_helpers::planner_entries::command_plans::read_selected_seed_fingerprints; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs index d96aedc5b0..fc4d785cc2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs @@ -8,10 +8,10 @@ use sqlbuild_analysis::semantic_checks::models::{ CompletedDiagnostic, CompletionModel, CompletionRequest, SemanticDiagnostic, SemanticLocation, }; -use crate::bindings::_helpers::analysis::model_reads::{inferred_names, lineage_inputs}; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::compiled_model_view::LineageInput; -use crate::bindings::_helpers::compiled_project::records::with_binding_diagnostics; +use crate::bindings::_helpers::compiled_views::compiled_model_view::LineageInput; +use crate::bindings::_helpers::compiled_views::model_reads::{inferred_names, lineage_inputs}; +use crate::bindings::_helpers::compiled_views::records::with_binding_diagnostics; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::semantic_checks::failures::semantic_error; use crate::bindings::_helpers::semantic_checks::metadata::{ShapeRows, shape_rows}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs index 02e58040ce..0f94b34c7b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs @@ -14,11 +14,11 @@ use sqlbuild_analysis::semantic_checks::models::{ }; use sqlbuild_analysis::semantic_validation::models as validation; -use crate::bindings::_helpers::analysis::model_reads::binding_validated; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ ModelMetadataTexts, NativeCompiledModel, }; +use crate::bindings::_helpers::compiled_views::model_reads::binding_validated; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs index cdf45c3cc2..78d4bec4fb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs @@ -14,9 +14,9 @@ use sqlbuild_analysis::semantic_checks::models::{ }; use crate::bindings::_helpers::boundary::panics::compiler_error; -use crate::bindings::_helpers::compiled_project::audit_views::audit_reference_rows; -use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::audit_views::audit_reference_rows; +use crate::bindings::_helpers::compiled_views::compiled_model_view::NativeCompiledModel; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs index 14e1670531..ec25af3008 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs @@ -6,10 +6,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRef use pyo3::types::{PyDict, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::analysis::model_reads::output_proven; use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::boundary::panics::NativeCompilerError; +use crate::bindings::_helpers::compiled_views::model_reads::output_proven; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::rules::early_builtin_rules::start_early_rules; use crate::bindings::_helpers::semantic_checks::completion::completed_diagnostics; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs index 88ef5a4e07..17c76962a9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs @@ -1,7 +1,8 @@ //! The Python models, enums and compile helpers the semantic completion stage reads and builds. -use crate::bindings::_helpers::compiled_project::records::project_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use sqlbuild_host::entries::models::AdapterHost; + +use crate::bindings::_helpers::compiled_views::records::project_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs index ec5af8c9ba..c75a2b2af4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs @@ -13,12 +13,12 @@ use sqlbuild_analysis::semantic_checks::types::RevisedBinding; use sqlbuild_analysis::semantic_validation::models as validation; use crate::bindings::_helpers::analysis::binding_catalog::schema_validations; -use crate::bindings::_helpers::analysis::model_reads::{inferred_names, lineage_inputs}; use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::compile_driver::stage_work::count_stage; -use crate::bindings::_helpers::compiled_project::compiled_model_view::LineageInput; -use crate::bindings::_helpers::compiled_project::records::with_type_recovery; +use crate::bindings::_helpers::compiled_views::compiled_model_view::LineageInput; +use crate::bindings::_helpers::compiled_views::model_reads::{inferred_names, lineage_inputs}; +use crate::bindings::_helpers::compiled_views::records::with_type_recovery; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::fields::mapping_items; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs index d3dc4ed58f..be48aa10f0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs @@ -6,11 +6,11 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyRes use pyo3::types::{PyBool, PyDict, PyDictMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; -use crate::bindings::_helpers::analysis::model_reads::{inferred_rows, star_flags}; -use crate::bindings::_helpers::compile_delta::coverage::ModelCoverage; -use crate::bindings::_helpers::compile_delta::report_hooks::semantic_reasons; -use crate::bindings::_helpers::compiled_project::compiled_model_view::InferredRow; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; +use crate::bindings::_helpers::compiled_views::compiled_model_view::InferredRow; +use crate::bindings::_helpers::compiled_views::model_reads::{inferred_rows, star_flags}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::semantic_shapes::delta_shapes::semantic_reasons; use crate::bindings::_helpers::semantic_shapes::shapes::project_shapes; const TYPE_CHECKED_DIALECTS: [&str; 4] = ["duckdb", "snowflake", "postgresql", "bigquery"]; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/delta_shapes.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/delta_shapes.rs new file mode 100644 index 0000000000..ef16cbe701 --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/delta_shapes.rs @@ -0,0 +1,119 @@ +//! Delta-compile hooks of semantic shapes: coverage reasons and the model shapes a compile publishes. + +use std::collections::HashSet; + +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; +use pyo3::types::{PyDict, PyDictMethods}; + +use crate::bindings::_helpers::compile_context::coverage::{ + coverage_reasons, merged_coverage, merged_order, +}; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; +use crate::bindings::_helpers::compile_context::delta::guarded; +use crate::bindings::_helpers::compile_context::delta::{ + ModelShape, capture, capturing, delta_unsupported, injection, +}; +use crate::bindings::_helpers::records::fields::field as native_field; + +/// The partial-check reasons of the `fresh` models, merged in a delta with the stored models'. +pub(crate) fn semantic_reasons( + order: Vec<(String, Vec)>, + fresh: Vec, +) -> PyResult)>> { + let (order, facts): (Vec<(String, Vec)>, Vec) = match injection() { + None => ( + order, + fresh.into_iter().filter(ModelCoverage::notable).collect(), + ), + Some(injection) => { + let Some(stored) = &injection.coverage else { + return Err(delta_unsupported( + "the stored compile recorded no semantic coverage", + )); + }; + ( + merged_order(&injection.coverage_order, &order), + merged_coverage(stored, &fresh), + ) + } + }; + let reasons: Vec<(String, Vec)> = coverage_reasons(&order, &facts); + if capturing() { + capture(|capture| { + if capture.coverage.is_none() { + capture.coverage = Some(facts); + } + }); + } + Ok(reasons) +} + +/// In a delta compile, publish the shapes of every model it does not compile again first. +pub(crate) fn inject_model_shapes( + models: &[Bound<'_, PyAny>], + shapes: &Bound<'_, PyDict>, +) -> PyResult<()> { + let Some(injection) = injection() else { + return Ok(()); + }; + let mut rerun: HashSet = HashSet::with_capacity(models.len()); + for model in models { + rerun.insert(native_field(model, "name")?.extract()?); + } + let py = shapes.py(); + for (name, columns) in &injection.model_shapes { + if rerun.contains(name) { + continue; + } + let shape: Bound<'_, PyDict> = PyDict::new(py); + for (column, column_type) in columns { + shape.set_item(column, column_type)?; + } + shapes.set_item(name, shape)?; + } + Ok(()) +} + +/// Record the model shapes the first semantic shape pass published. +fn record_model_shapes_inner( + project: &Bound<'_, PyAny>, + shapes: &Bound<'_, PyDict>, +) -> PyResult<()> { + if !capturing() { + return Ok(()); + } + let mut names: HashSet = HashSet::new(); + for model in native_field(project, "models")?.try_iter()? { + names.insert(native_field(&model?, "name")?.extract()?); + } + if let Some(injection) = injection() { + names.extend(injection.model_shapes.iter().map(|(name, _)| name.clone())); + } + let mut published: Vec = Vec::new(); + for (name, shape) in shapes.iter() { + let name: String = name.extract()?; + if !names.contains(&name) { + continue; + } + let shape: Bound<'_, PyDict> = shape.cast_into()?; + let mut columns: Vec<(String, String)> = Vec::with_capacity(shape.len()); + for (column, column_type) in shape.iter() { + columns.push((column.extract()?, column_type.extract()?)); + } + published.push((name, columns)); + } + capture(|capture| { + if capture.model_shapes.is_none() { + capture.model_shapes = Some(published); + } + }); + Ok(()) +} + +/// Record the model shapes the first semantic shape pass published. +pub(crate) fn record_model_shapes( + project: &Bound<'_, PyAny>, + shapes: &Bound<'_, PyDict>, +) -> PyResult<()> { + guarded(|| record_model_shapes_inner(project, shapes)) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/mod.rs index 7f20b6c6ef..11ccbb1fdc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/mod.rs @@ -1,6 +1,7 @@ pub(crate) mod constants; pub(crate) mod coverage; pub(crate) mod declarations; +pub(crate) mod delta_shapes; pub(crate) mod registration; pub(crate) mod shapes; pub(crate) mod source_bindings; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs index 04336f22b9..4f8d7a46ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs @@ -3,21 +3,21 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::AdapterHost; use crate::bindings::_helpers::analysis::binding_catalog::{ BindingCatalog, CASE_SENSITIVE_BINDING_DIALECTS, CatalogKey, }; -use crate::bindings::_helpers::analysis::model_reads::{ - declared_rows, dynamic_columns_declared, inferred_rows, star_flags, unchecked_columns, -}; use crate::bindings::_helpers::analysis::normalization::normalize_analysis_sql; use crate::bindings::_helpers::analysis_session::stage_functions::infer_native_expression_source_shapes; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compiled_project::compiled_model_view::{ +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::compiled_model_view::{ DeclaredRow, InferredRow, NativeCompiledModel, }; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::compiled_views::model_reads::{ + declared_rows, dynamic_columns_declared, inferred_rows, star_flags, unchecked_columns, +}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; @@ -326,7 +326,9 @@ fn model_shapes<'py>( let mut pending: Vec> = native_field(project, "models")? .try_iter()? .collect::>()?; - crate::bindings::_helpers::compile_delta::report_hooks::inject_model_shapes(&pending, shapes)?; + crate::bindings::_helpers::semantic_shapes::delta_shapes::inject_model_shapes( + &pending, shapes, + )?; while !pending.is_empty() { let mut remaining: Vec> = Vec::new(); for model in &pending { @@ -372,7 +374,7 @@ fn model_shapes<'py>( } pending = remaining; } - crate::bindings::_helpers::compile_delta::report_hooks::record_model_shapes(project, shapes) + crate::bindings::_helpers::semantic_shapes::delta_shapes::record_model_shapes(project, shapes) } fn all_known(names: &[String], shapes: &Bound<'_, PyDict>) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs index 3d14cfc6d3..bd4ad69b31 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs @@ -15,7 +15,7 @@ use crate::bindings::_helpers::analysis::schema_request::{ use crate::bindings::_helpers::analysis_session::stage_functions::infer_native_query_columns; use crate::bindings::_helpers::attachments::cursor_intrinsics::analysis_cursor_sql; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::keywords; use crate::bindings::_helpers::compile_driver::stage_work::count_stage; use crate::bindings::_helpers::records::construct::{enum_from_value, enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs index f0d0586175..5e34f9a244 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs @@ -1,17 +1,13 @@ //! `sqb test`: compile the selected SQL unit tests, inspect or run them, and report. -use std::collections::{BTreeSet, HashMap}; +use std::collections::BTreeSet; -use pyo3::exceptions::PyValueError; use pyo3::prelude::{ Bound, Py, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyInt, PyString, PyTuple}; use pyo3::{pyclass, pyfunction, pymethods, wrap_pyfunction}; use sqlbuild_core::cli_text::models::CliStyle; -use sqlbuild_core::json::main::dumps::dumps; -use sqlbuild_core::json::models::{JsonDialect, StdlibJsonOptions}; -use sqlbuild_core::test_command::main::parameterized_test_label::parameterized_test_label; use sqlbuild_core::test_command::main::render_test_completion::render_test_completion; use sqlbuild_core::test_command::main::render_test_inspection::render_test_inspection; use sqlbuild_core::test_command::main::render_test_ready::render_test_ready; @@ -19,26 +15,25 @@ use sqlbuild_core::test_command::main::test_exit_code::test_exit_code; use sqlbuild_core::test_command::main::test_group_name::test_group_name; use sqlbuild_core::test_command::main::test_name_width::test_name_width; use sqlbuild_core::test_command::main::test_outcome_status::test_outcome_status; -use sqlbuild_core::test_command::models::{ - TestFailure, TestInspectionEntry, TestParameter, TestPlanWarning, -}; +use sqlbuild_core::test_command::models::{TestFailure, TestInspectionEntry, TestPlanWarning}; +use sqlbuild_host::entries::models::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::keywords; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, call_with}; use crate::bindings::_helpers::build_progress::nested_progress::NestedCommandProgressCallbacks; -use crate::bindings::_helpers::build_progress::transient_status::status_reporter; -use crate::bindings::_helpers::cli::progress::current_native_progress_projector; -use crate::bindings::_helpers::cli::progress_reporters::ConnectionProgressReporter; -use crate::bindings::_helpers::cli::progress_text::{ +use crate::bindings::_helpers::build_progress::progress::current_native_progress_projector; +use crate::bindings::_helpers::build_progress::progress_reporters::ConnectionProgressReporter; +use crate::bindings::_helpers::build_progress::progress_text::{ format_expectation_detail, format_expectation_name, write_execution_header, }; +use crate::bindings::_helpers::build_progress::result_text::test_label; +use crate::bindings::_helpers::build_progress::transient_status::status_reporter; use crate::bindings::_helpers::command_runtime::concurrency::resolve_concurrency; use crate::bindings::_helpers::command_runtime::invocation::resolve_reported_command_invocation; use crate::bindings::_helpers::compile_driver::pipeline_entries::build_static_pipeline_result; -use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; -use crate::bindings::_helpers::compile_driver::selection_phases::compile_static_command_context; +use crate::bindings::_helpers::compile_driver::static_context::compile_static_command_context; use crate::bindings::_helpers::compile_outputs::runtime_target::write_test_runtime_target; use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external_sql_reference_resolver; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::command_plans::build_test_command_plan; use crate::bindings::_helpers::records::construct::error_class; @@ -48,13 +43,11 @@ use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::result_output::documents::format_test_execution_json; use crate::bindings::_helpers::result_output::documents::write_execution_json_output; use crate::bindings::_helpers::result_output::event_writer::ExecutionEventWriter; -use crate::bindings::_helpers::result_output::integration_values::json_value; use crate::bindings::_helpers::result_output::resource_ids::sql_test_identity; use crate::bindings::_helpers::sql_test_command::timeouts::{ RunTimeout, TimeoutKind, resolve_run_timeout, }; -const DECIMAL_KIND: &str = "decimal"; const PASS_OUTCOME: &str = "pass"; const EXPECT_LABEL: &str = "expect"; const UNKNOWN_GROUP: &str = "(unknown)"; @@ -69,65 +62,6 @@ fn strings(values: Bound<'_, PyAny>) -> PyResult> { values.try_iter()?.map(|value| value?.extract()).collect() } -/// A payload as `json.dumps(payload, ensure_ascii=True, separators=(",", ":"))`. -fn compact_json(payload: &Bound<'_, PyAny>) -> PyResult { - let Some(value) = json_value(payload)? else { - let options: Bound<'_, PyDict> = PyDict::new(payload.py()); - options.set_item("ensure_ascii", true)?; - options.set_item("separators", (",", ":"))?; - return payload - .py() - .import("json")? - .call_method("dumps", (payload,), Some(&options))? - .extract(); - }; - dumps( - &value, - &JsonDialect::Stdlib(StdlibJsonOptions::new(None).with_separators(",", ":")), - ) - .map_err(|error| PyValueError::new_err(format!("{error:?}"))) -} - -/// The label of one test or result: its name, plus source and values for parameterized cases. -pub(crate) fn test_label(item: &Bound<'_, PyAny>, name_field: &str) -> PyResult { - let name: String = native_field(item, name_field)?.extract()?; - let source_path: Bound<'_, PyAny> = item.getattr("source_path")?; - let values: Vec> = native_field(item, "parameter_values")? - .try_iter()? - .collect::>()?; - if source_path.is_none() || values.is_empty() { - return Ok(name); - } - let mut schema: HashMap> = HashMap::new(); - for declaration in item.getattr("parameter_schema")?.try_iter()? { - let declaration: Bound<'_, PyAny> = declaration?; - schema.insert(declaration.getattr("name")?.extract()?, declaration); - } - let mut parameters: Vec = Vec::new(); - for pair in values { - let (value_name, value): (String, Bound<'_, PyAny>) = pair.extract()?; - let declaration: &Bound<'_, PyAny> = schema - .get(&value_name) - .ok_or_else(|| pyo3::exceptions::PyKeyError::new_err(value_name.clone()))?; - let raw: Bound<'_, PyAny> = value.getattr("value")?; - let kind: String = value.getattr("kind")?.getattr("value")?.extract()?; - let payload: Bound<'_, PyAny> = if kind == DECIMAL_KIND { - raw.str()?.into_any() - } else { - raw - }; - parameters.push(TestParameter { - name: value_name, - value_type: native_field(&native_field(declaration, "value_type")?, "value")? - .extract()?, - nullable: declaration.getattr("nullable")?.is_truthy()?, - rendered: compact_json(&payload)?, - }); - } - let path: String = source_path.call_method0("as_posix")?.extract()?; - Ok(parameterized_test_label(&name, Some(&path), ¶meters)) -} - /// The shared name column width of test rows and their expectation rows. fn name_width(entries: &Bound<'_, PyAny>) -> PyResult { let mut labels: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs index e35b5a5709..b97b3d0a9b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs @@ -13,8 +13,8 @@ use sqlbuild_analysis::compiler::models::{ use sqlbuild_core::panics::main::native_failure::native_failure; use crate::bindings::_helpers::boundary::panics::value_error; -use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; -use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::compiled_project::rows::ReferenceRow; +use crate::bindings::_helpers::compiled_views::model_input_view::NativeModelInput; use crate::bindings::_helpers::records::fields::{ field as native_field, path_posix_text, path_stem, }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs index 6d122f641c..3807ce7aab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs @@ -8,11 +8,11 @@ use sqlbuild_cursor::algebra::main::compare::compare; use sqlbuild_cursor::algebra::main::floor_to_grain::floor_to_grain; use sqlbuild_cursor::algebra::models::{Grain, Scalar}; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::attachments::cursor_intrinsics::{ compile_input_error, resolve_cursor_intrinsics, }; -use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::boundary::python_calls::{call_with, imported}; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::{parse_value, render_value}; use crate::bindings::_helpers::model_config::config_values::config_str; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_assembly.rs index 6226495dee..a7cc24ece2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_assembly.rs @@ -3,8 +3,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::boundary::python_calls::KeywordArguments; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::planner_strategy::fixture_context::planning_context; use crate::bindings::_helpers::planner_strategy::models::RelationFixturePlanningContext; use crate::bindings::_helpers::records::construct::new_record_with; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs index f21ff48196..e58be88dda 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs @@ -1,11 +1,13 @@ //! Host SQL-test request preparation, native planning, and Python result conversion. -use crate::bindings::_helpers::compile_driver::compile_timings::add_compile_timing; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python, pyfunction}; +use pyo3::types::{PyDict, PyDictMethods, PyTuple}; +use sqlbuild_host::compile_context::main::add_compile_timing::add_compile_timing; + +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_strategy::fixture_context::count_chain_resolution; -use crate::bindings::_helpers::records::construct::error_class; -use crate::bindings::_helpers::records::construct::new_record_with; +use crate::bindings::_helpers::records::construct::{error_class, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::sql_test_glue::models::SqlTestPlanOptions; @@ -13,8 +15,6 @@ use crate::bindings::_helpers::sql_test_glue::plan_values::tuple; use crate::bindings::_helpers::sql_test_glue::planning::{ ChainRequest, PlanningRequest, plan_compiled_sql_tests, resolve_compiled_sql_test_chains, }; -use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python, pyfunction}; -use pyo3::types::{PyDict, PyTuple}; pub(super) fn chains<'py>( project: &Bound<'py, PyAny>, @@ -231,3 +231,19 @@ pub(crate) fn sql_test_plan_error_messages<'py>( } PyTuple::new(warnings.py(), messages) } + +/// Return model closures resolved natively in one project batch, keyed by SQL test key. +#[pyfunction] +#[pyo3(signature = (*, project, tests))] +pub(crate) fn sql_test_model_chain_names_by_key<'py>( + project: &Bound<'py, PyAny>, + tests: &Bound<'py, PyAny>, +) -> PyResult> { + let py = project.py(); + let chains = resolve_sql_test_model_chains(project, tests)?; + let by_key = PyDict::new(py); + for (test, chain) in tests.try_iter()?.zip(chains.try_iter()?) { + by_key.set_item(native_field(&test?, "key")?, chain?)?; + } + Ok(by_key) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs index 956ed039f2..346b4e7612 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs @@ -1,6 +1,6 @@ //! Project native planning failures into existing located diagnostic exceptions. -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs index f2681f10c1..9cb2fffba4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs @@ -1,7 +1,7 @@ //! Adapter rendering and declared cursor-window boundaries for native test planning. -use crate::bindings::_helpers::analysis::model_reads; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::sql_test_glue::plan_values::{model_payload, string}; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs index 54dbc3b4d6..ae22503d07 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs @@ -3,7 +3,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyString; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::RecordId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs index fa0241d2d1..0c8c62ff52 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs @@ -11,8 +11,8 @@ use sqlbuild_analysis::compiler::models::{ SqlTestPlanFunction, SqlTestPlanModel, SqlTestPlanPayload, SqlTestPlanTest, }; -use crate::bindings::_helpers::analysis::model_reads; use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::compiled_views::model_reads; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; use crate::bindings::types::CompilerDetach; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/ddl_effects.rs b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/ddl_effects.rs index baa50eca9a..77241f2e5d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/ddl_effects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/ddl_effects.rs @@ -4,13 +4,13 @@ use pyo3::prelude::{Bound, Py, PyAny, PyModule, PyModuleMethods, PyResult, Pytho use pyo3::sync::PyOnceLock; use pyo3::types::{PyBool, PyFrozenSet}; use pyo3::{pyfunction, wrap_pyfunction}; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_sqltext::ddl_effects::main::qualified_relation_name_key::qualified_relation_name_key as native_qualified_relation_name_key; use sqlbuild_sqltext::ddl_effects::main::relation_name_key::relation_name_key as native_relation_name_key; use sqlbuild_sqltext::ddl_effects::main::statement_metadata_effect::statement_metadata_effect as native_statement_metadata_effect; use sqlbuild_sqltext::ddl_effects::models::StatementMetadataEffect; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; const EFFECT_MODEL: AdapterHost = AdapterHost::StatementMetadataEffect; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs index ffd2158bac..cf8b9bf4a7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs @@ -12,7 +12,7 @@ use sqlbuild_sqltext::sql_references::models::{ use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; +use crate::bindings::_helpers::compile_context::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record_with, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs index 465a195eb1..a56554ad1d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs @@ -7,6 +7,7 @@ use pyo3::prelude::{ use pyo3::types::{PyDict, PyString}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::json::errors::JsonEmitError; +use sqlbuild_host::entries::models::ExecutorHost; use sqlbuild_state::events::errors::StateSqlError; use sqlbuild_state::events::main::column_migration_event_id::column_migration_event_id; use sqlbuild_state::events::main::event_cells::event_cells; @@ -16,7 +17,6 @@ use sqlbuild_state::events::main::old_name_view_event_id::old_name_view_event_id use sqlbuild_state::events::models::{EventRelation, StateCell, StateColumnType, StateValue}; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::state_rows::timestamps::{date_time_typed, presumed_utc}; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs index 225750664c..2a93fd2855 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs @@ -17,7 +17,7 @@ use sqlbuild_state::freshness::main::records_equivalent::records_equivalent; use sqlbuild_state::freshness::models::{AgeStatus, ComparableRecord, DataVersion}; use sqlbuild_state::freshness::types::TimestampParser; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::values::{DATETIME_MODULE, local_date_time}; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs index 681fb831cd..da6281fef6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs @@ -11,7 +11,7 @@ use sqlbuild_state::events::main::recorded_renames::recorded_renames; use sqlbuild_state::events::models::RecordedRenameKey; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::state_rows::constants::{ COLUMN_KIND, LOGGING_MODULE, MIGRATION_LOGGER, MIGRATION_WRITE_ATTEMPTS, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs index 3a249183eb..282825c64a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs @@ -11,7 +11,7 @@ use sqlbuild_state::events::constants::{ }; use sqlbuild_state::events::models::EventOrder; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs index 1074c0797e..d55f26d179 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs @@ -16,7 +16,7 @@ use sqlbuild_state::events::main::grants_json::grants_json; use sqlbuild_state::events::main::readable_columns::readable_columns; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs index e6d61f9339..40a1d39bf6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs @@ -7,6 +7,7 @@ use pyo3::prelude::{ use pyo3::types::{PyDict, PyString, PyStringMethods}; use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_core::constants::SOURCE_FRESHNESS_TABLE_NAME; +use sqlbuild_host::entries::models::AdapterHost; use sqlbuild_state::freshness::constants::{ SOURCE_FRESHNESS_COLUMN_TYPES, STRING_STATE_VALUE_TYPE, TEXT_TIMESTAMP_STATE_VALUE_TYPE, }; @@ -15,9 +16,8 @@ use sqlbuild_state::state_tables::main::values_insert_sql::values_insert_sql; use sqlbuild_state::state_tables::models::TableColumn; use crate::bindings::_helpers::boundary::keyword_request::Request; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::contracts::state_literals::render_state_sql_literal; -use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs index 49f5016608..432a921c39 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs @@ -3,7 +3,7 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use sqlbuild_cursor::algebra::models::LocalDateTime; -use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::boundary::python_calls::imported; use crate::bindings::_helpers::cursor::values::{DATETIME_MODULE, local_date_time}; use crate::bindings::_helpers::records::fields::field as native_field; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs b/crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs index cc2553b41a..cc781383a5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs @@ -7,10 +7,10 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyString; use sqlbuild_analysis::type_system::main::normalize_type::normalize_type; use sqlbuild_analysis::type_system::models::{NormalizedType, TypeNormalization}; +use sqlbuild_host::entries::models::ExecutorHost; use crate::bindings::_helpers::boundary::panics::compiler_guard; -use crate::bindings::_helpers::compile_driver::python_calls::call_with; -use crate::bindings::_helpers::native_host::executor::ExecutorHost; +use crate::bindings::_helpers::boundary::python_calls::call_with; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::type_system::normalization::normalization_error; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs b/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs index 8b44bb8a1e..b93aac64c4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs @@ -18,9 +18,9 @@ use sqlbuild_config::workspace::main::playground_project_dir::playground_project use sqlbuild_config::workspace::main::playground_summary::playground_summary; use sqlbuild_config::workspace::models::{PlaygroundRequest, SkillInstallRequest}; use sqlbuild_core::cli_text::models::CliStyle; +use sqlbuild_host::entries::models::FacadeHost; -use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; -use crate::bindings::_helpers::native_host::facade::FacadeHost; +use crate::bindings::_helpers::boundary::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::error_class; diff --git a/crates/sqlbuild-python/src/bindings/tests/helpers.rs b/crates/sqlbuild-python/src/bindings/tests/helpers.rs index f4fb041c20..c9ec506f5a 100644 --- a/crates/sqlbuild-python/src/bindings/tests/helpers.rs +++ b/crates/sqlbuild-python/src/bindings/tests/helpers.rs @@ -4,13 +4,15 @@ use sqlbuild_cache::project_reuse::types::ImageSections; use sqlbuild_config::models::ConfigValue; use sqlbuild_rules::models::{EvaluateRequest, RetainedRows}; -use crate::bindings::_helpers::compile_delta::context::{ +use crate::bindings::_helpers::compile_context::delta::BaseRules; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; +use crate::bindings::_helpers::compile_context::delta::PendingRules; +use crate::bindings::_helpers::compile_context::delta::{ CapturedDiagnostic, CapturedModel, CapturedTest, }; -use crate::bindings::_helpers::compile_delta::coverage::ModelCoverage; use crate::bindings::_helpers::compile_delta::image::{ - BaseRules, FACTS_SECTION, GATE_SECTION, IMAGE_FORMAT, ImageRelations, ImageRules, PendingRules, - ProjectImage, RULE_DIGESTS_SECTION, + FACTS_SECTION, GATE_SECTION, IMAGE_FORMAT, ImageRelations, ImageRules, ProjectImage, + RULE_DIGESTS_SECTION, }; /// The rows of a request without models: a zero model count. diff --git a/crates/sqlbuild-python/src/bindings/tests/test_coverage.rs b/crates/sqlbuild-python/src/bindings/tests/test_coverage.rs index 6edbf806ef..57501219d9 100644 --- a/crates/sqlbuild-python/src/bindings/tests/test_coverage.rs +++ b/crates/sqlbuild-python/src/bindings/tests/test_coverage.rs @@ -1,8 +1,9 @@ use std::collections::BTreeSet; -use crate::bindings::_helpers::compile_delta::coverage::{ - ModelCoverage, coverage_reasons, merged_coverage, merged_order, +use crate::bindings::_helpers::compile_context::coverage::{ + coverage_reasons, merged_coverage, merged_order, }; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; use crate::bindings::_helpers::compile_delta::driver::names_uncompiled_model; use crate::bindings::tests::helpers::{coverage, names, order, strings}; use crate::bindings::tests::test_types::{CoverageTestCase, UncompiledModelTestCase}; diff --git a/crates/sqlbuild-python/src/bindings/tests/test_types.rs b/crates/sqlbuild-python/src/bindings/tests/test_types.rs index eb32f89cee..5d4ab140dd 100644 --- a/crates/sqlbuild-python/src/bindings/tests/test_types.rs +++ b/crates/sqlbuild-python/src/bindings/tests/test_types.rs @@ -1,7 +1,7 @@ use sqlbuild_cache::project_reuse::types::ImageSections; use sqlbuild_config::models::ConfigValue; -use crate::bindings::_helpers::compile_delta::coverage::ModelCoverage; +use crate::bindings::_helpers::compile_context::delta::ModelCoverage; use crate::bindings::_helpers::compile_delta::image::ProjectImage; /// A stored report, a delta report and what splicing the delta into the stored one gives. diff --git a/crates/sqlbuild-python/src/bindings/tests/test_yaml_cache.rs b/crates/sqlbuild-python/src/bindings/tests/test_yaml_cache.rs index 60ea19a5f8..53c46aa186 100644 --- a/crates/sqlbuild-python/src/bindings/tests/test_yaml_cache.rs +++ b/crates/sqlbuild-python/src/bindings/tests/test_yaml_cache.rs @@ -1,6 +1,6 @@ use sqlbuild_config::models::{ConfigDate, ConfigDateTime, ConfigTime, ConfigValue}; -use crate::bindings::_helpers::compile_delta::yaml_cache::{decoded_document, encoded_document}; +use crate::bindings::_helpers::compile_context::yaml_cache::{decoded_document, encoded_document}; use crate::bindings::tests::helpers::text; use crate::bindings::tests::test_types::DocumentTestCase; diff --git a/fensu.toml b/fensu.toml index dad712116c..ecb8b05d64 100644 --- a/fensu.toml +++ b/fensu.toml @@ -1502,7 +1502,7 @@ tests = [] tooling = [] rule_packs = ["rust"] rule_modules = ["scripts.fensu_policy.rules.native_boundary"] -select = ["FPRS", "XSB072", "XSB073"] +select = ["FPRS", "XSB072", "XSB073", "XSB075"] [[targets.rust.rule_exceptions]] rule = "FPRSR307" @@ -1573,6 +1573,7 @@ crate_names = [ "sqlbuild-core", "sqlbuild-cursor", "sqlbuild-discovery", + "sqlbuild-host", "sqlbuild-model-config", "sqlbuild-pysource", "sqlbuild-python", @@ -1623,8 +1624,6 @@ edge_paths = [ ] pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=19", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=10", @@ -1641,7 +1640,9 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/sql_values.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/boundary/python_calls.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=20", @@ -1655,6 +1656,10 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/plan_facts.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_reporters.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_text.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs=23", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=9", @@ -1669,9 +1674,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/cli/surrogates.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=4", @@ -1699,6 +1701,10 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/surrogates.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs=63", + "crates/sqlbuild-python/src/bindings/_helpers/compile_context/compile_timings.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_context/diagnostic_collector.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_context/input_reads.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=3", @@ -1708,72 +1714,46 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=24", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_pipeline.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/static_context.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_external.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/audit_views.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_analysis.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_view.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/function_views.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/inputs_view.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_input_view.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/project_view.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/records.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/seed_views.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/source_views.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=12", @@ -1837,8 +1817,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/output.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=19", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=8", @@ -1848,10 +1828,11 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/discovery/hook_entries.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/discovery/locations.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_config.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_files.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_validation.rs=6", @@ -1900,11 +1881,32 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/attachment.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/audit_loop.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/function_loop.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/loop_classes.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_calls.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_contracts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_external.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_header.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_hooks.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_host.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_named.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_opt_out.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_python_hooks.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_schema.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_visibility.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/resource_diagnostics.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/scenario_loop.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/source_loop.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/sql_test_loop.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=7", @@ -1919,6 +1921,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_facts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=12", @@ -1935,6 +1938,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/model_config/authored_nodes.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_classes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=4", @@ -1971,6 +1975,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=1", @@ -2081,7 +2086,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/durations.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=8", @@ -2094,6 +2098,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/refactor/python_strings.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_facts.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/references/explicit_references.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/references/reference_facts.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs=1", @@ -2156,6 +2162,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=15", @@ -2180,6 +2187,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs=104", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=4", @@ -2218,14 +2226,14 @@ edge_paths = [ ] pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis/schema_request.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/sql_values.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/boundary/keyword_request.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/boundary/python_calls.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=6", @@ -2235,6 +2243,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_reporters.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=10", @@ -2243,20 +2253,21 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/test_artifact_cache.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_context/diagnostic_collector.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_context/input_reads.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=6", @@ -2264,49 +2275,28 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=25", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=24", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=20", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=22", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs=15", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=27", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment_inputs.rs=33", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/audit_views.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_analysis.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/compiled_model_view.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/function_views.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/inputs_view.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/model_input_view.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/project_view.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/seed_views.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views/source_views.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs=2", @@ -2334,6 +2324,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_config.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs=13", @@ -2356,11 +2347,27 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/audit_loop.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/function_loop.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_config.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_contracts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_header.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_hooks.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_host.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_opt_out.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_python_hooks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_schema.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_visibility.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/source_loop.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/sql_test_loop.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_facts.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=3", @@ -2369,6 +2376,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_classes.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_metadata.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs=11", @@ -2384,6 +2392,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=57", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/test_planning.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=4", @@ -2412,13 +2421,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/recall/replacements.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/references/explicit_references.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/references/reference_facts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=2", @@ -2450,6 +2460,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/test_command.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=8", @@ -2460,6 +2471,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs=2", @@ -2470,6 +2482,207 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/models.rs=4", ] +[targets.rust.rule_options.XSB075] +layer_order = ["infra", "front", "project", "plan|compile", "output", "commands", "registry"] +module_layers = [ + "*/registration=registry", + "analysis=compile", + "analysis/binding_catalog=project", + "analysis/conversions=project", + "analysis/normalization=project", + "analysis/normalization_results=project", + "analysis/relation_names=project", + "analysis/schema_request=project", + "analysis_session=compile", + "analysis_session/fixture_columns=project", + "analysis_session/fixture_inferences=project", + "analysis_session/models=project", + "analysis_session/nullability_rules=project", + "analysis_session/profile_inputs=project", + "analysis_session/query_columns=project", + "analysis_session/session=project", + "analysis_session/stage_functions=project", + "attachments=front", + "audit_command=commands", + "auditing=compile", + "auditing/render=project", + "authored_values=front", + "boundary=infra", + "build_command=commands", + "build_command/support=infra", + "build_progress=output", + "build_progress/progress=infra", + "build_progress/terminal=infra", + "build_progress/transient_lines=infra", + "build_progress/transient_status=infra", + "cache=infra", + "check=commands", + "cli=commands", + "cli/launch_state=infra", + "clone=commands", + "command_runtime=commands", + "command_runtime/adapters=infra", + "command_runtime/concurrency=front", + "compile_attachment=compile", + "compile_attachment/cursor_roles=project", + "compile_attachment/effective_config=front", + "compile_command=compile", + "compile_context=infra", + "compile_delta=compile", + "compile_driver=compile", + "compile_driver/config_validation=front", + "compile_driver/plan_pipeline=commands", + "compile_driver/plan_result=commands", + "compile_driver/stage_work=infra", + "compile_driver/static_context=commands", + "compile_outputs=compile", + "compile_outputs/json_report=infra", + "compile_records=infra", + "compiled_project=project", + "compiled_views=project", + "compiler_enums=infra", + "compiler_errors=infra", + "compiler_records=infra", + "compute_logs=output", + "contract_command=commands", + "contract_records=infra", + "contracts=project", + "contracts/effective_config=front", + "contracts/resource_identities=infra", + "contracts/spec_resolution=front", + "contracts/state_literals=infra", + "cost_command=commands", + "cost_report=output", + "cost_telemetry=output", + "cost_telemetry/context=front", + "cost_telemetry/values=front", + "cursor=front", + "dag_artifact=compile", + "dagster_invocation=commands", + "dbt_command=commands", + "dbt_events=commands", + "dbt_interop=commands", + "debug_command=commands", + "diagnostics=infra", + "diff_report=commands", + "discovery=front", + "event_exporting=output", + "event_exporting/constants=infra", + "event_exporting/models=infra", + "event_exporting/scope=infra", + "event_exporting/values=infra", + "execution_history=front", + "exported_constants=registry", + "fingerprints=project", + "format_command=commands", + "freshness=plan", + "freshness/freshness_command=commands", + "frontier=compile", + "frontier/encoder=infra", + "frontier/python_types=infra", + "graph=project", + "hand_built=commands", + "hand_built/compiled_model=compile", + "init_command=commands", + "input_loops=compile", + "janitor=commands", + "lifecycle_events=plan", + "lineage=compile", + "lineage/lineage_command=commands", + "lineage/lineage_facts=project", + "load=commands", + "macro_bridge=front", + "manifest=compile", + "microbatches=plan", + "model_config=front", + "native_host=infra", + "native_threads=infra", + "output_capture=output", + "plan_command=commands", + "plan_output=plan", + "planner_changes=plan", + "planner_entries=plan", + "planner_identity=plan", + "planner_identity/graph=project", + "planner_identity/hashing=project", + "planner_identity/json_values=infra", + "planner_migrations=plan", + "planner_phases=plan", + "planner_phases/models=project", + "planner_phases/objects=project", + "planner_phases/scopes=project", + "planner_records=infra", + "planner_registration=registry", + "planner_resolution=plan", + "planner_scenario=plan", + "planner_scope=project", + "planner_selection=project", + "planner_strategy=plan", + "planner_strategy/constants=project", + "planner_strategy/fixture_completion=project", + "planner_strategy/fixture_context=project", + "planner_strategy/fixture_metadata=project", + "planner_strategy/fixture_preparation=project", + "planner_strategy/fixture_reads=project", + "planner_strategy/fixture_selection=project", + "planner_strategy/fixture_sql=project", + "planner_strategy/fixture_types=project", + "planner_strategy/fixture_values=project", + "planner_strategy/models=project", + "planner_strategy/types=project", + "planner_warehouse=plan", + "presentation_text=infra", + "project_assembly=compile", + "python_values=infra", + "query_command=commands", + "recall=output", + "recall/command=commands", + "record_behaviours=registry", + "records=infra", + "refactor=front", + "refactor/offline_compile=commands", + "refactor/refactor_command=commands", + "references=project", + "relation_naming=project", + "render=front", + "result_output=output", + "result_output/integration_values=infra", + "rule_records=infra", + "rules=compile", + "scenario_command=commands", + "scope_records=infra", + "scopes=front", + "scopes/scope_command=commands", + "scopes/scope_loading=compile", + "seed_command=commands", + "semantic_checks=compile", + "semantic_shapes=project", + "sql_test_command=commands", + "sql_test_glue=compile", + "sql_test_glue/authored_ctes=front", + "sql_test_glue/constants=infra", + "sql_test_glue/cursor_window=project", + "sql_test_glue/fixture_validation=project", + "sql_test_glue/models=project", + "sql_test_glue/plan_assembly=project", + "sql_test_glue/plan_driver=project", + "sql_test_glue/plan_entries=project", + "sql_test_glue/plan_errors=project", + "sql_test_glue/plan_fixtures=project", + "sql_test_glue/plan_rendering=project", + "sql_test_glue/plan_rows=project", + "sql_test_glue/plan_values=project", + "sql_test_glue/planning=project", + "sqltext=front", + "state_rows=front", + "type_system=project", + "type_system/equality=infra", + "type_system/normalization=infra", + "workspace_commands=commands", +] +pending_budgets = [ +] + [[targets.python.rule_exceptions]] rule = "FFS120" path = "src/sqlbuild/executor/scheduling/classes/recovering_connection_pool.py" diff --git a/scripts/compiler_differential/constants.py b/scripts/compiler_differential/constants.py index bdfad436fa..68c62c7c03 100644 --- a/scripts/compiler_differential/constants.py +++ b/scripts/compiler_differential/constants.py @@ -668,13 +668,15 @@ def short_model_names(*, model: Model, ctx: RuleContext) -> list[Finding]: "crates/sqlbuild-analysis/src/semantic_checks/_helpers/resource_sql/diagnostics.rs", "crates/sqlbuild-analysis/src/contracts/constants.rs", "crates/sqlbuild-analysis/src/assembly/target_checks/constants.rs", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop.rs", ) NATIVE_CODE_TEST_DIRECTORY: str = "tests" RENDER_NATIVE_CODE_SCAN_ROOTS: tuple[str, ...] = ( "crates/sqlbuild-attachments/src", "crates/sqlbuild-render/src", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_views", + "crates/sqlbuild-python/src/bindings/_helpers/input_loops", ) NATIVE_CODE_CONSTANT_PATTERN: re.Pattern[str] = re.compile( r'const [A-Z0-9_]*_CODE: &str = "([A-Z][0-9]{3})";' diff --git a/scripts/fensu_policy/_helpers/native_crossings.py b/scripts/fensu_policy/_helpers/native_crossings.py index 41064e6977..430cc3fb78 100644 --- a/scripts/fensu_policy/_helpers/native_crossings.py +++ b/scripts/fensu_policy/_helpers/native_crossings.py @@ -20,7 +20,6 @@ NATIVE_STRING_QUOTE, NATIVE_TEST_DIRECTORY, NATIVE_TEST_FILE_NAME, - NATIVE_TEST_FILE_PREFIX, NATIVE_TEST_MODULE_MARKER, ) @@ -31,17 +30,13 @@ def is_checked_binding(*, path: str) -> bool: - """Whether `path` is non-test source of the native bindings crate.""" + """Whether `path` is non-test bindings source; tests live under `tests/` or in `tests.rs`.""" if not path.startswith(NATIVE_BINDINGS_ROOT) or not path.endswith(NATIVE_RUST_SUFFIX): return False parts: list[str] = path.split("/") name: str = parts[-1] - return ( - NATIVE_TEST_DIRECTORY not in parts[:-1] - and name != NATIVE_TEST_FILE_NAME - and not name.startswith(NATIVE_TEST_FILE_PREFIX) - ) + return NATIVE_TEST_DIRECTORY not in parts[:-1] and name != NATIVE_TEST_FILE_NAME def is_edge_path(*, path: str, edge_paths: Iterable[str]) -> bool: @@ -119,7 +114,12 @@ def budgeted_faults( path=path, edge_paths=ctx.option(NATIVE_EDGE_PATHS) ): return [] - found: list[int] = lines(source=ctx.source) + return budget_faults(ctx=ctx, path=path, found=lines(source=ctx.source), what=what) + + +def budget_faults(*, ctx: RuleContext, path: str, found: list[int], what: str) -> list[Fault]: + """Faults when the `found` lines of `path` exceed, or fall below, its pending budget.""" + budget: int | None = budgets_by_path(entries=ctx.option(NATIVE_PENDING_BUDGETS)).get(path) if budget is None: return [ctx.fault_for(path=ctx.path, line=line, column=0) for line in found] diff --git a/scripts/fensu_policy/_helpers/native_layers.py b/scripts/fensu_policy/_helpers/native_layers.py new file mode 100644 index 0000000000..015b8a50c9 --- /dev/null +++ b/scripts/fensu_policy/_helpers/native_layers.py @@ -0,0 +1,170 @@ +"""Locate imports between native binding helper modules that point against the layer order.""" + +from __future__ import annotations + +import re +from collections.abc import Iterable + +from scripts.fensu_policy._helpers.native_crossings import is_checked_binding +from scripts.fensu_policy.constants import ( + NATIVE_BUDGET_SEPARATOR, + NATIVE_GROUP_CLOSE, + NATIVE_GROUP_OPEN, + NATIVE_GROUP_SEPARATOR, + NATIVE_HELPERS_PATH, + NATIVE_HELPERS_ROOT, + NATIVE_LAYER_SIBLING_SEPARATOR, + NATIVE_LINE_COMMENT, + NATIVE_MODULE_FILE_STEM, + NATIVE_MODULE_PATH_SEPARATOR, + NATIVE_PATH_SELF, + NATIVE_PATH_SEPARATOR, + NATIVE_RUST_SUFFIX, + NATIVE_STRING_QUOTE, + NATIVE_TEST_MODULE_MARKER, +) +from scripts.fensu_policy.models import LayerPlan, LayerReference + +_IDENTIFIER: re.Pattern[str] = re.compile(r"\s*([A-Za-z_]\w*)") + + +def layer_plan(*, order: Iterable[str], modules: Iterable[str]) -> LayerPlan: + """Parse the ordered layer list and the `module/path=layer` assignments.""" + + ranks: dict[str, int] = {} + rank: int + entry: str + for rank, entry in enumerate(order): + name: str + for name in entry.split(NATIVE_LAYER_SIBLING_SEPARATOR): + ranks[name.strip()] = rank + assignments: dict[tuple[str, ...], str] = {} + for entry in modules: + path, _, named = entry.rpartition(NATIVE_BUDGET_SEPARATOR) + layer: str = named.strip() + if layer in ranks: + module: str = path.strip().strip(NATIVE_MODULE_PATH_SEPARATOR) + assignments[tuple(module.split(NATIVE_MODULE_PATH_SEPARATOR))] = layer + return LayerPlan(assignments=assignments, ranks=ranks) + + +def helper_module(*, path: str) -> tuple[str, ...] | None: + """The helper module path of a non-test bindings helper file, if `path` is one.""" + + if not is_checked_binding(path=path) or not path.startswith(NATIVE_HELPERS_ROOT): + return None + parts: list[str] = path[len(NATIVE_HELPERS_ROOT) :].removesuffix(NATIVE_RUST_SUFFIX).split("/") + if parts[-1] == NATIVE_MODULE_FILE_STEM: + parts.pop() + return tuple(parts) if parts else None + + +def _code_text(*, source: str) -> list[str]: + lines: list[str] = [] + line: str + for line in source.splitlines(): + stripped: str = line.strip() + if stripped.startswith(NATIVE_TEST_MODULE_MARKER): + break + if stripped.startswith(NATIVE_LINE_COMMENT): + lines.append("") + continue + lines.append(line if NATIVE_STRING_QUOTE in line else line.split(NATIVE_LINE_COMMENT, 1)[0]) + return lines + + +def helper_references(*, source: str) -> list[LayerReference]: + """Every helper module path a Rust source names, with brace groups expanded.""" + + lines: list[str] = _code_text(source=source) + text: str = "\n".join(lines) + starts: list[int] = [0] + line: str + for line in lines: + starts.append(starts[-1] + len(line) + 1) + references: list[LayerReference] = [] + position: int = text.find(NATIVE_HELPERS_PATH) + while position >= 0: + path_start: int = position + len(NATIVE_HELPERS_PATH) + path: tuple[str, ...] + offset: int + for path, offset in _expand(text=text, position=path_start, base=()): + number: int = _line_number(starts=starts, offset=offset) + references.append(LayerReference(line=number, target=path)) + position = text.find(NATIVE_HELPERS_PATH, path_start) + return references + + +def _line_number(*, starts: list[int], offset: int) -> int: + low: int = 0 + high: int = len(starts) - 1 + while low < high: + middle: int = (low + high + 1) // 2 + if starts[middle] <= offset: + low = middle + else: + high = middle - 1 + return low + 1 + + +def _expand( + *, text: str, position: int, base: tuple[str, ...] +) -> list[tuple[tuple[str, ...], int]]: + rest: str = text[position:] + if rest.lstrip().startswith(NATIVE_GROUP_OPEN): + return _expand_group(text=text, open_at=text.index(NATIVE_GROUP_OPEN, position), base=base) + match: re.Match[str] | None = _IDENTIFIER.match(rest) + if match is None: + return [(base, position)] if base else [] + segment: str = match.group(1) + after: int = position + match.end() + if text.startswith(NATIVE_PATH_SEPARATOR, after): + return _expand( + text=text, position=after + len(NATIVE_PATH_SEPARATOR), base=(*base, segment) + ) + if segment == NATIVE_PATH_SELF: + return [(base, position)] if base else [] + return [((*base, segment), position + match.start(1))] + + +def _expand_group( + *, text: str, open_at: int, base: tuple[str, ...] +) -> list[tuple[tuple[str, ...], int]]: + found: list[tuple[tuple[str, ...], int]] = [] + depth: int = 1 + item_start: int = open_at + 1 + index: int = open_at + 1 + while index < len(text) and depth: + character: str = text[index] + if character == NATIVE_GROUP_OPEN: + depth += 1 + elif character == NATIVE_GROUP_CLOSE: + depth -= 1 + if (character == NATIVE_GROUP_SEPARATOR and depth == 1) or depth == 0: + if text[item_start:index].strip(): + found.extend(_expand(text=text[:index], position=item_start, base=base)) + item_start = index + 1 + index += 1 + return found + + +def upward_reference_lines(*, path: str, source: str, plan: LayerPlan) -> list[int] | None: + """Lines of references that point against the layer order; None for an unassigned module.""" + + module: tuple[str, ...] | None = helper_module(path=path) + if module is None: + return [] + source_layer: str | None = plan.layer_of(module=module) + if source_layer is None: + return None + found: list[int] = [] + reference: LayerReference + for reference in helper_references(source=source): + if reference.target[: len(module)] == module: + continue + target_layer: str | None = plan.layer_of(module=reference.target) + if target_layer is not None and plan.points_upward( + source=source_layer, target=target_layer + ): + found.append(reference.line) + return found diff --git a/scripts/fensu_policy/constants.py b/scripts/fensu_policy/constants.py index d199a76cf2..c2b4068e93 100644 --- a/scripts/fensu_policy/constants.py +++ b/scripts/fensu_policy/constants.py @@ -304,7 +304,6 @@ NATIVE_RUST_SUFFIX: str = ".rs" NATIVE_TEST_DIRECTORY: str = "tests" NATIVE_TEST_FILE_NAME: str = "tests.rs" -NATIVE_TEST_FILE_PREFIX: str = "test_" NATIVE_LINE_COMMENT: str = "//" NATIVE_STRING_QUOTE: str = '"' NATIVE_SKIPPED_LINE_PREFIXES: tuple[str, ...] = ( @@ -327,6 +326,33 @@ default=(), description="`path=count` budgets for files that still cross; each may only fall.", ) +NATIVE_HELPERS_ROOT: str = "crates/sqlbuild-python/src/bindings/_helpers/" +NATIVE_HELPERS_PATH: str = "crate::bindings::_helpers::" +NATIVE_MODULE_FILE_STEM: str = "mod" +NATIVE_MODULE_PATH_SEPARATOR: str = "/" +NATIVE_LAYER_SIBLING_SEPARATOR: str = "|" +NATIVE_LAYER_WILDCARD: str = "*" +NATIVE_GROUP_OPEN: str = "{" +NATIVE_GROUP_CLOSE: str = "}" +NATIVE_GROUP_SEPARATOR: str = "," +NATIVE_PATH_SEPARATOR: str = "::" +NATIVE_PATH_SELF: str = "self" +NATIVE_LAYER_ORDER: RuleOption[tuple[str, ...]] = RuleOption.string_list( + name="layer_order", + default=(), + description=( + "Helper module layers from the bottom up; `a|b` makes sibling layers that may not " + "import each other." + ), +) +NATIVE_MODULE_LAYERS: RuleOption[tuple[str, ...]] = RuleOption.string_list( + name="module_layers", + default=(), + description=( + "`module/path=layer` assignments of helper modules under bindings/_helpers; the longest " + "matching path decides." + ), +) NATIVE_MODULE_PATH: str = "sqlbuild._native" NATIVE_MODULE_PACKAGE: str = "sqlbuild" NATIVE_MODULE_NAME: str = "_native" diff --git a/scripts/fensu_policy/models.py b/scripts/fensu_policy/models.py new file mode 100644 index 0000000000..3f66ea27fd --- /dev/null +++ b/scripts/fensu_policy/models.py @@ -0,0 +1,48 @@ +"""Data models for SQLBuild custom Fensu rules.""" + +from __future__ import annotations + +from dataclasses import dataclass + +from scripts.fensu_policy.constants import NATIVE_LAYER_WILDCARD + + +@dataclass(frozen=True) +class LayerReference: + """One reference from a helper file to a helper module path.""" + + line: int + target: tuple[str, ...] + + +@dataclass(frozen=True) +class LayerPlan: + """Layer assignments of helper module paths and the rank of each layer.""" + + assignments: dict[tuple[str, ...], str] + ranks: dict[str, int] + + def layer_of(self, *, module: tuple[str, ...]) -> str | None: + """The layer of the longest assigned prefix of `module`; `*` matches any one segment.""" + + best: tuple[int, int, str] | None = None + pattern: tuple[str, ...] + layer: str + for pattern, layer in self.assignments.items(): + if len(pattern) > len(module) or not all( + part in (NATIVE_LAYER_WILDCARD, segment) + for part, segment in zip(pattern, module, strict=False) + ): + continue + exact: int = sum(part != NATIVE_LAYER_WILDCARD for part in pattern) + key: tuple[int, int, str] = (len(pattern), exact, layer) + if best is None or key[:2] > best[:2]: + best = key + return None if best is None else best[2] + + def points_upward(self, *, source: str, target: str) -> bool: + """Whether an import from layer `source` into layer `target` breaks the order.""" + + if source == target: + return False + return self.ranks[target] >= self.ranks[source] diff --git a/scripts/fensu_policy/rules/native_boundary.py b/scripts/fensu_policy/rules/native_boundary.py index 4736d563a1..309c6afd8d 100644 --- a/scripts/fensu_policy/rules/native_boundary.py +++ b/scripts/fensu_policy/rules/native_boundary.py @@ -1,4 +1,4 @@ -"""Rules keeping the native bindings crate from calling back into Python outside its edges.""" +"""Rules keeping the native bindings crate within its Python edges and module layers.""" from __future__ import annotations @@ -7,18 +7,27 @@ from fensu import AnalyzerId, Family, Fault, File, RuleContext, rule from scripts.fensu_policy._helpers.native_crossings import ( + budget_faults, budgeted_faults, budgets_by_path, crossing_lines, python_field_lines, ) +from scripts.fensu_policy._helpers.native_layers import ( + helper_module, + layer_plan, + upward_reference_lines, +) from scripts.fensu_policy._helpers.native_patches import native_patch_lines from scripts.fensu_policy.constants import ( NATIVE_EDGE_PATHS, + NATIVE_LAYER_ORDER, + NATIVE_MODULE_LAYERS, NATIVE_PENDING_BUDGETS, NATIVE_TEST_PATCH_BUDGETS, NATIVE_TEST_PATH_PREFIX, ) +from scripts.fensu_policy.models import LayerPlan @rule( @@ -55,6 +64,40 @@ def native_python_storage(*, file: File, ctx: RuleContext) -> list[Fault]: return budgeted_faults(ctx=ctx, lines=python_field_lines, what="Python-typed fields") +@rule( + code="XSB075", + family=Family.CUSTOM, + slug="native-module-layering", + message="native binding helper modules must import only from lower layers", + remediation=( + "Move the shared item into a module of a lower layer, or move the importing code up; " + "assign every new helper module a layer in module_layers." + ), + analyzers=(AnalyzerId.RUST,), + options=(NATIVE_LAYER_ORDER, NATIVE_MODULE_LAYERS, NATIVE_PENDING_BUDGETS), +) +def native_module_layering(*, file: File, ctx: RuleContext) -> list[Fault]: + del file + path: str = "/".join(ctx.repo_relative_parts()) + if helper_module(path=path) is None: + return [] + plan: LayerPlan = layer_plan( + order=ctx.option(NATIVE_LAYER_ORDER), modules=ctx.option(NATIVE_MODULE_LAYERS) + ) + found: list[int] | None = upward_reference_lines(path=path, source=ctx.source, plan=plan) + if found is None: + return [ + ctx.fault_for( + path=ctx.path, + line=1, + column=0, + message="helper module has no layer", + remediation="Assign the module a layer in module_layers.", + ) + ] + return budget_faults(ctx=ctx, path=path, found=found, what="upward module imports") + + @rule( code="XSB074", family=Family.CUSTOM, diff --git a/scripts/native_module_paths/constants.py b/scripts/native_module_paths/constants.py index 407caf0bd7..e435e0bd72 100644 --- a/scripts/native_module_paths/constants.py +++ b/scripts/native_module_paths/constants.py @@ -2,7 +2,11 @@ import re -SCANNED_SOURCE_ROOTS: tuple[str, ...] = ("crates/sqlbuild-python/src", "crates/sqlbuild-cli/src") +SCANNED_SOURCE_ROOTS: tuple[str, ...] = ( + "crates/sqlbuild-python/src", + "crates/sqlbuild-cli/src", + "crates/sqlbuild-host/src", +) RUST_SOURCE_GLOB: str = "*.rs" PACKAGE_LITERAL: re.Pattern[str] = re.compile(r'"(sqlbuild\.[^"\\]*)"') DOTTED_PATH: re.Pattern[str] = re.compile(r"sqlbuild(?:\.[A-Za-z_][A-Za-z0-9_]*)+") diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index b50dac1653..73b4e6c43b 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -35,6 +35,14 @@ crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs ColumnMig crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs TransientLineCoordinator.lock crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs TransientLineCoordinator.lock crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs CliNamespace.command +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs CliNamespace.dbt_args +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs CliNamespace.json +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs CliNamespace.lineage_format +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs CliNamespace.query_format +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/progress_text.rs VerboseInspectionWriter.write +crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs SqlValueKind.value crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs BuildProgressCallbacks._spin_until_stopped crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs NestedCommandProgressCallbacks._spin_until_stopped crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs TransientStatusReporter._spin_until_stopped @@ -86,13 +94,6 @@ crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs EventExporterD crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs InvocationOutcome.consume crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs NativeProgressProjector.consume crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs TerminalEventIndex.consume -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.command -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.dbt_args -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.json -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.lineage_format -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.query_format -crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs TransientLineCoordinator.lock -crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs VerboseInspectionWriter.write crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs WarehouseGroup.value crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs NativeScopeIndex.grant_relationships crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs DbtCompileReferenceResolver.validate_model_names @@ -108,11 +109,6 @@ crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.entry_path crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.native crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.outcome -crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs ResourceKind.value -crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs DeclarationKind.value -crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs MacroArgumentError.offset -crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs ScopeKind.value -crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs CollectionRendering.value crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs LayoutConfig.__dataclass_fields__ crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs LayoutConfig.__dict__ crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs PythonHookEntry.__dataclass_fields__ @@ -154,6 +150,7 @@ crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs CompileInp crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs PreparedCompileArtifacts.publish crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs PythonNodeGraph.selected_sql_refs crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs PlannerScopeResolution.stale_warning_scope +crates/sqlbuild-python/src/bindings/_helpers/compiled_views/records.rs CollectionRendering.value crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs ConnectionProgressReporter.on_connection_complete crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs SqlValueKind.value crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs DbtInitProgressReporter.complete @@ -187,6 +184,7 @@ crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.help crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.message crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs EventExporterCommandScope.cached_extensions +crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs SourceWriteStrategy.value crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs DeclarationKind.value crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs ScopeKind.value crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs EventExporterCommandScope.cached_extensions @@ -234,7 +232,10 @@ crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs TableTypeSource crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs UsageKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs VisibilityReason.name crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs CompilerStage.value -crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs SourceWriteStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/input_loops/attachment.rs ResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/input_loops/loop_classes.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_macros.rs MacroArgumentError.offset +crates/sqlbuild-python/src/bindings/_helpers/input_loops/model_loop_named.rs ScopeKind.value crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs OldNameViewHistory.status crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs ColumnLineageMode.value crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs PlannerInputError.code @@ -422,7 +423,6 @@ crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs BindingCat crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs BindingCatalog.inferred_schema crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs BindingPositions.position crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs PlanningProgressReporter.on_progress -crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs SqlValueKind.value crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs CursorGrain.value crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs CursorType.value crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs CompiledResourceType.value diff --git a/tests/unit/scripts/fensu_policy/rules/_test_types.py b/tests/unit/scripts/fensu_policy/rules/_test_types.py index 684e28318b..318a8b279e 100644 --- a/tests/unit/scripts/fensu_policy/rules/_test_types.py +++ b/tests/unit/scripts/fensu_policy/rules/_test_types.py @@ -27,3 +27,33 @@ class NativePatchTestCase: source: str expected_fault_count: int budgets: tuple[str, ...] = () + + +@dataclass(frozen=True) +class NativeReferencesTestCase: + description: str + source: str + expected_references: tuple[tuple[int, tuple[str, ...]], ...] + + +@dataclass(frozen=True) +class NativeLayerTestCase: + description: str + module: tuple[str, ...] + expected_layer: str | None + + +@dataclass(frozen=True) +class NativeDirectionTestCase: + description: str + source: str + target: str + expected_upward: bool + + +@dataclass(frozen=True) +class NativeLayeringTestCase: + description: str + path: str + source: str + expected_lines: list[int] | None diff --git a/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py index 41b3817a4f..dd3e4ba20f 100644 --- a/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py +++ b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py @@ -4,10 +4,20 @@ from fensu import RuleCase, RuleResult, evaluate_rule from scripts.fensu_policy._helpers.native_crossings import crossing_lines, python_field_lines +from scripts.fensu_policy._helpers.native_layers import ( + helper_references, + layer_plan, + upward_reference_lines, +) +from scripts.fensu_policy.models import LayerPlan from scripts.fensu_policy.rules.native_boundary import native_module_test_patch from tests.unit.scripts.fensu_policy.rules._test_types import ( + NativeDirectionTestCase, + NativeLayeringTestCase, + NativeLayerTestCase, NativeLinesTestCase, NativePatchTestCase, + NativeReferencesTestCase, ) TEST_PATH: str = "tests/unit/src/sqlbuild/example/test_example.py" @@ -186,3 +196,229 @@ def test_given_rust_source_when_finding_python_fields_then_reports_struct_fields test_case: NativeLinesTestCase, ) -> None: assert tuple(python_field_lines(source=test_case.source)) == test_case.expected_lines + + +HELPERS: str = "crates/sqlbuild-python/src/bindings/_helpers" +LAYERS: LayerPlan = layer_plan( + order=("infra", "front", "plan|compile", "registry"), + modules=( + "boundary=infra", + "discovery=front", + "planner=plan", + "compile_driver=compile", + "compile_driver/python_calls=infra", + "*/registration=registry", + "misnamed=nowhere", + ), +) + + +@pytest.mark.parametrize( + "test_case", + [ + NativeReferencesTestCase( + description="single paths and nested brace groups expand to each named path", + source=dedent( + """ + use crate::bindings::_helpers::boundary::panics::guard; + use crate::bindings::_helpers::{ + compile_driver::{python_calls::imported, project}, + discovery, + }; + """ + ), + expected_references=( + (2, ("boundary", "panics", "guard")), + (4, ("compile_driver", "python_calls", "imported")), + (4, ("compile_driver", "project")), + (5, ("discovery",)), + ), + ), + NativeReferencesTestCase( + description="self in a group names the group's module", + source="use crate::bindings::_helpers::planner::{self, models::Entry};\n", + expected_references=((1, ("planner",)), (1, ("planner", "models", "Entry"))), + ), + NativeReferencesTestCase( + description="inline paths count; comments and test modules do not", + source=dedent( + """ + // use crate::bindings::_helpers::discovery::files; + fn read() { crate::bindings::_helpers::planner::run(); } + + #[cfg(test)] + mod tests { + use crate::bindings::_helpers::compile_driver::project; + } + """ + ), + expected_references=((3, ("planner", "run")),), + ), + ], + ids=lambda case: case.description, +) +def test_given_rust_source_when_finding_helper_references_then_expands_paths( + test_case: NativeReferencesTestCase, +) -> None: + found: tuple[tuple[int, tuple[str, ...]], ...] = tuple( + (reference.line, reference.target) + for reference in helper_references(source=test_case.source) + ) + + assert found == test_case.expected_references + + +@pytest.mark.parametrize( + "test_case", + [ + NativeLayerTestCase( + description="a module takes its top-level assignment", + module=("compile_driver", "project", "run"), + expected_layer="compile", + ), + NativeLayerTestCase( + description="a longer assignment overrides its parent", + module=("compile_driver", "python_calls", "imported"), + expected_layer="infra", + ), + NativeLayerTestCase( + description="a wildcard assignment overrides a shorter one", + module=("discovery", "registration"), + expected_layer="registry", + ), + NativeLayerTestCase( + description="a submodule without its own entry inherits", + module=("discovery", "files"), + expected_layer="front", + ), + NativeLayerTestCase( + description="an entry naming an unknown layer is ignored", + module=("misnamed",), + expected_layer=None, + ), + NativeLayerTestCase( + description="an unassigned module has no layer", + module=("unknown",), + expected_layer=None, + ), + ], + ids=lambda case: case.description, +) +def test_given_module_path_when_resolving_layer_then_longest_assignment_wins( + test_case: NativeLayerTestCase, +) -> None: + assert LAYERS.layer_of(module=test_case.module) == test_case.expected_layer + + +@pytest.mark.parametrize( + "test_case", + [ + NativeDirectionTestCase( + description="importing a lower layer passes", + source="compile", + target="infra", + expected_upward=False, + ), + NativeDirectionTestCase( + description="importing the same layer passes", + source="compile", + target="compile", + expected_upward=False, + ), + NativeDirectionTestCase( + description="importing a higher layer is upward", + source="front", + target="compile", + expected_upward=True, + ), + NativeDirectionTestCase( + description="importing a sibling layer is upward", + source="plan", + target="compile", + expected_upward=True, + ), + NativeDirectionTestCase( + description="the top layer may import anything below", + source="registry", + target="plan", + expected_upward=False, + ), + ], + ids=lambda case: case.description, +) +def test_given_two_layers_when_checking_direction_then_lower_and_same_layers_pass( + test_case: NativeDirectionTestCase, +) -> None: + upward: bool = LAYERS.points_upward(source=test_case.source, target=test_case.target) + + assert upward is test_case.expected_upward + + +@pytest.mark.parametrize( + "test_case", + [ + NativeLayeringTestCase( + description="imports into higher and sibling layers are reported", + path=f"{HELPERS}/planner/entries.rs", + source=dedent( + """ + use crate::bindings::_helpers::boundary::panics::guard; + use crate::bindings::_helpers::compile_driver::{project, python_calls::imported}; + use crate::bindings::_helpers::discovery::registration::register; + """ + ), + expected_lines=[3, 4], + ), + NativeLayeringTestCase( + description="references within the file's own module pass", + path=f"{HELPERS}/compile_driver/python_calls.rs", + source="use crate::bindings::_helpers::compile_driver::python_calls::models::Call;\n", + expected_lines=[], + ), + NativeLayeringTestCase( + description="a lower-layer file importing its higher-layer parent module is reported", + path=f"{HELPERS}/compile_driver/python_calls.rs", + source="use crate::bindings::_helpers::compile_driver::project::Project;\n", + expected_lines=[1], + ), + NativeLayeringTestCase( + description="mod.rs files take their directory's module", + path=f"{HELPERS}/discovery/mod.rs", + source="pub(crate) mod files;\nuse crate::bindings::_helpers::boundary::panics;\n", + expected_lines=[], + ), + NativeLayeringTestCase( + description="an unassigned helper module is reported", + path=f"{HELPERS}/unknown/reader.rs", + source="fn read() {}\n", + expected_lines=None, + ), + NativeLayeringTestCase( + description="test files and files outside the helpers are skipped", + path=f"{HELPERS}/discovery/tests/test_files.rs", + source="use crate::bindings::_helpers::compile_driver::project;\n", + expected_lines=[], + ), + NativeLayeringTestCase( + description="tests.rs module roots are skipped", + path=f"{HELPERS}/discovery/tests.rs", + source="use crate::bindings::_helpers::compile_driver::project;\n", + expected_lines=[], + ), + NativeLayeringTestCase( + description="a test_ file name outside a tests directory is source and is checked", + path=f"{HELPERS}/discovery/test_command.rs", + source="use crate::bindings::_helpers::compile_driver::project;\n", + expected_lines=[1], + ), + ], + ids=lambda case: case.description, +) +def test_given_helper_file_when_checking_layers_then_reports_upward_imports( + test_case: NativeLayeringTestCase, +) -> None: + found: list[int] | None = upward_reference_lines( + path=test_case.path, source=test_case.source, plan=LAYERS + ) + + assert found == test_case.expected_lines diff --git a/tests/unit/scripts/native_module_paths/_helpers/_test_types.py b/tests/unit/scripts/native_module_paths/_helpers/_test_types.py index 89d2e334f2..fc872e19c0 100644 --- a/tests/unit/scripts/native_module_paths/_helpers/_test_types.py +++ b/tests/unit/scripts/native_module_paths/_helpers/_test_types.py @@ -47,3 +47,10 @@ class HostDeadCodeRootCase: description: str expected_missing_targets: tuple[tuple[str, str], ...] expected_extra_targets: tuple[tuple[str, str], ...] + + +@dataclass(frozen=True) +class HostResultMirrorCase: + description: str + expected_mirror_count: int + expected_mismatches: tuple[str, ...] diff --git a/tests/unit/scripts/native_module_paths/_helpers/helpers.py b/tests/unit/scripts/native_module_paths/_helpers/helpers.py index 5f2fe828c8..90a86a7438 100644 --- a/tests/unit/scripts/native_module_paths/_helpers/helpers.py +++ b/tests/unit/scripts/native_module_paths/_helpers/helpers.py @@ -1,4 +1,9 @@ +import dataclasses +import importlib +import re +from enum import Enum from pathlib import Path +from typing import Any from scripts.native_module_paths._helpers.crates import native_module_path_errors from scripts.native_module_paths._helpers.scan import scan_native_source @@ -25,3 +30,43 @@ def resolved_kind(value: object) -> str: is_class: bool = isinstance(value, type) is_exception: bool = BaseException in getattr(value, "__mro__", ()) return KIND_BY_TRAITS[(is_class, is_exception, callable(value))] + + +HOST_RESULT_MODELS: Path = Path(__file__).parents[5] / "crates/sqlbuild-host/src/models.rs" +MIRRORED_ITEM: str = r"/// [^\n]* Mirrors `([\w.]+)`[^\n]*\n#\[derive[^\n]*\]\npub {kind} (\w+)" +ENUM_VALUE: re.Pattern[str] = re.compile(r'=> "([^"]*)",') +STRUCT_FIELD: re.Pattern[str] = re.compile(r"\n pub (\w+): ") + + +def mirrored_items(*, source: str, kind: str) -> dict[str, str]: + """Each Python path the source mirrors with an item of `kind`, mapped to the Rust item name.""" + return dict(re.findall(MIRRORED_ITEM.format(kind=kind), source)) + + +def rust_enum_values(*, source: str, name: str) -> tuple[str, ...]: + """The Python values the `ResultEnum` implementation of `name` lists, in order.""" + body: str = source.split(f"impl ResultEnum for {name} {{", 1)[1].split("\n}", 1)[0] + return tuple(ENUM_VALUE.findall(body)) + + +def rust_struct_fields(*, source: str, name: str) -> tuple[str, ...]: + """The field names of the Rust struct `name`, in order.""" + body: str = re.split(rf"pub struct {name}\b[^{{]*\{{", source, maxsplit=1)[1].split("\n}", 1)[0] + return tuple(STRUCT_FIELD.findall("\n" + body)) + + +def python_object(*, path: str) -> Any: + """The Python object at a dotted `module.name` path.""" + module, _, name = path.rpartition(".") + return getattr(importlib.import_module(module), name) + + +def python_enum_values(*, path: str) -> tuple[str, ...]: + """The values of the Python string enum at `path`, in definition order.""" + members: type[Enum] = python_object(path=path) + return tuple(str(member.value) for member in members) + + +def python_dataclass_fields(*, path: str) -> tuple[str, ...]: + """The field names of the Python dataclass at `path`, in order.""" + return tuple(field.name for field in dataclasses.fields(python_object(path=path))) diff --git a/tests/unit/scripts/native_module_paths/_helpers/test_host_results.py b/tests/unit/scripts/native_module_paths/_helpers/test_host_results.py new file mode 100644 index 0000000000..0bb2761e76 --- /dev/null +++ b/tests/unit/scripts/native_module_paths/_helpers/test_host_results.py @@ -0,0 +1,45 @@ +"""The executor result types in `sqlbuild-host` mirror the Python result dataclasses and enums.""" + +from __future__ import annotations + +import pytest + +from tests.unit.scripts.native_module_paths._helpers._test_types import HostResultMirrorCase +from tests.unit.scripts.native_module_paths._helpers.helpers import ( + HOST_RESULT_MODELS, + mirrored_items, + python_dataclass_fields, + python_enum_values, + rust_enum_values, + rust_struct_fields, +) + + +@pytest.mark.parametrize( + "test_case", + [ + HostResultMirrorCase( + description="every mirrored result enum and struct matches its Python values or fields", + expected_mirror_count=32, + expected_mismatches=(), + ) + ], + ids=lambda case: case.description, +) +def test_given_host_result_types_when_compared_with_python_then_fields_and_values_agree( + test_case: HostResultMirrorCase, +) -> None: + source: str = HOST_RESULT_MODELS.read_text(encoding="utf-8") + enums: dict[str, str] = mirrored_items(source=source, kind="enum") + structs: dict[str, str] = mirrored_items(source=source, kind="struct") + rust: set[tuple[str, tuple[str, ...]]] = { + (path, rust_enum_values(source=source, name=name)) for path, name in enums.items() + } | {(path, rust_struct_fields(source=source, name=name)) for path, name in structs.items()} + python: set[tuple[str, tuple[str, ...]]] = { + (path, python_enum_values(path=path)) for path in enums + } | {(path, python_dataclass_fields(path=path)) for path in structs} + + mismatches: set[str] = {path for path, _ in rust ^ python} + + assert len(enums) + len(structs) == test_case.expected_mirror_count + assert tuple(sorted(mismatches)) == test_case.expected_mismatches