grafbase_sql_ast/ast/
table.rs1use super::{ExpressionKind, Join, JoinData};
2use crate::ast::{Expression, Select, Values};
3use std::borrow::Cow;
4
5pub trait Aliasable<'a> {
7 type Target;
8
9 fn alias<T>(self, alias: T) -> Self::Target
11 where
12 T: Into<Cow<'a, str>>;
13}
14
15#[derive(Clone, Debug, PartialEq)]
16pub enum TableType<'a> {
18 Table(Cow<'a, str>),
19 JoinedTable(Box<(Cow<'a, str>, Vec<Join<'a>>)>),
20 Query(Box<Select<'a>>),
21 Values(Values<'a>),
22}
23
24#[derive(Clone, Debug)]
26pub struct Table<'a> {
27 pub typ: TableType<'a>,
28 pub alias: Option<Cow<'a, str>>,
29 pub database: Option<Cow<'a, str>>,
30}
31
32impl<'a> PartialEq for Table<'a> {
33 fn eq(&self, other: &Table) -> bool {
34 self.typ == other.typ && self.database == other.database
35 }
36}
37
38impl<'a> Table<'a> {
39 pub fn database<T>(mut self, database: T) -> Self
41 where
42 T: Into<Cow<'a, str>>,
43 {
44 self.database = Some(database.into());
45 self
46 }
47
48 pub fn asterisk(self) -> Expression<'a> {
50 Expression {
51 kind: ExpressionKind::Asterisk(Some(Box::new(self))),
52 alias: None,
53 }
54 }
55
56 pub fn left_join<J>(mut self, join: J) -> Self
59 where
60 J: Into<JoinData<'a>>,
61 {
62 match self.typ {
63 TableType::Table(table_name) => {
64 self.typ =
65 TableType::JoinedTable(Box::new((table_name, vec![Join::Left(join.into())])))
66 }
67 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Left(join.into())),
68 TableType::Query(_) => {
69 panic!("You cannot left_join on a table of type Query")
70 }
71 TableType::Values(_) => {
72 panic!("You cannot left_join on a table of type Values")
73 }
74 }
75
76 self
77 }
78
79 pub fn inner_join<J>(mut self, join: J) -> Self
82 where
83 J: Into<JoinData<'a>>,
84 {
85 match self.typ {
86 TableType::Table(table_name) => {
87 self.typ =
88 TableType::JoinedTable(Box::new((table_name, vec![Join::Inner(join.into())])))
89 }
90 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Inner(join.into())),
91 TableType::Query(_) => {
92 panic!("You cannot inner_join on a table of type Query")
93 }
94 TableType::Values(_) => {
95 panic!("You cannot inner_join on a table of type Values")
96 }
97 }
98
99 self
100 }
101
102 pub fn right_join<J>(mut self, join: J) -> Self
105 where
106 J: Into<JoinData<'a>>,
107 {
108 match self.typ {
109 TableType::Table(table_name) => {
110 self.typ =
111 TableType::JoinedTable(Box::new((table_name, vec![Join::Right(join.into())])))
112 }
113 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Right(join.into())),
114 TableType::Query(_) => {
115 panic!("You cannot right_join on a table of type Query")
116 }
117 TableType::Values(_) => {
118 panic!("You cannot right_join on a table of type Values")
119 }
120 }
121
122 self
123 }
124
125 pub fn full_join<J>(mut self, join: J) -> Self
128 where
129 J: Into<JoinData<'a>>,
130 {
131 match self.typ {
132 TableType::Table(table_name) => {
133 self.typ =
134 TableType::JoinedTable(Box::new((table_name, vec![Join::Full(join.into())])))
135 }
136 TableType::JoinedTable(ref mut jt) => jt.1.push(Join::Full(join.into())),
137 TableType::Query(_) => {
138 panic!("You cannot full_join on a table of type Query")
139 }
140 TableType::Values(_) => {
141 panic!("You cannot full_join on a table of type Values")
142 }
143 }
144
145 self
146 }
147}
148
149impl<'a> From<&'a str> for Table<'a> {
150 fn from(s: &'a str) -> Table<'a> {
151 Table {
152 typ: TableType::Table(s.into()),
153 alias: None,
154 database: None,
155 }
156 }
157}
158
159impl<'a> From<&'a String> for Table<'a> {
160 fn from(s: &'a String) -> Table<'a> {
161 Table {
162 typ: TableType::Table(s.into()),
163 alias: None,
164 database: None,
165 }
166 }
167}
168
169impl<'a> From<(&'a str, &'a str)> for Table<'a> {
170 fn from(s: (&'a str, &'a str)) -> Table<'a> {
171 let table: Table<'a> = s.1.into();
172 table.database(s.0)
173 }
174}
175
176impl<'a> From<(&'a str, &'a String)> for Table<'a> {
177 fn from(s: (&'a str, &'a String)) -> Table<'a> {
178 let table: Table<'a> = s.1.into();
179 table.database(s.0)
180 }
181}
182
183impl<'a> From<(&'a String, &'a str)> for Table<'a> {
184 fn from(s: (&'a String, &'a str)) -> Table<'a> {
185 let table: Table<'a> = s.1.into();
186 table.database(s.0)
187 }
188}
189
190impl<'a> From<(&'a String, &'a String)> for Table<'a> {
191 fn from(s: (&'a String, &'a String)) -> Table<'a> {
192 let table: Table<'a> = s.1.into();
193 table.database(s.0)
194 }
195}
196
197impl<'a> From<String> for Table<'a> {
198 fn from(s: String) -> Self {
199 Table {
200 typ: TableType::Table(s.into()),
201 alias: None,
202 database: None,
203 }
204 }
205}
206
207impl<'a> From<(String, String)> for Table<'a> {
208 fn from(s: (String, String)) -> Table<'a> {
209 let table: Table<'a> = s.1.into();
210 table.database(s.0)
211 }
212}
213
214impl<'a> From<Select<'a>> for Table<'a> {
215 fn from(select: Select<'a>) -> Self {
216 Table {
217 typ: TableType::Query(Box::new(select)),
218 alias: None,
219 database: None,
220 }
221 }
222}
223
224impl<'a> Aliasable<'a> for Table<'a> {
225 type Target = Table<'a>;
226
227 fn alias<T>(mut self, alias: T) -> Self::Target
228 where
229 T: Into<Cow<'a, str>>,
230 {
231 self.alias = Some(alias.into());
232 self
233 }
234}