toolu_orm_core/
relation.rs1use std::collections::BTreeMap;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum RelationKind {
13 One,
15 Many,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct JoinColumn {
22 pub local: String,
24 pub foreign: String,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct ThroughDef {
31 pub junction_table: String,
33 pub local_column: String,
35 pub foreign_column: String,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
41pub struct RelationDef {
42 pub field_name: String,
44 pub kind: RelationKind,
46 pub target_table: String,
48 pub join_columns: Vec<JoinColumn>,
50 pub through: Option<ThroughDef>,
52}
53
54pub fn one(field_name: &str, target_table: &str, columns: &[(&str, &str)]) -> RelationDef {
58 RelationDef {
59 field_name: field_name.to_owned(),
60 kind: RelationKind::One,
61 target_table: target_table.to_owned(),
62 join_columns: columns
63 .iter()
64 .map(|(local, foreign)| JoinColumn {
65 local: (*local).to_owned(),
66 foreign: (*foreign).to_owned(),
67 })
68 .collect(),
69 through: None,
70 }
71}
72
73pub fn many(field_name: &str, target_table: &str, columns: &[(&str, &str)]) -> RelationDef {
77 RelationDef {
78 field_name: field_name.to_owned(),
79 kind: RelationKind::Many,
80 target_table: target_table.to_owned(),
81 join_columns: columns
82 .iter()
83 .map(|(local, foreign)| JoinColumn {
84 local: (*local).to_owned(),
85 foreign: (*foreign).to_owned(),
86 })
87 .collect(),
88 through: None,
89 }
90}
91
92pub fn many_through(
94 field_name: &str,
95 target_table: &str,
96 columns: &[(&str, &str)],
97 junction_table: &str,
98 junction_local: &str,
99 junction_foreign: &str,
100) -> RelationDef {
101 RelationDef {
102 field_name: field_name.to_owned(),
103 kind: RelationKind::Many,
104 target_table: target_table.to_owned(),
105 join_columns: columns
106 .iter()
107 .map(|(local, foreign)| JoinColumn {
108 local: (*local).to_owned(),
109 foreign: (*foreign).to_owned(),
110 })
111 .collect(),
112 through: Some(ThroughDef {
113 junction_table: junction_table.to_owned(),
114 local_column: junction_local.to_owned(),
115 foreign_column: junction_foreign.to_owned(),
116 }),
117 }
118}
119
120#[derive(Debug, Clone)]
122pub struct RelationRegistry {
123 entries: BTreeMap<String, Vec<RelationDef>>,
124}
125
126impl RelationRegistry {
127 pub fn new() -> Self {
129 Self {
130 entries: BTreeMap::new(),
131 }
132 }
133
134 pub fn register(&mut self, source_table: &str, relations: Vec<RelationDef>) {
136 self.entries.insert(source_table.to_owned(), relations);
137 }
138
139 pub fn get(&self, source_table: &str) -> Option<&[RelationDef]> {
141 self.entries.get(source_table).map(Vec::as_slice)
142 }
143}
144
145impl Default for RelationRegistry {
146 fn default() -> Self {
147 Self::new()
148 }
149}