Платформа игры — использование анормы с Option[LocalDate] \ Option[LocalDateTime]

Я пытаюсь определить поле даты с нулевым значением в postgres, используя anorm в качестве подключения к базе данных.

Я пытаюсь обновить запись:

def update(id: Long, startTime: Option[LocalDate]){
   SQL("""UPDATE my_table
        |SET start_date = {start_date}
        |WHERE id = {id}
      """.stripMargin)
      .on(
        'id ->id,
        'start_date -> startDate,
      ).executeUpdate()
 }

Но я получаю ошибку компиляции, похоже, что anorm не может обрабатывать Option[DateTime], хотя, когда я настроил синтаксический анализатор, он у меня работает:

val parser: RowParser[Info] = {
  get[Long]("id") ~
  get[Option[DateTime]]("start_date") map {
  case id ~ startTime => Info(id, startDate)
}

}

Что мне здесь не хватает? Спасибо!


person Tomer    schedule 16.11.2015    source источник
comment
Попробуйте добавить import JodaParameterMetaData._   -  person Lars Arnbak    schedule 16.11.2015
comment
@Lars Arnbak как насчет Option[LocalDate], нужно импортировать что-то еще?   -  person Tomer    schedule 16.11.2015
comment
или Option[LocalDateTime]   -  person Tomer    schedule 16.11.2015
comment
Возможный дубликат Миграция на anorm2.4 (с играть 2.4): ToStatement[T] и ToStatement[Option[T]]   -  person cchantep    schedule 21.11.2015
comment
@cchantep это не решило мою проблему. Вы должны добавить соответствующие неявные определения, чтобы anorm мог обрабатывать LocalDate. Я также отредактировал свое решение, включив в него класс ParameterMetaData.   -  person Tomer    schedule 22.11.2015
comment
Возможный дубликат Play + Anorm + Postgres - загрузить значение json в класс дела   -  person Tomer    schedule 26.11.2015


Ответы (2)


Я добавил свои собственные неявные определения:

implicit def rowToLocalDate: Column[LocalDate] = Column.nonNull {(value, meta) =>
   val MetaDataItem(qualified, nullable, clazz) = meta
   value match {
      case ts: java.sql.Timestamp => Right(new LocalDate(ts.getTime))
      case d: java.sql.Date => Right(new LocalDate(d.getTime))
      case str: java.lang.String => Right(fmt.parseLocalDate(str))
      case _ => Left(TypeDoesNotMatch("Cannot convert " + value + ":" + value.asInstanceOf[AnyRef].getClass) )
}

}

implicit val localDateToStatement = new ToStatement[LocalDate] {
    def set(s: java.sql.PreparedStatement, index: Int, aValue: LocalDate): Unit = {
       s.setTimestamp(index, new java.sql.Timestamp(aValue.toDateTimeAtStartOfDay().getMillis()))
}

}

И соответствующие ParameterMetaData

implicit object LocalDateClassMetaData extends  ParameterMetaData[LocalDate] {
   val sqlType = ParameterMetaData.DateParameterMetaData.sqlType
   val jdbcType = ParameterMetaData.DateParameterMetaData.jdbcType
}

Это сделало трюк

person Tomer    schedule 16.11.2015
comment
Да, это сработает. Однако вы должны уметь делать val parser: RowParser[Info] = { import JodaParameterMetaData._ get[Long]("id") ~ get[Option[DateTime]]("start_date") map { case id ~ startTime => Info(id, startDate) } и иметь нужные вам типы. - person Lars Arnbak; 16.11.2015

Связанный вопрос, Anorm сравнение/поиск по java.time LocalDateTime что это у меня сработало просто обновление до новой версии (еще не выпущенной)

person ses    schedule 04.11.2016