Slight refactor, implement having methods
This commit is contained in:
parent
f7efadeb66
commit
9183e2f475
@ -50,6 +50,8 @@ pub enum QueryClauseType {
|
|||||||
GroupEnd,
|
GroupEnd,
|
||||||
/// Starting a parenthetical grouping
|
/// Starting a parenthetical grouping
|
||||||
GroupStart,
|
GroupStart,
|
||||||
|
/// A having clause
|
||||||
|
Having,
|
||||||
/// A join clause
|
/// A join clause
|
||||||
Join,
|
Join,
|
||||||
/// A like clause
|
/// A like clause
|
||||||
|
@ -164,7 +164,7 @@ impl QueryBuilder {
|
|||||||
|
|
||||||
/// Generates an OR Like clause
|
/// 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: 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
|
/// Generates a NOI Like clause
|
||||||
@ -182,13 +182,13 @@ 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: Vec<Box<dyn Any>>) -> &mut Self {
|
||||||
unimplemented!();
|
self._having(key, value, "AND")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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: Vec<Box<dyn Any>>) -> &mut Self {
|
||||||
unimplemented!();
|
self._having(key, value, "OR")
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -266,6 +266,13 @@ impl QueryBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a table join to the query
|
/// 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(
|
pub fn join(
|
||||||
&mut self,
|
&mut self,
|
||||||
table: &str,
|
table: &str,
|
||||||
@ -307,16 +314,11 @@ impl QueryBuilder {
|
|||||||
|
|
||||||
/// Add an order by clause to the query
|
/// Add an order by clause to the query
|
||||||
pub fn order_by(&mut self, field: &str, direction: OrderDirection) -> &mut Self {
|
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 field = self.driver.quote_identifier(field);
|
||||||
let dir = match direction {
|
let dir = match direction {
|
||||||
OrderDirection::Asc => String::from("ASC"),
|
OrderDirection::Asc => String::from("ASC"),
|
||||||
OrderDirection::Desc => String::from("DESC"),
|
OrderDirection::Desc => String::from("DESC"),
|
||||||
OrderDirection::Rand => String::from("RAND"),
|
OrderDirection::Rand => self.driver.random(),
|
||||||
};
|
};
|
||||||
self.state.append_order_map(&field, &dir);
|
self.state.append_order_map(&field, &dir);
|
||||||
|
|
||||||
@ -327,11 +329,7 @@ impl QueryBuilder {
|
|||||||
&order_clauses.push(clause);
|
&order_clauses.push(clause);
|
||||||
}
|
}
|
||||||
|
|
||||||
let order_str = if direction != OrderDirection::Rand {
|
let order_str = "\nORDER BY ".to_string() + &order_clauses.join(", ");
|
||||||
"\nORDER BY ".to_string() + &order_clauses.join(", ")
|
|
||||||
} else {
|
|
||||||
unimplemented!();
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state.set_order_string(&order_str);
|
self.state.set_order_string(&order_str);
|
||||||
|
|
||||||
@ -358,28 +356,16 @@ impl QueryBuilder {
|
|||||||
|
|
||||||
/// Start a logical grouping in the current query
|
/// Start a logical grouping in the current query
|
||||||
pub fn group_start(&mut self) -> &mut Self {
|
pub fn group_start(&mut self) -> &mut Self {
|
||||||
let conj = if self.state.query_map_empty() {
|
|
||||||
" WHERE "
|
|
||||||
} else {
|
|
||||||
" "
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.append_query_map(QueryClauseType::GroupStart, conj, "(");
|
.append_query_map(QueryClauseType::GroupStart, " ", "(");
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a logical grouping, prefixed with `not`
|
/// Start a logical grouping, prefixed with `not`
|
||||||
pub fn not_group_start(&mut self) -> &mut Self {
|
pub fn not_group_start(&mut self) -> &mut Self {
|
||||||
let conj = if self.state.query_map_empty() {
|
|
||||||
" WHERE "
|
|
||||||
} else {
|
|
||||||
" AND "
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.append_query_map(QueryClauseType::GroupStart, conj, "NOT (");
|
.append_query_map(QueryClauseType::GroupStart, " AND ", "NOT (");
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -505,12 +491,6 @@ impl QueryBuilder {
|
|||||||
LikeWildcard::Both => format!("%{}%", *string_val),
|
LikeWildcard::Both => format!("%{}%", *string_val),
|
||||||
};
|
};
|
||||||
|
|
||||||
let conj = if self.state.query_map_empty() {
|
|
||||||
" WHERE "
|
|
||||||
} else {
|
|
||||||
conj
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.append_query_map(QueryClauseType::Like, conj, &like);
|
.append_query_map(QueryClauseType::Like, conj, &like);
|
||||||
self.state.append_where_values(Box::new(value));
|
self.state.append_where_values(Box::new(value));
|
||||||
@ -518,10 +498,40 @@ impl QueryBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _where(&mut self, key: &str, values: Vec<Box<dyn Any>>) -> HashMap<String, Box<dyn Any>> {
|
fn _having(&mut self, key: &str, values: Vec<Box<dyn Any>>, conj: &str) -> &mut Self {
|
||||||
let mut map: HashMap<String, Box<dyn Any>> = HashMap::new();
|
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 {
|
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);
|
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(","));
|
let str = format!("{} {} ({}) ", key, in_str, placeholders.join(","));
|
||||||
|
|
||||||
self.state.append_query_map(QueryClauseType::WhereIn, conj, &str);
|
self.state.append_query_map(QueryClauseType::WhereIn, conj, &str);
|
||||||
|
@ -104,11 +104,20 @@ impl QueryState {
|
|||||||
|
|
||||||
pub fn append_having_map(
|
pub fn append_having_map(
|
||||||
&mut self,
|
&mut self,
|
||||||
clause_type: QueryClauseType,
|
|
||||||
conj: &str,
|
conj: &str,
|
||||||
s: &str,
|
s: &str,
|
||||||
) -> &mut Self {
|
) -> &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
|
self
|
||||||
}
|
}
|
||||||
@ -143,6 +152,12 @@ impl QueryState {
|
|||||||
conj: &str,
|
conj: &str,
|
||||||
s: &str,
|
s: &str,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
|
let conj = if self.query_map.len() == 0 {
|
||||||
|
" WHERE "
|
||||||
|
} else {
|
||||||
|
conj
|
||||||
|
};
|
||||||
|
|
||||||
self.query_map.push(QueryClause::new(clause_type, conj, s));
|
self.query_map.push(QueryClause::new(clause_type, conj, s));
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -196,10 +211,6 @@ impl QueryState {
|
|||||||
&self.where_values
|
&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 {
|
pub fn set_from_string(&mut self, s: &str) -> &mut Self {
|
||||||
self.from_string = String::from(s);
|
self.from_string = String::from(s);
|
||||||
|
|
||||||
@ -217,8 +228,4 @@ impl QueryState {
|
|||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn query_map_empty(&self) -> bool {
|
|
||||||
self.query_map.len() == 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user