This commit is contained in:
Timothy Warren 2019-04-10 19:49:06 -04:00
parent 324c98dfa4
commit c1bb5d642b

View File

@ -7,6 +7,9 @@ use std::collections::HashMap;
use crate::drivers::{DatabaseDriver, DefaultDriver};
use crate::split_map_join;
/// The Wild type is any type, until examined
pub type Wild = Box<dyn Any>;
/// The position of the wildcard(s)
/// for a `like` clause
#[derive(Debug)]
@ -103,10 +106,10 @@ struct QueryState {
group_array: Vec<String>,
// Values to apply to prepared statements
values: Vec<Box<dyn Any>>,
values: Vec<Wild>,
// Values to apply to where clauses in prepared statements
where_values: Vec<Box<dyn Any>>,
where_values: Vec<Wild>,
limit: Option<usize>,
@ -154,7 +157,7 @@ impl QueryState {
self
}
pub fn append_where_values(&mut self, val: Box<dyn Any>) -> &mut Self {
pub fn append_where_values(&mut self, val: Wild) -> &mut Self {
self.where_values.push(val);
self
@ -248,39 +251,22 @@ impl QueryBuilder {
// --------------------------------------------------------------------------
/// Creates a `like` clause in the sql statement
pub fn like(&mut self, field: &str, value: Box<dyn Any>, position: LikeWildcard) -> &mut Self {
pub fn like(&mut self, field: &str, value: Wild, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "LIKE", "AND")
}
/// Generates an OR Like clause
pub fn or_like(
&mut self,
field: &str,
value: Box<dyn Any>,
position: LikeWildcard,
) -> &mut Self {
pub fn or_like(&mut self, field: &str, value: Wild, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "LIKE", "OR")
}
/// Generates a NOI Like clause
pub fn not_like(
&mut self,
field: &str,
value: Box<dyn Any>,
position: LikeWildcard,
) -> &mut Self {
pub fn not_like(&mut self, field: &str, value: Wild, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "NOT LIKE", "AND")
}
/// Generates an OR NOT Like clause
pub fn or_not_like(
&mut self,
field: &str,
value: Box<dyn Any>,
position: LikeWildcard,
) -> &mut Self {
pub fn or_not_like(&mut self, field: &str, value: Wild, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "NOT LIKE", "OR")
}
@ -289,12 +275,12 @@ impl QueryBuilder {
// --------------------------------------------------------------------------
/// Add a `having` clause to the query
pub fn having(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
pub fn having(&mut self, key: &str, value: Wild) -> &mut Self {
unimplemented!();
}
/// Add a `having` clause to the query, prefixed with an `or`
pub fn or_having(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
pub fn or_having(&mut self, key: &str, value: Wild) -> &mut Self {
unimplemented!();
}
@ -303,7 +289,7 @@ impl QueryBuilder {
// --------------------------------------------------------------------------
/// 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 {
pub fn r#where(&mut self, key: &str, op: &str, value: Wild) -> &mut Self {
// @TODO actually implement setting the keys for the where
self.state.where_values.push(value);
@ -311,32 +297,32 @@ impl QueryBuilder {
}
/// 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 {
pub fn where_eq(&mut self, key: &str, value: Wild) -> &mut Self {
self.r#where(key, "=", value)
}
/// 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 {
pub fn or_where(&mut self, key: &str, value: Wild) -> &mut Self {
unimplemented!();
}
/// Specify a `where in` clause for the query
pub fn where_in(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
pub fn where_in(&mut self, key: &str, value: Vec<Wild>) -> &mut Self {
unimplemented!();
}
/// Specify a `where in` clause for the query, prefixed with `or`
pub fn or_where_in(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
pub fn or_where_in(&mut self, key: &str, value: Vec<Wild>) -> &mut Self {
unimplemented!();
}
/// Specify a `where not in` clause for the query
pub fn where_not_in(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
pub fn where_not_in(&mut self, key: &str, value: Vec<Wild>) -> &mut Self {
unimplemented!();
}
/// Specify a `where not in` clause for the query, prefixed with `or`
pub fn or_where_not_in(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
pub fn or_where_not_in(&mut self, key: &str, value: Vec<Wild>) -> &mut Self {
unimplemented!();
}
@ -345,7 +331,7 @@ impl QueryBuilder {
// --------------------------------------------------------------------------
/// Set a key and value for an insert or update query
pub fn set(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
pub fn set(&mut self, key: &str, value: Wild) -> &mut Self {
// @TODO figure a way to make this easier to use
self.state.set_array_keys.push(key.to_string());
self.state.values.push(value);
@ -354,7 +340,7 @@ impl QueryBuilder {
}
/// Set a map of data for an insert or update query
pub fn set_map(&mut self, data: HashMap<String, Box<dyn Any>>) -> &mut Self {
pub fn set_map(&mut self, data: HashMap<String, Wild>) -> &mut Self {
for (key, value) in data {
self.set(&key, value);
}
@ -583,16 +569,25 @@ impl QueryBuilder {
// ! Implementation Details
// --------------------------------------------------------------------------
fn _like(&mut self, field: &str, value: Box<dyn Any>, position: LikeWildcard, like: &str, conj: &str) -> &mut Self {
fn _like(
&mut self,
field: &str,
value: Wild,
position: LikeWildcard,
like: &str,
conj: &str,
) -> &mut Self {
let field = self.driver.quote_identifier(field);
let like = format!("{} {} ?", field, like);
let string_val = value.downcast::<String>().unwrap();
// @TODO Properly parse types of `value` for string formatting
let value = match position {
LikeWildcard::Before => format!("%{:?}", value),
LikeWildcard::After => format!("{:?}%s", value),
LikeWildcard::Both => format!("%{:?}%", value),
LikeWildcard::Before => format!("%{}", *string_val),
LikeWildcard::After => format!("{}%s", *string_val),
LikeWildcard::Both => format!("%{}%", *string_val),
};
let conj = if self.state.query_map.len() == 0 {
@ -601,25 +596,26 @@ impl QueryBuilder {
conj
};
self.state.append_query_map(QueryClauseType::Like, conj, &like);
self.state
.append_query_map(QueryClauseType::Like, conj, &like);
self.state.append_where_values(Box::new(value));
self
}
fn _where(key: &str, values: Vec<Box<dyn Any>>) -> HashMap<String, Box<dyn Any>> {
fn _where(key: &str, values: Vec<Wild>) -> HashMap<String, Wild> {
unimplemented!();
}
fn _where_in(&mut self, key: &str, values: Vec<Box<dyn Any>>) -> &mut Self {
fn _where_in(&mut self, key: &str, values: Vec<Wild>) -> &mut Self {
unimplemented!();
}
fn _where_in_string(&mut self, key: &str, values: Vec<Box<dyn Any>>) -> &mut Self {
fn _where_in_string(&mut self, key: &str, values: Vec<Wild>) -> &mut Self {
unimplemented!();
}
fn _where_string(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
fn _where_string(&mut self, key: &str, value: Wild) -> &mut Self {
unimplemented!();
}
@ -653,7 +649,7 @@ mod tests {
fn set_hashmap() {
let mut qb = QueryBuilder::default();
let mut authors: HashMap<String, Box<dyn Any>> = HashMap::new();
let mut authors: HashMap<String, Wild> = HashMap::new();
authors.insert(
String::from("Chinua Achebe"),
Box::new(String::from("Nigeria")),