【问题标题】:Get or Insert within a Transaction on Doobie in Scala在 Scala 中的 Doobie 上的事务中获取或插入
【发布时间】:2018-12-24 13:29:19
【问题描述】:

我正在阅读 Doobie 文档并尝试在事务中进行简单的获取或创建。我从第一个查询中获得了一个选项,并尝试执行 getOrElse 并在 else 中运行插入,但是我在 getOrElse 调用中不断收到 value map is not a member of Any。在instances 中获取现有行或创建新行并在事务中返回该结果的正确方法是什么?

import doobie._
import doobie.implicits._
import cats._
import cats.effect._
import cats.implicits._
import org.joda.time.DateTime

import scala.concurrent.ExecutionContext

case class Instance(id : Int, hostname : String)

case class User(id : Int, instanceId: Int, username : String, email : String, created : DateTime)

class Database(dbUrl : String, dbUser: String, dbPass: String) {

  implicit val cs = IO.contextShift(ExecutionContext.global)

  val xa = Transactor.fromDriverManager[IO](
    "org.postgresql.Driver", dbUrl, dbUser, dbPass
  )

  def getOrCreateInstance(hostname: String) = for {
    existingInstance <- sql"SELECT id, hostname FROM instances i WHERE i.hostname = $hostname".query[Instance].option
    ensuredInstance <- existingInstance.getOrElse(sql"INSERT INTO instances(hostname) VALUES(?)".update.withGeneratedKeys[Instance]("id", "hostname"))
  } yield ensuredInstance

}

【问题讨论】:

    标签: sql scala doobie


    【解决方案1】:

    感谢#scala/freenode 聊天室的人们,我得到了以下答案。我在这里发布它是为了完整性,如果人们有兴趣在没有其他答案的理解的情况下这样做。

      def getOrCreateInstance(hostname: String): ConnectionIO[Instance] =
            OptionT(sql"SELECT id, hostname FROM instances i WHERE i.hostname = $hostname".query[Instance].option)
              .getOrElseF(sql"INSERT INTO instances(hostname) VALUES($hostname)".update.withGeneratedKeys[Instance]("id", "hostname").compile.lastOrError)
    

    【讨论】:

      【解决方案2】:

      我相信这样的东西应该适合你,

      def getOrCreateInstance(hostname: String): ConnectionIO[Instance] = for {
        existingInstance <- sql"SELECT id, hostname FROM instances i WHERE i.hostname = $hostname".query[Instance].option
        ensuredInstance <- existingInstance.fold(sql"INSERT INTO instances(hostname) VALUES($hostname)".update.withGeneratedKeys[Instance]("id", "hostname").take(1).compile.lastOrError)(_.pure[ConnectionIO])
      } yield ensuredInstance
      

      您在哪里编译 fs2 Stream 并在现有实例已经存在的情况下将其提升到 ConnectionIO

      【讨论】:

        猜你喜欢
        • 2021-02-13
        • 1970-01-01
        • 2021-07-17
        • 2013-08-05
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        • 2013-04-19
        • 1970-01-01
        相关资源
        最近更新 更多