From 2b44fa3609220111c287f9cb0e9a0a4574764f54 Mon Sep 17 00:00:00 2001 From: jules Ivanic Date: Wed, 25 Oct 2023 17:12:37 +0400 Subject: [PATCH] Implement `java.time.*` decoders --- .../src/main/scala/zio/jdbc/JdbcDecoder.scala | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/core/src/main/scala/zio/jdbc/JdbcDecoder.scala b/core/src/main/scala/zio/jdbc/JdbcDecoder.scala index ce1360e5..3c90ca39 100644 --- a/core/src/main/scala/zio/jdbc/JdbcDecoder.scala +++ b/core/src/main/scala/zio/jdbc/JdbcDecoder.scala @@ -19,6 +19,7 @@ import zio._ import java.io._ import java.sql.{ Array => _, _ } +import java.time._ import scala.collection.immutable.ListMap /** @@ -71,7 +72,7 @@ object JdbcDecoder extends JdbcDecoderLowPriorityImplicits { def apply[A]()(implicit decoder: JdbcDecoder[A]): JdbcDecoder[A] = decoder - def apply[A](f: ResultSet => (Int => A), expected: String = "value"): JdbcDecoder[A] = + def apply[A](f: ResultSet => Int => A, expected: String = "value"): JdbcDecoder[A] = new JdbcDecoder[A] { override def unsafeDecode( inputColumnIndex: Int, @@ -91,20 +92,36 @@ object JdbcDecoder extends JdbcDecoderLowPriorityImplicits { } } - implicit val intDecoder: JdbcDecoder[Int] = JdbcDecoder(_.getInt) - implicit val longDecoder: JdbcDecoder[Long] = JdbcDecoder(_.getLong) - implicit val doubleDecoder: JdbcDecoder[Double] = JdbcDecoder(_.getDouble) - implicit val stringDecoder: JdbcDecoder[String] = JdbcDecoder(_.getString) - implicit val booleanDecoder: JdbcDecoder[Boolean] = JdbcDecoder(_.getBoolean) - implicit val bigDecimalDecoder: JdbcDecoder[java.math.BigDecimal] = JdbcDecoder(_.getBigDecimal) - implicit val shortDecoder: JdbcDecoder[Short] = JdbcDecoder(_.getShort) - implicit val floatDecoder: JdbcDecoder[Float] = JdbcDecoder(_.getFloat) - implicit val byteDecoder: JdbcDecoder[Byte] = JdbcDecoder(_.getByte) - implicit val byteArrayDecoder: JdbcDecoder[Array[Byte]] = JdbcDecoder(_.getBytes) - implicit val blobDecoder: JdbcDecoder[Blob] = JdbcDecoder(_.getBlob) - implicit val dateDecoder: JdbcDecoder[java.sql.Date] = JdbcDecoder(_.getDate) - implicit val timeDecoder: JdbcDecoder[java.sql.Time] = JdbcDecoder(_.getTime) - implicit val timestampDecoder: JdbcDecoder[java.sql.Timestamp] = JdbcDecoder(_.getTimestamp) + implicit val intDecoder: JdbcDecoder[Int] = JdbcDecoder(_.getInt) + implicit val longDecoder: JdbcDecoder[Long] = JdbcDecoder(_.getLong) + implicit val doubleDecoder: JdbcDecoder[Double] = JdbcDecoder(_.getDouble) + implicit val stringDecoder: JdbcDecoder[String] = JdbcDecoder(_.getString) + implicit val booleanDecoder: JdbcDecoder[Boolean] = JdbcDecoder(_.getBoolean) + implicit val bigDecimalDecoder: JdbcDecoder[java.math.BigDecimal] = JdbcDecoder(_.getBigDecimal) + implicit val shortDecoder: JdbcDecoder[Short] = JdbcDecoder(_.getShort) + implicit val floatDecoder: JdbcDecoder[Float] = JdbcDecoder(_.getFloat) + implicit val byteDecoder: JdbcDecoder[Byte] = JdbcDecoder(_.getByte) + implicit val byteArrayDecoder: JdbcDecoder[Array[Byte]] = JdbcDecoder(_.getBytes) + implicit val blobDecoder: JdbcDecoder[Blob] = JdbcDecoder(_.getBlob) + implicit val dateDecoder: JdbcDecoder[java.sql.Date] = JdbcDecoder(_.getDate) + implicit val timeDecoder: JdbcDecoder[java.sql.Time] = JdbcDecoder(_.getTime) + implicit val timestampDecoder: JdbcDecoder[java.sql.Timestamp] = JdbcDecoder(_.getTimestamp) + // These `java.time.*` decoders are copied from Quill's 'ObjectGenericTimeDecoders' trait. + // Note: These decoders probably don't work for SQLite. Quill as a separate trait, named `BasicTimeDecoders` which seems dedicated to SQLite. + implicit val localDateDecoder: JdbcDecoder[java.time.LocalDate] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[LocalDate]), "java.time.LocalDate") + implicit val localTimeDecoder: JdbcDecoder[java.time.LocalTime] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[LocalTime]), "java.time.LocalTime") + implicit val localDateTimeDecoder: JdbcDecoder[java.time.LocalDateTime] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[LocalDateTime]), "java.time.LocalDateTime") + implicit val zonedDateTimeDecoder: JdbcDecoder[java.time.ZonedDateTime] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[OffsetDateTime]).toZonedDateTime, "java.time.ZonedDateTime") + implicit val instantDecoder: JdbcDecoder[java.time.Instant] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[OffsetDateTime]).toInstant, "java.time.Instant") + implicit val offsetTimeDecoder: JdbcDecoder[java.time.OffsetTime] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[OffsetTime]), "java.time.OffsetTime") + implicit val offsetDateTimeDecoder: JdbcDecoder[java.time.OffsetDateTime] = + JdbcDecoder(rs => i => rs.getObject(i, classOf[OffsetDateTime]), "java.time.OffsetDateTime") implicit def optionDecoder[A](implicit decoder: JdbcDecoder[A]): JdbcDecoder[Option[A]] = JdbcDecoder(rs =>