diff --git a/addons/joda-time/src/test/scala/com/github/tminglei/slickpg/PgDateSupportJodaSuite.scala b/addons/joda-time/src/test/scala/com/github/tminglei/slickpg/PgDateSupportJodaSuite.scala index b3f571f9..31ded482 100644 --- a/addons/joda-time/src/test/scala/com/github/tminglei/slickpg/PgDateSupportJodaSuite.scala +++ b/addons/joda-time/src/test/scala/com/github/tminglei/slickpg/PgDateSupportJodaSuite.scala @@ -87,15 +87,15 @@ class PgDateSupportJodaSuite extends FunSuite { Datetimes.filter(_.id === 101L.bind).map(r => r.time + r.date).result.head.map( r => assert(LocalDateTime.parse("2010-11-03T12:33:01.101") === r) ), - Datetimes.filter(_.id === 101L.bind).map(r => r.date +++ r.interval).result.head.map( - r => assert(LocalDateTime.parse("2010-11-04T01:01:00.335") === r) - ), - Datetimes.filter(_.id === 101L.bind).map(r => r.time +++ r.interval).result.head.map( - r => assert(LocalTime.parse("13:34:01.436") === r) - ), - Datetimes.filter(_.id === 101L.bind).map(r => r.datetime +++ r.interval).result.head.map( - r => assert(LocalDateTime.parse("2001-01-04T14:22:00.558") === r) - ), + Datetimes.filter(_.id === 101L.bind).map(r => (r.date +++ r.interval, r.date +++ Period.days(1))).result.head.map { + case (r1, r2) => assert(LocalDateTime.parse("2010-11-04T01:01:00.335") === r1); assert(LocalDateTime.parse("2010-11-04T00:00:00.000") === r2) + }, + Datetimes.filter(_.id === 101L.bind).map(r => (r.time +++ r.interval, r.time +++ Period.hours(1))).result.head.map { + case (r1, r2) => assert(LocalTime.parse("13:34:01.436") === r1); assert(LocalTime.parse("13:33:01.101") === r2) + }, + Datetimes.filter(_.id === 101L.bind).map(r => (r.datetime +++ r.interval, r.datetime +++ Period.days(1))).result.head.map { + case (r1, r2) => assert(LocalDateTime.parse("2001-01-04T14:22:00.558") === r1); assert(LocalDateTime.parse("2001-01-04T13:21:00.223") === r2) + }, Datetimes.filter(_.id === 101L.bind).map(r => r.date ++ 7.bind).result.head.map( r => assert(LocalDate.parse("2010-11-10") === r) ), @@ -118,15 +118,15 @@ class PgDateSupportJodaSuite extends FunSuite { Datetimes.filter(_.id === 101L.bind).map(r => r.time - LocalTime.parse("02:37:00").bind).result.head.map( r => assert(Period.parse("PT9H56M1.100S") === r) ), - Datetimes.filter(_.id === 101L.bind).map(r => r.datetime --- r.interval).result.head.map( - r => assert(LocalDateTime.parse("2001-01-02T12:19:59.888") === r) - ), - Datetimes.filter(_.id === 101L.bind).map(r => r.time --- r.interval).result.head.map( - r => assert(LocalTime.parse("11:32:00.766") === r) - ), - Datetimes.filter(_.id === 101L.bind).map(r => r.date --- r.interval).result.head.map( - r => assert(LocalDateTime.parse("2010-11-01T22:58:59.665") === r) - ), + Datetimes.filter(_.id === 101L.bind).map(r => (r.datetime --- r.interval, r.datetime --- Period.days(1))).result.head.map { + case (r1, r2) => assert(LocalDateTime.parse("2001-01-02T12:19:59.888") === r1); assert(LocalDateTime.parse("2001-01-02T13:21:00.223") === r2) + }, + Datetimes.filter(_.id === 101L.bind).map(r => (r.time --- r.interval, r.time --- Period.hours(1))).result.head.map { + case (r1, r2) => assert(LocalTime.parse("11:32:00.766") === r1); assert(LocalTime.parse("11:33:01.101") === r2) + }, + Datetimes.filter(_.id === 101L.bind).map(r => (r.date --- r.interval, r.date --- Period.days(1))).result.head.map { + case (r1, r2) => assert(LocalDateTime.parse("2010-11-01T22:58:59.665") === r1); assert(LocalDateTime.parse("2010-11-02T00:00:00.000") === r2) + }, // age // Datetimes.filter(_.id === 101L.bind).map(r => r.datetime.age === r.datetime.age(Functions.currentDate.asColumnOf[LocalDateTime])).result.head.map( // r => assert(true === r) @@ -164,7 +164,7 @@ class PgDateSupportJodaSuite extends FunSuite { r => assert(Period.parse("P-1DT-1H-1M-1S").plus(Period.parse("PT0.665S")) === r) ), // - - Datetimes.filter(_.id === 101L.bind).map(r => r.interval - Period.parse("PT2H").bind).result.head.map( + Datetimes.filter(_.id === 101L.bind).map(r => r.interval - Period.hours(2)).result.head.map( r => assert(Period.parse("P1DT-58M-60S").plus(Period.parse("PT0.335S")) === r) ), // * diff --git a/core/src/main/scala/com/github/tminglei/slickpg/date/PgDateExtensions.scala b/core/src/main/scala/com/github/tminglei/slickpg/date/PgDateExtensions.scala index 496aeff1..9f9769e5 100644 --- a/core/src/main/scala/com/github/tminglei/slickpg/date/PgDateExtensions.scala +++ b/core/src/main/scala/com/github/tminglei/slickpg/date/PgDateExtensions.scala @@ -1,9 +1,9 @@ package com.github.tminglei.slickpg package date -import slick.ast.TypedType +import slick.ast.{Library, LiteralNode, TypedType} import slick.ast.Library.{SqlFunction, SqlOperator} -import slick.lifted.{ExtensionMethods} +import slick.lifted.ExtensionMethods import slick.driver.{JdbcTypesComponent, PostgresDriver} import slick.jdbc.JdbcType @@ -28,15 +28,23 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => val AtTimeZone = new SqlOperator("at time zone") } + trait DateExtHelper[INTERVAL] { + protected def toCastedIntervalNode[P](e: Rep[P])(implicit tm: JdbcType[INTERVAL]) = e.toNode match { + case n: LiteralNode => Library.Cast.typed(tm, n, LiteralNode("interval")) + case n => n + } + } + + /// !!!NOTE: if `TIMESTAMP` is `timestamp with time zone`, `TIMESTAMP_TZ` should be `timestamp without time zone` class TimestampColumnExtensionMethods[DATE, TIME, TIMESTAMP, TIMESTAMP_TZ, INTERVAL, P1](val c: Rep[P1])( implicit tm: JdbcType[INTERVAL], tm1: JdbcType[DATE], tm2: JdbcType[TIME], tm3: JdbcType[TIMESTAMP], tm4: JdbcType[TIMESTAMP_TZ] - ) extends ExtensionMethods[TIMESTAMP, P1] { + ) extends ExtensionMethods[TIMESTAMP, P1] with DateExtHelper[INTERVAL] { protected implicit def b1Type: TypedType[TIMESTAMP] = implicitly[TypedType[TIMESTAMP]] def +++[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIMESTAMP, R]) = { - om.column(DateLibrary.+, n, e.toNode) + om.column(DateLibrary.+, n, toCastedIntervalNode(e)) } def - [P2, R](e: Rep[P2])(implicit om: o#to[INTERVAL, R]) = { om.column(DateLibrary.-, n, e.toNode) @@ -45,7 +53,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => om.column(DateLibrary.-, n, e.toNode) } def ---[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIMESTAMP, R]) = { - om.column(DateLibrary.-, n, e.toNode) + om.column(DateLibrary.-, n, toCastedIntervalNode(e)) } def age[R](implicit om: o#to[INTERVAL, R], tm: JdbcType[INTERVAL]) = om.column(DateLibrary.Age, n) @@ -67,7 +75,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => /// !!!NOTE: if `TIME` is `time with time zone`, `TIME_TZ` should be `time without time zone` class TimeColumnExtensionMethods[DATE, TIME, TIMESTAMP, TIME_TZ, INTERVAL, P1](val c: Rep[P1])( implicit tm: JdbcType[INTERVAL], tm1: JdbcType[DATE], tm2: JdbcType[TIME], tm3: JdbcType[TIMESTAMP], tm4: JdbcType[TIME_TZ] - ) extends ExtensionMethods[TIME, P1] { + ) extends ExtensionMethods[TIME, P1] with DateExtHelper[INTERVAL] { protected implicit def b1Type: TypedType[TIME] = implicitly[TypedType[TIME]] @@ -75,13 +83,13 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => om.column(DateLibrary.+, n, e.toNode) } def +++[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIME, R]) = { - om.column(DateLibrary.+, n, e.toNode) + om.column(DateLibrary.+, n, toCastedIntervalNode(e)) } def - [P2, R](e: Rep[P2])(implicit om: o#arg[TIME, P2]#to[INTERVAL, R]) = { om.column(DateLibrary.-, n, e.toNode) } def ---[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIME, R]) = { - om.column(DateLibrary.-, n, e.toNode) + om.column(DateLibrary.-, n, toCastedIntervalNode(e)) } def atTimeZone[R](tz: Rep[String])(implicit om: o#to[TIME_TZ, R]) = @@ -91,7 +99,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => /// class DateColumnExtensionMethods[DATE, TIME, TIMESTAMP, INTERVAL, P1](val c: Rep[P1])( implicit tm: JdbcType[INTERVAL], tm1: JdbcType[DATE], tm2: JdbcType[TIME], tm3: JdbcType[TIMESTAMP] - ) extends ExtensionMethods[DATE, P1] { + ) extends ExtensionMethods[DATE, P1] with DateExtHelper[INTERVAL] { protected implicit def b1Type: TypedType[DATE] = implicitly[TypedType[DATE]] @@ -102,7 +110,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => om.column(DateLibrary.+, n, e.toNode) } def +++[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIMESTAMP, R]) = { - om.column(DateLibrary.+, n, e.toNode) + om.column(DateLibrary.+, n, toCastedIntervalNode(e)) } def - [P2, R](e: Rep[P2])(implicit om: o#arg[DATE, P2]#to[Int, R]) = { om.column(DateLibrary.-, n, e.toNode) @@ -111,7 +119,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresDriver => om.column(DateLibrary.-, n, e.toNode) } def ---[P2, R](e: Rep[P2])(implicit om: o#arg[INTERVAL, P2]#to[TIMESTAMP, R]) = { - om.column(DateLibrary.-, n, e.toNode) + om.column(DateLibrary.-, n, toCastedIntervalNode(e)) } def isFinite[R](implicit om: o#to[Boolean, R]) = om.column(DateLibrary.IsFinite, n) }