Skip to main content

sim_relation_schema/
builders.rs

1use crate::{
2    Column, Constraint, DefaultValue, GeneratedValue, Index, Schema, SchemaError, Table,
3    ValueShapeValidator, View,
4};
5use sim_kernel::Datum;
6use sim_relation_core::{ColumnName, DomainCatalog, DomainId, SchemaName, TableName};
7
8/// Compact column builder.
9pub struct ColumnBuilder(Column);
10impl ColumnBuilder {
11    /// Starts a required column.
12    pub fn required(name: ColumnName, domain: DomainId) -> Self {
13        Self(Column {
14            name,
15            domain,
16            nullable: false,
17            default: None,
18            generated: None,
19        })
20    }
21    /// Starts a nullable column.
22    pub fn nullable(name: ColumnName, domain: DomainId) -> Self {
23        Self(Column {
24            name,
25            domain,
26            nullable: true,
27            default: None,
28            generated: None,
29        })
30    }
31    /// Adds a literal default.
32    pub fn default(mut self, value: Datum) -> Self {
33        self.0.default = Some(DefaultValue(value));
34        self
35    }
36    /// Adds a generated expression.
37    pub fn generated(mut self, value: GeneratedValue) -> Self {
38        self.0.generated = Some(value);
39        self
40    }
41    /// Finishes the declaration.
42    pub fn build(self) -> Column {
43        self.0
44    }
45}
46/// Compact table builder.
47pub struct TableBuilder(Table);
48impl TableBuilder {
49    /// Starts a table.
50    pub fn new(name: TableName) -> Self {
51        Self(Table {
52            name,
53            columns: Vec::new(),
54            constraints: Vec::new(),
55            indexes: Vec::new(),
56        })
57    }
58    /// Appends a semantic column.
59    pub fn column(mut self, column: Column) -> Self {
60        self.0.columns.push(column);
61        self
62    }
63    /// Adds an unordered constraint declaration.
64    pub fn constraint(mut self, value: Constraint) -> Self {
65        self.0.constraints.push(value);
66        self
67    }
68    /// Adds an unordered index declaration.
69    pub fn index(mut self, value: Index) -> Self {
70        self.0.indexes.push(value);
71        self
72    }
73    /// Finishes the declaration; graph validation occurs in [`SchemaBuilder::build`].
74    pub fn build(self) -> Table {
75        self.0
76    }
77}
78/// Compact complete-schema builder.
79pub struct SchemaBuilder {
80    name: SchemaName,
81    tables: Vec<Table>,
82    views: Vec<View>,
83}
84impl SchemaBuilder {
85    /// Starts a logical schema.
86    pub fn new(name: SchemaName) -> Self {
87        Self {
88            name,
89            tables: Vec::new(),
90            views: Vec::new(),
91        }
92    }
93    /// Adds a table.
94    pub fn table(mut self, value: Table) -> Self {
95        self.tables.push(value);
96        self
97    }
98    /// Adds a view.
99    pub fn view(mut self, value: View) -> Self {
100        self.views.push(value);
101        self
102    }
103    /// Validates and constructs the schema.
104    pub fn build(
105        self,
106        domains: &DomainCatalog,
107        validator: &impl ValueShapeValidator,
108    ) -> Result<Schema, SchemaError> {
109        Schema::new(self.name, self.tables, self.views, domains, validator)
110    }
111}