use std::collections::BTreeMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RelationKind {
One,
Many,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JoinColumn {
pub local: String,
pub foreign: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ThroughDef {
pub junction_table: String,
pub local_column: String,
pub foreign_column: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RelationDef {
pub field_name: String,
pub kind: RelationKind,
pub target_table: String,
pub join_columns: Vec<JoinColumn>,
pub through: Option<ThroughDef>,
}
pub fn one(field_name: &str, target_table: &str, columns: &[(&str, &str)]) -> RelationDef {
RelationDef {
field_name: field_name.to_owned(),
kind: RelationKind::One,
target_table: target_table.to_owned(),
join_columns: columns
.iter()
.map(|(local, foreign)| JoinColumn {
local: (*local).to_owned(),
foreign: (*foreign).to_owned(),
})
.collect(),
through: None,
}
}
pub fn many(field_name: &str, target_table: &str, columns: &[(&str, &str)]) -> RelationDef {
RelationDef {
field_name: field_name.to_owned(),
kind: RelationKind::Many,
target_table: target_table.to_owned(),
join_columns: columns
.iter()
.map(|(local, foreign)| JoinColumn {
local: (*local).to_owned(),
foreign: (*foreign).to_owned(),
})
.collect(),
through: None,
}
}
pub fn many_through(
field_name: &str,
target_table: &str,
columns: &[(&str, &str)],
junction_table: &str,
junction_local: &str,
junction_foreign: &str,
) -> RelationDef {
RelationDef {
field_name: field_name.to_owned(),
kind: RelationKind::Many,
target_table: target_table.to_owned(),
join_columns: columns
.iter()
.map(|(local, foreign)| JoinColumn {
local: (*local).to_owned(),
foreign: (*foreign).to_owned(),
})
.collect(),
through: Some(ThroughDef {
junction_table: junction_table.to_owned(),
local_column: junction_local.to_owned(),
foreign_column: junction_foreign.to_owned(),
}),
}
}
#[derive(Debug, Clone)]
pub struct RelationRegistry {
entries: BTreeMap<String, Vec<RelationDef>>,
}
impl RelationRegistry {
pub fn new() -> Self {
Self {
entries: BTreeMap::new(),
}
}
pub fn register(&mut self, source_table: &str, relations: Vec<RelationDef>) {
self.entries.insert(source_table.to_owned(), relations);
}
pub fn get(&self, source_table: &str) -> Option<&[RelationDef]> {
self.entries.get(source_table).map(Vec::as_slice)
}
}
impl Default for RelationRegistry {
fn default() -> Self {
Self::new()
}
}