Универсальное чтение scala-cass из таблицы cassandra в качестве класса case

Я пытаюсь использовать scala-cass для чтения из cassandra и преобразования набора результатов в класс case с использованием resultSet.as[CaseClass]. Это прекрасно работает при выполнении следующего.

import com.weather.scalacass.syntax._    
case class TestTable(id: String, data1: Int, data2: Long)
val resultSet = session.execute(s"select * from test.testTable limit 10")
resultSet.one.as[TestTable]

Теперь я пытаюсь сделать это более общим, и я не могу найти правильное ограничение типа для универсального класса.

import com.weather.scalacass.syntax._    
case class TestTable(id: String, data1: Int, data2: Long)

abstract class GenericReader[T] {
  val table: String
  val keyspace: String

  def getRows(session: Session): T = {
    val resultSet = session.execute(s"select * from $keyspace.$table limit 10")
    resultSet.one.as[T]
  }
}

Я реализую этот класс с желаемым классом case и пытаюсь вызвать getRows для созданного объекта.

object TestTable extends GenericReader[TestTable] {
  val keyspace = "test"
  val table = "TestTable"
}

TestTable.getRows(session)

Это вызывает исключение could not find implicit value for parameter ccd: com.weather.scalacass.CCCassFormatDecoder[T].

Я пытаюсь добавить ограничение типа в GenericReader, чтобы убедиться, что неявное преобразование будет работать. Однако я не могу найти правильный тип. Я пытаюсь прочитать scala-cass, чтобы найти правильное ограничение, но пока мне не повезло.

Я также был бы рад использовать любую другую библиотеку, которая может достичь этого.


person Alex Naspo    schedule 26.06.2017    source источник


Ответы (2)


Похоже, что as[T] требует неявного значения, которого у вас нет в области видимости, поэтому вам также потребуется этот неявный параметр в методе getRows.

def getRows(session: Session)(implicit cfd: CCCassFormatDecoder[T]): T

Вы можете выразить это как ограничение типа (то, что вы искали в исходном вопросе), используя границы контекста:

abstract class GenericReader[T:CCCassFormatDecoder]
person Sander Hartlage    schedule 26.06.2017

Вместо того, чтобы пытаться связать ваш общий тип T, может быть проще просто передать отсутствующий неявный параметр:

abstract class GenericReader[T](implicit ccd: CCCassFormatDecoder[T]) {
  val table: String
  val keyspace: String

  def getRows(session: Session): T = {
    val resultSet = session.execute(s"select * from $keyspace.$table limit 10")
    resultSet.one.as[T]
  }
}

Затем поиск конкретного значения для этого неявного значения можно отложить, когда вы сузите этот T до определенного класса (например, object TestTable extends GenericReader[TestTable])

person Joe K    schedule 26.06.2017