用于组合各种形状的编译查询的Scala Slick策略

时间:2017-07-25 13:06:11

标签: scala slick slick-pg

我正在使用postgresql 9.6,光滑的3.2并且已连接slick-pg

我正在Scala中实现graphql后端,我需要实现查询来解析各种形状的GraphQL游标。输入的形状是可枚举的。影响查询的一些输入可能是:

  • 用户可选择的订购。
  • 各种过滤条件(全文搜索,日期范围等)。
  • 在向后或向前遍历之间进行选择。

我当前的简单游标将后向和前向硬编码为已编译的查询。两者都具有相同的形状,我使用标准的光滑抽象来分解重用的共性(带有操作的值类,“实体”表的继承层次结构和代码生成)。但是仍然有很多样板,除非我将它们全部列出,否则它不会扩展到更加动态的形状。

这是使用此模式的类的摘录:

private [shard] class SchemaAllTypeCursor(shard: SlickShard) extends CursorSpec[TypeModel] {
  import shard.PostgresProfile.api._
  private val forwardQC = Compiled { (tenantIdUrls: Rep[List[String]], low: Rep[Long], take: ConstColumn[Long]) =>
    Queries.listTypesByTenantIds(tenantIdUrls).forwardCursorById(low, take)
  }
  private val backwardQC = Compiled { (tenantIdUrls: Rep[List[String]], high: Rep[Long], take: ConstColumn[Long]) =>
    Queries.listTypesByTenantIds(tenantIdUrls).backwardCursorById(high, take)
  }

  def executor(tenantIdUrls: List[String])(c: CursorRequest)(implicit req: Req[_]): Observable[TypeModel] = {
    implicit val ec = req.ctx.ec
    Observable fromFuture {
      shard.db.run {
        if (c.forward) forwardQC(tenantIdUrls, c.base, c.take).result
        else backwardQC(tenantIdUrls, c.base, c.take).result
      } flatMap materializeAllTypes(req.ctx, tenantIdUrls)
    } flatMap Observable.fromIterable
  }
}

总的问题是如何在没有大量样板的情况下获得针对此用例的编译查询?我想获得的一些见解是:

  1. 我有什么抽象来编写部分查询?在上面的示例中,backwardCursorByIdforwardCursorById是查询的一部分。我希望能够从部件构建编译函数并以某种方式缓存它们....
  2. 如何在已编译的函数中使用记录类型? (在光滑的文档中暗示这是可能的,但我找不到示例)。
  3. 有没有办法缓存已编译的查询而不列出它们? - 据我所知。如果我在上面的执行程序函数中编译一个函数,它将在执行函数的每个函数调用上重复编译。
  4. 我愿意使用slick-pg支持的postgres特定类型。

0 个答案:

没有答案