Тип клиента Mapper для Slick SQL

Я нашел этот пример из теста slick:
https://github.com/slick/slick/blob/master/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/MapperTest.scala

sealed trait Bool
case object True extends Bool
case object False extends Bool

implicit val boolTypeMapper = MappedColumnType.base[Bool, String](
  { b =>
    assertNotNull(b)
    if(b == True) "y" else "n"
  }, { i =>
    assertNotNull(i)
    if(i == "y") True else False
  }
)

Но я пытаюсь создать TypeMapper для org.joda.time.DateTime в/из java.sql.Timestamp - но без особого успеха. Пример Bool очень специфичен, и мне сложно адаптировать его. Время Джоды очень распространено - так что любая помощь будет высоко оценена.

Чтобы быть ясным, я использую интерполированный sql "" select colA, colB from tableA, где id = ${id} "" " и тому подобное. При выполнении выбора система работает хорошо, используя типы jodaDate в неявном преобразователе GetResult.

Однако для вставок не существует способа сделать неявное преобразование или он игнорирует приведенный ниже код в ответе # 1 - ту же ошибку, что и раньше: не удалось найти неявное значение параметра pconv: scala.slick.jdbc.SetParameter [(Опция [Int], String, String, Option [org.joda.time.DateTime])]

Я не использую конфигурацию Slick Lifted Style с объектами аннотированной таблицы, возможно, поэтому не находит/не использует TypeMapper

Ответ 1

Я использую следующее в своем коде, которое также может работать для вас:

import java.sql.Timestamp
import org.joda.time.DateTime
import org.joda.time.DateTimeZone.UTC
import scala.slick.lifted.MappedTypeMapper.base
import scala.slick.lifted.TypeMapper

implicit val DateTimeMapper: TypeMapper[DateTime] = 
  base[DateTime, Timestamp](
    d => new Timestamp(d millis), 
    t => new DateTime(t getTime, UTC))

Изменить (после вашего редактирования = ^. ~ =): (немного поздно, но я надеюсь, что это все еще помогает)

А, ОК, так как вы не используете поднятое вложение, вам придется определять разные неявные значения (как указано сообщением об ошибке от компилятора). Что-то вроде следующего должно работать (хотя я сам не пробовал):

implicit val SetDateTime: SetParameter[DateTime] = new SetParameter { 
  def apply(d: DateTime, p: PositionedParameters): Unit =
    p setTimestamp (new Timestamp(d millis))
}

С другой стороны (получение результатов SELECT), похоже, вам нужно определить GetResult:

implicit val GetDateTime: GetResult[DateTime] = new GetResult {
  def apply(r: PositionedResult) = new DateTime(r.nextTimestamp getTime, UTC))
}

Итак, в основном это то же самое, что и с поднятым вложением, просто закодированным с разными типами.