1use super::{Column, Comparable, ConditionTree, DefaultValue, ExpressionKind, IndexDefinition, Join, JoinData};
2use crate::{
3 ast::{Expression, Row, Select, Values},
4 error::{Error, ErrorKind},
5};
6use std::borrow::Cow;
7
8pub trait Aliasable<'a> {
10 type Target;
11
12 fn alias<T>(self, alias: T) -> Self::Target
14 where
15 T: Into<Cow<'a, str>>;
16}
17
18#[derive(Clone, Debug, PartialEq)]
19pub enum TableType<'a> {
21 Table(Cow<'a, str>),
22 JoinedTable(Box<(Cow<'a, str>, Vec<Join<'a>>)>),
23 Query(Box<Select<'a>>),
24 Values(Values<'a>),
25}
26
27#[derive(Clone, Debug)]
29pub struct Table<'a> {
30 pub typ: TableType<'a>,
31 pub alias: Option<Cow<'a, str>>,
32 pub database: Option<Cow<'a, str>>,
33 pub(crate) index_definitions: Vec<IndexDefinition<'a>>,
34}
35
36impl<'a> PartialEq for Table<'a> {
37 fn eq(&self, other: &Table) -> bool {
38 self.typ == other.typ && self.database == other.database
39 }
40}
41
42impl<'a> Table<'a> {
43 pub fn database<T>(mut self, database: T) -> Self
45 where
46 T: Into<Cow<'a, str>>,
47 {
48 self.database = Some(database.into());
49 self
50 }
51
52 pub fn asterisk(self) -> Expression<'a> {
54 Expression { kind: ExpressionKind::Asterisk(Some(Box::new(self))), alias: None }
55 }
56
57 pub fn add_unique_index(mut self, i: impl Into<IndexDefinition<'a>>) -> Self {
59 let definition = i.into();
60 self.index_definitions.push(definition.set_table(self.clone()));
61 self
62 }
63
64 pub(crate) fn join_conditions(&self, inserted_columns: &[Column<'a>]) -> crate::Result<ConditionTree<'a>> {
73 let mut result = ConditionTree::NegativeCondition;
74
75 let join_cond = |column: &Column<'a>| {
76 let cond = if !inserted_columns.contains(column) {
77 match column.default.clone() {
78 Some(DefaultValue::Provided(val)) => Some(column.clone().equals(val).into()),
79 Some(DefaultValue::Generated) => None,
80 None => {
81 let kind =
82 ErrorKind::conversion("A unique column missing from insert and table has no default.");
83
84 return Err(Error::builder(kind).build());
85 }
86 }
87 } else {
88 let dual_col = column.clone().table("dual");
89 Some(dual_col.equals(column.clone()).into())
90 };
91
92 Ok::<Option<ConditionTree>, Error>(cond)
93 };
94
95 for index in self.index_definitions.iter() {
96 match index {
97 IndexDefinition::Single(column) => {
98 if let Some(right_cond) = join_cond(column)? {
99 match result {
100 ConditionTree::NegativeCondition => result = right_cond,
101 left_cond => result = left_cond.or(right_cond),
102 }
103 }
104 }
105 IndexDefinition::Compound(cols) => {
106 let mut sub_result = ConditionTree::NoCondition;
107
108 for right in cols.iter() {
109 let right_cond = join_cond(right)?.unwrap_or(ConditionTree::NegativeCondition);
110
111 match sub_result {
112 ConditionTree::NoCondition => sub_result = right_cond,
113 left_cond => sub_result = left_cond.and(right_cond),
114 }
115 }
116
117 match result {
118 ConditionTree::NegativeCondition => result = sub_result,
119 left_cond => result = left_cond.or(sub_result),
120 }
121 }
122 }
123 }
124
125 Ok(result)
126 }
127
128 pub fn left_join<J>(mut self, join: J) -> Self
156 where
157 J: Into<JoinData<'a>>,
158 {
159 match self.typ {
160 TableType::Table(table_name) => {
161 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Left(join.into())])))
162 }
163 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Left(join.into())),
164 TableType::Query(_) => {
165 panic!("You cannot left_join on a table of type Query")
166 }
167 TableType::Values(_) => {
168 panic!("You cannot left_join on a table of type Values")
169 }
170 }
171
172 self
173 }
174
175 pub fn inner_join<J>(mut self, join: J) -> Self
203 where
204 J: Into<JoinData<'a>>,
205 {
206 match self.typ {
207 TableType::Table(table_name) => {
208 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Inner(join.into())])))
209 }
210 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Inner(join.into())),
211 TableType::Query(_) => {
212 panic!("You cannot inner_join on a table of type Query")
213 }
214 TableType::Values(_) => {
215 panic!("You cannot inner_join on a table of type Values")
216 }
217 }
218
219 self
220 }
221
222 pub fn right_join<J>(mut self, join: J) -> Self
250 where
251 J: Into<JoinData<'a>>,
252 {
253 match self.typ {
254 TableType::Table(table_name) => {
255 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Right(join.into())])))
256 }
257 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Right(join.into())),
258 TableType::Query(_) => {
259 panic!("You cannot right_join on a table of type Query")
260 }
261 TableType::Values(_) => {
262 panic!("You cannot right_join on a table of type Values")
263 }
264 }
265
266 self
267 }
268
269 pub fn full_join<J>(mut self, join: J) -> Self
297 where
298 J: Into<JoinData<'a>>,
299 {
300 match self.typ {
301 TableType::Table(table_name) => {
302 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Full(join.into())])))
303 }
304 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Full(join.into())),
305 TableType::Query(_) => {
306 panic!("You cannot full_join on a table of type Query")
307 }
308 TableType::Values(_) => {
309 panic!("You cannot full_join on a table of type Values")
310 }
311 }
312
313 self
314 }
315}
316
317impl<'a> From<&'a str> for Table<'a> {
318 fn from(s: &'a str) -> Table<'a> {
319 Table { typ: TableType::Table(s.into()), alias: None, database: None, index_definitions: Vec::new() }
320 }
321}
322
323impl<'a> From<&'a String> for Table<'a> {
324 fn from(s: &'a String) -> Table<'a> {
325 Table { typ: TableType::Table(s.into()), alias: None, database: None, index_definitions: Vec::new() }
326 }
327}
328
329impl<'a> From<(&'a str, &'a str)> for Table<'a> {
330 fn from(s: (&'a str, &'a str)) -> Table<'a> {
331 let table: Table<'a> = s.1.into();
332 table.database(s.0)
333 }
334}
335
336impl<'a> From<(&'a str, &'a String)> for Table<'a> {
337 fn from(s: (&'a str, &'a String)) -> Table<'a> {
338 let table: Table<'a> = s.1.into();
339 table.database(s.0)
340 }
341}
342
343impl<'a> From<(&'a String, &'a str)> for Table<'a> {
344 fn from(s: (&'a String, &'a str)) -> Table<'a> {
345 let table: Table<'a> = s.1.into();
346 table.database(s.0)
347 }
348}
349
350impl<'a> From<(&'a String, &'a String)> for Table<'a> {
351 fn from(s: (&'a String, &'a String)) -> Table<'a> {
352 let table: Table<'a> = s.1.into();
353 table.database(s.0)
354 }
355}
356
357impl<'a> From<String> for Table<'a> {
358 fn from(s: String) -> Self {
359 Table { typ: TableType::Table(s.into()), alias: None, database: None, index_definitions: Vec::new() }
360 }
361}
362
363impl<'a> From<Vec<Row<'a>>> for Table<'a> {
364 fn from(values: Vec<Row<'a>>) -> Self {
365 Table::from(Values::from(values.into_iter()))
366 }
367}
368
369impl<'a> From<Values<'a>> for Table<'a> {
370 fn from(values: Values<'a>) -> Self {
371 Self { typ: TableType::Values(values), alias: None, database: None, index_definitions: Vec::new() }
372 }
373}
374
375impl<'a> From<(String, String)> for Table<'a> {
376 fn from(s: (String, String)) -> Table<'a> {
377 let table: Table<'a> = s.1.into();
378 table.database(s.0)
379 }
380}
381
382impl<'a> From<Select<'a>> for Table<'a> {
383 fn from(select: Select<'a>) -> Self {
384 Table { typ: TableType::Query(Box::new(select)), alias: None, database: None, index_definitions: Vec::new() }
385 }
386}
387
388impl<'a> Aliasable<'a> for Table<'a> {
389 type Target = Table<'a>;
390
391 fn alias<T>(mut self, alias: T) -> Self::Target
392 where
393 T: Into<Cow<'a, str>>,
394 {
395 self.alias = Some(alias.into());
396 self
397 }
398}
399
400aliasable!(String, (String, String));
401aliasable!(&'a str, (&'a str, &'a str));