chain_builder/
lib.rs

1#[cfg(feature = "mysql")]
2mod mysql;
3#[cfg(all(feature = "mysql", feature = "sqlx_mysql"))]
4mod sqlx_mysql;
5
6// mods
7mod join;
8mod operator;
9mod query_builder;
10
11// use
12use serde_json::Value;
13
14// export
15pub use join::{JoinBuilder, JoinMethods};
16pub use operator::Operator;
17pub use query_builder::{QueryCommon, WhereClauses};
18
19#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
20pub enum Client {
21    Mysql,
22    Postgres,
23}
24
25#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
26pub enum Statement {
27    Value(String, Operator, serde_json::Value),
28    SubChain(Box<QueryBuilder>),
29    OrChain(Box<QueryBuilder>),
30    Raw((String, Option<Vec<serde_json::Value>>)),
31}
32
33impl Statement {
34    pub fn to_query_builder(&mut self) -> &mut QueryBuilder {
35        match self {
36            Statement::OrChain(query) => query,
37            Statement::SubChain(query) => query,
38            _ => panic!("Statement::to_chain_builder()"),
39        }
40    }
41}
42
43#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
44pub enum Method {
45    Select,
46    Insert,
47    InsertMany,
48    Update,
49    Delete,
50}
51
52#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
53pub struct ChainBuilder {
54    client: Client,
55    db: Option<String>,
56    table: Option<String>,
57    table_raw: Option<(String, Option<Vec<serde_json::Value>>)>,
58    as_name: Option<String>,
59    select: Vec<Select>,
60    query: QueryBuilder,
61    method: Method,
62    insert_update: Value,
63    sql_str: String,
64    is_distinct: bool,
65}
66
67#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
68pub struct QueryBuilder {
69    statement: Vec<Statement>,
70    raw: Vec<(String, Option<Vec<serde_json::Value>>)>,
71    join: Vec<JoinBuilder>,
72    query_common: Vec<Common>,
73}
74
75#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
76pub enum Select {
77    Columns(Vec<String>),
78    Raw(String, Option<Vec<serde_json::Value>>),
79    // column name, builder
80    Builder(String, ChainBuilder),
81}
82
83#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
84pub enum Common {
85    With(String, bool, ChainBuilder),
86    Union(bool, ChainBuilder),
87    Limit(usize),
88    Offset(usize),
89    GroupBy(Vec<String>),
90    GroupByRaw(String, Option<Vec<serde_json::Value>>),
91    OrderBy(String, String),
92    OrderByRaw(String, Option<Vec<serde_json::Value>>),
93}
94
95impl ChainBuilder {
96    pub fn new(client: Client) -> ChainBuilder {
97        ChainBuilder {
98            client,
99            table: None,
100            table_raw: None,
101            select: Vec::new(),
102            as_name: None,
103            db: None,
104            query: QueryBuilder::default(),
105            method: Method::Select,
106            insert_update: Value::Null,
107            sql_str: String::new(),
108            is_distinct: false,
109        }
110    }
111
112    #[cfg(feature = "mysql")]
113    pub fn new_mysql() -> ChainBuilder {
114        ChainBuilder::new(Client::Mysql)
115    }
116
117    pub fn db(&mut self, db: &str) -> &mut ChainBuilder {
118        self.db = Some(db.to_string());
119        self
120    }
121
122    pub fn table(&mut self, table: &str) -> &mut ChainBuilder {
123        self.table = Some(table.to_string());
124        self
125    }
126
127    pub fn table_raw(
128        &mut self,
129        table: &str,
130        val: Option<Vec<serde_json::Value>>,
131    ) -> &mut ChainBuilder {
132        self.table_raw = Some((table.to_string(), val));
133        self
134    }
135
136    pub fn distinct(&mut self) -> &mut ChainBuilder {
137        self.is_distinct = true;
138        self
139    }
140
141    pub fn select(&mut self, select: Select) -> &mut ChainBuilder {
142        self.method = Method::Select;
143        self.select.push(select);
144        self
145    }
146
147    pub fn insert(&mut self, data: Value) -> &mut ChainBuilder {
148        self.method = Method::Insert;
149        self.insert_update = data;
150        self
151    }
152
153    pub fn insert_many(&mut self, data: Vec<Value>) -> &mut ChainBuilder {
154        self.method = Method::InsertMany;
155        self.insert_update = Value::Array(data);
156        self
157    }
158
159    pub fn update(&mut self, data: Value) -> &mut ChainBuilder {
160        self.method = Method::Update;
161        self.insert_update = data;
162        self
163    }
164
165    pub fn delete(&mut self) -> &mut ChainBuilder {
166        self.method = Method::Delete;
167        self
168    }
169
170    pub fn as_name(&mut self, name: &str) -> &mut ChainBuilder {
171        self.as_name = Some(name.to_string());
172        self
173    }
174
175    pub fn with(&mut self, alias: &str, chain_builder: ChainBuilder) -> &mut ChainBuilder {
176        self.query
177            .query_common
178            .push(Common::With(alias.to_string(), false, chain_builder));
179        self
180    }
181
182    pub fn with_recursive(
183        &mut self,
184        alias: &str,
185        chain_builder: ChainBuilder,
186    ) -> &mut ChainBuilder {
187        self.query
188            .query_common
189            .push(Common::With(alias.to_string(), true, chain_builder));
190        self
191    }
192
193    pub fn union(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
194        self.query
195            .query_common
196            .push(Common::Union(false, chain_builder));
197        self
198    }
199
200    pub fn union_all(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
201        self.query
202            .query_common
203            .push(Common::Union(true, chain_builder));
204        self
205    }
206
207    pub fn query(&mut self, query: impl FnOnce(&mut QueryBuilder)) {
208        query(&mut self.query);
209    }
210
211    pub fn add_raw(&mut self, sql: &str, val: Option<Vec<serde_json::Value>>) {
212        self.query.raw.push((sql.to_string(), val));
213    }
214
215    pub fn to_sql(&mut self) -> (String, Vec<serde_json::Value>) {
216        match self.client {
217            #[cfg(feature = "mysql")]
218            Client::Mysql => {
219                let rs = mysql::merge_to_sql(mysql::to_sql(self));
220                self.sql_str = rs.0.clone();
221                (self.sql_str.clone(), rs.1)
222            }
223            #[cfg(feature = "postgres")]
224            Client::Postgres => {
225                panic!("not support client");
226            }
227            _ => {
228                panic!("not support client");
229            }
230        }
231    }
232}