上下文:rust、sqlx 库
问题:如何在不丢失类型检查的情况下从较小的部分组成类似的查询?
macro_rules! select {
() => {"select col from tab"}
}
macro_rules! guard1 {
() => {"where col > 1"}
}
macro_rules! guard2 {
() => {"where col > 2"}
}
let mut conn = get_pg_connection_from_somewhere();
if some_condition() {
sqlx::query!(select!() + guard1!()).fetch_all(&mut conn).await?;
} else {
sqlx::query!(select!() + guard2!()).fetch_all(&mut conn).await?;
}
Run Code Online (Sandbox Code Playgroud)
文档说:
查询必须是字符串文字,或使用 + 连接字符串文字(对于宏生成的查询很有用),否则它无法进行内省(因此不能是动态的或另一个宏的结果)。
你可以看到它说“对于宏生成的查询有用”(尽管后来“不能是另一个宏的结果”)
我想解决的问题是,根据条件,我想运行不同但相似的(例如它们都具有相同的列)查询,并且我想从较小的可重用部分组成查询[
小智 2
您可以使用如下宏来完成此操作
macro_rules! fetch_all_todos_with_predicate {
($executor:ident, $predicate:tt) => {
sqlx::query!(
"SELECT id, title, completed_at FROM todos " + $predicate
).fetch_all($executor).await
}
}
Run Code Online (Sandbox Code Playgroud)
并根据某些条件提供谓词
let kind = QueryKind::Complete;
let mut conn = get_pg_connection_from_somewhere();
let result = match kind {
QueryKind::Complete => fetch_all_todos_with_predicate!(conn, "WHERE completed_at IS NOT NULL"),
QueryKind::Incomplete => fetch_all_todos_with_predicate!(conn, "WHERE completed_at IS NULL"),
QueryKind::All => fetch_all_todos_with_predicate!(conn, ""),
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2158 次 |
| 最近记录: |