toolu_orm_query/select/relational/
config.rs1#[derive(Debug, Clone)]
5pub struct RelationConfig {
6 pub field_name: String,
8 pub target_table: String,
10 pub local_key: String,
12 pub foreign_key: String,
14 pub target_columns: Vec<String>,
16 pub is_many: bool,
18 pub nested: Vec<RelationConfig>,
20}
21
22impl RelationConfig {
23 fn new(
24 field_name: &str,
25 target_table: &str,
26 local_key: &str,
27 foreign_key: &str,
28 target_columns: &[&str],
29 is_many: bool,
30 ) -> Self {
31 Self {
32 field_name: field_name.to_owned(),
33 target_table: target_table.to_owned(),
34 local_key: local_key.to_owned(),
35 foreign_key: foreign_key.to_owned(),
36 target_columns: target_columns.iter().map(|c| (*c).to_owned()).collect(),
37 is_many,
38 nested: Vec::new(),
39 }
40 }
41}
42
43pub struct RelationalSelectBuilder {
45 pub(super) source_table: String,
46 pub(super) source_columns: Vec<String>,
47 pub(super) relations: Vec<RelationConfig>,
48}
49
50impl RelationalSelectBuilder {
51 pub fn new(source_table: &str, columns: &[&str]) -> Self {
53 Self {
54 source_table: source_table.to_owned(),
55 source_columns: columns.iter().map(|c| (*c).to_owned()).collect(),
56 relations: Vec::new(),
57 }
58 }
59
60 pub fn with_many(
62 mut self,
63 field_name: &str,
64 target_table: &str,
65 local_key: &str,
66 foreign_key: &str,
67 target_columns: &[&str],
68 ) -> Self {
69 self.relations.push(RelationConfig::new(
70 field_name,
71 target_table,
72 local_key,
73 foreign_key,
74 target_columns,
75 true,
76 ));
77 self
78 }
79
80 pub fn with_one(
82 mut self,
83 field_name: &str,
84 target_table: &str,
85 local_key: &str,
86 foreign_key: &str,
87 target_columns: &[&str],
88 ) -> Self {
89 self.relations.push(RelationConfig::new(
90 field_name,
91 target_table,
92 local_key,
93 foreign_key,
94 target_columns,
95 false,
96 ));
97 self
98 }
99
100 pub fn relation_configs(&self) -> &[RelationConfig] {
102 &self.relations
103 }
104
105 pub fn source_table(&self) -> &str {
107 &self.source_table
108 }
109
110 pub fn source_columns(&self) -> &[String] {
112 &self.source_columns
113 }
114
115 pub(super) fn push_source_select(&self, sql: &mut String) {
119 for (i, col) in self.source_columns.iter().enumerate() {
120 if i > 0 {
121 sql.push_str(", ");
122 }
123 push_qualified(sql, &self.source_table, col);
124 }
125 }
126
127 pub(super) fn push_column_list(sql: &mut String, qualifier: &str, columns: &[String]) {
129 for (i, col) in columns.iter().enumerate() {
130 if i > 0 {
131 sql.push_str(", ");
132 }
133 push_qualified(sql, qualifier, col);
134 }
135 }
136
137 pub(super) fn push_join_where(
139 &self,
140 sql: &mut String,
141 target_qualifier: &str,
142 rel: &RelationConfig,
143 ) {
144 sql.push_str(" WHERE ");
145 push_qualified(sql, target_qualifier, &rel.foreign_key);
146 sql.push_str(" = ");
147 push_qualified(sql, &self.source_table, &rel.local_key);
148 if !rel.is_many {
149 sql.push_str(" LIMIT 1");
150 }
151 }
152}
153
154fn push_qualified(sql: &mut String, qualifier: &str, column: &str) {
156 sql.push('"');
157 sql.push_str(qualifier);
158 sql.push_str("\".\"");
159 sql.push_str(column);
160 sql.push('"');
161}