use std::fmt;
use crate::{
DeltaSourceReport, MssqlOutputWriteStatus, MssqlWorkflowWriteReport, PhaseTimingReport,
support::sanitize_text_for_display,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WriteAllReport {
workflow: MssqlWorkflowWriteReport,
cache: WriteAllCacheReport,
sources: Vec<DeltaSourceReport>,
phase_timings: Vec<PhaseTimingReport>,
}
impl WriteAllReport {
pub(crate) fn new(
workflow: MssqlWorkflowWriteReport,
cache: WriteAllCacheReport,
sources: Vec<DeltaSourceReport>,
) -> Self {
Self {
workflow,
cache,
sources,
phase_timings: Vec::new(),
}
}
pub(crate) fn with_phase_timings(mut self, phase_timings: Vec<PhaseTimingReport>) -> Self {
self.phase_timings = phase_timings;
self
}
#[must_use]
pub const fn workflow(&self) -> &MssqlWorkflowWriteReport {
&self.workflow
}
#[must_use]
pub const fn cache(&self) -> &WriteAllCacheReport {
&self.cache
}
#[must_use]
pub fn sources(&self) -> &[DeltaSourceReport] {
&self.sources
}
#[must_use]
pub fn phase_timings(&self) -> &[PhaseTimingReport] {
&self.phase_timings
}
#[must_use]
pub fn len(&self) -> usize {
self.workflow.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.workflow.is_empty()
}
#[must_use]
pub fn outputs(&self) -> &[MssqlOutputWriteStatus] {
self.workflow.outputs()
}
#[must_use]
pub fn all_succeeded(&self) -> bool {
self.workflow.all_succeeded()
}
#[must_use]
pub fn succeeded_count(&self) -> usize {
self.workflow.succeeded_count()
}
#[must_use]
pub fn failed_count(&self) -> usize {
self.workflow.failed_count()
}
#[must_use]
pub fn skipped_count(&self) -> usize {
self.workflow.skipped_count()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WriteAllCacheReport {
Disabled,
NoCache {
reason: WriteAllNoCacheReason,
skipped_candidates: Vec<WriteAllCacheCandidateSkip>,
},
CacheAliases {
aliases: Vec<WriteAllCacheAliasReport>,
skipped_candidates: Vec<WriteAllCacheCandidateSkip>,
},
}
impl WriteAllCacheReport {
pub(crate) fn disabled() -> Self {
Self::Disabled
}
pub(crate) fn no_cache(
reason: WriteAllNoCacheReason,
skipped_candidates: Vec<WriteAllCacheCandidateSkip>,
) -> Self {
Self::NoCache {
reason,
skipped_candidates,
}
}
pub(crate) fn cache_aliases(
aliases: Vec<WriteAllCacheAliasReport>,
skipped_candidates: Vec<WriteAllCacheCandidateSkip>,
) -> Self {
Self::CacheAliases {
aliases,
skipped_candidates,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteAllNoCacheReason {
FewerThanTwoOutputs,
NoSharedRegisteredDerivedAlias,
AmbiguousSharedDerivedAlias,
}
#[derive(Clone, PartialEq, Eq)]
pub struct WriteAllCacheAliasReport {
table_id: u64,
alias: String,
output_indexes: Vec<usize>,
status: WriteAllCacheAliasStatus,
}
impl WriteAllCacheAliasReport {
pub(crate) fn new(
table_id: u64,
alias: impl Into<String>,
output_indexes: Vec<usize>,
status: WriteAllCacheAliasStatus,
) -> Self {
Self {
table_id,
alias: alias.into(),
output_indexes,
status,
}
}
#[must_use]
pub const fn table_id(&self) -> u64 {
self.table_id
}
#[must_use]
pub fn alias(&self) -> &str {
&self.alias
}
#[must_use]
pub fn output_indexes(&self) -> &[usize] {
&self.output_indexes
}
#[must_use]
pub const fn status(&self) -> WriteAllCacheAliasStatus {
self.status
}
}
impl fmt::Debug for WriteAllCacheAliasReport {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("WriteAllCacheAliasReport")
.field("table_id", &self.table_id)
.field("alias", &sanitize_text_for_display(&self.alias))
.field("output_indexes", &self.output_indexes)
.field("status", &self.status)
.finish()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteAllCacheAliasStatus {
Selected,
MaterializedAndRestored,
}
#[derive(Clone, PartialEq, Eq)]
pub struct WriteAllCacheCandidateSkip {
table_id: u64,
alias: String,
reason: WriteAllCacheCandidateSkipReason,
}
impl WriteAllCacheCandidateSkip {
pub(crate) fn new(
table_id: u64,
alias: impl Into<String>,
reason: WriteAllCacheCandidateSkipReason,
) -> Self {
Self {
table_id,
alias: alias.into(),
reason,
}
}
#[must_use]
pub const fn table_id(&self) -> u64 {
self.table_id
}
#[must_use]
pub fn alias(&self) -> &str {
&self.alias
}
#[must_use]
pub const fn reason(&self) -> &WriteAllCacheCandidateSkipReason {
&self.reason
}
}
impl fmt::Debug for WriteAllCacheCandidateSkip {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("WriteAllCacheCandidateSkip")
.field("table_id", &self.table_id)
.field("alias", &sanitize_text_for_display(&self.alias))
.field("reason", &self.reason)
.finish()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WriteAllCacheCandidateSkipReason {
NotShared {
output_count: usize,
},
MissingSqlText,
IncompleteLineage,
CoveredByDeeperSharedAlias {
selected_table_id: u64,
},
AmbiguousDepth,
}