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

[WIP] Add DSL for datetime/duration #1635

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 @@ -17,7 +17,7 @@ trait Decoders {

case class AsyncDecoder[T](sqlType: DecoderSqlType)(implicit decoder: BaseDecoder[T])
extends BaseDecoder[T] {
override def apply(index: Index, row: ResultRow) =
override def apply(index: Index, row: ResultRow): T =
decoder(index, row)
}

Expand All @@ -26,7 +26,7 @@ trait Decoders {
sqlType: DecoderSqlType
): Decoder[T] =
AsyncDecoder[T](sqlType)(new BaseDecoder[T] {
def apply(index: Index, row: ResultRow) = {
def apply(index: Index, row: ResultRow): T = {
row(index) match {
case value: T => value
case value if f.isDefinedAt(value) => f(value)
Expand All @@ -45,7 +45,7 @@ trait Decoders {
})

trait NumericDecoder[T] extends BaseDecoder[T] {
def apply(index: Index, row: ResultRow) =
def apply(index: Index, row: ResultRow): T =
row(index) match {
case v: Byte => decode(v)
case v: Short => decode(v)
Expand All @@ -63,7 +63,7 @@ trait Decoders {

implicit def optionDecoder[T](implicit d: Decoder[T]): Decoder[Option[T]] =
AsyncDecoder(d.sqlType)(new BaseDecoder[Option[T]] {
def apply(index: Index, row: ResultRow) = {
def apply(index: Index, row: ResultRow): Option[T] = {
row(index) match {
case null => None
case value => Some(d(index, row))
Expand Down Expand Up @@ -99,25 +99,25 @@ trait Decoders {

implicit val intDecoder: Decoder[Int] =
AsyncDecoder(SqlTypes.INTEGER)(new NumericDecoder[Int] {
def decode[U](v: U)(implicit n: Numeric[U]) =
def decode[U](v: U)(implicit n: Numeric[U]): Int =
n.toInt(v)
})

implicit val longDecoder: Decoder[Long] =
AsyncDecoder(SqlTypes.BIGINT)(new NumericDecoder[Long] {
def decode[U](v: U)(implicit n: Numeric[U]) =
def decode[U](v: U)(implicit n: Numeric[U]): Long =
n.toLong(v)
})

implicit val floatDecoder: Decoder[Float] =
AsyncDecoder(SqlTypes.FLOAT)(new NumericDecoder[Float] {
def decode[U](v: U)(implicit n: Numeric[U]) =
def decode[U](v: U)(implicit n: Numeric[U]): Float =
n.toFloat(v)
})

implicit val doubleDecoder: Decoder[Double] =
AsyncDecoder(SqlTypes.DOUBLE)(new NumericDecoder[Double] {
def decode[U](v: U)(implicit n: Numeric[U]) =
def decode[U](v: U)(implicit n: Numeric[U]): Double =
n.toDouble(v)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait Encoders {

case class AsyncEncoder[T](sqlType: DecoderSqlType)(implicit encoder: BaseEncoder[T])
extends BaseEncoder[T] {
override def apply(index: Index, value: T, row: PrepareRow) =
override def apply(index: Index, value: T, row: PrepareRow): PrepareRow =
encoder.apply(index, value, row)
}

Expand All @@ -23,19 +23,19 @@ trait Encoders {

def encoder[T](f: T => Any, sqlType: DecoderSqlType): Encoder[T] =
AsyncEncoder[T](sqlType)(new BaseEncoder[T] {
def apply(index: Index, value: T, row: PrepareRow) =
def apply(index: Index, value: T, row: PrepareRow): PrepareRow =
row :+ f(value)
})

implicit def mappedEncoder[I, O](implicit mapped: MappedEncoding[I, O], e: Encoder[O]): Encoder[I] =
AsyncEncoder(e.sqlType)(new BaseEncoder[I] {
def apply(index: Index, value: I, row: PrepareRow) =
def apply(index: Index, value: I, row: PrepareRow): PrepareRow =
e(index, mapped.f(value), row)
})

implicit def optionEncoder[T](implicit d: Encoder[T]): Encoder[Option[T]] =
AsyncEncoder(d.sqlType)(new BaseEncoder[Option[T]] {
def apply(index: Index, value: Option[T], row: PrepareRow) = {
def apply(index: Index, value: Option[T], row: PrepareRow): PrepareRow = {
value match {
case None => nullEncoder(index, null, row)
case Some(v) => d(index, v, row)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.getquill.context.jdbc

import java.sql.{ Timestamp, Date => SqlDate }
import java.sql.Timestamp
import java.sql.Types._
import java.time.LocalDate
import java.time.{ LocalDate, LocalDateTime, LocalTime, OffsetDateTime }
import java.util.Date

import io.getquill.context.sql.encoding.ArrayEncoding
Expand All @@ -22,7 +22,11 @@ trait ArrayEncoders extends ArrayEncoding {
implicit def arrayDoubleEncoder[Col <: Seq[Double]]: Encoder[Col] = arrayRawEncoder[Double, Col](DOUBLE)
implicit def arrayDateEncoder[Col <: Seq[Date]]: Encoder[Col] = arrayRawEncoder[Date, Col](TIMESTAMP)
implicit def arrayTimestampEncoder[Col <: Seq[Timestamp]]: Encoder[Col] = arrayRawEncoder[Timestamp, Col](TIMESTAMP)
implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayEncoder[LocalDate, Col](parseJdbcType(DATE), SqlDate.valueOf)
// Taken from https://jdbc.postgresql.org/documentation/head/8-date-time.html
implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayRawEncoder[LocalDate, Col](parseJdbcType(DATE))
implicit def arrayLocalTimeEncoder[Col <: Seq[LocalTime]]: Encoder[Col] = arrayRawEncoder[LocalTime, Col](parseJdbcType(TIME))
implicit def arrayLocalDateTimeEncoder[Col <: Seq[LocalDateTime]]: Encoder[Col] = arrayRawEncoder[LocalDateTime, Col](parseJdbcType(TIMESTAMP))
implicit def arrayOffsetDateTimeEncoder[Col <: Seq[OffsetDateTime]]: Encoder[Col] = arrayRawEncoder[OffsetDateTime, Col](parseJdbcType(TIMESTAMP_WITH_TIMEZONE))

/**
* Generic encoder for JDBC arrays.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ trait PostgresJdbcContextBase[N <: NamingStrategy] extends JdbcContextBase[Postg
with BooleanObjectEncoding
with UUIDObjectEncoding
with ArrayDecoders
with ArrayEncoders {
with ArrayEncoders
with PostgresDateTimeDecoders
with PostgresDateTimeEncoders {

val idiom = PostgresDialect

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait Decoders {
type Decoder[T] = JdbcDecoder[T]

case class JdbcDecoder[T](decoder: BaseDecoder[T]) extends BaseDecoder[T] {
def apply(index: Index, row: ResultRow) =
def apply(index: Index, row: ResultRow): T =
decoder(index + 1, row)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ trait Encoders {

type Encoder[T] = JdbcEncoder[T]

protected val dateTimeZone = TimeZone.getDefault
protected val dateTimeZone: TimeZone = TimeZone.getDefault

case class JdbcEncoder[T](sqlType: Int, encoder: BaseEncoder[T]) extends BaseEncoder[T] {
override def apply(index: Index, value: T, row: PrepareRow) =
override def apply(index: Index, value: T, row: PrepareRow): PrepareRow =
encoder(index + 1, value, row)
}

Expand Down Expand Up @@ -60,4 +60,4 @@ trait Encoders {
implicit val localDateTimeEncoder: Encoder[LocalDateTime] =
encoder(Types.TIMESTAMP, (index, value, row) =>
row.setTimestamp(index, Timestamp.valueOf(value), Calendar.getInstance(dateTimeZone)))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.getquill.context.jdbc

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

trait PostgresDateTimeDecoders {
self: JdbcContextBase[_, _] with Decoders =>
// Taken from https://jdbc.postgresql.org/documentation/head/8-date-time.html

override implicit val localDateDecoder: Decoder[LocalDate] =
decoder(
(index, row) =>
row.getObject(index, classOf[LocalDate])
)

implicit val localTimeDecoder: Decoder[LocalTime] =
decoder(
(index, row) =>
row.getObject(index, classOf[LocalTime])
)

override implicit val localDateTimeDecoder: Decoder[LocalDateTime] =
decoder(
(index, row) =>
row.getObject(index, classOf[LocalDateTime])
)

implicit val offsetDateTimeDecoder: Decoder[OffsetDateTime] =
decoder(
(index, row) =>
row.getObject(index, classOf[OffsetDateTime])
)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.getquill.context.jdbc

import java.sql.Types._
import java.time.{ LocalDate, LocalDateTime, LocalTime, OffsetDateTime }

trait PostgresDateTimeEncoders {
self: JdbcContextBase[_, _] with Encoders =>
// Taken from https://jdbc.postgresql.org/documentation/head/8-date-time.html

final private[this] def objectEncoder[T](sqlType: Int): Encoder[T] = encoder(
sqlType,
(index, value, row) => row.setObject(index, value)
)

override implicit val localDateEncoder: Encoder[LocalDate] = objectEncoder[LocalDate](DATE)
implicit val localTimeEncoder: Encoder[LocalTime] = objectEncoder[LocalTime](TIME)
override implicit val localDateTimeEncoder: Encoder[LocalDateTime] = objectEncoder[LocalDateTime](TIMESTAMP)
implicit val offsetDateTimeEncoder: Encoder[OffsetDateTime] = objectEncoder[OffsetDateTime](TIMESTAMP_WITH_TIMEZONE)
}