Skip to main content

flyer_orm/databases/sqlite/
mod.rs

1mod builder;
2
3use anyhow::Result;
4use sqlx::{Arguments, Pool, Sqlite};
5
6use crate::{Executor, databases::sqlite::builder::Builder, query::{Pagination, QueryBuilder, Statement, Total, logic::Where}};
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(Where {
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
67        println!("{:?}", &Builder::new(&statement.query).update().unwrap());
68
69
70        println!("RESULT COUNT {:?}\r\n\r\n", statement.arguments.len());
71
72        let a= sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).update().unwrap(), statement.arguments.clone())
73            .execute(&self.db)
74            .await
75            .unwrap();
76
77
78        println!("RESULT {:?}\r\n\r\n", a);
79
80
81        return Ok(());
82    }
83    
84    async fn count<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<u64> {
85        let query = {
86            let mut query = statement.query.clone();
87            query.select = vec!["COUNT(*) as total".to_string()];
88            query
89        };
90
91        return Ok(
92            sqlx::query_as_with::<Self::T, Total, _>(&Builder::new(&query).query().unwrap(), statement.arguments.clone())
93                .fetch_one(&self.db)
94                .await
95                .unwrap()
96                .total
97        );
98    }
99    
100    async fn delete<'q>(&self, statement: &'q Statement<'q, Self::T>) -> Result<()> {
101        sqlx::query_with::<Self::T, _>(&Builder::new(&statement.query).delete().unwrap(), statement.arguments.clone())
102            .execute(&self.db)
103            .await
104            .unwrap();
105        return Ok(());
106    }
107    
108    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>>
109    where
110        O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
111    {
112        let mut arguments: <Self::T as sqlx::Database>::Arguments<'q> = Default::default();
113
114        for arg in args { arguments.add(arg).unwrap(); }
115
116        return Ok(
117            sqlx::query_as_with::<Self::T, O, _>(sql, arguments)
118                .fetch_all(&self.db)
119                .await
120                .unwrap()
121        )
122    }
123    
124    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>
125    where
126        O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
127    {
128        let mut arguments: <Self::T as sqlx::Database>::Arguments<'q> = Default::default();
129
130        for arg in args {
131            arguments.add(arg).unwrap();
132        }
133
134        return Ok(
135            sqlx::query_as_with::<Self::T, O, _>(sql, arguments)
136                .fetch_one(&self.db)
137                .await
138                .unwrap()
139        )
140    }
141    
142    async fn first<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<O>
143    where
144        O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
145    {
146        return Ok(
147            sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
148                .fetch_one(&self.db)
149                .await
150                .unwrap()
151        );
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 Ok(
159            sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
160                .fetch_all(&self.db)
161                .await
162                .unwrap(),
163        );
164    }
165    
166    // TODO: refactor...
167    async fn paginate<'q, O>(&self, statement: &'q Statement<'q, Self::T>) -> Result<Pagination<O>>
168    where
169        O: for<'r> sqlx::FromRow<'r, <Self::T as sqlx::Database>::Row> + Send + Unpin + Sized
170    {
171        let mut query = statement.query.clone();
172
173        query.select = vec!["COUNT(*) as total".to_string()];
174        query.limit = None;
175        query.page = None;
176
177        return Ok(
178            Pagination {
179                page: statement.query.page.unwrap(),
180                per_page: statement.query.limit.unwrap(),
181                total:
182                    sqlx::query_as_with::<Self::T, Total, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
183                        .fetch_one(&self.db)
184                        .await
185                        .unwrap()
186                        .total,
187                items:
188                    sqlx::query_as_with::<Self::T, O, _>(&self.to_sql(statement).unwrap(), statement.arguments.clone())
189                        .fetch_all(&self.db)
190                        .await
191                        .unwrap(),
192            }
193        );
194    }
195}
196
197