Как добавить дополнительный неявный экстрактор в Play 2.1.4 и использовать его?

Я использую Play 2.1.4 против базы данных postgresql. В базе данных postgresql я использую uuid в качестве типа данных pk, который соответствует java.util.UUID. Функция SqlParser.getT в стандарте не имеет неявного экстрактора для java.util.UUID. Это имеет смысл, потому что я не думаю, что многие люди его используют; однако я не могу найти инструкции о том, как я могу его добавить. Кто-нибудь знает, как добавить дополнительный неявный экстрактор в anorm.SqlParser в Play?

Ошибка, которую я получаю, приведена ниже:

не удалось найти неявное значение для экстрактора параметров: anorm.Column[java.util.UUID]

Я действительно новичок в Scala и Play, поэтому, если мой подход совершенно неверен, дайте мне знать, но мне бы очень хотелось иметь возможность сделать что-то вроде того, что вы видите ниже.

case class App(appId: UUID, appName: String, appServerName: String,
               appComponent: String, appDescription: String,
               appDateCreated: DateTime, appDateModified: DateTime,
               appValidated: Boolean)

val app = {
    get[UUID]("app_id") ~
    get[String]("app_name") ~
    get[String]("app_server_name") ~
    get[String]("app_component") ~
    get[String]("app_description") ~
    get[java.util.Date]("app_date_created") ~
    get[java.util.Date]("app_date_modified") ~
    get[Boolean]("app_validated") map {
      case id ~ name ~ serverName ~ component ~ description ~ dateCreated ~
        dateModified ~ validated  => App(id, name, serverName, component,
      description, new DateTime(dateCreated.getTime),
        new DateTime(dateModified.getTime), validated)
    }
  }

def all(): List[App] = DB.withConnection { implicit conn =>
  SQL("SELECT * FROM apps").as(app *)
}

person smashedtoatoms    schedule 16.09.2013    source источник
comment
Этот ответ должен помочь вам начать работу, хотя он о преобразовании JodaTime.   -  person maba    schedule 17.09.2013


Ответы (2)


Возможно, этот пост будет полезен. (Используется в моем проекте. Работает нормально)

 /**
   * Attempt to convert a SQL value into a UUID
   *
   * @param value value to convert
   * @return UUID
   */
  private def valueToUUIDOption(value: Any): Option[UUID] = {
    try {
      valueToByteArrayOption(value) match {
        case Some(bytes) => Some(UUIDHelper.fromByteArray(bytes))
        case _ => None
      }
    }
    catch {
      case e: Exception => None
    }
  }
/**
   * Implicit conversion from UUID to anorm statement value
   */
  implicit def uuidToStatement = new ToStatement[UUID] {
    def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
  }
 /**
   * Implicit converstion from anorm row to uuid
   */
  implicit def rowToUUID: Column[UUID] = {
    Column.nonNull[UUID] { (value, meta) =>
      val u = UUID.fromString(value.toString)
      val MetaDataItem(qualified, nullable, clazz) = meta
      valueToUUIDOption(value) match {
        case Some(uuid) => Right(uuid)
        case _ => Left(TypeDoesNotMatch("Cannot convert " + value + ":" + value.asInstanceOf[AnyRef].getClass + " to UUID for column " + qualified))
      }
    }
  }
person r.piesnikowski    schedule 17.09.2013
comment
Вы джентльмен и ученый. Это сработало отлично. Мне пришлось немного изменить его, потому что я использую его с postgresql, который возвращает UUID как тип данных вместо массива байтов; однако, просмотр вашего кода дал мне ОГРОМНУЮ возможность понять, как делать то, что я хотел сделать, и теперь я могу использовать любую БД, и это фантастика. Большое спасибо. - person smashedtoatoms; 17.09.2013
comment
@jlegler - ТАК место для помощи другим;) - person r.piesnikowski; 18.09.2013

Вот упрощенный вариант ответа @r.piesnikowski для драйвера JDBC, который возвращает java.util.UUID, как это делает PostgreSQL:

  /**
   * Implicit conversion from UUID to Anorm statement value
   */
  implicit def uuidToStatement = new ToStatement[UUID] {
    def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
  }

  /**
   * Implicit conversion from Anorm row to UUID
   */
  implicit def rowToUUID: Column[UUID] = {
    Column.nonNull[UUID] { (value, meta) =>
      value match {
        case v: UUID => Right(v)
        case _ => Left(TypeDoesNotMatch(s"Cannot convert $value:${value.asInstanceOf[AnyRef].getClass} to UUID for column ${meta.column}"))
      }
    }
  }
person Alex Zolotko    schedule 31.10.2013
comment
Ваша версия мне подходит, в отличие от версии @r.piesnikowski. Есть ли между ними разница? - person アレックス; 31.12.2013