Skip to main content

flyer_orm/sqlite/
mod.rs

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    // TODO: refactor...
146    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