在没有显式匹配的情况下转换 Doobie ConnectionIO[Option[Int]]
Transforming Doobie ConnectionIO[Option[Int]] without explicit match
我有一个 ConnectionIO[Option[Int]]
并映射到 Option
以生成带有查询 Some[Int]
的 ConnectionIO[Option[String]]
否则保留 Nones. I was able to do this with a
forcomprehension and a
匹配`:
def findWidgetByOwner(name: String): ConnectionIO[Option[String]] = for {
opt <- sql"SELECT owner_id FROM owners WHERE name = $name".query[Int].option
widget <- opt match {
case None => None.pure[ConnectionIO]
case Some(id) => sql"SELECT widget_name FROM widgets WHERE owner_id = $id".query[String].option
}
} yield widget
我知道我被 ConnectionIO
容器绊倒了,但我找不到更清晰的映射方法来将 ConnectionIO[Option[Int]]
转换为 ConnectionIO[Option[String]]
。
使用 SQL 而不是 scala 加入会更干净:
def findWidgetByOwner(name: String): ConnectionIO[Option[String]] =
sql"""
SELECT widgets.widget_name FROM widgets WHERE owner_id = $id
INNER JOIN owners ON widgets.owner_id = owners.owner_id
WHERE owners.name = $name
""".query[Int].option
但是如果你想清理原来的,sequence
的一些咒语可能会起作用(未测试):
import cats._, cats.data._, cats.implicits._
...
widget <- opt.map {id =>
sql"SELECT widget_name FROM widgets WHERE owner_id = $id".query[String].unique
}.sequence
注意:你必须把query[String].option
改成.query[String].unique
否则widget
就变成了Option[Option[String]]
如果小部件查询可以为空,可能是可取的,但最后需要一个 .flatten
。
我有一个 ConnectionIO[Option[Int]]
并映射到 Option
以生成带有查询 Some[Int]
的 ConnectionIO[Option[String]]
否则保留 Nones. I was able to do this with a
forcomprehension and a
匹配`:
def findWidgetByOwner(name: String): ConnectionIO[Option[String]] = for {
opt <- sql"SELECT owner_id FROM owners WHERE name = $name".query[Int].option
widget <- opt match {
case None => None.pure[ConnectionIO]
case Some(id) => sql"SELECT widget_name FROM widgets WHERE owner_id = $id".query[String].option
}
} yield widget
我知道我被 ConnectionIO
容器绊倒了,但我找不到更清晰的映射方法来将 ConnectionIO[Option[Int]]
转换为 ConnectionIO[Option[String]]
。
使用 SQL 而不是 scala 加入会更干净:
def findWidgetByOwner(name: String): ConnectionIO[Option[String]] =
sql"""
SELECT widgets.widget_name FROM widgets WHERE owner_id = $id
INNER JOIN owners ON widgets.owner_id = owners.owner_id
WHERE owners.name = $name
""".query[Int].option
但是如果你想清理原来的,sequence
的一些咒语可能会起作用(未测试):
import cats._, cats.data._, cats.implicits._
...
widget <- opt.map {id =>
sql"SELECT widget_name FROM widgets WHERE owner_id = $id".query[String].unique
}.sequence
注意:你必须把query[String].option
改成.query[String].unique
否则widget
就变成了Option[Option[String]]
如果小部件查询可以为空,可能是可取的,但最后需要一个 .flatten
。