предоставить экземпляр Get для Seq - PullRequest
3 голосов
/ 07 ноября 2019

Например, у меня есть несколько сущностей с некоторыми параметрами и две таблицы базы данных, представляющие эти сущности:

 entity                 param
╔════╦═════════╗       ╔═══════════╦════════╗
║ id ║ name    ║       ║ entity_id ║ value  ║
╠════╬═════════╣       ╠═══════════╬════════╣
║ 1  ║ "One"   ║       ║ 1         ║ "aaa"  ║
║ 2  ║ "Two"   ║       ║ 1         ║ "bbb"  ║
║ 3  ║ "Three" ║       ║ 1         ║ "ccc"  ║
╚════╩═════════╝       ╚═══════════╩════════╝

И модель scala:

case class Entity(id: Long, name: String, params: Seq[String])

И я хочуполучить эти данные через Doobie, но я не могу сделать это напрямую с экземпляром Entity, потому что params - это последовательность строк, а не просто строка:

val sql = sql"select e.id, e.name, p.value from entity e left join param p on e.id = p.entity_id"

sql.query[Entity].to[Seq]   //Error Cannot find or construct a Read instance for type: Entity

Где-нибудьтрюк для предоставления Get экземпляра для Seq?

Если нет, то какой способ, Doobie предлагает получить такие данные:

  1. Записывать примитивы вместо Entity введите:
    sql.query[(Long, String, String)].to[Seq] и скомпонуйте этот Seq кортежей с экземпляром Entity.
    Потенциально не удобно, потому что в таблицах может быть много столбцов, что приводит к копированию этого длинного кортежа в каждый новыйquery.
  2. Составьте эти примитивы для аннотаций классов дел:
    case class EntityRow(id: Long, name: String)
    case class ParamRow(value: String)
    sql.query[(EntityRow, ParamRow)].to[Seq] и составьте для экземпляра Entity, как в 1..
  3. Как и 2., но с использованием HNil:
    val entity = Long :: String :: HNil
    val param = String :: HNil
    sql.query[entity ++ param].to[Seq] и составление в Entityнапример, как 1..
    Я не знаю никаких преимуществ или недостатков этого способа, так как shapeless для меня новость.
  4. Извлечение данных двумя отдельными запросами:
    val entities = sql"select id, name from entity".query[EntityRow].to[Seq]
    val params = sql"select value from param".query[ParamRow].to[Seq]
    Скорее всего, не такой, как с помощью одного запроса.
  5. Как-нибудь иначе?

Спасибо.

...