halo-sqlx 0.1.0

一个可组合的 SQL 拼接与参数收集库(参考 go-sqlbuilder 的设计)
Documentation
# sql_builder

一个 100% 对齐 [huandu/go-sqlbuilder](https://github.com/huandu/go-sqlbuilder) 设计的 Rust crate。它提供:

- `Args` + `Flavor`:支持 `?``$1``@p1``:1` 等多种占位符策略,并且允许通过 `Flavor` 跟随不同 SQL 方言;
- 完整的各类 Builder:`SelectBuilder``InsertBuilder``UpdateBuilder``DeleteBuilder``UnionBuilder``CTEBuilder``CTEQueryBuilder``CreateTableBuilder`,同时内建查、插、改、删、聚合、CTE、Union 和 clone 重用模式;
- `Build`/`Buildf`/`BuildNamed`:支持 `${name}``$0``$?``$$``Raw``List``Tuple` 等语法,并支持嵌套 builder、named arg 重用、literal `$` 等特殊行为;
- `Struct` + `field_mapper`:通过 `macro_rules!` 生成 `FieldMeta`,支持 `db`/`fieldtag`/`fieldopt`/`fieldas``with_tag`/`without_tag`、自定义 field mapper(如 snake_case/kebab_case/prefix/suffix)并兼容 `SqlValuer`- `Scan` + `ScanCell`:仿照 Go 的 `Addr` 实现数据扫描;
- `interpolate`:为不支持参数化的驱动提供 SQL 插值,涵盖多 flavor 的字符串/数字/日期/布尔等转义;
- `SqlValuer`:支持延迟计算参数,兼容自定义数据源;
- 全部示例/单测对齐 Go:138 条单测 + doc-test,覆盖 README 中的 builder、Struct、CTE、Union、field mapper、命名参数等场景。

## 典型用法

### 创建 SELECT

```rust
use halo::sqlx::select::SelectBuilder;

let mut sb = SelectBuilder::new();
sb.select(["id"]).from(["user"]);
sb.where_([sb.in_("status", [1_i64, 2, 3])]);

let (sql, args) = sb.build();
assert_eq!(sql, "SELECT id FROM user WHERE status IN (?, ?, ?)");
assert_eq!(args.len(), 3);
```

### 嵌套 Builder / Buildf

```rust
use halo::sqlx::builder::buildf;

let mut sb = SelectBuilder::new();
sb.select(["id"]).from(["user"]);

let explain = buildf(
    "EXPLAIN %v LEFT JOIN SELECT * FROM banned WHERE state IN (%v, %v)",
    [sb.into(), 1_i64, 2_i64],
);
let (sql, _) = explain.build();
assert!(sql.contains("EXPLAIN SELECT id FROM user"));
```

### named 参数

```rust
use halo::sqlx::{
    builder::build_named,
    modifiers::{SqlNamedArg, raw, list},
};

let mut named = std::collections::HashMap::new();
named.insert("table".to_string(), raw("user"));
named.insert("status".to_string(), list([1_i64, 2, 3]));
named.insert("time".to_string(), SqlNamedArg::new("start", 1_514_458_225_i64).into());

let (sql, args) = build_named(
    "SELECT * FROM ${table} WHERE status IN (${status}) AND created_at > ${time}",
    named,
)
.build();
assert!(sql.contains("@start"));
```

### Struct ORM + field mapper

```rust
use halo::sqlx::{field_mapper::snake_case_mapper, Struct};

let _= halo::sqlx::field_mapper::set_default_field_mapper_scoped(std::sync::Arc::new(snake_case_mapper));

halo::sqlx::sql_struct! {
    impl User {
        id: { db: "id", tags: [], omitempty: [], quote: false, as: None },
        user_name: { db: "", tags: [], omitempty: [], quote: false, as: None }
    }
}

    let s = Struct::<User>::new();
let (sql, _) = s.select_from("user").build();
assert!(sql.contains("user.user_name"));
```

### CTE 与 Union

```rust
use halo::sqlx::{cte::with, cte_query::CTEQueryBuilder, select::SelectBuilder};

let mut users_cte = CTEQueryBuilder::new();
let mut query = SelectBuilder::new();
query.select(["id"]).from(["users"]).where_(["name IS NOT NULL"]);
users_cte.table("users", ["id"]).as_(query);

let cte = with([users_cte]);
let mut sb = cte.select(["users.id"]);
sb.from(["users"]);
let (sql, _) = sb.build();
assert!(sql.contains("WITH users"));
```

## 维护与测试

```bash
cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test
```

## 许可证

MIT