review: use INNER JOIN to create filter statement
This commit is contained in:
@@ -1,19 +1,18 @@
|
||||
use crate::*;
|
||||
|
||||
const BASE_SELECT: &str = r#"SELECT * FROM entity WHERE 1=1"#;
|
||||
const BASE_SELECT: &str = r#"SELECT * FROM entity"#;
|
||||
|
||||
// REVIEW: instead of nested queries, switch to an inner join model
|
||||
pub fn run(filter: &Filter) -> Result<String, FailedTo> {
|
||||
let mut statement = String::from(BASE_SELECT);
|
||||
for (i, (name, _comparison, condition)) in filter.conditions().enumerate() {
|
||||
let fragment = match (_comparison, condition) {
|
||||
(_, Condition::Bool(_)) => format!(
|
||||
" AND id IN (SELECT entity_id FROM attribute WHERE id = '{}' AND value_bool = ?{})",
|
||||
" INNER JOIN attribute ON entity.id = attribute.entity_id AND attribute.id = '{}' AND value_bool = ?{}",
|
||||
name,
|
||||
i + 1
|
||||
),
|
||||
(Comparison::Equal, Condition::SignedInt(_)) => format!(
|
||||
" AND id IN (SELECT entity_id FROM attribute WHERE id = '{}' AND value_int = ?{})",
|
||||
" INNER JOIN attribute ON entity.id = attribute.entity_id AND attribute.id = '{}' AND value_int = ?{}",
|
||||
name,
|
||||
i + 1
|
||||
),
|
||||
@@ -23,69 +22,3 @@ pub fn run(filter: &Filter) -> Result<String, FailedTo> {
|
||||
}
|
||||
Ok(statement)
|
||||
}
|
||||
|
||||
// REVIEW: evaluate to avoid these tests, do they make sense?
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Filter;
|
||||
#[test]
|
||||
fn builds_statement_with_no_conditions() {
|
||||
let filter = Filter::new();
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(statement, BASE_SELECT);
|
||||
}
|
||||
#[test]
|
||||
fn builds_statement_with_one_bool_condition() {
|
||||
let filter = Filter::new().with_bool("is_active", true);
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(
|
||||
statement,
|
||||
"SELECT * FROM entity WHERE 1=1 AND id IN (SELECT entity_id FROM attribute WHERE id = 'is_active' AND value_bool = ?1)"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn builds_statement_with_multiple_bool_conditions() {
|
||||
let filter = Filter::new()
|
||||
.with_bool("is_active", true)
|
||||
.with_bool("is_deleted", false);
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(
|
||||
statement,
|
||||
"SELECT * FROM entity WHERE 1=1 AND id IN (SELECT entity_id FROM attribute WHERE id = 'is_active' AND value_bool = ?1) AND id IN (SELECT entity_id FROM attribute WHERE id = 'is_deleted' AND value_bool = ?2)"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn builds_statement_with_one_signed_int_equal_condition() {
|
||||
let filter = Filter::new().with_signed_int("level", Comparison::Equal, 10);
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(
|
||||
statement,
|
||||
"SELECT * FROM entity WHERE 1=1 AND id IN (SELECT entity_id FROM attribute WHERE id = 'level' AND value_int = ?1)"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn builds_statement_with_multiple_signed_int_equal_conditions() {
|
||||
let filter = Filter::new()
|
||||
.with_signed_int("level", Comparison::Equal, 10)
|
||||
.with_signed_int("score", Comparison::Equal, 100);
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(
|
||||
statement,
|
||||
"SELECT * FROM entity WHERE 1=1 AND id IN (SELECT entity_id FROM attribute WHERE id = 'level' AND value_int = ?1) AND id IN (SELECT entity_id FROM attribute WHERE id = 'score' AND value_int = ?2)"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn builds_statement_with_mixed_bool_and_signed_int_conditions() {
|
||||
let filter = Filter::new().with_bool("is_active", true).with_signed_int(
|
||||
"level",
|
||||
Comparison::Equal,
|
||||
5,
|
||||
);
|
||||
let statement = run(&filter).unwrap();
|
||||
assert_eq!(
|
||||
statement,
|
||||
"SELECT * FROM entity WHERE 1=1 AND id IN (SELECT entity_id FROM attribute WHERE id = 'is_active' AND value_bool = ?1) AND id IN (SELECT entity_id FROM attribute WHERE id = 'level' AND value_int = ?2)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user