103 lines
2.1 KiB
Rust
103 lines
2.1 KiB
Rust
//! QueryBuilder
|
|
//!
|
|
//! The QueryBuilder creates sql queries from chained methods
|
|
use std::any::{Any, TypeId};
|
|
use std::collections::HashMap;
|
|
|
|
use crate::drivers::DatabaseDriver;
|
|
|
|
#[derive(Debug)]
|
|
enum QueryClauseType {
|
|
AndGroupStart,
|
|
GroupEnd,
|
|
GroupStart,
|
|
Like,
|
|
OrGroupStart,
|
|
Where,
|
|
WhereIn,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct QueryClause {
|
|
clause_type: QueryClauseType,
|
|
conjunction: String,
|
|
string: String,
|
|
}
|
|
|
|
#[derive(Default, Debug)]
|
|
struct QueryState {
|
|
select_string: String,
|
|
from_string: String,
|
|
set_string: String,
|
|
order_string: String,
|
|
group_string: String,
|
|
|
|
// Keys for insert/update statement
|
|
pub set_array_keys: Vec<String>,
|
|
|
|
// Order by clause
|
|
order_array: HashMap<String, String>,
|
|
|
|
// Group by clause
|
|
group_array: HashMap<String, String>,
|
|
|
|
// Values to apply to prepared statements
|
|
pub values: Vec<Box<dyn Any>>,
|
|
|
|
// Values to apply to where clauses in prepared statements
|
|
pub where_values: Vec<Box<dyn Any>>,
|
|
|
|
limit: u32,
|
|
|
|
offset: u32,
|
|
|
|
// Query components for complex selects
|
|
query_map: Vec<QueryClause>,
|
|
|
|
// Query components for having clauses
|
|
having_map: Vec<QueryClause>,
|
|
}
|
|
|
|
impl QueryState {
|
|
pub fn new() -> QueryState {
|
|
QueryState::default()
|
|
}
|
|
}
|
|
|
|
/// The struct representing a query builder
|
|
#[derive(Default, Debug)]
|
|
pub struct QueryBuilder {
|
|
state: QueryState,
|
|
driver: Option<Box<dyn DatabaseDriver>>,
|
|
}
|
|
|
|
impl QueryBuilder {
|
|
/// Creates a new QueryBuilder instance
|
|
pub fn new() -> QueryBuilder {
|
|
QueryBuilder {
|
|
state: QueryState::new(),
|
|
driver: None,
|
|
}
|
|
}
|
|
|
|
/// Set a key and value for an insert or update query
|
|
pub fn set(mut self, key: String, value: Box<dyn Any>) -> Self {
|
|
self.state.set_array_keys.push(key);
|
|
self.state.values.push(value);
|
|
|
|
self
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn set_key_value() {
|
|
let builder = QueryBuilder::new();
|
|
let builder = builder.set("foo".to_string(), Box::new("bar".to_string()));
|
|
|
|
assert!(builder.state.values[0].is::<String>());
|
|
}
|
|
} |