1 个不稳定版本
0.1.0 | 2024年6月18日 |
---|
#896 在 数据库接口
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