1

我一直在尝试使用过滤器表达式构建柴油查询,这些表达式对时间戳和时间间隔进行算术和比较。我相信使用开箱即用的柴油无法编写以下表达式。不幸的是,我采用了使用该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. 如果这不能用香草柴油写,我怎么能把它分解成一个更安全、对柴油更友好的表达式?哪些部分是自定义的,我需要实现哪些特征?
4

1 回答 1

2

我错了吗?这可以用没有自定义类型的柴油编写吗?

是的,这可以用柴油提供的方法和一些小的架构更改来编写。请参阅相应的文档

Diesel 要求您只能在时间戳中添加/减去间隔。这意味着你需要你的模式来使这成为可能:

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))

如果这不能用香草柴油写,我怎么能把它分解成一个更安全、对柴油更友好的表达方式?哪些部分是自定义的,我需要实现哪些特征?

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

于 2020-01-30T21:11:14.797 回答