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 {
55 kind: ExpressionKind::Asterisk(Some(Box::new(self))),
56 alias: None,
57 }
58 }
59
60 pub fn add_unique_index(mut self, i: impl Into<IndexDefinition<'a>>) -> Self {
62 let definition = i.into();
63 self.index_definitions.push(definition.set_table(self.clone()));
64 self
65 }
66
67 pub(crate) fn join_conditions(&self, inserted_columns: &[Column<'a>]) -> crate::Result<ConditionTree<'a>> {
76 let mut result = ConditionTree::NegativeCondition;
77
78 let join_cond = |column: &Column<'a>| {
79 let cond = if !inserted_columns.contains(column) {
80 match column.default.clone() {
81 Some(DefaultValue::Provided(val)) => Some(column.clone().equals(val).into()),
82 Some(DefaultValue::Generated) => None,
83 None => {
84 let kind =
85 ErrorKind::conversion("A unique column missing from insert and table has no default.");
86
87 return Err(Error::builder(kind).build());
88 }
89 }
90 } else {
91 let dual_col = column.clone().table("dual");
92 Some(dual_col.equals(column.clone()).into())
93 };
94
95 Ok::<Option<ConditionTree>, Error>(cond)
96 };
97
98 for index in self.index_definitions.iter() {
99 match index {
100 IndexDefinition::Single(column) => {
101 if let Some(right_cond) = join_cond(column)? {
102 match result {
103 ConditionTree::NegativeCondition => result = right_cond,
104 left_cond => result = left_cond.or(right_cond),
105 }
106 }
107 }
108 IndexDefinition::Compound(cols) => {
109 let mut sub_result = ConditionTree::NoCondition;
110
111 for right in cols.iter() {
112 let right_cond = join_cond(right)?.unwrap_or(ConditionTree::NegativeCondition);
113
114 match sub_result {
115 ConditionTree::NoCondition => sub_result = right_cond,
116 left_cond => sub_result = left_cond.and(right_cond),
117 }
118 }
119
120 match result {
121 ConditionTree::NegativeCondition => result = sub_result,
122 left_cond => result = left_cond.or(sub_result),
123 }
124 }
125 }
126 }
127
128 Ok(result)
129 }
130
131 pub fn left_join<J>(mut self, join: J) -> Self
159 where
160 J: Into<JoinData<'a>>,
161 {
162 match self.typ {
163 TableType::Table(table_name) => {
164 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Left(join.into())])))
165 }
166 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Left(join.into())),
167 TableType::Query(_) => {
168 panic!("You cannot left_join on a table of type Query")
169 }
170 TableType::Values(_) => {
171 panic!("You cannot left_join on a table of type Values")
172 }
173 }
174
175 self
176 }
177
178 pub fn inner_join<J>(mut self, join: J) -> Self
206 where
207 J: Into<JoinData<'a>>,
208 {
209 match self.typ {
210 TableType::Table(table_name) => {
211 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Inner(join.into())])))
212 }
213 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Inner(join.into())),
214 TableType::Query(_) => {
215 panic!("You cannot inner_join on a table of type Query")
216 }
217 TableType::Values(_) => {
218 panic!("You cannot inner_join on a table of type Values")
219 }
220 }
221
222 self
223 }
224
225 pub fn right_join<J>(mut self, join: J) -> Self
253 where
254 J: Into<JoinData<'a>>,
255 {
256 match self.typ {
257 TableType::Table(table_name) => {
258 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Right(join.into())])))
259 }
260 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Right(join.into())),
261 TableType::Query(_) => {
262 panic!("You cannot right_join on a table of type Query")
263 }
264 TableType::Values(_) => {
265 panic!("You cannot right_join on a table of type Values")
266 }
267 }
268
269 self
270 }
271
272 pub fn full_join<J>(mut self, join: J) -> Self
300 where
301 J: Into<JoinData<'a>>,
302 {
303 match self.typ {
304 TableType::Table(table_name) => {
305 self.typ = TableType::JoinedTable(Box::new((table_name, vec![Join::Full(join.into())])))
306 }
307 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Full(join.into())),
308 TableType::Query(_) => {
309 panic!("You cannot full_join on a table of type Query")
310 }
311 TableType::Values(_) => {
312 panic!("You cannot full_join on a table of type Values")
313 }
314 }
315
316 self
317 }
318}
319
320impl<'a> From<&'a str> for Table<'a> {
321 fn from(s: &'a str) -> Table<'a> {
322 Table {
323 typ: TableType::Table(s.into()),
324 alias: None,
325 database: None,
326 index_definitions: Vec::new(),
327 }
328 }
329}
330
331impl<'a> From<&'a String> for Table<'a> {
332 fn from(s: &'a String) -> Table<'a> {
333 Table {
334 typ: TableType::Table(s.into()),
335 alias: None,
336 database: None,
337 index_definitions: Vec::new(),
338 }
339 }
340}
341
342impl<'a> From<(&'a str, &'a str)> for Table<'a> {
343 fn from(s: (&'a str, &'a str)) -> Table<'a> {
344 let table: Table<'a> = s.1.into();
345 table.database(s.0)
346 }
347}
348
349impl<'a> From<(&'a str, &'a String)> for Table<'a> {
350 fn from(s: (&'a str, &'a String)) -> Table<'a> {
351 let table: Table<'a> = s.1.into();
352 table.database(s.0)
353 }
354}
355
356impl<'a> From<(&'a String, &'a str)> for Table<'a> {
357 fn from(s: (&'a String, &'a str)) -> Table<'a> {
358 let table: Table<'a> = s.1.into();
359 table.database(s.0)
360 }
361}
362
363impl<'a> From<(&'a String, &'a String)> for Table<'a> {
364 fn from(s: (&'a String, &'a String)) -> Table<'a> {
365 let table: Table<'a> = s.1.into();
366 table.database(s.0)
367 }
368}
369
370impl<'a> From<String> for Table<'a> {
371 fn from(s: String) -> Self {
372 Table {
373 typ: TableType::Table(s.into()),
374 alias: None,
375 database: None,
376 index_definitions: Vec::new(),
377 }
378 }
379}
380
381impl<'a> From<Vec<Row<'a>>> for Table<'a> {
382 fn from(values: Vec<Row<'a>>) -> Self {
383 Table::from(Values::from(values.into_iter()))
384 }
385}
386
387impl<'a> From<Values<'a>> for Table<'a> {
388 fn from(values: Values<'a>) -> Self {
389 Self {
390 typ: TableType::Values(values),
391 alias: None,
392 database: None,
393 index_definitions: Vec::new(),
394 }
395 }
396}
397
398impl<'a> From<(String, String)> for Table<'a> {
399 fn from(s: (String, String)) -> Table<'a> {
400 let table: Table<'a> = s.1.into();
401 table.database(s.0)
402 }
403}
404
405impl<'a> From<Select<'a>> for Table<'a> {
406 fn from(select: Select<'a>) -> Self {
407 Table {
408 typ: TableType::Query(Box::new(select)),
409 alias: None,
410 database: None,
411 index_definitions: Vec::new(),
412 }
413 }
414}
415
416impl<'a> Aliasable<'a> for Table<'a> {
417 type Target = Table<'a>;
418
419 fn alias<T>(mut self, alias: T) -> Self::Target
420 where
421 T: Into<Cow<'a, str>>,
422 {
423 self.alias = Some(alias.into());
424 self
425 }
426}
427
428aliasable!(String, (String, String));
429aliasable!(&'a str, (&'a str, &'a str));