pub struct DependencyGraph { /* private fields */ }Expand description
The dependency graph of one semantic model and the reports sharing it.
Build it once with DependencyGraph::build, then query: who uses an
object (consumers_of), what an object
uses (producers_of), and what nothing
reaches (unused_objects).
Implementations§
Source§impl DependencyGraph
impl DependencyGraph
Sourcepub fn build(db: &TabularDatabase, reports: &[&ReportModel]) -> Self
pub fn build(db: &TabularDatabase, reports: &[&ReportModel]) -> Self
Builds the graph for one model and every report that shares it.
Never fails: resolution misses are data, never errors. Passing no reports leaves every model object unused unless a role keeps it alive.
Sourcepub fn object_ids(&self) -> impl Iterator<Item = &ObjectId>
pub fn object_ids(&self) -> impl Iterator<Item = &ObjectId>
Every object in the graph, in build order (model order, then relationships, roles, shared expressions, functions, report measures).
Sourcepub fn consumers_of(&self, id: &ObjectId) -> Vec<(ObjectId, Provenance)>
pub fn consumers_of(&self, id: &ObjectId) -> Vec<(ObjectId, Provenance)>
The objects that use id, with what kind of use each edge records —
the query the ripbi deps view is built on. Report bindings are not
object-to-object edges; they are answered by
roots_of.
Sourcepub fn producers_of(&self, id: &ObjectId) -> Vec<(ObjectId, Provenance)>
pub fn producers_of(&self, id: &ObjectId) -> Vec<(ObjectId, Provenance)>
The objects that id uses, with what kind of use each edge records.
Sourcepub fn roots(&self) -> &[(ObjectId, Provenance)]
pub fn roots(&self) -> &[(ObjectId, Provenance)]
Every reachability root: the report bindings, with their targets and provenance, in report order. Deterministic for a given set of reports.
Sourcepub fn roots_of(&self, id: &ObjectId) -> Vec<&Provenance>
pub fn roots_of(&self, id: &ObjectId) -> Vec<&Provenance>
The provenance of every report binding that targets id.
Sourcepub fn broken_bindings(&self) -> &[BrokenBinding]
pub fn broken_bindings(&self) -> &[BrokenBinding]
Every report binding whose written field reference resolves to nothing in the model — the table is gone, or the column/measure/hierarchy is gone — plus the bindings that land on an artifact whose own DAX no longer resolves. Sorted by where the binding lives; deterministic for a given set of reports.
This is the liveness graph’s inverted question. The conservatism rule mirrors: a liveness claim may over-keep, a breakage claim must under-claim, so anything the resolution machinery might resolve — KPI-suffixed variants, auto date/time hierarchies, same-named hierarchies behind a stale qualifier — never appears here.
Sourcepub fn named_by_m(&self, id: &ObjectId) -> &[ObjectId]
pub fn named_by_m(&self, id: &ObjectId) -> &[ObjectId]
The M expressions that name id — its Power Query supply chain. A
name is not a consumer: unloading a column these expressions produce
cannot break refresh. But removing the column entirely — model and
script — means editing each of them, which is what this answers.
Non-empty only ever for Data columns: an M step can only name a column
it produces, so an engine-computed column matching an M name is
coincidence, not supply chain.
Sourcepub fn unused_objects(&self) -> Vec<UnusedObject>
pub fn unused_objects(&self) -> Vec<UnusedObject>
Every object reachability never reached, sorted by object identity:
the scan findings. Each finding names who still references it —
empty for a true orphan, and every referencing object is either
itself unused, a key column kept alive only as an active relationship
endpoint, or the table of an inactive relationship it cannot keep
alive.
Sourcepub fn auto_date_time_tables(
&self,
db: &TabularDatabase,
) -> Vec<AutoDateTimeVerdict>
pub fn auto_date_time_tables( &self, db: &TabularDatabase, ) -> Vec<AutoDateTimeVerdict>
Every auto date/time table — flagged at ingestion or matching the
engine’s LocalDateTable_ / DateTableTemplate_ name prefixes — with
the second verdict over the same graph the reachability findings come
from, sorted by object identity.
The verdict is deliberately not reachability. The engine’s own
relationship to the user’s date column keeps the machinery alive for
as long as that column is used, so “alive” says nothing about whether
a report binds it; a table counts as used only when a report binding
(Provenance::Binding) lands on the table itself or on one of its
members. This is the same data the reachability findings are computed
from, read with a different question — not a separate analysis.