1mod builder;
2
3use anyhow::Result;
4use sqlx::{Arguments, Pool, Sqlite};
5
6use crate::{Executor, query::{Pagination, QueryBuilder, Statement, Total, WhereQuery}, sqlite::builder::Builder};
7
8#[derive(Debug)]
9pub struct SQLite {
10 db: Pool<Sqlite>,
11}
12
13impl Executor for SQLite {
14 type T = sqlx::Sqlite;
15
16 async fn new(url: &str) -> Self where Self: Sized {
17 return Self {
18 db: sqlx::SqlitePool::connect(url).await.unwrap(),
19 }
20 }
21
22 fn db<'q>(&'q self) -> &'q Pool<Self::T> {
23 return &self.db;
24 }
25
26 fn to_sql<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<String> {
27 return Ok(Builder::new(&statement.query).query().unwrap());
28 }
29
30 async fn execute<'q>(&self, sql: &'q str) -> Result<()> {
31 todo!();
32 }
33
34 async fn insert<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()> {
35 sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).insert().unwrap(), statement.arguments.clone())
36 .execute(&self.db)
37 .await
38 .unwrap();
39 return Ok(());
40 }
41
42 async fn insert_as<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<O>
43 where
44 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
45 {
46 let query_result = sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).insert().unwrap(), statement.arguments.clone())
47 .execute(&self.db)
48 .await
49 .unwrap();
50
51 let mut statement = Statement::<Self::T>::new(&statement.query.table);
52
53 statement.query.where_queries.push(WhereQuery {
54 column: Some("rowid".to_string()),
55 operator: Some("=".to_string()),
56 position: None,
57 group: None
58 });
59
60 statement.arguments.add(query_result.last_insert_rowid()).unwrap();
61
62 return Ok(self.first(&statement).await.unwrap());
63 }
64
65 async fn update<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()> {
66 sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).update().unwrap(), statement.arguments.clone())
67 .execute(&self.db)
68 .await
69 .unwrap();
70 return Ok(());
71 }
72
73 async fn count<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<u64> {
74 return Ok(0);
75 }
76
77 async fn delete<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()> {
78 sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).delete().unwrap(), statement.arguments.clone())
79 .execute(&self.db)
80 .await
81 .unwrap();
82 return Ok(());
83 }
84
85 async fn query_all<'q, O, T: 'q + sqlx::Encode<'q, Self::T> + sqlx::Type<Self::T>>(&self, sql: &str, args: Vec<T>) -> Result<Vec<O>>
86 where
87 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
88 {
89 let mut arguments: <Self::T as sqlx::Database>::Arguments<'q> = Default::default();
90
91 for arg in args {
92 arguments.add(arg).unwrap();
93 }
94
95 return Ok(
96 sqlx::query_as_with::<Self::T, O, _>(sql, arguments)
97 .fetch_all(&self.db)
98 .await
99 .unwrap()
100 )
101 }
102
103 async fn query_one<'q, O, T: 'q + sqlx::Encode<'q, Self::T> + sqlx::Type<Self::T>>(&self, sql: &str, args: Vec<T>) -> Result<O>
104 where
105 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
106 {
107 let mut arguments: <Self::T as sqlx::Database>::Arguments<'q> = Default::default();
108
109 for arg in args {
110 arguments.add(arg).unwrap();
111 }
112
113 return Ok(
114 sqlx::query_as_with::<Self::T, O, _>(sql, arguments)
115 .fetch_one(&self.db)
116 .await
117 .unwrap()
118 )
119 }
120
121 async fn first<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<O>
122 where
123 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
124 {
125 return Ok(
126 sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
127 .fetch_one(&self.db)
128 .await
129 .unwrap()
130 );
131 }
132
133 async fn all<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<Vec<O>>
134 where
135 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
136 {
137 return Ok(
138 sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
139 .fetch_all(&self.db)
140 .await
141 .unwrap(),
142 );
143 }
144
145 async fn paginate<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<Pagination<O>>
147 where
148 O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
149 {
150 let mut query = statement.query.clone();
151
152 query.select = vec!["COUNT(*) as total".to_string()];
153 query.limit = None;
154 query.page = None;
155
156 return Ok(
157 Pagination {
158 page: statement.query.page.unwrap(),
159 per_page: statement.query.limit.unwrap(),
160 total: sqlx::query_as_with::<Self::T, Total, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
161 .fetch_one(&self.db)
162 .await
163 .unwrap()
164 .total,
165 items: sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
166 .fetch_all(&self.db)
167 .await
168 .unwrap(),
169 }
170 );
171 }
172}
173
174