Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add raw joda time encoding to quill-async #837

Merged
merged 1 commit into from
Jul 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.getquill.context.async.mysql
import java.time.{ LocalDate, LocalDateTime }

import io.getquill.context.sql.EncodingSpec
import org.joda.time.{ LocalDate => JodaLocalDate, LocalDateTime => JodaLocalDateTime }

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
Expand Down Expand Up @@ -85,21 +86,21 @@ class MysqlAsyncEncodingSpec extends EncodingSpec {
()
}

"decode local date types" in {
case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDate, v3: LocalDate)
val entity = DateEncodingTestEntity(LocalDate.now, LocalDate.now, LocalDate.now)
"decode joda LocalDate and LocalDateTime types" in {
case class DateEncodingTestEntity(v1: JodaLocalDate, v2: JodaLocalDateTime)
val entity = DateEncodingTestEntity(JodaLocalDate.now, JodaLocalDateTime.now)
val r = for {
_ <- testContext.run(query[DateEncodingTestEntity].delete)
_ <- testContext.run(query[DateEncodingTestEntity].insert(lift(entity)))
result <- testContext.run(query[DateEncodingTestEntity])
} yield result
Await.result(r, Duration.Inf) must contain(entity)
Await.result(r, Duration.Inf)
}

"decode local date time types" in {
case class DateEncodingTestEntity(v1: LocalDateTime, v2: LocalDateTime, v3: LocalDateTime)
"decode LocalDate and LocalDateTime types" in {
case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDateTime, v3: LocalDateTime)
//since localdatetime is converted to joda which doesn't store nanos need to zero the nano part
val entity = DateEncodingTestEntity(LocalDate.now().atStartOfDay(), LocalDateTime.now.withNano(0), LocalDateTime.now.withNano(0))
val entity = DateEncodingTestEntity(LocalDate.now(), LocalDateTime.now.withNano(0), LocalDateTime.now.withNano(0))
val r = for {
_ <- testContext.run(query[DateEncodingTestEntity].delete)
_ <- testContext.run(query[DateEncodingTestEntity].insert(lift(entity)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ trait ArrayDecoders extends ArrayEncoding {
implicit def arrayDateDecoder[Col <: Seq[Date]](implicit bf: CBF[Date, Col]): Decoder[Col] = arrayDecoder[JodaLocalDateTime, Date, Col](_.toDate)
implicit def arrayLocalDateTimeJodaDecoder[Col <: Seq[JodaLocalDateTime]](implicit bf: CBF[JodaLocalDateTime, Col]): Decoder[Col] = arrayRawEncoder[JodaLocalDateTime, Col]
implicit def arrayLocalDateJodaDecoder[Col <: Seq[JodaLocalDate]](implicit bf: CBF[JodaLocalDate, Col]): Decoder[Col] = arrayRawEncoder[JodaLocalDate, Col]
implicit def arrayLocalDateDecoder[Col <: Seq[LocalDate]](implicit bf: CBF[LocalDate, Col]): Decoder[Col] =
arrayDecoder[JodaLocalDate, LocalDate, Col](d => LocalDate.of(d.getYear, d.getMonthOfYear, d.getDayOfMonth))
implicit def arrayLocalDateDecoder[Col <: Seq[LocalDate]](implicit bf: CBF[LocalDate, Col]): Decoder[Col] = arrayDecoder[JodaLocalDate, LocalDate, Col](decodeLocalDate.f)

def arrayDecoder[I, O, Col <: Seq[O]](mapper: I => O)(implicit bf: CBF[O, Col], iTag: ClassTag[I], oTag: ClassTag[O]): Decoder[Col] =
AsyncDecoder[Col](SqlTypes.ARRAY)(new BaseDecoder[Col] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ trait ArrayEncoders extends ArrayEncoding {
implicit def arrayDateEncoder[Col <: Seq[Date]]: Encoder[Col] = arrayRawEncoder[Date, Col]
implicit def arrayLocalDateTimeJodaEncoder[Col <: Seq[JodaLocalDateTime]]: Encoder[Col] = arrayRawEncoder[JodaLocalDateTime, Col]
implicit def arrayLocalDateJodaEncoder[Col <: Seq[JodaLocalDate]]: Encoder[Col] = arrayRawEncoder[JodaLocalDate, Col]
implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayRawEncoder[LocalDate, Col]
implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayEncoder[LocalDate, Col](encodeLocalDate.f)

def arrayEncoder[T, Col <: Seq[T]](mapper: T => Any): Encoder[Col] =
encoder[Col]((col: Col) => col.toIndexedSeq.map(mapper), SqlTypes.ARRAY)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.getquill.context.async.postgres

import java.time.LocalDate
import java.time.{ LocalDate, LocalDateTime }

import io.getquill.context.sql.encoding.ArrayEncodingBaseSpec
import org.joda.time.{ LocalDate => JodaLocalDate, LocalDateTime => JodaLocalDateTime }
Expand Down Expand Up @@ -30,6 +30,16 @@ class ArrayAsyncEncodingSpec extends ArrayEncodingBaseSpec {
actual.dates mustBe jE.dates
}

"Java8 times" in {
case class Java8Times(timestamps: Seq[LocalDateTime], dates: Seq[LocalDate])
val jE = Java8Times(Seq(LocalDateTime.now()), Seq(LocalDate.now()))
val jQ = quote(querySchema[Java8Times]("ArraysTestEntity"))
await(ctx.run(jQ.insert(lift(jE))))
val actual = await(ctx.run(jQ)).head
actual.timestamps mustBe jE.timestamps
actual.dates mustBe jE.dates
}

"Support Traversable encoding basing on MappedEncoding" in {
val wrapQ = quote(querySchema[WrapEntity]("ArraysTestEntity"))
await(ctx.run(wrapQ.insert(lift(wrapE))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.getquill.context.async.postgres
import java.time.{ LocalDate, LocalDateTime }

import io.getquill.context.sql.EncodingSpec
import org.joda.time.{ LocalDate => JodaLocalDate, LocalDateTime => JodaLocalDateTime }

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
Expand Down Expand Up @@ -87,20 +88,20 @@ class PostgresAsyncEncodingSpec extends EncodingSpec {
success must not be empty
}

"encodes localdate type" in {
case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDate)
val entity = DateEncodingTestEntity(LocalDate.now, LocalDate.now)
"decode joda LocalDate and LocalDateTime types" in {
case class DateEncodingTestEntity(v1: JodaLocalDate, v2: JodaLocalDateTime)
val entity = DateEncodingTestEntity(JodaLocalDate.now, JodaLocalDateTime.now)
val r = for {
_ <- testContext.run(query[DateEncodingTestEntity].delete)
_ <- testContext.run(query[DateEncodingTestEntity].insert(lift(entity)))
result <- testContext.run(query[DateEncodingTestEntity])
} yield result
Await.result(r, Duration.Inf) must contain(entity)
Await.result(r, Duration.Inf)
}

"encodes localdatetime type" in {
case class DateEncodingTestEntity(v1: LocalDateTime, v2: LocalDateTime)
val entity = DateEncodingTestEntity(LocalDateTime.now, LocalDateTime.now)
"decode LocalDate and LocalDateTime types" in {
case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDateTime)
val entity = DateEncodingTestEntity(LocalDate.now, LocalDateTime.now)
val r = for {
_ <- testContext.run(query[DateEncodingTestEntity].delete)
_ <- testContext.run(query[DateEncodingTestEntity].insert(lift(entity)))
Expand Down
56 changes: 19 additions & 37 deletions quill-async/src/main/scala/io/getquill/context/async/Decoders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,42 +123,24 @@ trait Decoders {

implicit val byteArrayDecoder: Decoder[Array[Byte]] = decoder[Array[Byte]](PartialFunction.empty, SqlTypes.TINYINT)

implicit val dateDecoder: Decoder[Date] =
decoder[Date]({
case localDateTime: JodaLocalDateTime =>
localDateTime.toDate
case localDate: JodaLocalDate =>
localDate.toDate
}, SqlTypes.TIMESTAMP)

override implicit val localDateDecoder: Decoder[LocalDate] =
decoder[LocalDate]({
case localDateTime: JodaLocalDateTime =>
LocalDate.of(
localDateTime.getYear,
localDateTime.getMonthOfYear,
localDateTime.getDayOfMonth
)
case localDate: JodaLocalDate =>
LocalDate.of(
localDate.getYear,
localDate.getMonthOfYear,
localDate.getDayOfMonth
)
}, SqlTypes.DATE)

implicit val localDateTimeDecoder: Decoder[LocalDateTime] =
decoder[LocalDateTime]({
case localDateTime: JodaLocalDateTime =>
LocalDateTime.ofInstant(
localDateTime.toDate.toInstant,
ZoneId.systemDefault()
)
case localDate: JodaLocalDate =>
LocalDateTime.ofInstant(
localDate.toDate.toInstant,
ZoneId.systemDefault()
)
}, SqlTypes.TIMESTAMP)
implicit val jodaLocalDateDecoder: Decoder[JodaLocalDate] = decoder[JodaLocalDate]({
case localDate: JodaLocalDate => localDate
}, SqlTypes.DATE)

implicit val jodaLocalDateTimeDecoder: Decoder[JodaLocalDateTime] = decoder[JodaLocalDateTime]({
case localDateTime: JodaLocalDateTime => localDateTime
}, SqlTypes.TIMESTAMP)

implicit val dateDecoder: Decoder[Date] = decoder[Date]({
case localDateTime: JodaLocalDateTime => localDateTime.toDate
case localDate: JodaLocalDate => localDate.toDate
}, SqlTypes.TIMESTAMP)

implicit val decodeLocalDate: MappedEncoding[JodaLocalDate, LocalDate] =
MappedEncoding(jld => LocalDate.of(jld.getYear, jld.getMonthOfYear, jld.getDayOfMonth))

implicit val decodeLocalDateTime: MappedEncoding[JodaLocalDateTime, LocalDateTime] =
MappedEncoding(jldt => LocalDateTime.ofInstant(jldt.toDate.toInstant, ZoneId.systemDefault()))

implicit val localDateDecoder: Decoder[LocalDate] = mappedDecoder(decodeLocalDate, jodaLocalDateDecoder)
}
29 changes: 11 additions & 18 deletions quill-async/src/main/scala/io/getquill/context/async/Encoders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,15 @@ trait Encoders {
implicit val floatEncoder: Encoder[Float] = encoder[Float](SqlTypes.FLOAT)
implicit val doubleEncoder: Encoder[Double] = encoder[Double](SqlTypes.DOUBLE)
implicit val byteArrayEncoder: Encoder[Array[Byte]] = encoder[Array[Byte]](SqlTypes.VARBINARY)
implicit val dateEncoder: Encoder[Date] =
encoder[Date]({ (value: Date) =>
new JodaLocalDateTime(value)
}, SqlTypes.TIMESTAMP)
implicit val localDateEncoder: Encoder[LocalDate] =
encoder[LocalDate]({ (value: LocalDate) =>
new JodaLocalDate(
value.getYear,
value.getMonthValue,
value.getDayOfMonth
)
}, SqlTypes.DATE)
implicit val localDateTimeEncoder: Encoder[LocalDateTime] =
encoder[LocalDateTime]({ (value: LocalDateTime) =>
new JodaLocalDateTime(
value.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli
)
}, SqlTypes.TIMESTAMP)
implicit val jodaLocalDateEncoder: Encoder[JodaLocalDate] = encoder[JodaLocalDate](SqlTypes.DATE)
implicit val jodaLocalDateTimeEncoder: Encoder[JodaLocalDateTime] = encoder[JodaLocalDateTime](SqlTypes.TIMESTAMP)
implicit val dateEncoder: Encoder[Date] = encoder[Date]((d: Date) => new JodaLocalDateTime(d), SqlTypes.TIMESTAMP)

implicit val encodeLocalDate: MappedEncoding[LocalDate, JodaLocalDate] =
MappedEncoding(ld => new JodaLocalDate(ld.getYear, ld.getMonthValue, ld.getDayOfMonth))

implicit val encodeLocalDateTime: MappedEncoding[LocalDateTime, JodaLocalDateTime] =
MappedEncoding(ldt => new JodaLocalDateTime(ldt.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli))

implicit val localDateEncoder: Encoder[LocalDate] = mappedEncoder(encodeLocalDate, jodaLocalDateEncoder)
}