vantage_table/table/base/relations.rs
1//! The table's relations and contained relations as Vista references.
2
3use vantage_types::Entity;
4
5use super::Table;
6use crate::{references::ContainedRelation, traits::table_source::TableSource};
7
8impl<T: TableSource, E: Entity<T::Value>> Table<T, E> {
9 /// Snapshot the table's relations as Vista references (name, target,
10 /// cardinality, join key). Driver factories fold this into
11 /// `VistaMetadata` so the erased `Vista` carries enough to drive nested
12 /// insert and relation traversal.
13 ///
14 /// A reference's target is the table name of its built target, the name
15 /// a catalog resolves. Building a target is offline: no I/O runs until a
16 /// query does.
17 ///
18 /// Each relation gets one join key. A `has_many` key is fully known
19 /// here: this table's id column into the target's foreign key. A
20 /// `has_one` key constrains the target's id column, so it is
21 /// [`JoinKey::to_target_id`](vantage_vista::JoinKey::to_target_id),
22 /// resolved at traversal from the target the traversal builds.
23 pub fn vista_references(&self) -> Vec<vantage_vista::Reference> {
24 self.vista_references_keyed(&self.id_field_name())
25 }
26
27 /// [`vista_references`](Self::vista_references) with `source_id` as the
28 /// column a `has_many` reads from this table's rows. A contained record
29 /// passes its relation's id column, which may differ from the table's id
30 /// field.
31 pub(crate) fn vista_references_keyed(&self, source_id: &str) -> Vec<vantage_vista::Reference> {
32 let Some(refs) = &self.refs else {
33 return Vec::new();
34 };
35 refs.iter()
36 .map(|(name, r)| {
37 r.vista_reference(name, r.target_table_name(&self.data_source), source_id)
38 })
39 .collect()
40 }
41
42 /// The contained relations declared on this table as Vista references of
43 /// a contained kind, for driver factories to fold into `VistaMetadata`.
44 /// The records' schema is derived at traversal from each relation's
45 /// `build_target` closure.
46 pub fn vista_contained(&self) -> Vec<vantage_vista::Reference> {
47 self.contained.iter().map(|c| c.reference()).collect()
48 }
49
50 /// Look up a contained relation by name (for the driver's traversal).
51 pub fn contained_relation(&self, name: &str) -> Option<&ContainedRelation<T>> {
52 self.contained.iter().find(|c| c.name() == name)
53 }
54}