Implement the remaining query builder methods, except those that call the database

This commit is contained in:
Timothy Warren 2019-04-16 15:51:27 -04:00
parent 9183e2f475
commit 296e87e3e9
4 changed files with 75 additions and 18 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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,12 +617,18 @@ 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);
// Handle explain
if self.state.explain == true {
self.driver.explain(&sql)
} else {
sql
}
}
fn compile_type(&self, query_type: QueryType, table: &str) -> String {
match query_type {

View File

@ -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(""),