Skip to content

Commit

Permalink
feat(postgres to_timestamp): Implementing Postgres to_timestamp funct…
Browse files Browse the repository at this point in the history
…ion. zio#215
  • Loading branch information
brbrown25 committed Nov 23, 2020
1 parent 1d7c8f9 commit 20b40a7
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 10 deletions.
12 changes: 9 additions & 3 deletions jdbc/src/main/scala/zio/sql/jdbc.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package zio.sql

import java.sql._

import java.io.IOException

import java.time.{ ZoneId, ZoneOffset }
import zio.{ Chunk, Has, IO, Managed, ZIO, ZLayer, ZManaged }
import zio.blocking.Blocking
import zio.stream.{ Stream, ZStream }
Expand Down Expand Up @@ -193,7 +192,14 @@ trait Jdbc extends zio.sql.Sql {
tryDecode[java.util.UUID](
java.util.UUID.fromString(column.fold(resultSet.getString(_), resultSet.getString(_)))
)
case TZonedDateTime => ???
case TZonedDateTime =>
tryDecode[java.time.ZonedDateTime](
java.time.ZonedDateTime
.ofInstant(
column.fold(resultSet.getTimestamp(_), resultSet.getTimestamp(_)).toInstant,
ZoneId.of(ZoneOffset.UTC.getId)
)
)
case TDialectSpecific(_) => ???
case t @ Nullable() => extractColumn(column, resultSet, t.typeTag, false).map(Option(_))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package zio.sql.postgresql

import java.time.LocalDate

import java.time.{ LocalDate, ZonedDateTime }
import zio.sql.Jdbc

/**
Expand Down Expand Up @@ -30,6 +29,7 @@ trait PostgresModule extends Jdbc { self =>
val Degrees = FunctionDef[Double, Double](FunctionName("degrees"))
val Div = FunctionDef[(Double, Double), Double](FunctionName("div"))
val Factorial = FunctionDef[Int, Int](FunctionName("factorial"))
val ToTimestamp = FunctionDef[Long, ZonedDateTime](FunctionName("to_timestamp"))
}

override def renderRead(read: self.Read[_]): String = {
Expand Down
16 changes: 15 additions & 1 deletion postgres/src/test/resources/shop_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ create table order_details
unit_price money not null
);

create table timestamp_test
(
timestamp_id uuid not null,
created_timestamp_string varchar not null,
created_timestamp timestamp with time zone default now()
);

insert into customers
(id, first_name, last_name, verified, dob)
Expand Down Expand Up @@ -189,4 +195,12 @@ values
('852E2DC9-4EC3-4225-A6F7-4F42F8FF728E', 'D5137D3A-894A-4109-9986-E982541B434F', 1, 45.45),
('D6D8DDDC-4B0B-4D74-8EDC-A54E9B7F35F7', 'D5137D3A-894A-4109-9986-E982541B434F', 2, 50.00),
('2C3FC180-D0DF-4D7B-A271-E6CCD2440393', 'D5137D3A-894A-4109-9986-E982541B434F', 2, 50.00),
('5883CB62-D792-4EE3-ACBC-FE85B6BAA998', 'D5137D3A-894A-4109-9986-E982541B434F', 1, 55.00);
('5883CB62-D792-4EE3-ACBC-FE85B6BAA998', 'D5137D3A-894A-4109-9986-E982541B434F', 1, 55.00);

insert into timestamp_test
(timestamp_id, created_timestamp_string, created_timestamp)
values
('354ec738-71b6-4166-9c62-aa092ede73c4', '2020-11-21 19:10:25+00', '2020-11-21 19:10:25+00'),
('2f97e2c5-62de-478e-bb30-742f2614f3cd', '2020-11-21 15:10:25-04', '2020-11-21 15:10:25-04'),
('261a4290-2da4-4e3f-bbab-3f0af31d1914', '2020-11-22 02:10:25+07', '2020-11-22 02:10:25+07'),
('2e9d0d70-b947-4126-9149-7a8e6d492171', '2020-11-21 12:10:25-07', '2020-11-21 12:10:25-07')
31 changes: 29 additions & 2 deletions postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package zio.sql.postgresql

import java.time.LocalDate
import java.time.{ LocalDate, ZoneId, ZoneOffset, ZonedDateTime }
import java.util.UUID

import zio.Cause
import zio.test._
import zio.test.Assertion._
Expand Down Expand Up @@ -523,6 +522,34 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
r <- result.runCollect
} yield assert(r)(hasSameElements(expected))

assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("to_timestamp") {
import this.TimestampTests._

val query = select(ToTimestamp(1284352323L)) from customers
val expected = ZonedDateTime.of(2010, 9, 13, 4, 32, 3, 0, ZoneId.of(ZoneOffset.UTC.getId))
val testResult = execute(query).to[ZonedDateTime, ZonedDateTime](identity)

val expectedRoundTripTimestamp = ZonedDateTime.of(2020, 11, 21, 19, 10, 25, 0, ZoneId.of(ZoneOffset.UTC.getId))
val roundTripQuery =
select(createdString ++ createdTimestamp) from timestampTests
val roundTripResults = execute(roundTripQuery).to[String, ZonedDateTime, (String, ZonedDateTime)] { case row =>
row
}
val roundTripExpected = List(
("2020-11-21 19:10:25+00", expectedRoundTripTimestamp),
("2020-11-21 15:10:25-04", expectedRoundTripTimestamp),
("2020-11-22 02:10:25+07", expectedRoundTripTimestamp),
("2020-11-21 12:10:25-07", expectedRoundTripTimestamp)
)

val assertion = for {
single <- testResult.runCollect
roundTrip <- roundTripResults.runCollect
} yield assert(single.head)(equalTo(expected)) &&
assert(roundTrip)(hasSameElementsDistinct(roundTripExpected))

assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
}
)
Expand Down
13 changes: 11 additions & 2 deletions postgres/src/test/scala/zio/sql/postgresql/ShopSchema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ trait ShopSchema extends Jdbc { self =>

object Customers {
val customers =
(uuid("id") ++ localDate("dob") ++ string("first_name") ++ string("last_name") ++ boolean("verified"))
(uuid("id") ++ localDate("dob") ++ string("first_name") ++ string("last_name") ++ boolean(
"verified"
) ++ zonedDateTime("created_timestamp"))
.table("customers")

val customerId :*: dob :*: fName :*: lName :*: verified :*: _ = customers.columns
val customerId :*: dob :*: fName :*: lName :*: verified :*: createdTimestamp :*: _ = customers.columns
}
object Orders {
val orders = (uuid("id") ++ uuid("customer_id") ++ localDate("order_date")).table("orders")
Expand Down Expand Up @@ -39,4 +41,11 @@ trait ShopSchema extends Jdbc { self =>

val fkOrderId :*: fkProductId :*: quantity :*: unitPrice :*: _ = orderDetails.columns
}

object TimestampTests {
val timestampTests =
(uuid("timestamp_id") ++ string("created_timestamp_string") ++ zonedDateTime("created_timestamp"))
.table("timestamp_test")
val tId :*: createdString :*: createdTimestamp :*: _ = timestampTests.columns
}
}

0 comments on commit 20b40a7

Please sign in to comment.