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