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