I've found this example from slick testing:
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
}
)
But I'm trying to create a TypeMapper for org.joda.time.DateTime to/from java.sql.Timestamp - but without much success. The Bool example is very particular and I'm having trouble adapting it. Joda Time is super common - so any help would be much appreciated.
To be clear, I'm using interpolated sql"""select colA,colB from tableA where id = ${id}""" and such. When doing a select the system works well by using jodaDate types in the implicit GetResult converter.
However, for inserts there doesn't seem to be a way to do an implicit conversion or it is ignoring the code provided below in Answer #1 - same error as before: could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(Option[Int], String, String, Option[org.joda.time.DateTime])]
I'm not using the Lifted style Slick configuration with the annotated Table objects perhaps that is why it is not finding/using the TypeMapper
I use the following in my code, which might also work for you:
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))
Edit (after your edit =^.~= ): (a bit late but I hope it still helps)
Ah, OK, since you're not using lifted embedding, you'll have to define different implicit values (as indicated by the error message from the compiler). Something like the following should work (though I haven't tried myself):
implicit val SetDateTime: SetParameter[DateTime] = new SetParameter {
def apply(d: DateTime, p: PositionedParameters): Unit =
p setTimestamp (new Timestamp(d millis))
}
For the other way round (retrieving the results of the SELECT
), it looks like you'd need to define a GetResult
:
implicit val GetDateTime: GetResult[DateTime] = new GetResult {
def apply(r: PositionedResult) = new DateTime(r.nextTimestamp getTime, UTC))
}
So, basically this is just the same as with the lifted embedding, just encoded with different types.