#query-builder #compile-time #sql-query #typed #builds #mysql #typechecks

nightly typed-qb

编译时构建和类型检查查询的查询构建器

3个不稳定版本

0.2.0 2021年11月8日
0.1.1 2021年11月4日
0.1.0 2021年11月4日

#2785数据库接口

MPL-2.0 许可证

155KB
4K SLoC

crates.io docs

typed-qb: 编译时类型化的 "查询构建器"

typed-qb 是一个编译时类型化的查询构建器。本包的目标是探索原始SQL查询(如 sqlx)的编译时验证和通过查询构建器(如 diesel)在运行时生成查询之间的差距。

查询在编译时转换为一个SQL查询字符串。如果代码编译且代码中的模式与数据库中的模式匹配,则几乎不可能编写产生错误的查询。

用法

您可以通过将 SHOW CREATE TABLE .. 的输出粘贴到 tables! 宏中来指定您的表结构。您需要清理反引号(`),因为Rust无法解析它们。例如

tables! {
    CREATE TABLE Users (
        Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
        Name VARCHAR(64) NOT NULL,
        PRIMARY KEY(Id)
    );
}

如果您以 camelCasePascalCase 写入字段名,它们将自动转换为 snake_case。然后您可以这样查询表

let conn = ...; // some connection

let all_users = conn.typed_query(
    Users::query(|user| data! {
        id: user.id,
        name: user.name,
    })
)?;

for user in all_users {
    let user = user?;
    println!("{} ({})", user.id, user.name);
}

查询在 编译时 转换为

SELECT `t0`.`Id` AS `id`, `t0`.`Name` AS `name` 
FROM `Users` AS t0

您可以使用 select 函数指定 WHEREORDER BY 等子句

Users::query(|user| select(data! {
    id: user.id,
    name: user.name,
}, |selected| {
    expr!(selected.id < 5)
        .order_by(selected.name.asc()
            .then_by(selected.id.desc())
        )
        .limit::<3>()
}))

typed_query 返回的类型取决于查询本身。上面的两个查询返回一个匿名 struct 的迭代器。如果选择单个值,例如

let user_count = conn.typed_query(Users::query(|_| expr!(COUNT(*))))?;

user_count 的类型将是 u64

请参阅 更多示例

(不稳定)

此项目需要Rust nightly,并使用了许多功能,其中一些是不完整的。您可能会遇到ICE。typed-qb 本身可能会进行许多破坏性更改。您可能不应该将 typed-qb 用于重要项目。

许可证

typed-qb 使用 Mozilla 公共许可证 2.0 (MPL2.0)。请参阅 LICENSE 文件。

依赖项

约 15-27MB
约 446K SLoC