如何在 Rust Diesel 中使用时间戳和间隔进行算术运算

How to do arithmetic with timestamps and intervals in Rust Diesel

我一直在尝试使用过滤器表达式构建柴油查询,这些过滤器表达式对时间戳和时间间隔进行算术和比较。我相信使用开箱即用的柴油机无法编写以下表达式。不幸的是,我采用了使用 sql(...) 函数的大锤方法:

let query = videos::table
    .inner_join(events::table)
    .filter(sql(r#""events"."start_date" <= NOW() + interval '60 seconds'"#))
    .filter(sql(r#""events"."start_date" + ("videos"."duration" * interval '1 second') > NOW()"#))

我的(缩写)模式:

table! {
    events (id) {
        id -> Int4,
        video_id -> Int4,
        start_date -> Timestamp,
    }
}

table! {
    videos (id) {
        id -> Int4,
        duration -> Float4,
    }
}

我的问题:

  1. 我错了吗?这可以用没有自定义类型的柴油编写吗?
  2. 如果这不能用原版柴油编写,我如何才能将其分解为类型更安全、对柴油更友好的表达式?哪些部分是自定义的,我需要实现哪些特征?

Am I wrong? Can this be written in diesel with no custom types?

是的,这可以用 diesel 提供的方法和一些小的架构更改来编写。见对应的documentation

Diesel 要求您只能 add/substract 间隔时间戳。这意味着您需要一点架构才能使这成为可能:

table! {
    videos (id) {
        id -> Int4,
        duration -> Interval,
    }
}

你的查询是这样写的:

let query = videos::table
    .inner_join(events::table)
    .filter(events::start_date.le(now + 60.seconds()))
    .filter(now.lt(events::start_date + videos::duration))

If this cannot be written in vanilla diesel, how can I break this up into a more type-safe, diesel-friendly expression? Which parts are custom and what traits do I need to implement?

理论上应该可以在柴油之外实施。该代码很可能与用于在柴油机中实现的代码相同。可能您需要使用本地类型和更具体的实现。因此,如果您不能更改 videos::duration 的类型,那么沿着这条路走下去可能是有意义的。