#sql #inline #postgresql #prelude #opinionated #tiny #write

inline-postgres

小巧且具有意见的 postgres SQL 库

1 个不稳定版本

0.1.0 2024年6月18日

#896数据库接口

MIT 许可证

13KB
53

在您的 Rust 程序中内联编写 SQL 代码!

示例

您可以像习惯一样几乎像编写 SQL。

use inline_postgres as pg;
use pg::prelude::*;

fn main() -> Result<(), pg::Error> {
    // connect to the database
    let mut db = pg::Client::connect("host=localhost, user=postgres", pg::NoTls)?;


    // we can execute arbitrary code on the database, like creating a table.
    db.exec(stmt! {
        CREATE TABLE PERSON (
            FIRST_NAME VARCHAR(100),
            LAST_NAME  VARCHAR(100)
        )
    })?;

    
    // we can also use values from the surrounding scope to in the query like so:
    let max = 4;
    db.exec(stmt! {
        DELETE FROM PERSON
        WHERE LENGTH(LAST_NAME) > {max}
    })?;

    // note that we need to use double-quotes to write SQL string literals. 
    let given_name = "Wanda";
    db.exec(stmt! {
        INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES({given_name}, "Maximoff")
    })?;

    // to query values from the database we can use the `Client::fetch` method.
    // instead of returning a record object, the values are directly inserted into 
    // a generated struct which has all the queried fields.
    // 
    // the field names and types are written in the query like so:
    let rows = db.fetch(sql! {
        SELECT FIRST_NAME AS [name: String] FROM PERSON
    })?;

    assert_eq!(rows.len(), 1);
    assert_eq!(rows[0].name, "Wanda");

    Ok(())
}

限制

Rust 标识符解析器是为 Rust 设计的,而不是 SQL。因此,它不知道如何处理单引号定界的字符串字面量(')。

任何创建此类字符串字面量如 'Peter Parker' 的尝试都无法被 Rust 解析,并会导致编译错误。为了解决这个问题,决定使用 Rust 的双引号语法来嵌入 SQL 字符串。

安全性

如下查询 SELECT * FROM PERSON WHERE FIRST_NAME = {name} 看起来它将直接将值连接到查询中,这将是相当不安全的。幸运的是,它并没有这样做,而是像预处理语句一样运行查询,并单独传递参数。

事实上,任何使用 sql! 宏(及其相关宏)都不会导致 SQL 注入攻击。它在编译时生成 SQL 语句,因此没有任何运行时值可以偷偷进入查询。

依赖项

~9–21MB
~327K SLoC