#table #queries #macro #helper #help #sql-query #database

db-helpers-derive

提供各种宏以帮助进行数据库查询和表操作

6 个版本 (重大更改)

0.5.0 2022年4月8日
0.4.0 2022年3月19日
0.3.1 2022年3月13日
0.2.0 2022年3月6日
0.1.0 2022年3月3日

#86#queries


db-helpers 中使用

GPL-2.0 许可证

14KB
487

db_helpers

db_helpers 提供各种助手以简化与数据库的交互并提高安全性。
这不是一个 ORM 库,想法很简单,能够替换内联查询并开始获得好处,而不需要学习新库。

为什么我创建了 db_helpers

  • 查询中编译时检查字段名称,使常规 SQL 稍微更加安全。
  • 减少样板(为每个结构体创建 From)

功能

  • 创建表创建和索引查询。(功能标志)
  • 通过实现某些默认功能(例如行到结构的转换)来减少样板(功能标志)
  • 编译时字段名称验证
  • 有意义的错误信息

用法

use db_helpers::{Table,Q};
#[derive(Table)]
//index is optional
//__TABLE__ key is automatically replaced with table_name
#[table(name = "users", index = "create unique index if not exists unique_usernames_of_users on __TABLE__ (username)")]
struct User
{
//if name is not specified lowercase fieldname is used by default 
//q is mandatory
	#[table(name = "id", q = "bigserial primary key not null")]
	_id: i64,
	//name of this field is assumed username
	#[table( q = "text")]
	username: String,
}
#[derive(Table)]
//index is optional
#[table(name = "ops")]
struct Op{
#[table(q="bigserial not null primary key")]
id:i64,
#[table(q="bigint not null references")]
user_id:i64,
}
db.batch_execure(
//Available if pg feature is enabled
[User::__pg_create_table_str(),User::__pg_index()].join(";")
).await;
//unfortunately for the time being `<struct>::{` part cannot contain spaces smarter parsing is in the todo list
let User:User = db.query_one(Q!("select User::{_id,username} from User::__TABLE__"),params!()).await.unwrap();
db.execute(Q!("insert into ( Foo::{username} ) VALUES ($1)"),params!("superman")).await.unwrap();
//you can also use tablename.fieldname format using > in the beginning of the field
//produces `select id , users.username from users`
let User:User = db.query_one(Q!("select User::{_id,>username} from User::__TABLE__"),params!()).await.unwrap();
let ops : Vec<Op> = db
.query(Q!("select * from Op::__TABLE__ where Op::{user_id} = (select Foo::{_id} from Foo::__TABLE__ where Foo::{username} = $1)"),
params!("superman"))
.await.unwrap().iter(Into::into).collect();


//it also supports runtime args using format macro
//if no additional arguments provided Q produces a &'static str otherwise it passes everything to format! macro 
Q!(
		"select Foo::{>username} from Foo::__TABLE__ where Foo::{>_id} in ({})",
		["1", "2", "3"].join(",")
	)

错误信息

invalid_struct missing_fields no_field missing_close

如何从 0x 版本升级

请查看 变更日志 获取详细信息

待办事项

  • 允许在 Q 中使用格式宏
  • 添加对原始字符串字面量的支持
  • *- 运算符表示所有字段,但不是定义的字段 Users::{*-password}
  • 尽可能从 Rust 类型推断出 PostgreSQL 类型,使 q 参数可选
  • 更智能地解析 Q 以允许在更多位置使用空格,以及在像插入这样的位置不使用空格
  • SQLite 后端

依赖项

~1.6–7MB
~47K SLoC