Skip to main content

flyer_orm/
query.rs

1use std::marker::PhantomData;
2
3use anyhow::Result;
4use serde::Serialize;
5use sqlx::{Encode, Transaction as SqlxTransaction, types::Type};
6
7pub(crate) trait QueryBuilder<'q> {
8    fn new(statement: &'q QueryStatement) -> Self where Self: Sized;
9    fn insert(&self) -> Result<String>;
10    fn update(&self) -> Result<String>;
11    fn delete(&self) -> Result<String>;
12    fn query(&self) -> Result<String>;
13    fn select(&self) -> Result<String>;
14    fn join(&self) -> Result<String>;
15    fn r#where(&self) -> Result<String>;
16    fn group_by(&self) -> Result<String>;
17}
18
19#[derive(Clone, Debug)]
20pub struct WhereQuery {
21    pub column: Option<String>,
22    pub operator: Option<String>,
23    pub position: Option<QueryPosition>,
24    pub group: Option<Box<WhereQuery>>
25}
26
27#[derive(Debug)]
28pub struct WhereQueryGroup<'q, DB: sqlx::Database> {
29    pub queries: Vec<WhereQuery>,
30    _marker: PhantomData<DB>,
31    _life: PhantomData<&'q ()>
32}
33
34impl <'q, DB>WhereQueryGroup<'q, DB>
35where
36    DB: sqlx::Database
37{
38    pub fn new() -> Self {
39        return Self {
40            queries: Vec::new(),
41            _marker: PhantomData,
42            _life: PhantomData
43        }
44    }
45
46    pub fn r#where<T: 'q + Encode<'q, DB> + Type<DB>>(&mut self, column: &str, operator: &str, val: T) -> &mut Self {
47        todo!()
48    }
49}
50
51
52#[derive(Clone, Debug, Default)]
53pub enum QueryPosition {
54    #[default]
55    AND,
56    OR
57}
58
59#[derive(Clone, Debug)]
60pub enum Order {
61    ASC,
62    DESC
63}
64
65#[derive(Clone, Debug)]
66pub struct OrderQuery {
67    pub column: String,
68    pub order: Order
69}
70
71#[derive(Clone, Debug, Default)]
72pub enum JoinType {
73    InnerJoin,
74    #[default]
75    LeftJoin,
76    RightJoin,
77    FullOuterJoin,
78    CrossJoin
79}
80
81#[derive(Clone, Debug, Default)]
82pub struct JoinQuery {
83    pub table: String,
84    pub column: String,
85    pub operator: String,
86    pub column_table: String, 
87    pub join_type: JoinType
88}
89
90#[derive(Clone, Debug)]
91pub struct Statement<'q, DB: sqlx::Database> {
92    pub query: QueryStatement,
93    pub arguments: DB::Arguments<'q>, 
94}
95
96#[derive(Clone, Debug, Default)]
97pub struct HavingQuery {
98    pub column: String,
99    pub operator: String,
100    pub value: String,
101    pub position: Option<QueryPosition>
102}
103
104#[derive(Clone, Debug, Default)]
105pub struct QueryStatement {
106    pub table: String,
107    pub select: Vec<String>,
108    pub join: Vec<JoinQuery>,
109    pub where_queries: Vec<WhereQuery>,
110    pub group_by: Option<String>,
111    pub having: Vec<HavingQuery>,
112    pub order_by: Vec<OrderQuery>,
113    pub limit: Option<u64>,
114    pub page: Option<u64>, // TODO: must use `offset` or `page` must decide...
115    pub columns: Option<Vec<String>>,
116}
117
118impl QueryStatement {
119    pub fn new(table: &str) -> Self {
120        return Self {
121            table: table.to_string(),
122            select: Vec::new(),
123            join: Vec::new(),
124            where_queries: Vec::new(),
125            having: Vec::new(),
126            group_by: None,
127            order_by: Vec::new(),
128            limit: None,
129            page: None,
130            columns: None,
131        }
132    }
133}
134
135#[derive(Debug, sqlx::FromRow)]
136pub(crate) struct Total {
137    pub total: u64
138}
139
140impl <'q, DB>Statement<'q, DB>
141where
142    DB: sqlx::Database
143{
144    pub(crate) fn new(table: &str) -> Self {
145        return Self {
146            query: QueryStatement::new(table),
147            arguments: Default::default(),
148        }
149    }
150}
151
152#[derive(Debug)]
153pub struct Transaction<'t, T: sqlx::Database> {
154    transaction: SqlxTransaction<'t, T>
155}
156
157impl <'t, T: sqlx::Database>Transaction<'t, T> {
158    pub(crate) fn new(transaction: SqlxTransaction<'t, T>) -> Self {
159        return Self {
160            transaction: transaction
161        }
162    }
163
164    pub async fn commit(self) -> Result<()> {
165        return self.transaction.commit().await.map_err(|e| e.into());
166    }
167
168    pub async fn rollback(self) -> Result<()> {
169        return self.transaction.rollback().await.map_err(|e| e.into());
170    }
171}
172
173#[derive(Serialize, Clone, Debug)]
174pub struct Pagination<Entity> {
175    pub total: u64,
176    pub page: u64,
177    pub per_page: u64,
178    pub items: Vec<Entity>
179}