Skip to main content

ergonomic_query/
ergonomic_query.rs

1
2//! 运行方式:`cargo run --example ergonomic_query`
3//!
4//! 核心改进:所有条件值(`where_eq` / `where_gt` / `where_like` / `where_in`
5//! 等)都通过 `impl Into<SqlValue>` 自动接收原生 Rust 值,无需手写
6//! `SqlValue::String(...)` / `SqlValue::I32(...)`。
7//!
8//! ```text
9//! 现在:Query::new("users").where_eq("age", 18).where_like("name", "A%")
10//! ```
11
12use torm::{AdvancedQuery, Database, Query, WhereCondition};
13
14#[tokio::main]
15async fn main() -> Result<(), Box<dyn std::error::Error>> {
16    let db = Database::sqlite(":memory:").await?;
17
18    db.execute(
19        "CREATE TABLE IF NOT EXISTS users (
20            id INTEGER PRIMARY KEY AUTOINCREMENT,
21            name TEXT,
22            age INTEGER,
23            score REAL,
24            active INTEGER
25        )",
26        &[],
27    )
28    .await?;
29
30    // 插入示例数据(raw SQL 参数用 .into() 由原生值自动转换)
31    for (name, age, score, active) in [
32        ("Alice", 25i64, 88.5f64, 1),
33        ("Bob", 17, 76.2, 0),
34        ("Carol", 30, 95.0, 1),
35        ("Dave", 22, 63.8, 1),
36        ("Eve", 41, 91.3, 0),
37    ] {
38        db.execute(
39            "INSERT INTO users (name, age, score, active) VALUES (?, ?, ?, ?)",
40            &[name.into(), age.into(), score.into(), active.into()],
41        )
42        .await?;
43    }
44
45    println!("=== 1. 基础链式条件(自动类型转换)===");
46    let result = Query::new("users")
47        .where_gte("age", 18)          // i32 自动转
48        .where_gt("score", 80.0)       // f64 自动转
49        .where_like("name", "A%")      // &str 自动转
50        .query(&db)
51        .select()
52        .await?;
53    for row in &result.rows {
54        println!(
55            "  name={} age={} score={}",
56            row.get("name").and_then(|v| v.as_str()).unwrap_or(""),
57            row.get("age").and_then(|v| v.as_i64()).unwrap_or(0),
58            row.get("score").and_then(|v| v.as_f64()).unwrap_or(0.0),
59        );
60    }
61
62    println!("\n=== 2. 整型 / 浮点 / 字符串全自动 ===");
63    let result = Query::new("users")
64        .where_in("id", vec![1, 3, 5]) // Vec<i32> 自动转
65        .query(&db)
66        .select()
67        .await?;
68    println!("  IN (1,3,5) -> {} 条", result.rows.len());
69
70    let result = Query::new("users")
71        .where_between("score", 70.0, 92.0) // f64 区间自动转
72        .where_eq("active", 1i32)
73        .query(&db)
74        .select()
75        .await?;
76    println!("  score BETWEEN 70 AND 92 AND active -> {} 条", result.rows.len());
77
78    println!("\n=== 3. 排序 + 分页 + 条件 ===");
79    let result = Query::new("users")
80        .where_gt("age", 0)
81        .order_by_desc("score")
82        .limit(2)
83        .query(&db)
84        .select()
85        .await?;
86    for row in &result.rows {
87        println!(
88            "  name={} score={}",
89            row.get("name").and_then(|v| v.as_str()).unwrap_or(""),
90            row.get("score").and_then(|v| v.as_f64()).unwrap_or(0.0),
91        );
92    }
93
94    println!("\n=== 4. AdvancedQuery 聚合 + HAVING ===");
95    let (sql, params) = AdvancedQuery::new("users")
96        .group_by(&["active"])
97        .having(WhereCondition::Gt("COUNT(*)".to_string(), 1i64.into()))
98        .build_select();
99    let result = db.query(&sql, &params).await?;
100    println!("  生成 SQL: {}", sql);
101    for row in &result.rows {
102        println!("  {:?}", row.values);
103    }
104
105    println!("\n✅ 查询 API 无需再写 SqlValue::Type(...),直接书写原生值即可。");
106    Ok(())
107}