1pub mod sqlite;
2pub mod postgres;
3pub mod mysql;
4pub mod query;
5
6use std::{collections::HashMap, marker::PhantomData, str, sync::LazyLock};
7
8use anyhow::{Ok, Result};
9use sqlx::{Arguments, Encode, FromRow, Pool, types::Type};
10
11use crate::query::{JoinQuery, JoinType, Order, OrderQuery, Pagination, Statement, Transaction, WhereQuery, WhereQueryGroup};
12
13pub(crate) static mut CONNECTIONS: LazyLock<HashMap<&str, String>> = LazyLock::new(|| HashMap::new());
14
15#[allow(async_fn_in_trait)]
16pub trait Executor {
17 type T: sqlx::Database;
18
19 async fn new(url: &str) -> Self where Self: Sized;
20
21 fn db<'q>(&'q self) -> &'q Pool<Self::T>;
22
23 fn to_sql<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<String>;
24
25 async fn execute<'q>(&self, sql: &'q str) -> Result<()>;
26
27 async fn insert<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()>;
28
29 async fn update<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()>;
30
31 async fn count<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<u64>;
32
33 async fn delete<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()>;
34
35 async fn insert_as<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<O>
36 where
37 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
38
39 async fn query_all<'q, O, T: 'q + Encode<'q, Self::T> + Type<Self::T>>(&self, sql: &str, args: Vec<T>) -> Result<Vec<O>>
40 where
41 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
42
43 async fn query_one<'q, O, T: 'q + Encode<'q, Self::T> + Type<Self::T>>(&self, sql: &str, args: Vec<T>) -> Result<O>
44 where
45 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
46
47 async fn all<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<Vec<O>>
48 where
49 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
50
51 async fn first<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<O>
52 where
53 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
54
55 async fn paginate<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<Pagination<O>>
56 where
57 O: for<'r> FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized;
58}
59
60pub struct DB;
61
62impl DB {
63 #[allow(static_mut_refs)]
64 pub fn add(connection: &'static str, url: &str) {
65 unsafe { CONNECTIONS.insert(connection, url.to_string()); }
66 }
67
68 #[allow(static_mut_refs)]
69 pub fn remove(connection: &str) {
70 unsafe { CONNECTIONS.remove(connection); }
71 }
72
73 #[allow(static_mut_refs)]
74 pub async fn db<E: Executor>(connection: &str) -> Database::<E> {
75 return unsafe { Database::new(CONNECTIONS.get(connection).unwrap()).await };
76 }
77
78 pub async fn db_with_url<E: Executor>(url: &str) -> Database::<E> {
79 return Database::new(url).await;
80 }
81}
82
83#[derive(Debug)]
84pub struct Database<E: Executor> {
85 executor: E,
86}
87
88impl <E: Executor>Database<E> {
89 pub async fn new(url: &str) -> Self {
90 return Self {
91 executor: E::new(url).await,
92 }
93 }
94
95 pub async fn transaction<'q>(&self) -> Result<Transaction<'q, E::T>> {
96 return Ok(Transaction::new(self.executor.db().begin().await.unwrap()));
97 }
98
99 pub async fn execute(&self, sql: &str) -> Result<()> {
100 todo!();
101 }
102
103 pub fn query<'q>(&'q self, table: &str) -> Query<'q, E> {
104 return Query::new(table, &self.executor);
105 }
106
107 pub async fn close(&self) -> Result<()> {
108 return Ok(self.executor.db().close().await);
109 }
110}
111
112pub struct Query<'q, E: Executor> {
113 db: &'q E,
114 statement: Statement<'q, E::T>,
115 _marker: PhantomData<E>
116}
117
118impl <'q, E>Query<'q, E>
119where
120 E: Executor
121{
122 pub fn new(table: &str, exc: &'q E) -> Self {
123 return Self {
124 db: exc,
125 statement: Statement::<'q, E::T>::new(table),
126 _marker: PhantomData,
127 }
128 }
129
130 pub fn table(&mut self, name: &'q str) -> &mut Self {
131 self.statement.query.table = name.to_string();
132
133 return self;
134 }
135
136 pub fn select(&mut self, columns: Vec<&str>) -> &mut Self {
137 self.statement.query.select = columns.iter().map(|c| c.to_string()).collect();
138
139 return self;
140 }
141
142 pub fn r#where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
143 if self.statement.query.where_queries.len() != 0 {
144 return self.and_where(column, operator, val);
145 }
146
147 self.statement.query.where_queries.push(WhereQuery {
149 column: Some(column.to_string()),
150 operator: Some(operator.to_string()),
151 position: None,
152 group: None
153 });
154
155 self.statement.arguments.add(val).unwrap();
156
157 return self;
158 }
159
160 pub fn and_where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
161 if self.statement.query.where_queries.len() == 0 {
162 return self.r#where(column, operator, val);
163 }
164
165 self.statement.query.where_queries.push(WhereQuery {
166 column: Some(column.to_string()),
167 operator: Some(operator.to_string()),
168 position: Some(query::QueryPosition::AND),
169 group: None
170 });
171
172 self.statement.arguments.add(val).unwrap();
173
174 return self;
175 }
176
177 pub fn or_where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
178 if self.statement.query.where_queries.len() == 0 {
179 return self.r#where(column, operator, val);
180 }
181
182 self.statement.query.where_queries.push(WhereQuery {
183 column: Some(column.to_string()),
184 operator: Some(operator.to_string()),
185 position: Some(query::QueryPosition::OR),
186 group: None
187 });
188
189 self.statement.arguments.add(val).unwrap();
190
191 return self;
192 }
193
194 pub fn where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
195 return self;
196 }
197
198 pub fn and_where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
199 return self;
200 }
201
202 pub fn or_where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
203 return self;
204 }
205
206 pub fn order_by(&mut self, column: &str, order: Order) -> &mut Self {
207 self.statement.query.order_by.push(OrderQuery {
208 column: column.to_string(),
209 order: order
210 });
211
212 return self;
213 }
214
215 pub fn join(&mut self, table: &str, column: &str, column_table: &str) -> &mut Self {
216 self.statement.query.join.push(JoinQuery {
217 table: table.to_string(),
218 column: column.to_string(),
219 operator: "=".to_string(),
220 column_table: column_table.to_string(),
221 join_type: JoinType::LeftJoin
222 });
223
224 return self;
225 }
226
227 pub fn limit(&mut self, limit: u64) -> &mut Self {
228 self.statement.query.limit = Some(limit);
229
230 return self;
231 }
232
233 pub fn bind<T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, value: T) -> &'q mut Self {
234 self.statement.arguments.add(value).unwrap();
235
236 return self;
237 }
238
239 pub async fn query<O, T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, sql: &str, args: Vec<T>) -> Result<Vec<O>>
240 where
241 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
242 {
243 return Ok(self.db.query_all::<O, T>(sql, args).await.unwrap());
244 }
245
246 pub async fn query_all<O, T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, sql: &str, args: Vec<T>) -> Result<Vec<O>>
248 where
249 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
250 {
251 return Ok(self.db.query_all::<O, T>(sql, args).await.unwrap());
252 }
253
254 pub async fn query_one<O, T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, sql: &str, args: Vec<T>) -> Result<O>
256 where
257 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
258 {
259 return Ok(self.db.query_one::<O, T>(sql, args).await.unwrap())
260 }
261
262 pub fn insert_as<O>(&'q mut self, columns: Vec<&str>) -> InsertAs<'q, E, O>
263 where
264 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
265 {
266 self.statement.query.columns = Some(columns.iter().map(|c| c.to_string()).collect());
267
268 return InsertAs::new(self.db, &mut self.statement);
269 }
270
271 pub fn insert(&'q mut self, columns: Vec<&str>) -> Insert<'q, E> {
272 self.statement.query.columns = Some(columns.iter().map(|c| c.to_string()).collect());
273
274 return Insert::new(&self.db, &mut self.statement);
275 }
276
277 pub fn update(&'q mut self, columns: Vec<&str>) -> Update<'q, E> {
278 self.statement.query.columns = Some(columns.iter().map(|c| c.to_string()).collect());
279
280 return Update::new(&self.db, &mut self.statement);
281 }
282
283 pub async fn delete(&'q mut self) -> Result<()>
284 {
285 return Ok(self.db.delete(&self.statement).await.unwrap())
286 }
287
288 pub async fn first<O>(&'q mut self) -> Result<O>
289 where
290 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
291 {
292 return Ok(self.db.first::<O>(&self.statement).await.unwrap())
293 }
294
295 pub async fn all<O>(&'q mut self) -> Result<Vec<O>>
296 where
297 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
298 {
299 return Ok(self.db.all::<O>(&self.statement).await.unwrap())
300 }
301
302 pub async fn paginate<O>(&'q mut self, limit: u64, page: u64) -> Result<Pagination<O>>
303 where
304 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
305 {
306 self.statement.query.limit = Some(limit);
307 self.statement.query.page = Some(page); return Ok(self.db.paginate::<O>(&self.statement).await.unwrap());
310 }
311
312 pub fn to_sql(&'q mut self) -> Result<String> {
313 return Ok(self.db.to_sql(&self.statement).unwrap())
314 }
315}
316
317pub struct InsertAs<'q, E: Executor, O> {
318 db: &'q E,
319 statement: &'q mut Statement<'q, E::T>,
320 _marker: PhantomData<E>,
321 _type: PhantomData<O>
322}
323
324impl <'q, E, O>InsertAs<'q, E, O>
325where
326 E: Executor,
327 O: for<'r> FromRow<'r, <E::T as sqlx::Database>::Row> + Send + Unpin + Sized
328{
329 pub(crate) fn new(db: &'q E, statement: &'q mut Statement<'q, E::T>) -> Self {
330 return Self {
331 db: db,
332 statement: statement,
333 _marker: PhantomData,
334 _type: PhantomData
335 }
336 }
337
338 pub fn bind<T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, value: T) -> &'q mut Self {
339 self.statement.arguments.add(value).unwrap();
340
341 return self;
342 }
343
344 pub async fn execute(&'q mut self) -> Result<O> {
345 return Ok(self.db.insert_as::<O>(self.statement).await.unwrap());
346 }
347}
348
349pub struct Insert<'q, E: Executor> {
350 db: &'q E,
351 statement: &'q mut Statement<'q, E::T>,
352 _marker: PhantomData<E>
353}
354
355impl <'q, E>Insert<'q, E>
356where
357 E: Executor
358{
359 pub(crate) fn new(db: &'q E, statement: &'q mut Statement<'q, E::T>) -> Self {
360 return Self {
361 db: db,
362 statement: statement,
363 _marker: PhantomData,
364 }
365 }
366
367 pub fn bind<T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, value: T) -> &'q mut Self {
368 self.statement.arguments.add(value).unwrap();
369
370 return self;
371 }
372
373 pub async fn execute(&'q mut self) -> Result<()> {
374 return self.db.insert(self.statement).await;
375 }
376}
377
378pub struct Update<'q, E: Executor> {
379 db: &'q E,
380 statement: &'q mut Statement<'q, E::T>,
381 _marker: PhantomData<E>
382}
383
384impl <'q, E>Update<'q, E>
385where
386 E: Executor
387{
388 pub(crate) fn new(db: &'q E, statement: &'q mut Statement<'q, E::T>) -> Self {
389 return Self {
390 db: db,
391 statement: statement,
392 _marker: PhantomData,
393 }
394 }
395
396 pub fn bind<T: 'q + Encode<'q, E::T> + Type<E::T>>(&'q mut self, value: T) -> &'q mut Self {
397 self.statement.arguments.add(value).unwrap();
398
399 return self;
400 }
401
402
403 pub fn r#where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
404 if self.statement.query.where_queries.len() != 0 {
405 return self.and_where(column, operator, val);
406 }
407
408 self.statement.query.where_queries.push(WhereQuery {
410 column: Some(column.to_string()),
411 operator: Some(operator.to_string()),
412 position: None,
413 group: None
414 });
415
416 self.statement.arguments.add(val).unwrap();
417
418 return self;
419 }
420
421 pub fn and_where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
422 if self.statement.query.where_queries.len() == 0 {
423 return self.r#where(column, operator, val);
424 }
425
426 self.statement.query.where_queries.push(WhereQuery {
427 column: Some(column.to_string()),
428 operator: Some(operator.to_string()),
429 position: Some(query::QueryPosition::AND),
430 group: None
431 });
432
433 self.statement.arguments.add(val).unwrap();
434
435 return self;
436 }
437
438 pub fn or_where<T: 'q + Encode<'q, E::T> + Type<E::T>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
439 if self.statement.query.where_queries.len() == 0 {
440 return self.r#where(column, operator, val);
441 }
442
443 self.statement.query.where_queries.push(WhereQuery {
444 column: Some(column.to_string()),
445 operator: Some(operator.to_string()),
446 position: Some(query::QueryPosition::OR),
447 group: None
448 });
449
450 self.statement.arguments.add(val).unwrap();
451
452 return self;
453 }
454
455 pub fn where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
456 return self;
457 }
458
459 pub fn and_where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
460 return self;
461 }
462
463 pub fn or_where_group(&mut self, callback: fn(group: WhereQueryGroup<'q, E::T>) -> WhereQueryGroup<'q, E::T>) -> &mut Self {
464 return self;
465 }
466
467 pub async fn execute(&'q mut self) -> Result<()> {
468 return self.db.update(self.statement).await;
469 }
470}