Skip to main content

sim_relation_schema/
fixtures.rs

1use crate::{
2    ColumnBuilder, Constraint, ForeignKey, PrimaryKey, Schema, SchemaBuilder, SchemaError,
3    TableBuilder, UniqueConstraint, ValueShapeValidator,
4};
5use sim_kernel::Symbol;
6use sim_relation_core::{BaseDomain, ColumnName, DomainCatalog, TableName};
7
8fn n<T: TryFrom<Symbol>>(value: &str) -> T
9where
10    T::Error: std::fmt::Debug,
11{
12    T::try_from(Symbol::new(value)).expect("fixture name")
13}
14fn domains() -> DomainCatalog {
15    DomainCatalog::new([
16        BaseDomain::Bool.spec(),
17        BaseDomain::I64.spec(),
18        BaseDomain::F64.spec(),
19        BaseDomain::Text.spec(),
20        BaseDomain::Bytes.spec(),
21    ])
22    .expect("fixture domains")
23}
24fn base(
25    name: &str,
26    validator: &impl ValueShapeValidator,
27    extra: bool,
28) -> Result<Schema, SchemaError> {
29    let id: ColumnName = n("id");
30    let owner: ColumnName = n("owner_id");
31    let items: TableName = n("items");
32    let owners: TableName = n("owners");
33    let owners_t = TableBuilder::new(owners.clone())
34        .column(ColumnBuilder::required(id.clone(), BaseDomain::I64.id()).build())
35        .constraint(Constraint::Primary(PrimaryKey {
36            name: n("owners_pk"),
37            columns: vec![id.clone()],
38        }))
39        .build();
40    let mut item = TableBuilder::new(items.clone())
41        .column(ColumnBuilder::required(id.clone(), BaseDomain::I64.id()).build())
42        .column(ColumnBuilder::required(owner.clone(), BaseDomain::I64.id()).build())
43        .column(ColumnBuilder::required(n("title"), BaseDomain::Text.id()).build())
44        .constraint(Constraint::Primary(PrimaryKey {
45            name: n("items_pk"),
46            columns: vec![id.clone()],
47        }))
48        .constraint(Constraint::Foreign(ForeignKey {
49            name: n("items_owner_fk"),
50            columns: vec![owner],
51            target_table: owners.clone(),
52            target_columns: vec![id],
53        }));
54    if extra {
55        item = item.constraint(Constraint::Unique(UniqueConstraint {
56            name: n("items_title_uq"),
57            columns: vec![n("title")],
58        }));
59    }
60    SchemaBuilder::new(n(name))
61        .table(item.build())
62        .table(owners_t)
63        .build(&domains(), validator)
64}
65/// Exact logical fixture for document stores.
66pub fn document(v: &impl ValueShapeValidator) -> Result<Schema, SchemaError> {
67    base("document", v, false)
68}
69/// Exact logical fixture for Gantt stores.
70pub fn gantt(v: &impl ValueShapeValidator) -> Result<Schema, SchemaError> {
71    base("gantt", v, true)
72}
73/// Exact logical fixture for ledger stores.
74pub fn ledger(v: &impl ValueShapeValidator) -> Result<Schema, SchemaError> {
75    base("ledger", v, true)
76}
77/// Exact logical fixture for relation-directory stores.
78pub fn relation_directory(v: &impl ValueShapeValidator) -> Result<Schema, SchemaError> {
79    base("relation-directory", v, false)
80}