gpt4 book ai didi

rust - 如何使用 Diesel 根据动态参数按列有条件地排序?

转载 作者:行者123 更新时间:2023-12-03 11:39:59 27 4
gpt4 key购买 nike

我正在尝试根据外部参数为 order_by 指定不同的列。

这行得通,但是很丑:

#[macro_use]
extern crate diesel;

use crate::diesel::prelude::*;
use diesel::pg::PgConnection;

mod schema {
table! {
items (id) {
id -> Int4,
name -> Text,
}
}
}

#[derive(Queryable, Debug)]
pub struct Item {
pub id: i32,
pub name: String,
}

fn load_items(conn: PgConnection, sort_prop: String, sort_dir: String) -> Vec<Item> {
use schema::items::dsl::*;

let mut query = items.into_boxed();

// ugly: duplicating condition by sort_dir and query.order_by() calls
query = match sort_prop.as_str() {
"name" => {
if sort_dir == "asc" {
query.order_by(name.asc())
} else {
query.order_by(name.desc())
}
}
_ => {
if sort_dir == "asc" {
query.order_by(id.asc())
} else {
query.order_by(id.desc())
}
}
};

query.load::<Item>(&conn).expect("Failed to load items")
}

fn main() {}

我的 Cargo.toml 有这个:

[dependencies]
diesel = { version = "1.4.3", features = ["postgres"] }

我只想按列而不是整个查询进行条件处理,例如:

use schema::items::dsl::*;

let mut column = match sort_prop.as_str() {
"name" => name,
_ => id // error: match arms have incompatible types
}

column = if sort_dir == "asc" {
column.asc()
} else {
column.desc()
}

let results = items
.order_by(column)
.load::<Item>(connection)
.expect("Failed to load items");

这可能吗?还有其他方法可以重构吗?

我读过 Querying a Diesel table with dynamic parameters ,但它基本上是关于整个查询的条件,这是我试图避免的。

我也读过 Creating Diesel.rs queries with a dynamic number of .and()'s ,这是关于过滤器的调节。这可能接近我对 order_by 的需求,但我很难将 BoxableExpression 怪异应用到我的案例中,因为我的确切案例缺乏很好的例子文档和缺少 RLS 支持以在我的 IDE 中显示任何 schema::items::dsl::* 类型,所以我可以自己乱搞。

最佳答案

给定以下架构:

table! {
flights (id) {
id -> Int4,
name -> Text,
country -> Text,
launch_date -> Timestamptz,
}
}

以及以下包含排序选项的结构:

pub struct SearchFlight {
pub sort: Option<String>,
pub sort_dir: Option<String>
}

可以实现以下:

let mut query = flights.into_boxed();
match search.sort.as_ref().map(String::as_str) {
Some("name") => sort_by_column(query, flights_schema::name, search.sort_dir),
Some("country") => sort_by_column(query, flights_schema::country, search.sort_dir),
Some("launch_date") => sort_by_column(query, flights_schema::launch_date, search.sort_dir),
_ => query
}
query.load_page::<Flight>(con)

如果下面的函数是 sort_by_column

fn sort_by_column<U: 'static>(mut query: BoxedQuery<'static, Pg>,
column: U,
sort_dir: Option<String>) -> BoxedQuery<'static, Pg>
where U: ExpressionMethods + QueryFragment<Pg> + AppearsOnTable<flights_schema::table>{
match sort_dir.as_ref().map(String::as_str) {
Some("asc") => query.order_by(column.asc()),
Some("desc") => query.order_by(column.desc()),
_ => query
}
}

关于rust - 如何使用 Diesel 根据动态参数按列有条件地排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59291037/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com