Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
WIP timstampz works, but no interval
Browse files Browse the repository at this point in the history
  • Loading branch information
brbrown25 committed Jan 13, 2021
1 parent 38162b7 commit 85ee9ac
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 40 deletions.
2 changes: 1 addition & 1 deletion core/jvm/src/main/scala/zio/sql/typetag.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ trait TypeTagModule {
implicit case object TBigDecimalIsNumeric extends AbstractIsNumeric[BigDecimal]
}

type PostgresTypeTagExtension
// type PostgresTypeTagExtension
}
51 changes: 20 additions & 31 deletions postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,21 @@ import zio.sql.{ Jdbc, Renderer }
/**
*/
trait PostgresModule extends Jdbc { self =>
override type PostgresTypeTagExtension = TypeTagExtension[PostgresSpecific]

sealed trait PostgresSpecific
override type TypeTagExtension = PostgresSpecific

object PostgresSpecific {
sealed case class Timestampz(
def timestampz(
year: Int = 0,
month: Int = 0,
day: Int = 0,
hour: Int = 0,
minute: Int = 0,
second: BigDecimal = 0.0,
timeZone: String = "+00"
) extends PostgresSpecific {
override def toString =
s"""${year}, ${month}, ${day}, ${hour}, ${minute}, ${second}, '${timeZone}'"""
def decode[ZonedDateTime]: Either[Int, String] => java.time.ZonedDateTime = tz =>
java.time.ZonedDateTime
.ofInstant(tz.fold(i => Instant.ofEpochMilli(i.toLong), Instant.parse(_)), ZoneId.of(ZoneOffset.UTC.getId))
}

object Timestampz {
def toZonedDateTime(tz: Timestampz): ZonedDateTime = {
val ldt = LocalDateTime.of(tz.year, tz.month, tz.day, tz.hour, tz.minute, tz.second.toInt)
ZonedDateTime.of(ldt, ZoneOffset.of(tz.timeZone))
}
): ZonedDateTime = {
val ldt: LocalDateTime = LocalDateTime.of(year, month, day, hour, minute, second.toInt)
ZonedDateTime.of(ldt, ZoneOffset.of(timeZone))
}

//Based upon https://github.com/tminglei/slick-pg/blob/master/src/main/scala/com/github/tminglei/slickpg/PgDateSupport.scala
Expand Down Expand Up @@ -116,8 +105,7 @@ trait PostgresModule extends Jdbc { self =>
}

object Interval {
def apply(interval: String): Interval = fromPgInterval(new PGInterval(interval))

def apply(interval: String): Interval = fromPgInterval(new PGInterval(interval))
def fromPgInterval(interval: PGInterval): Interval =
new Interval(
interval.getYears,
Expand Down Expand Up @@ -184,13 +172,13 @@ trait PostgresModule extends Jdbc { self =>
val StatementTimestamp = FunctionDef[Any, ZonedDateTime](FunctionName("statement_timestamp"))
val TransactionTimestamp = FunctionDef[Any, ZonedDateTime](FunctionName("transaction_timestamp"))
val MakeDate = FunctionDef[(Int, Int, Int), LocalDate](FunctionName("make_date"))
val MakeInterval = FunctionDef[Interval, Interval](FunctionName("make_interval"))
val MakeInterval = FunctionDef[(Int, Int, Int, Int, Int, BigDecimal), Interval](FunctionName("make_interval"))
val MakeTime = FunctionDef[(Int, Int, Double), LocalTime](FunctionName("make_time"))
val MakeTimestamp =
FunctionDef[(Int, Int, Int, Int, Int, Double), LocalDateTime](
FunctionName("make_timestamp")
)
val MakeTimestampz = FunctionDef[Timestampz, ZonedDateTime](FunctionName("make_timestamptz"))
val MakeTimestampz = FunctionDef[ZonedDateTime, ZonedDateTime](FunctionName("make_timestamptz"))
}

override def renderRead(read: self.Read[_]): String = {
Expand Down Expand Up @@ -256,6 +244,7 @@ trait PostgresModule extends Jdbc { self =>

private[zio] def renderLit[A, B](lit: self.Expr.Literal[_])(implicit render: Renderer): Unit = {
import TypeTag._
import PostgresSpecific._
lit.typeTag match {
case tt @ TByteArray => render(tt.cast(lit.value)) // todo still broken
//something like? render(tt.cast(lit.value).map("\\\\%03o" format _).mkString("E\'", "", "\'"))
Expand All @@ -270,17 +259,17 @@ trait PostgresModule extends Jdbc { self =>
case tt @ TUUID => render(tt.cast(lit.value)) // todo still broken
case tt @ TZonedDateTime => render(tt.cast(lit.value)) // todo still broken

case TByte => render(lit.value) //default toString is probably ok
case TBigDecimal => render(lit.value) //default toString is probably ok
case TBoolean => render(lit.value) //default toString is probably ok
case TDouble => render(lit.value) //default toString is probably ok
case TFloat => render(lit.value) //default toString is probably ok
case TInt => render(lit.value) //default toString is probably ok
case TLong => render(lit.value) //default toString is probably ok
case TShort => render(lit.value) //default toString is probably ok
case TString => render("'", lit.value, "'") //todo fix escaping

case _ => render(lit.value) //todo fix add TypeTag.Nullable[_] =>
case TByte => render(lit.value) //default toString is probably ok
case TBigDecimal => render(lit.value) //default toString is probably ok
case TBoolean => render(lit.value) //default toString is probably ok
case TDouble => render(lit.value) //default toString is probably ok
case TFloat => render(lit.value) //default toString is probably ok
case TInt => render(lit.value) //default toString is probably ok
case TLong => render(lit.value) //default toString is probably ok
case TShort => render(lit.value) //default toString is probably ok
case TString => render("'", lit.value, "'") //todo fix escaping
case TDialectSpecific(value: Interval) => render(value.toString)
case _ => render(lit.value) //todo fix add TypeTag.Nullable[_] =>
}
}

Expand Down
27 changes: 19 additions & 8 deletions postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,16 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
},
testM("make_interval") {
def runTest(interval: Interval) = {
val query = select(MakeInterval(interval)) from customers
val query = select(
MakeInterval(
interval.years,
interval.months,
interval.days,
interval.hours,
interval.minutes,
interval.seconds
)
) from customers

for {
r <- execute(query).to[Interval, Interval](identity).runCollect
Expand Down Expand Up @@ -1122,8 +1131,8 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("make_timestampz") {
def runTest(timestampz: Timestampz) = {
val query = select(MakeTimestampz(timestampz)) from customers
def runTest(zdt: ZonedDateTime) = {
val query = select(MakeTimestampz(zdt)) from customers
for {
r <- execute(query).to[ZonedDateTime, ZonedDateTime](identity).runCollect
} yield r.head
Expand All @@ -1132,13 +1141,15 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
val expectedRoundTripTimestamp = ZonedDateTime.of(2020, 11, 21, 19, 10, 25, 0, ZoneId.of(ZoneOffset.UTC.getId))

(for {
t1 <- assertM(runTest(Timestampz(2013, 7, 15, 8, 15, 23.5)))(
t1 <- assertM(runTest(timestampz(2013, 7, 15, 8, 15, 23.5)))(
equalTo(ZonedDateTime.parse("2013-07-15T08:15:23.5+00:00"))
)
t2 <- assertM(runTest(Timestampz(2020, 11, 21, 19, 10, 25, "+00:00")))(equalTo(expectedRoundTripTimestamp))
t3 <- assertM(runTest(Timestampz(2020, 11, 21, 15, 10, 25, "-04:00")))(equalTo(expectedRoundTripTimestamp))
t4 <- assertM(runTest(Timestampz(2020, 11, 22, 2, 10, 25, "+07:00")))(equalTo(expectedRoundTripTimestamp))
t5 <- assertM(runTest(Timestampz(2020, 11, 21, 12, 10, 25, "-07:00")))(equalTo(expectedRoundTripTimestamp))
t2 <- assertM(runTest(timestampz(2020, 11, 21, 19, 10, 25, "+00:00")))(
equalTo(expectedRoundTripTimestamp)
)
t3 <- assertM(runTest(timestampz(2020, 11, 21, 15, 10, 25, "-04:00")))(equalTo(expectedRoundTripTimestamp))
t4 <- assertM(runTest(timestampz(2020, 11, 22, 2, 10, 25, "+07:00")))(equalTo(expectedRoundTripTimestamp))
t5 <- assertM(runTest(timestampz(2020, 11, 21, 12, 10, 25, "-07:00")))(equalTo(expectedRoundTripTimestamp))
} yield t1 && t2 && t3 && t4 && t5).mapErrorCause(cause => Cause.stackless(cause.untraced))
}
) @@ timeout(5.minutes)
Expand Down

0 comments on commit 85ee9ac

Please sign in to comment.