#[derive(Debug, Clone)]
pub enum JoinModifier {
Inner,
ForeignKey(String),
}
#[derive(Debug, Clone)]
pub struct JoinSpec {
pub relation: String,
pub columns: Vec<String>,
pub alias: Option<String>,
pub modifier: Option<JoinModifier>,
}
impl JoinSpec {
pub fn new(relation: &str, columns: &[&str]) -> Self {
Self {
relation: relation.to_owned(),
columns: columns.iter().map(|s| (*s).to_string()).collect(),
alias: None,
modifier: None,
}
}
pub fn inner(mut self) -> Self {
self.modifier = Some(JoinModifier::Inner);
self
}
pub fn foreign_key(mut self, fk_name: &str) -> Self {
self.modifier = Some(JoinModifier::ForeignKey(fk_name.to_owned()));
self
}
pub fn alias(mut self, alias: &str) -> Self {
self.alias = Some(alias.to_owned());
self
}
pub fn to_select_fragment(&self) -> String {
let cols = self.columns.join(",");
let relation_part = match &self.modifier {
Some(JoinModifier::Inner) => format!("{}!inner", self.relation),
Some(JoinModifier::ForeignKey(fk)) => format!("{}!{}", self.relation, fk),
None => self.relation.clone(),
};
let fragment = format!("{}({})", relation_part, cols);
if let Some(ref alias) = self.alias {
format!("{}:{}", alias, fragment)
} else {
fragment
}
}
}