Skip to main content

flyer_orm/query/
mod.rs

1use anyhow::Result;
2use serde::Serialize;
3use sqlx::{Transaction as SqlxTransaction};
4
5use crate::query::logic::{Condition, Join, OrderQuery, Where};
6
7pub mod logic;
8
9pub(crate) trait QueryBuilder<'q> {
10    fn new(statement: &'q Query) -> Self where Self: Sized;
11    fn query(&self) -> Result<String>;
12    fn insert(&self) -> Result<String>;
13    fn update(&self) -> Result<String>;
14    fn delete(&self) -> Result<String>;
15    fn select(&self) -> Result<String>;
16    fn join(&self) -> Result<String>;
17    fn r#where(&self) -> Result<String>;
18    fn group_by(&self) -> Result<String>;
19}
20
21#[derive(Clone, Debug)]
22pub enum Order {
23    ASC,
24    DESC
25}
26
27impl ToString for Order {
28    fn to_string(&self) -> String {
29        return match self {
30            Order::ASC => String::from("ASC"),
31            Order::DESC => String::from("DESC"),
32        };
33    }
34}
35
36
37#[derive(Clone, Debug)]
38pub struct Statement<'q, DB: sqlx::Database> {
39    pub query: Query,
40    pub arguments: DB::Arguments<'q>, 
41}
42
43#[derive(Clone, Debug, Default)]
44pub struct Having {
45    pub column: String,
46    pub operator: String,
47    pub value: String,
48    pub position: Option<Condition>
49}
50
51#[derive(Clone, Debug, Default)]
52pub struct Query {
53    pub table: String,
54    pub select: Vec<String>,
55    pub join: Vec<Join>,
56    pub where_queries: Vec<Where>,
57    pub group_by: Option<String>,
58    pub having: Vec<Having>,
59    pub order_by: Vec<OrderQuery>,
60    pub limit: Option<u64>,
61    pub page: Option<u64>, // TODO: must use `offset` or `page` must decide...
62    pub columns: Option<Vec<String>>,
63}
64
65impl Query {
66    pub fn new(table: &str) -> Self {
67        return Self {
68            table: table.to_string(),
69            select: Vec::new(),
70            join: Vec::new(),
71            where_queries: Vec::new(),
72            having: Vec::new(),
73            group_by: None,
74            order_by: Vec::new(),
75            limit: None,
76            page: None,
77            columns: None,
78        }
79    }
80}
81
82#[derive(Debug, sqlx::FromRow)]
83pub(crate) struct Total {
84    pub total: u64
85}
86
87impl <'q, DB>Statement<'q, DB>
88where
89    DB: sqlx::Database
90{
91    pub(crate) fn new(table: &str) -> Self {
92        return Self {
93            query: Query::new(table),
94            arguments: Default::default(),
95        }
96    }
97}
98
99#[derive(Debug)]
100pub struct Transaction<'t, T: sqlx::Database> {
101    transaction: SqlxTransaction<'t, T>
102}
103
104impl <'t, T: sqlx::Database>Transaction<'t, T> {
105    pub(crate) fn new(transaction: SqlxTransaction<'t, T>) -> Self {
106        return Self {
107            transaction: transaction
108        }
109    }
110
111    pub async fn commit(self) -> Result<()> {
112        return self.transaction.commit().await.map_err(|e| e.into());
113    }
114
115    pub async fn rollback(self) -> Result<()> {
116        return self.transaction.rollback().await.map_err(|e| e.into());
117    }
118}
119
120#[derive(Serialize, Clone, Debug)]
121pub struct Pagination<Entity> {
122    pub total: u64,
123    pub page: u64,
124    pub per_page: u64,
125    pub items: Vec<Entity>
126}