Skip to main content

d1_orm_query/
build.rs

1use crate::{
2    condition::ConditionKind,
3    group::{Conjunction, Node},
4    query::Query,
5    value::Value,
6};
7
8pub fn build_conditions(query: &Query, start: usize) -> (String, Vec<Value>) {
9    let mut values: Vec<Value> = vec![];
10    let mut n = start;
11    let parts: Vec<String> = query.nodes.iter()
12        .map(|node| build_node(node, &mut n, &mut values))
13        .collect();
14    (parts.join(" AND "), values)
15}
16
17fn build_node(node: &Node, n: &mut usize, values: &mut Vec<Value>) -> String {
18    match node {
19        Node::Cond(c) => build_cond(&c.kind, &c.values, n, values),
20        Node::Group(g) => {
21            let sep = match g.conjunction {
22                Conjunction::And => " AND ",
23                Conjunction::Or => " OR ",
24            };
25            let parts: Vec<String> = g.nodes.iter()
26                .map(|node| build_node(node, n, values))
27                .collect();
28            format!("({})", parts.join(sep))
29        }
30    }
31}
32
33fn build_cond(kind: &ConditionKind, vals: &[Value], n: &mut usize, values: &mut Vec<Value>) -> String {
34    match kind {
35        ConditionKind::Eq(col) => { let s = format!("{} = ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
36        ConditionKind::Ne(col) => { let s = format!("{} != ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
37        ConditionKind::Gt(col) => { let s = format!("{} > ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
38        ConditionKind::Gte(col) => { let s = format!("{} >= ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
39        ConditionKind::Lt(col) => { let s = format!("{} < ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
40        ConditionKind::Lte(col) => { let s = format!("{} <= ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
41        ConditionKind::IsNull(col) => format!("{} IS NULL", col),
42        ConditionKind::IsNotNull(col) => format!("{} IS NOT NULL", col),
43        ConditionKind::FilterOptional(col) => {
44            let s = format!("(?{0} IS NULL OR {1} = ?{0})", n, col);
45            values.push(vals[0].clone()); *n += 1; s
46        }
47        ConditionKind::FilterOptionalGte(col) => {
48            let s = format!("(?{0} IS NULL OR {1} >= ?{0})", n, col);
49            values.push(vals[0].clone()); *n += 1; s
50        }
51        ConditionKind::FilterOptionalLte(col) => {
52            let s = format!("(?{0} IS NULL OR {1} <= ?{0})", n, col);
53            values.push(vals[0].clone()); *n += 1; s
54        }
55        ConditionKind::In(col) => {
56            let phs: Vec<String> = (0..vals.len()).map(|i| format!("?{}", *n + i)).collect();
57            let s = format!("{} IN ({})", col, phs.join(", "));
58            values.extend(vals.iter().cloned());
59            *n += vals.len();
60            s
61        }
62        ConditionKind::NotIn(col) => {
63            let phs: Vec<String> = (0..vals.len()).map(|i| format!("?{}", *n + i)).collect();
64            let s = format!("{} NOT IN ({})", col, phs.join(", "));
65            values.extend(vals.iter().cloned());
66            *n += vals.len();
67            s
68        }
69        ConditionKind::Like(col) => { let s = format!("{} LIKE ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
70        ConditionKind::NotLike(col) => { let s = format!("{} NOT LIKE ?{}", col, n); values.push(vals[0].clone()); *n += 1; s }
71        ConditionKind::Between(col) => {
72            let s = format!("{} BETWEEN ?{} AND ?{}", col, *n, *n + 1);
73            values.push(vals[0].clone());
74            values.push(vals[1].clone());
75            *n += 2;
76            s
77        }
78    }
79}
80
81pub fn build_tail(query: &Query) -> String {
82    let mut sql = String::new();
83    if let Some((col, dir)) = &query.order {
84        sql.push_str(&format!(" ORDER BY {} {}", col, dir.as_sql()));
85    }
86    if let Some(l) = query.limit {
87        sql.push_str(&format!(" LIMIT {}", l));
88    }
89    if let Some(o) = query.offset {
90        sql.push_str(&format!(" OFFSET {}", o));
91    }
92    sql
93}