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