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