1#![cfg_attr(docsrs, feature(doc_cfg))]
3#![warn(missing_docs)]
4
5#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
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 = "postgres")]
57use crate::create_column::CreateColumnPostgresData;
58#[cfg(feature = "sqlite")]
59use crate::create_column::CreateColumnSQLiteData;
60use crate::create_column::{CreateColumnImpl, SQLAnnotation};
61use crate::create_index::{CreateIndex, CreateIndexData, CreateIndexImpl};
62use crate::create_table::{CreateTable, CreateTableData, CreateTableImpl};
63use crate::create_trigger::{
64 SQLCreateTrigger, SQLCreateTriggerOperation, SQLCreateTriggerPointInTime,
65};
66use crate::delete::{Delete, DeleteData, DeleteImpl};
67use crate::drop_table::{DropTable, DropTableData, DropTableImpl};
68use crate::insert::{Insert, InsertData, InsertImpl};
69use crate::join_table::{JoinTableData, JoinTableImpl, JoinType};
70use crate::on_conflict::OnConflict;
71use crate::ordering::OrderByEntry;
72use crate::select::Select;
73use crate::select_column::{SelectColumnData, SelectColumnImpl};
74use crate::update::{Update, UpdateData, UpdateImpl};
75use crate::value::Value;
76
77#[derive(Copy, Clone, Debug)]
81pub enum DBImpl {
82 #[cfg(feature = "sqlite")]
84 SQLite,
85 #[cfg(feature = "postgres")]
87 Postgres,
88}
89
90impl DBImpl {
91 pub fn create_table<'until_build, 'post_build>(
98 &self,
99 name: &'until_build str,
100 ) -> impl CreateTable<'until_build, 'post_build>
101 where
102 'post_build: 'until_build,
103 {
104 let d = CreateTableData {
105 name,
106 columns: vec![],
107 if_not_exists: false,
108 lookup: vec![],
109 pre_statements: vec![],
110 statements: vec![],
111 };
112
113 match self {
114 #[cfg(feature = "sqlite")]
115 DBImpl::SQLite => CreateTableImpl::SQLite(d),
116 #[cfg(feature = "postgres")]
117 DBImpl::Postgres => CreateTableImpl::Postgres(d),
118 }
119 }
120
121 pub fn create_trigger(
131 &self,
132 name: &str,
133 table_name: &str,
134 point_in_time: Option<SQLCreateTriggerPointInTime>,
135 operation: SQLCreateTriggerOperation,
136 ) -> SQLCreateTrigger {
137 SQLCreateTrigger {
138 name: name.to_string(),
139 table_name: table_name.to_string(),
140 if_not_exists: false,
141 point_in_time,
142 operation,
143 statements: vec![],
144 for_each_row: false,
145 }
146 }
147
148 pub fn create_index<'until_build>(
156 &self,
157 name: &'until_build str,
158 table_name: &'until_build str,
159 ) -> impl CreateIndex<'until_build> {
160 let d = CreateIndexData {
161 name,
162 table_name,
163 unique: false,
164 if_not_exists: false,
165 columns: vec![],
166 condition: None,
167 };
168
169 match self {
170 #[cfg(feature = "sqlite")]
171 DBImpl::SQLite => CreateIndexImpl::Sqlite(d),
172 #[cfg(feature = "postgres")]
173 DBImpl::Postgres => CreateIndexImpl::Postgres(d),
174 }
175 }
176
177 pub fn drop_table<'until_build>(
184 &self,
185 name: &'until_build str,
186 ) -> impl DropTable + 'until_build {
187 let d = DropTableData {
188 name,
189 if_exists: false,
190 };
191 match self {
192 #[cfg(feature = "sqlite")]
193 DBImpl::SQLite => DropTableImpl::SQLite(d),
194 #[cfg(feature = "postgres")]
195 DBImpl::Postgres => DropTableImpl::Postgres(d),
196 }
197 }
198
199 pub fn alter_table<'until_build, 'post_build>(
207 &self,
208 name: &'until_build str,
209 operation: AlterTableOperation<'until_build, 'post_build>,
210 ) -> impl AlterTable<'post_build> + 'until_build
211 where
212 'post_build: 'until_build,
213 {
214 let d = AlterTableData {
215 name,
216 operation,
217 lookup: vec![],
218 statements: vec![],
219 };
220
221 match self {
222 #[cfg(feature = "sqlite")]
223 DBImpl::SQLite => AlterTableImpl::SQLite(d),
224 #[cfg(feature = "postgres")]
225 DBImpl::Postgres => AlterTableImpl::Postgres(d),
226 }
227 }
228
229 pub fn create_column<'until_build, 'post_build>(
239 &self,
240 table_name: &'until_build str,
241 name: &'until_build str,
242 data_type: DbType,
243 annotations: &'post_build [Annotation],
244 ) -> CreateColumnImpl<'until_build, 'post_build> {
245 #[cfg(not(any(feature = "postgres", feature = "sqlite")))]
246 let _ = table_name;
247
248 let mut a = vec![];
250
251 for x in annotations {
252 if matches!(x, Annotation::PrimaryKey) {
253 a.push(SQLAnnotation { annotation: x });
254 }
255 }
256
257 for x in annotations {
258 if !matches!(x, Annotation::PrimaryKey) {
259 a.push(SQLAnnotation { annotation: x });
260 }
261 }
262
263 match self {
264 #[cfg(feature = "sqlite")]
265 DBImpl::SQLite => CreateColumnImpl::SQLite(CreateColumnSQLiteData {
266 name,
267 table_name,
268 data_type,
269 annotations: a,
270 statements: None,
271 lookup: None,
272 }),
273 #[cfg(feature = "postgres")]
274 DBImpl::Postgres => CreateColumnImpl::Postgres(CreateColumnPostgresData {
275 name,
276 table_name,
277 data_type,
278 annotations: a,
279 pre_statements: None,
280 statements: None,
281 }),
282 }
283 }
284
285 pub fn select<'until_build, 'post_build>(
294 &self,
295 columns: &'until_build [SelectColumnImpl],
296 from_clause: &'until_build str,
297 joins: &'until_build [JoinTableImpl<'until_build, 'post_build>],
298 order_by_clause: &'until_build [OrderByEntry<'until_build>],
299 ) -> Select<'until_build, 'post_build> {
300 Select {
301 db_impl: *self,
302 resulting_columns: columns,
303 from_clause,
304 join_tables: joins,
305 order_by_clause,
306
307 limit: None,
308 offset: None,
309 where_clause: None,
310 distinct: false,
311 #[cfg(feature = "postgres-only")]
312 locking_clause: None,
313 }
314 }
315
316 pub fn insert<'until_build, 'post_build>(
326 &self,
327 into_clause: &'until_build str,
328 insert_columns: &'until_build [&'until_build str],
329 insert_values: &'until_build [&'until_build [Value<'post_build>]],
330 returning_clause: Option<&'until_build [&'until_build str]>,
331 ) -> impl Insert<'post_build> + 'until_build
332 where
333 'post_build: 'until_build,
334 {
335 let d = InsertData {
336 into_clause,
337 columns: insert_columns,
338 row_values: insert_values,
339 lookup: vec![],
340 on_conflict: OnConflict::ABORT,
341 returning_clause,
342 };
343 match self {
344 #[cfg(feature = "sqlite")]
345 DBImpl::SQLite => InsertImpl::SQLite(d),
346 #[cfg(feature = "postgres")]
347 DBImpl::Postgres => InsertImpl::Postgres(d),
348 }
349 }
350
351 pub fn delete<'until_build, 'post_query>(
358 &self,
359 table_name: &'until_build str,
360 ) -> impl Delete<'until_build, 'post_query>
361 where
362 'post_query: 'until_build,
363 {
364 let d = DeleteData {
365 model: table_name,
366 lookup: vec![],
367 where_clause: None,
368 };
369 match self {
370 #[cfg(feature = "sqlite")]
371 DBImpl::SQLite => DeleteImpl::SQLite(d),
372 #[cfg(feature = "postgres")]
373 DBImpl::Postgres => DeleteImpl::Postgres(d),
374 }
375 }
376
377 pub fn update<'until_build, 'post_query>(
384 &self,
385
386 table_name: &'until_build str,
387 ) -> impl Update<'until_build, 'post_query>
388 where
389 'post_query: 'until_build,
390 {
391 let d = UpdateData {
392 model: table_name,
393 on_conflict: OnConflict::ABORT,
394 updates: vec![],
395 where_clause: None,
396 lookup: vec![],
397 };
398 match self {
399 #[cfg(feature = "sqlite")]
400 DBImpl::SQLite => UpdateImpl::SQLite(d),
401 #[cfg(feature = "postgres")]
402 DBImpl::Postgres => UpdateImpl::Postgres(d),
403 }
404 }
405
406 pub fn join_table<'until_build, 'post_query>(
416 &self,
417 join_type: JoinType,
418 table_name: &'until_build str,
419 join_alias: &'until_build str,
420 join_condition: Cow<'until_build, Condition<'post_query>>,
421 ) -> JoinTableImpl<'until_build, 'post_query> {
422 let d = JoinTableData {
423 join_type,
424 table_name,
425 join_alias,
426 join_condition,
427 };
428
429 match self {
430 #[cfg(feature = "sqlite")]
431 DBImpl::SQLite => JoinTableImpl::SQLite(d),
432 #[cfg(feature = "postgres")]
433 DBImpl::Postgres => JoinTableImpl::Postgres(d),
434 }
435 }
436
437 pub fn select_column<'until_build>(
447 &self,
448 table_name: Option<&'until_build str>,
449 column_name: &'until_build str,
450 select_alias: Option<&'until_build str>,
451 aggregation: Option<SelectAggregator>,
452 ) -> SelectColumnImpl<'until_build> {
453 let d = SelectColumnData {
454 table_name,
455 column_name,
456 select_alias,
457 aggregation,
458 };
459
460 match self {
461 #[cfg(feature = "sqlite")]
462 DBImpl::SQLite => SelectColumnImpl::SQLite(d),
463 #[cfg(feature = "postgres")]
464 DBImpl::Postgres => SelectColumnImpl::Postgres(d),
465 }
466 }
467}