Преобразование Doobie ConnectionIO[Option[Int]] без явного соответствия
У меня есть ConnectionIO[Option[Int]]
и карта над Option
производить ConnectionIO[Option[String]]
с запросом Some[Int]
в противном случае сохраните Nones. I was able to do this with a
заcomprehension and a
match`:
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]]
,
1 ответ
Было бы лучше присоединиться с использованием 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
в конце.