1#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
3#![warn(missing_docs)]
4
5#[cfg(not(any(feature = "sqlite", feature = "postgres", feature = "mysql")))]
6compile_error!("One of the features sqlite, postgres, mysql must be activated");
7
8pub mod aggregation;
10pub mod alter_table;
12pub mod conditional;
14pub mod create_column;
16pub mod create_index;
18pub mod create_table;
20pub mod create_trigger;
22pub mod delete;
24pub mod drop_table;
26pub mod error;
28pub mod insert;
30pub mod join_table;
32pub mod limit_clause;
34pub mod on_conflict;
36pub mod ordering;
38pub mod select;
40pub mod select_column;
42pub mod update;
44pub mod value;
46
47mod db_specific;
48
49use std::borrow::Cow;
50
51use rorm_declaration::imr::{Annotation, DbType};
52
53use crate::aggregation::SelectAggregator;
54use crate::alter_table::{AlterTable, AlterTableData, AlterTableImpl, AlterTableOperation};
55use crate::conditional::Condition;
56#[cfg(feature = "mysql")]
57use crate::create_column::CreateColumnMySQLData;
58#[cfg(feature = "postgres")]
59use crate::create_column::CreateColumnPostgresData;
60#[cfg(feature = "sqlite")]
61use crate::create_column::CreateColumnSQLiteData;
62use crate::create_column::{CreateColumnImpl, SQLAnnotation};
63use crate::create_index::{CreateIndex, CreateIndexData, CreateIndexImpl};
64use crate::create_table::{CreateTable, CreateTableData, CreateTableImpl};
65use crate::create_trigger::{
66 SQLCreateTrigger, SQLCreateTriggerOperation, SQLCreateTriggerPointInTime,
67};
68use crate::delete::{Delete, DeleteData, DeleteImpl};
69use crate::drop_table::{DropTable, DropTableData, DropTableImpl};
70use crate::insert::{Insert, InsertData, InsertImpl};
71use crate::join_table::{JoinTableData, JoinTableImpl, JoinType};
72use crate::on_conflict::OnConflict;
73use crate::ordering::OrderByEntry;
74use crate::select::{Select, SelectData, SelectImpl};
75use crate::select_column::{SelectColumnData, SelectColumnImpl};
76use crate::update::{Update, UpdateData, UpdateImpl};
77use crate::value::Value;
78
79#[derive(Copy, Clone)]
83pub enum DBImpl {
84 #[cfg(feature = "sqlite")]
86 SQLite,
87 #[cfg(feature = "postgres")]
89 Postgres,
90 #[cfg(feature = "mysql")]
92 MySQL,
93}
94
95impl DBImpl {
96 pub fn create_table<'until_build, 'post_build>(
103 &self,
104 name: &'until_build str,
105 ) -> impl CreateTable<'until_build, 'post_build>
106 where
107 'post_build: 'until_build,
108 {
109 let d = CreateTableData {
110 name,
111 columns: vec![],
112 if_not_exists: false,
113 lookup: vec![],
114 pre_statements: vec![],
115 statements: vec![],
116 };
117
118 match self {
119 #[cfg(feature = "sqlite")]
120 DBImpl::SQLite => CreateTableImpl::SQLite(d),
121 #[cfg(feature = "mysql")]
122 DBImpl::MySQL => CreateTableImpl::MySQL(d),
123 #[cfg(feature = "postgres")]
124 DBImpl::Postgres => CreateTableImpl::Postgres(d),
125 }
126 }
127
128 pub fn create_trigger(
138 &self,
139 name: &str,
140 table_name: &str,
141 point_in_time: Option<SQLCreateTriggerPointInTime>,
142 operation: SQLCreateTriggerOperation,
143 ) -> SQLCreateTrigger {
144 SQLCreateTrigger {
145 name: name.to_string(),
146 table_name: table_name.to_string(),
147 if_not_exists: false,
148 point_in_time,
149 operation,
150 statements: vec![],
151 for_each_row: false,
152 }
153 }
154
155 pub fn create_index<'until_build>(
163 &self,
164 name: &'until_build str,
165 table_name: &'until_build str,
166 ) -> impl CreateIndex<'until_build> {
167 let d = CreateIndexData {
168 name,
169 table_name,
170 unique: false,
171 if_not_exists: false,
172 columns: vec![],
173 condition: None,
174 };
175
176 match self {
177 #[cfg(feature = "sqlite")]
178 DBImpl::SQLite => CreateIndexImpl::Sqlite(d),
179 #[cfg(feature = "mysql")]
180 DBImpl::MySQL => CreateIndexImpl::MySQL(d),
181 #[cfg(feature = "postgres")]
182 DBImpl::Postgres => CreateIndexImpl::Postgres(d),
183 }
184 }
185
186 pub fn drop_table<'until_build>(
193 &self,
194 name: &'until_build str,
195 ) -> impl DropTable + 'until_build {
196 let d = DropTableData {
197 name,
198 if_exists: false,
199 };
200 match self {
201 #[cfg(feature = "sqlite")]
202 DBImpl::SQLite => DropTableImpl::SQLite(d),
203 #[cfg(feature = "mysql")]
204 DBImpl::MySQL => DropTableImpl::MySQL(d),
205 #[cfg(feature = "postgres")]
206 DBImpl::Postgres => DropTableImpl::Postgres(d),
207 }
208 }
209
210 pub fn alter_table<'until_build, 'post_build>(
218 &self,
219 name: &'until_build str,
220 operation: AlterTableOperation<'until_build, 'post_build>,
221 ) -> impl AlterTable<'post_build> + 'until_build
222 where
223 'post_build: 'until_build,
224 {
225 let d = AlterTableData {
226 name,
227 operation,
228 lookup: vec![],
229 statements: vec![],
230 };
231
232 match self {
233 #[cfg(feature = "sqlite")]
234 DBImpl::SQLite => AlterTableImpl::SQLite(d),
235 #[cfg(feature = "mysql")]
236 DBImpl::MySQL => AlterTableImpl::MySQL(d),
237 #[cfg(feature = "postgres")]
238 DBImpl::Postgres => AlterTableImpl::Postgres(d),
239 }
240 }
241
242 pub fn create_column<'until_build, 'post_build>(
252 &self,
253 table_name: &'until_build str,
254 name: &'until_build str,
255 data_type: DbType,
256 annotations: &'post_build [Annotation],
257 ) -> CreateColumnImpl<'until_build, 'post_build> {
258 #[cfg(not(any(feature = "postgres", feature = "sqlite")))]
259 let _ = table_name;
260
261 let mut a = vec![];
263
264 for x in annotations {
265 if x.eq_shallow(&Annotation::PrimaryKey) {
266 a.push(SQLAnnotation { annotation: x });
267 }
268 }
269
270 for x in annotations {
271 if !x.eq_shallow(&Annotation::PrimaryKey) {
272 a.push(SQLAnnotation { annotation: x });
273 }
274 }
275
276 match self {
277 #[cfg(feature = "sqlite")]
278 DBImpl::SQLite => CreateColumnImpl::SQLite(CreateColumnSQLiteData {
279 name,
280 table_name,
281 data_type,
282 annotations: a,
283 statements: None,
284 lookup: None,
285 }),
286 #[cfg(feature = "mysql")]
287 DBImpl::MySQL => CreateColumnImpl::MySQL(CreateColumnMySQLData {
288 name,
289 data_type,
290 annotations: a,
291 statements: None,
292 lookup: None,
293 }),
294 #[cfg(feature = "postgres")]
295 DBImpl::Postgres => CreateColumnImpl::Postgres(CreateColumnPostgresData {
296 name,
297 table_name,
298 data_type,
299 annotations: a,
300 pre_statements: None,
301 statements: None,
302 }),
303 }
304 }
305
306 pub fn select<'until_build, 'post_build>(
315 &self,
316 columns: &'until_build [SelectColumnImpl],
317 from_clause: &'until_build str,
318 joins: &'until_build [JoinTableImpl<'until_build, 'post_build>],
319 order_by_clause: &'until_build [OrderByEntry<'until_build>],
320 ) -> impl Select<'until_build, 'post_build> {
321 let d = SelectData {
322 join_tables: joins,
323 resulting_columns: columns,
324 limit: None,
325 offset: None,
326 from_clause,
327 where_clause: None,
328 distinct: false,
329 lookup: vec![],
330 order_by_clause,
331 };
332 match self {
333 #[cfg(feature = "sqlite")]
334 DBImpl::SQLite => SelectImpl::SQLite(d),
335 #[cfg(feature = "mysql")]
336 DBImpl::MySQL => SelectImpl::MySQL(d),
337 #[cfg(feature = "postgres")]
338 DBImpl::Postgres => SelectImpl::Postgres(d),
339 }
340 }
341
342 pub fn insert<'until_build, 'post_build>(
352 &self,
353 into_clause: &'until_build str,
354 insert_columns: &'until_build [&'until_build str],
355 insert_values: &'until_build [&'until_build [Value<'post_build>]],
356 returning_clause: Option<&'until_build [&'until_build str]>,
357 ) -> impl Insert<'post_build> + 'until_build
358 where
359 'post_build: 'until_build,
360 {
361 let d = InsertData {
362 into_clause,
363 columns: insert_columns,
364 row_values: insert_values,
365 lookup: vec![],
366 on_conflict: OnConflict::ABORT,
367 returning_clause,
368 };
369 match self {
370 #[cfg(feature = "sqlite")]
371 DBImpl::SQLite => InsertImpl::SQLite(d),
372 #[cfg(feature = "mysql")]
373 DBImpl::MySQL => InsertImpl::MySQL(d),
374 #[cfg(feature = "postgres")]
375 DBImpl::Postgres => InsertImpl::Postgres(d),
376 }
377 }
378
379 pub fn delete<'until_build, 'post_query>(
386 &self,
387 table_name: &'until_build str,
388 ) -> impl Delete<'until_build, 'post_query>
389 where
390 'post_query: 'until_build,
391 {
392 let d = DeleteData {
393 model: table_name,
394 lookup: vec![],
395 where_clause: None,
396 };
397 match self {
398 #[cfg(feature = "sqlite")]
399 DBImpl::SQLite => DeleteImpl::SQLite(d),
400 #[cfg(feature = "mysql")]
401 DBImpl::MySQL => DeleteImpl::MySQL(d),
402 #[cfg(feature = "postgres")]
403 DBImpl::Postgres => DeleteImpl::Postgres(d),
404 }
405 }
406
407 pub fn update<'until_build, 'post_query>(
414 &self,
415
416 table_name: &'until_build str,
417 ) -> impl Update<'until_build, 'post_query>
418 where
419 'post_query: 'until_build,
420 {
421 let d = UpdateData {
422 model: table_name,
423 on_conflict: OnConflict::ABORT,
424 updates: vec![],
425 where_clause: None,
426 lookup: vec![],
427 };
428 match self {
429 #[cfg(feature = "sqlite")]
430 DBImpl::SQLite => UpdateImpl::SQLite(d),
431 #[cfg(feature = "mysql")]
432 DBImpl::MySQL => UpdateImpl::MySQL(d),
433 #[cfg(feature = "postgres")]
434 DBImpl::Postgres => UpdateImpl::Postgres(d),
435 }
436 }
437
438 pub fn join_table<'until_build, 'post_query>(
448 &self,
449 join_type: JoinType,
450 table_name: &'until_build str,
451 join_alias: &'until_build str,
452 join_condition: Cow<'until_build, Condition<'post_query>>,
453 ) -> JoinTableImpl<'until_build, 'post_query> {
454 let d = JoinTableData {
455 join_type,
456 table_name,
457 join_alias,
458 join_condition,
459 };
460
461 match self {
462 #[cfg(feature = "sqlite")]
463 DBImpl::SQLite => JoinTableImpl::SQLite(d),
464 #[cfg(feature = "mysql")]
465 DBImpl::MySQL => JoinTableImpl::MySQL(d),
466 #[cfg(feature = "postgres")]
467 DBImpl::Postgres => JoinTableImpl::Postgres(d),
468 }
469 }
470
471 pub fn select_column<'until_build>(
481 &self,
482 table_name: Option<&'until_build str>,
483 column_name: &'until_build str,
484 select_alias: Option<&'until_build str>,
485 aggregation: Option<SelectAggregator>,
486 ) -> SelectColumnImpl<'until_build> {
487 let d = SelectColumnData {
488 table_name,
489 column_name,
490 select_alias,
491 aggregation,
492 };
493
494 match self {
495 #[cfg(feature = "sqlite")]
496 DBImpl::SQLite => SelectColumnImpl::SQLite(d),
497 #[cfg(feature = "mysql")]
498 DBImpl::MySQL => SelectColumnImpl::MySQL(d),
499 #[cfg(feature = "postgres")]
500 DBImpl::Postgres => SelectColumnImpl::Postgres(d),
501 }
502 }
503}