rullst_orm/schema/
join.rs1use super::validation::{ALLOWED_OPERATORS, validate_identifier, validate_table_name};
2
3pub struct JoinClause {
4 pub table: String,
5 pub conditions: Vec<String>,
6 pub bindings: Vec<crate::RullstValue>,
7 pub errors: Vec<crate::Error>,
8}
9
10impl JoinClause {
11 pub fn new(table: impl Into<String>) -> Self {
12 let table = table.into();
13 let mut clause = Self {
14 table,
15 conditions: vec![],
16 bindings: vec![],
17 errors: vec![],
18 };
19 if let Err(error) = validate_table_name(&clause.table) {
20 clause.errors.push(error);
21 }
22 clause
23 }
24
25 pub fn on(&mut self, first: &str, operator: &str, second: &str) -> &mut Self {
30 if let Err(e) = validate_identifier(first) {
31 self.errors.push(crate::Error::Validation(format!(
32 "JoinClause::on — invalid identifier for `first`: {:?}",
33 e
34 )));
35 }
36 if let Err(e) = validate_identifier(second) {
37 self.errors.push(crate::Error::Validation(format!(
38 "JoinClause::on — invalid identifier for `second`: {:?}",
39 e
40 )));
41 }
42 if !ALLOWED_OPERATORS.contains(&operator) {
43 self.errors.push(crate::Error::Validation(format!(
44 "JoinClause::on — invalid operator '{}'. Allowed: {:?}",
45 operator, ALLOWED_OPERATORS
46 )));
47 }
48 self.conditions
49 .push(format!("{} {} {}", first, operator, second));
50 self
51 }
52
53 pub fn on_eq<T: Into<crate::RullstValue>>(&mut self, column: &str, value: T) -> &mut Self {
54 if let Err(e) = validate_identifier(column) {
55 self.errors.push(crate::Error::Validation(format!(
56 "JoinClause::on_eq — invalid identifier for `column`: {:?}",
57 e
58 )));
59 }
60 self.conditions.push(format!("{} = ?", column));
61 self.bindings.push(value.into());
62 self
63 }
64
65 pub fn to_sql(&self) -> String {
66 self.conditions.join(" AND ")
67 }
68}