Slight refactor, implement having methods
This commit is contained in:
parent
f7efadeb66
commit
9183e2f475
@ -50,6 +50,8 @@ pub enum QueryClauseType {
|
||||
GroupEnd,
|
||||
/// Starting a parenthetical grouping
|
||||
GroupStart,
|
||||
/// A having clause
|
||||
Having,
|
||||
/// A join clause
|
||||
Join,
|
||||
/// A like clause
|
||||
|
@ -164,7 +164,7 @@ impl QueryBuilder {
|
||||
|
||||
/// Generates an OR Like clause
|
||||
pub fn or_like(&mut self, field: &str, value: Box<dyn Any>, position: LikeWildcard) -> &mut Self {
|
||||
self._like(field, Box::new(value), position, "LIKE", "OR")
|
||||
self._like(field, value, position, "LIKE", "OR")
|
||||
}
|
||||
|
||||
/// Generates a NOI Like clause
|
||||
@ -182,13 +182,13 @@ impl QueryBuilder {
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/// Add a `having` clause to the query
|
||||
pub fn having(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
|
||||
unimplemented!();
|
||||
pub fn having(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
|
||||
self._having(key, value, "AND")
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
unimplemented!();
|
||||
pub fn or_having(&mut self, key: &str, value: Vec<Box<dyn Any>>) -> &mut Self {
|
||||
self._having(key, value, "OR")
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@ -266,6 +266,13 @@ impl QueryBuilder {
|
||||
}
|
||||
|
||||
/// Add a table join to the query
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use stringqb::prelude::*;
|
||||
/// # let mut qb = QueryBuilder::default();
|
||||
/// // Note that the value is not escaped, due to it often being a column
|
||||
/// qb.join("table1", "column1", "<>", "foo", JoinType::Inner);
|
||||
/// ```
|
||||
pub fn join(
|
||||
&mut self,
|
||||
table: &str,
|
||||
@ -307,16 +314,11 @@ impl QueryBuilder {
|
||||
|
||||
/// Add an order by clause to the query
|
||||
pub fn order_by(&mut self, field: &str, direction: OrderDirection) -> &mut Self {
|
||||
if direction == OrderDirection::Rand {
|
||||
// @TODO handle random sorting
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
let field = self.driver.quote_identifier(field);
|
||||
let dir = match direction {
|
||||
OrderDirection::Asc => String::from("ASC"),
|
||||
OrderDirection::Desc => String::from("DESC"),
|
||||
OrderDirection::Rand => String::from("RAND"),
|
||||
OrderDirection::Rand => self.driver.random(),
|
||||
};
|
||||
self.state.append_order_map(&field, &dir);
|
||||
|
||||
@ -327,11 +329,7 @@ impl QueryBuilder {
|
||||
&order_clauses.push(clause);
|
||||
}
|
||||
|
||||
let order_str = if direction != OrderDirection::Rand {
|
||||
"\nORDER BY ".to_string() + &order_clauses.join(", ")
|
||||
} else {
|
||||
unimplemented!();
|
||||
};
|
||||
let order_str = "\nORDER BY ".to_string() + &order_clauses.join(", ");
|
||||
|
||||
self.state.set_order_string(&order_str);
|
||||
|
||||
@ -358,28 +356,16 @@ impl QueryBuilder {
|
||||
|
||||
/// Start a logical grouping in the current query
|
||||
pub fn group_start(&mut self) -> &mut Self {
|
||||
let conj = if self.state.query_map_empty() {
|
||||
" WHERE "
|
||||
} else {
|
||||
" "
|
||||
};
|
||||
|
||||
self.state
|
||||
.append_query_map(QueryClauseType::GroupStart, conj, "(");
|
||||
.append_query_map(QueryClauseType::GroupStart, " ", "(");
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Start a logical grouping, prefixed with `not`
|
||||
pub fn not_group_start(&mut self) -> &mut Self {
|
||||
let conj = if self.state.query_map_empty() {
|
||||
" WHERE "
|
||||
} else {
|
||||
" AND "
|
||||
};
|
||||
|
||||
self.state
|
||||
.append_query_map(QueryClauseType::GroupStart, conj, "NOT (");
|
||||
.append_query_map(QueryClauseType::GroupStart, " AND ", "NOT (");
|
||||
|
||||
self
|
||||
}
|
||||
@ -505,12 +491,6 @@ impl QueryBuilder {
|
||||
LikeWildcard::Both => format!("%{}%", *string_val),
|
||||
};
|
||||
|
||||
let conj = if self.state.query_map_empty() {
|
||||
" WHERE "
|
||||
} else {
|
||||
conj
|
||||
};
|
||||
|
||||
self.state
|
||||
.append_query_map(QueryClauseType::Like, conj, &like);
|
||||
self.state.append_where_values(Box::new(value));
|
||||
@ -518,10 +498,40 @@ impl QueryBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
fn _where(&mut self, key: &str, values: Vec<Box<dyn Any>>) -> HashMap<String, Box<dyn Any>> {
|
||||
let mut map: HashMap<String, Box<dyn Any>> = HashMap::new();
|
||||
fn _having(&mut self, key: &str, values: Vec<Box<dyn Any>>, conj: &str) -> &mut Self {
|
||||
let keys = self._where(key, values);
|
||||
|
||||
unimplemented!();
|
||||
for k in keys {
|
||||
self._having_key(&k, conj);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn _having_key(&mut self, key: &str, conj:&str) -> &mut Self {
|
||||
let field = key.trim().split(" ").collect::<Vec<&str>>();
|
||||
|
||||
let mut item = self.driver.quote_identifier(field[0]);;
|
||||
|
||||
let item2 = if field.len() == 1 {
|
||||
String::from("=?")
|
||||
} else {
|
||||
format!(" {} ?", &field[1])
|
||||
};
|
||||
|
||||
item += &item2;
|
||||
|
||||
self.state.append_having_map(conj, &item);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn _where(&mut self, key: &str, values: Vec<Box<dyn Any>>) -> Vec<String> {
|
||||
for x in values {
|
||||
self.state.append_where_values(x);
|
||||
}
|
||||
|
||||
vec![String::from(key)]
|
||||
}
|
||||
|
||||
fn _where_in(&mut self, key: &str, values: Vec<Box<dyn Any>>, in_str: &str, conj: &str) -> &mut Self {
|
||||
@ -532,12 +542,6 @@ impl QueryBuilder {
|
||||
self.state.append_where_values(value);
|
||||
}
|
||||
|
||||
let conj = if self.state.query_map_empty() {
|
||||
" WHERE "
|
||||
} else {
|
||||
conj
|
||||
};
|
||||
|
||||
let str = format!("{} {} ({}) ", key, in_str, placeholders.join(","));
|
||||
|
||||
self.state.append_query_map(QueryClauseType::WhereIn, conj, &str);
|
||||
|
@ -104,11 +104,20 @@ impl QueryState {
|
||||
|
||||
pub fn append_having_map(
|
||||
&mut self,
|
||||
clause_type: QueryClauseType,
|
||||
conj: &str,
|
||||
s: &str,
|
||||
) -> &mut Self {
|
||||
self.having_map.push(QueryClause::new(clause_type, conj, s));
|
||||
let conj = if self.having_map.len() == 0 {
|
||||
String::from(" HAVING ")
|
||||
} else {
|
||||
format!(" {} ", conj)
|
||||
};
|
||||
|
||||
self.having_map.push(QueryClause::new(
|
||||
QueryClauseType::Having,
|
||||
&conj,
|
||||
s
|
||||
));
|
||||
|
||||
self
|
||||
}
|
||||
@ -143,6 +152,12 @@ impl QueryState {
|
||||
conj: &str,
|
||||
s: &str,
|
||||
) -> &mut Self {
|
||||
let conj = if self.query_map.len() == 0 {
|
||||
" WHERE "
|
||||
} else {
|
||||
conj
|
||||
};
|
||||
|
||||
self.query_map.push(QueryClause::new(clause_type, conj, s));
|
||||
|
||||
self
|
||||
@ -196,10 +211,6 @@ impl QueryState {
|
||||
&self.where_values
|
||||
}
|
||||
|
||||
pub fn having_map_empty(&self) -> bool {
|
||||
self.having_map.len() == 0
|
||||
}
|
||||
|
||||
pub fn set_from_string(&mut self, s: &str) -> &mut Self {
|
||||
self.from_string = String::from(s);
|
||||
|
||||
@ -217,8 +228,4 @@ impl QueryState {
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn query_map_empty(&self) -> bool {
|
||||
self.query_map.len() == 0
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user