Как кодировать/декодировать временную метку для json в цирке?

При использовании circe в slick для получения данных в json я мог получить данные без полей date(Timestamp/DateTime) в Entities. Но когда я использую поля Timestamp в Entities, возникает ошибка:

[error] /var/www/html/scala-api/src/main/scala/oc/api/http/routes/TestApi.scala:40: could not find implicit value for parameter encoder: io.circe.Encoder[Seq[oc.api.models.UserEntity]]
[error]             auth => complete(userDao.getAll().map(_.asJson))

Вот код, который я использовал для Slick Entities и CIRCE для кодирования json.

Базовая таблица:

abstract class BaseTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def createdAt = column[Timestamp]("created_at")
  def updatedAt = column[Timestamp]("updated_at")
  def deletedAt = column[Timestamp]("deleted_at")
}

Базовая сущность:

trait BaseEntity {
  val id : Long
  def isValid : Boolean = true
}

UserEntity: createdAt генерирует ошибку кодировщика

case class UserEntity(id: Long, email: String, password: String, createdAt: Timestamp) extends BaseEntity

UserEntity: работает отлично

case class UserEntity(id: Long, email: String, password: String) extends BaseEntity

UserTable(Slick):

object UserTables {

  class UserTable(tag : Tag) extends BaseTable[UserEntity](tag, "users") {
    def name = column[String]("name")
    def password = column[String]("password")
    def * = (id, name, password) <> (UserEntity.tupled, UserEntity.unapply)
  }

  implicit val accountsTableQ : TableQuery[UserTable] = TableQuery[UserTable]
}

Я что-то упустил в коде? Любая помощь будет высоко оценен.


person Sujit Baniya    schedule 02.01.2017    source источник


Ответы (1)


Вы должны использовать собственный кодировщик и декодер для своего кода, что-то вроде этого:

  implicit val TimestampFormat : Encoder[Timestamp] with Decoder[Timestamp] = new Encoder[Timestamp] with Decoder[Timestamp] {
    override def apply(a: Timestamp): Json = Encoder.encodeLong.apply(a.getTime)

    override def apply(c: HCursor): Result[Timestamp] = Decoder.decodeLong.map(s => new Timestamp(s)).apply(c)
  }

Поместите это значение в любой код, необходимый для кодирования/декодирования временных меток. Например, вы можете поместить его в объект и импортировать объект туда, где это необходимо.

person C4stor    schedule 05.01.2017
comment
Я попытался добавить таблицу n как объект UserTables { class UserTable(tag : Tag) extends BaseTable[UserEntity](tag, users) { def updated_at = column[Option[String]](updated_at) def * = (..., updated_at ) ‹› (...) } неявный val TimestampFormat : Encoder[Timestamp] with Decoder[Timestamp] = new Encoder[Timestamp] with Decoder[Timestamp] { override def apply(a: Timestamp): Json = Encoder.encodeLong.apply (a.getTime) override def apply(c: HCursor): Result[Timestamp] = Decoder.decodeLong.map(s => new Timestamp(s)).apply(c) } } Но как и раньше получил ошибку кодировщика - person Sujit Baniya; 05.01.2017
comment
Вы должны поместить val в область, где фактически выполняется кодирование/декодирование (так что, возможно, где-то рядом с кодом, связанным с http?), а не в классах sql! - person C4stor; 06.01.2017
comment
При декодировании, как я могу использовать DateTimeFormat, т.е. Y-m-d H:i:s для декодирования вместо decodeLong - person Sujit Baniya; 06.01.2017
comment
Вы можете использовать decodeString.map(s =› function(s)), где функция должна быть функцией для преобразования строки, которая у вас есть в Timestamp (используя DateTimeFormat в процессе, я полагаю). - person C4stor; 06.01.2017
comment
Ваше здоровье! decodeString.map(s => new Timestamp(timestampFormatter.parse(s).getTime)).apply(c) работал - person Sujit Baniya; 06.01.2017