2
votes

I am trying to write a Mapper that would convert Option[sql.Date] to Option[sql.Timestamp]. For this, I am using the following code:

package model.db

import java.sql.Date

import com.typesafe.slick.driver.ms.SQLServerDriver.simple._

abstract class RichTable[T](tag: Tag, name: String, schema: Option[String] = Some("dbo")) extends Table[T](tag, schema, name) {
  def id: Column[Option[Long]] = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
  def cancelled: Column[Option[Date]] = column[Option[Date]]("cancelled")(DateMapper.sqlDate2SqlTimestampOptionMapper)
}

abstract class LoggableTable[T](tag: Tag, name: String, schema: Option[String] = Some("dbo")) extends RichTable[T](tag, name, schema) {
  def createdAt: Column[Date] = column[Date]("created_at", O.NotNull)(DateMapper.sqlDate2SqlTimestampMapper)
}

object DateMapper {
  val sqlDate2SqlTimestampMapper = MappedColumnType.base[java.sql.Date, java.sql.Timestamp](
    { sqlDate => new java.sql.Timestamp(sqlDate.getTime) },
    { sqlTimestamp => new java.sql.Date(sqlTimestamp.getTime) })

  val sqlDate2SqlTimestampOptionMapper = MappedColumnType.base[scala.Option[java.sql.Date], scala.Option[java.sql.Timestamp]](
    { sqlDate => scala.Some(new java.sql.Timestamp(sqlDate.get.getTime)) },
    { sqlTimestamp => scala.Some(new java.sql.Date(sqlTimestamp.get.getTime)) })
} 

The sqlDate2SqlTimestampMapper works fine, so I used it as a base code for the sqlDate2SqlTimestampOptionMapper.

When I try to compile, I get the following error:

Error:(21, 126) could not find implicit value for evidence parameter of type com.typesafe.slick.driver.ms.SQLServerDriver.BaseColumnType[Option[java.sql.Timestamp]] val sqlDate2SqlTimestampOptionMapper = MappedColumnType.base[scala.Option[java.sql.Date], scala.Option[java.sql.Timestamp]](

Error:(21, 126) not enough arguments for method base: (implicit evidence$5: scala.reflect.ClassTag[Option[java.sql.Date]], implicit evidence$6: com.typesafe.slick.driver.ms.SQLServerDriver.BaseColumnType[Option[java.sql.Timestamp]])com.typesafe.slick.driver.ms.SQLServerDriver.BaseColumnType[Option[java.sql.Date]]. Unspecified value parameter evidence$6. val sqlDate2SqlTimestampOptionMapper = MappedColumnType.base[scala.Option[java.sql.Date], scala.Option[java.sql.Timestamp]](

How can I fix this?

Thank you in advance.

2

2 Answers

2
votes

You do not need option mapper. Remove this piece of code.

val sqlDate2SqlTimestampOptionMapper = MappedColumnType.base[scala.Option[java.sql.Date], scala.Option[java.sql.Timestamp]](
    { sqlDate => scala.Some(new java.sql.Timestamp(sqlDate.get.getTime)) },
    { sqlTimestamp => scala.Some(new java.sql.Date(sqlTimestamp.get.getTime)) })

Now your date mapper becomes

object DateMapper {
  val sqlDate2SqlTimestampMapper = MappedColumnType.base[java.sql.Date, java.sql.Timestamp](
    { sqlDate => new java.sql.Timestamp(sqlDate.getTime) },
    { sqlTimestamp => new java.sql.Date(sqlTimestamp.getTime) })
}

In Slick if you give mapping for some T then you need not implement mapping for Option[T]

0
votes

Just like @pamu said, there is no need for a mapper for an Option. The stacktrace was complaining for a implicit value; so what I did was make the mapper implict, and the problem was solved.

package model.db

import java.sql.Date

import com.typesafe.slick.driver.ms.SQLServerDriver.simple._

abstract class RichTable[T](tag: Tag, name: String, schema: Option[String] = Some("dbo")) extends Table[T](tag, schema, name) {
  def id: Column[Option[Long]] = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
  def cancelled: Column[Option[Date]] = column[Option[Date]]("cancelled")
}

abstract class LoggableTable[T](tag: Tag, name: String, schema: Option[String] = Some("dbo")) extends RichTable[T](tag, name, schema) {
  def createdAt: Column[Date] = column[Date]("created_at", O.NotNull)
}

object DateMapper {
  implicit val sqlDate2SqlTimestampMapper = MappedColumnType.base[java.sql.Date, java.sql.Timestamp](
    { sqlDate => new java.sql.Timestamp(sqlDate.getTime) },
    { sqlTimestamp => new java.sql.Date(sqlTimestamp.getTime) })
}