1use indexmap::IndexMap;
2
3use crate::dict::Compound;
4use crate::span::Span;
5
6#[derive(Debug, Clone)]
8pub enum Origin {
9 Own,
11 Mixin {
12 name: String,
13 def_span: Span,
14 },
15 Blueprint {
16 name: String,
17 def_span: Span,
18 apply_span: Span,
19 },
20 Generated {
22 by: String,
23 },
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub enum Val {
28 Literal(String),
29 Eval(String),
30}
31
32#[derive(Debug, Clone)]
33pub struct Column {
34 pub name: String,
35 pub ty: String,
36 pub null: bool,
37 pub default: Option<Val>,
38 pub on_update: Option<Val>,
39 pub comment: Option<String>,
40 pub origin: Origin,
41 pub span: Span,
42}
43
44#[derive(Debug, Clone)]
45pub struct Index {
46 pub name: String,
47 pub columns: Vec<String>,
48 pub unique: bool,
49 pub span: Span,
50}
51
52#[derive(Debug, Clone)]
53pub struct ForeignKey {
54 pub alias: String,
56 pub columns: Vec<String>,
57 pub ref_table: String,
58 pub ref_columns: Vec<String>,
59 pub on_delete: String,
60 pub on_update: String,
61 pub span: Span,
62}
63
64#[derive(Debug, Clone)]
66pub struct Reverse {
67 pub alias: String,
68 pub from_table: String,
70 pub via: Vec<String>,
72 pub unique: bool,
74 pub span: Span,
75}
76
77#[derive(Debug, Clone)]
78pub struct Table {
79 pub name: String,
81 pub noun: Option<Compound>,
83 pub comment: Option<String>,
84 pub columns: IndexMap<String, Column>,
85 pub pk: Vec<String>,
86 pub indexes: Vec<Index>,
87 pub foreign_keys: Vec<ForeignKey>,
88 pub reverses: Vec<Reverse>,
89 pub origin: Origin,
90 pub span: Span,
91}
92
93#[derive(Debug, Clone, Default)]
94pub struct Schema {
95 pub tables: Vec<Table>,
96}
97
98impl Schema {
99 pub fn table(&self, name: &str) -> Option<&Table> {
100 self.tables.iter().find(|t| t.name == name)
101 }
102
103 pub fn table_by_noun(&self, name: &str) -> Option<&Table> {
105 self.tables
106 .iter()
107 .find(|t| t.noun.as_ref().and_then(Compound::as_single_noun) == Some(name))
108 }
109}