Implement the remaining query builder methods, except those that call the database
This commit is contained in:
parent
9183e2f475
commit
296e87e3e9
@ -44,7 +44,7 @@ pub enum OrderDirection {
|
||||
}
|
||||
|
||||
/// The type of Query Clause
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum QueryClauseType {
|
||||
/// Ending a parenthetical grouping
|
||||
GroupEnd,
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
.set("buzz", Box::new((1, 2.0, true, 'q')));
|
||||
|
||||
// This just makes me sad
|
||||
qb.r#where("foo", "<>", Box::new(2));
|
||||
qb.r#where("foo <>", Box::new(2));
|
||||
|
||||
println!("QueryBuilder object: {:#?}", &qb);
|
||||
|
||||
|
@ -124,6 +124,14 @@ impl QueryBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Tell the database to give you query plain info, rather
|
||||
/// than a result set
|
||||
pub fn explain(&mut self) -> &mut Self {
|
||||
self.state.explain = true;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the database table to select from
|
||||
///
|
||||
/// ```
|
||||
@ -195,22 +203,31 @@ impl QueryBuilder {
|
||||
// ! 'Where' methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/// Specify a condition for the `where` clause of the query
|
||||
pub fn r#where(&mut self, key: &str, op: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
// @TODO actually implement setting the keys for the where
|
||||
self.state.append_where_values(value);
|
||||
|
||||
unimplemented!();
|
||||
/// Alias method for `r#where`.
|
||||
pub fn filter(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
self.r#where(key, value)
|
||||
}
|
||||
|
||||
/// Specify a condition for a `where` clause where a column has a value
|
||||
pub fn where_eq(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
self.r#where(key, "=", value)
|
||||
/// Specify a condition for the `where` clause of the query. Can be called
|
||||
/// multiple times, which will then add additional where conditions, prefixed
|
||||
/// with 'AND'.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use stringqb::prelude::*;
|
||||
/// # let mut qb = QueryBuilder::default();
|
||||
/// // By default, key = value
|
||||
/// qb.r#where("key", Box::new("value"));
|
||||
///
|
||||
/// // Other operators can be used with a separating space
|
||||
/// qb.r#where("key >", Box::new(4));
|
||||
/// ```
|
||||
pub fn r#where(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
self._where_string(key, value, "AND")
|
||||
}
|
||||
|
||||
/// Specify a condition for the `where` clause of the query, prefixed with `or`
|
||||
pub fn or_where(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
unimplemented!();
|
||||
self._where_string(key, value, "OR")
|
||||
}
|
||||
|
||||
/// Specify a `where in` clause for the query
|
||||
@ -549,8 +566,38 @@ impl QueryBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
fn _where_string(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
unimplemented!();
|
||||
fn _where_string(&mut self, key: &str, value: Box<dyn Any>, conj: &str) -> &mut Self {
|
||||
let keys = self._where(key, vec![value]);
|
||||
|
||||
for k in keys {
|
||||
self._where_string_key(key, conj);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn _where_string_key(&mut self, key: &str, conj: &str) {
|
||||
let field = key.trim().split(" ").collect::<Vec<&str>>();
|
||||
let query_map = self.state.get_query_map();
|
||||
|
||||
let last_item = &query_map[query_map.len() - 1];
|
||||
let mut item = self.driver.quote_identifier(field[0]);
|
||||
|
||||
let item2 = if field.len() == 1 {
|
||||
String::from("=?")
|
||||
} else {
|
||||
format!(" {} ?", &field[1])
|
||||
};
|
||||
|
||||
item += &item2;
|
||||
|
||||
let conj = if last_item.clause_type == QueryClauseType::GroupStart {
|
||||
String::from("")
|
||||
} else {
|
||||
format!(" {} ", conj)
|
||||
};
|
||||
|
||||
self.state.append_query_map(QueryClauseType::Where, &conj, &item);
|
||||
}
|
||||
|
||||
fn compile(&self, query_type: QueryType, table: &str) -> String {
|
||||
@ -570,11 +617,17 @@ impl QueryBuilder {
|
||||
&parts.push(clause.to_string());
|
||||
}
|
||||
|
||||
let sql = parts.join("");
|
||||
let mut sql = parts.join("");
|
||||
|
||||
// @TODO handle limit / offset
|
||||
// Add limit/ offset
|
||||
sql = self.driver.limit(&sql, self.state.limit, self.state.offset);
|
||||
|
||||
sql
|
||||
// Handle explain
|
||||
if self.state.explain == true {
|
||||
self.driver.explain(&sql)
|
||||
} else {
|
||||
sql
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_type(&self, query_type: QueryType, table: &str) -> String {
|
||||
|
@ -2,7 +2,7 @@ use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct QueryClause {
|
||||
clause_type: QueryClauseType,
|
||||
pub clause_type: QueryClauseType,
|
||||
conjunction: String,
|
||||
string: String,
|
||||
}
|
||||
@ -23,6 +23,8 @@ impl QueryClause {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct QueryState {
|
||||
pub explain: bool,
|
||||
|
||||
select_string: String,
|
||||
from_string: String,
|
||||
set_string: String,
|
||||
@ -58,6 +60,8 @@ pub struct QueryState {
|
||||
impl Default for QueryState {
|
||||
fn default() -> Self {
|
||||
QueryState {
|
||||
explain: false,
|
||||
|
||||
select_string: String::from(""),
|
||||
from_string: String::from(""),
|
||||
set_string: String::from(""),
|
||||
|
Loading…
Reference in New Issue
Block a user