8000 Make sure a LocalDateTime is returned for timestamps without timezone… · mst-appear/postgresql-async@23f407c · GitHub
[go: up one dir, main page]

Skip to content

Commit 23f407c

Browse files
committed
Make sure a LocalDateTime is returned for timestamps without timezones (as the driver documentation states) - fixes mauricio#52
1 parent eb7e32c commit 23f407c

File tree

7 files changed

+41
-16
lines changed

7 files changed

+41
-16
lines changed

db-async-common/src/main/scala/com/github/mauricio/async/db/column/TimestampEncoderDecoder.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ package com.github.mauricio.async.db.column
1919
import com.github.mauricio.async.db.exceptions.DateEncoderNotAvailableException
2020
import java.sql.Timestamp
2121
import java.util.{Calendar, Date}
22-
import org.joda.time.format.{DateTimeFormatter, DateTimeFormatterBuilder, DateTimeFormat}
23-
import org.joda.time.{ReadableDateTime, DateTime}
22+
import org.joda.time._
23+
import org.joda.time.format.DateTimeFormatterBuilder
2424

2525
object TimestampEncoderDecoder {
2626
val Instance = new TimestampEncoderDecoder()
@@ -41,15 +41,16 @@ class TimestampEncoderDecoder extends ColumnEncoderDecoder {
4141

4242
def formatter = format
4343

44-
override def decode(value: String): DateTime = {
45-
formatter.parseDateTime(value)
44+
override def decode(value: String): Any = {
45+
formatter.parseLocalDateTime(value)
4646
}
4747

4848
override def encode(value: Any): String = {
4949
value match {
5050
case t: Timestamp => this.formatter.print(new DateTime(t))
5151
case t: Date => this.formatter.print(new DateTime(t))
5252
case t: Calendar => this.formatter.print(new DateTime(t))
53+
case t: LocalDateTime => this.formatter.print(t)
5354
case t: ReadableDateTime => this.formatter.print(t)
5455
case _ => throw new DateEncoderNotAvailableException(value)
5556
}

db-async-common/src/main/scala/com/github/mauricio/async/db/column/TimestampWithTimezoneEncoderDecoder.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.github.mauricio.async.db.column
1818

19+
import org.joda.time.DateTime
1920
import org.joda.time.format.DateTimeFormat
2021

2122
object TimestampWithTimezoneEncoderDecoder extends TimestampEncoderDecoder {
@@ -24,4 +25,8 @@ object TimestampWithTimezoneEncoderDecoder extends TimestampEncoderDecoder {
2425

2526
override def formatter = format
2627

28+
override def decode(value: String): Any = {
29+
formatter.parseDateTime(value)
30+
}
31+
2732
}

postgresql-async/src/main/scala/com/github/mauricio/async/db/postgresql/column/PostgreSQLColumnEncoderRegistry.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class PostgreSQLColumnEncoderRegistry extends ColumnEncoderRegistry {
5151
classOf[java.math.BigDecimal] -> (BigDecimalEncoderDecoder -> ColumnTypes.Numeric),
5252

5353
classOf[LocalDate] -> ( DateEncoderDecoder -> ColumnTypes.Date ),
54+
classOf[LocalDateTime] -> (TimestampEncoderDecoder.Instance -> ColumnTypes.TimestampWithTimezone),
5455
classOf[DateTime] -> (TimestampWithTimezoneEncoderDecoder -> ColumnTypes.TimestampWithTimezone),
5556
classOf[ReadableDateTime] -> (TimestampWithTimezoneEncoderDecoder -> ColumnTypes.TimestampWithTimezone),
5657
classOf[ReadableInstant] -> (DateEncoderDecoder -> ColumnTypes.Date),

postgresql-async/src/main/scala/com/github/mauricio/async/db/postgresql/column/PostgreSQLTimestampEncoderDecoder.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import io.netty.buffer.ByteBuf
2525
import java.nio.charset.Charset
2626
import java.sql.Timestamp
2727
import java.util.{Calendar, Date}
28+
import org.joda.time._
2829
import org.joda.time.format.DateTimeFormatterBuilder
29-
import org.joda.time.{ReadableDateTime, DateTime}
3030

3131
object PostgreSQLTimestampEncoderDecoder extends ColumnEncoderDecoder {
3232

@@ -59,20 +59,21 @@ object PostgreSQLTimestampEncoderDecoder extends ColumnEncoderDecoder {
5959

6060
val columnType = kind.asInstanceOf[PostgreSQLColumnData]
6161

62-
val format = columnType.dataType match {
63-
case ColumnTypes.Timestamp | ColumnTypes.TimestampArray | ColumnTypes.TimestampWithTimezoneArray => {
64-
selectFormatter(text)
62+
columnType.dataType match {
63+
case ColumnTypes.Timestamp | ColumnTypes.TimestampArray => {
64+
selectFormatter(text).parseLocalDateTime(text)
65+
}
66+
case ColumnTypes.TimestampWithTimezoneArray => {
67+
selectFormatter(text).parseDateTime(text)
6568
}
6669
case ColumnTypes.TimestampWithTimezone => {
6770
if ( columnType.dataTypeModifier > 0 ) {
68-
internalFormatters(columnType.dataTypeModifier - 1)
71+
internalFormatters(columnType.dataTypeModifier - 1).parseDateTime(text)
6972
} else {
70-
selectFormatter(text)
73+
selectFormatter(text).parseDateTime(text)
7174
}
7275
}
7376
}
74-
75-
format.parseDateTime(text)
7677
}
7778

7879
private def selectFormatter( text : String ) = {
@@ -90,6 +91,7 @@ object PostgreSQLTimestampEncoderDecoder extends ColumnEncoderDecoder {
9091
case t: Timestamp => this.formatter.print(new DateTime(t))
9192
case t: Date => this.formatter.print(new DateTime(t))
9293
case t: Calendar => this.formatter.print(new DateTime(t))
94+
case t: LocalDateTime => this.formatter.print(t)
9395
case t: ReadableDateTime => this.formatter.print(t)
9496
case _ => throw new DateEncoderNotAvailableException(value)
9597
}

postgresql-async/src/test/scala/com/github/mauricio/async/db/postgresql/TimeAndDateSpec.scala

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package com.github.mauricio.async.db.postgresql
1818

1919
import org.specs2.mutable.Specification
20-
import org.joda.time.{LocalTime, DateTime, Period}
20+
import org.joda.time._
2121

2222
class TimeAndDateSpec extends Specification with DatabaseTestHelper {
2323

@@ -186,18 +186,33 @@ class TimeAndDateSpec extends Specification with DatabaseTestHelper {
186186
}
187187
}
188188

189-
"handle a change in timezone inside the connection" in {
189+
"handle sending a time with timezone and return a LocalDateTime for a timestamp without timezone column" in {
190190

191191
withTimeHandler {
192192
conn =>
193193
val date1 = new DateTime(2190319)
194194

195-
await(conn.sendPreparedStatement(s"alter database ${databaseName.get} set timezone to 'GMT'"))
196195
await(conn.sendPreparedStatement("CREATE TEMP TABLE TEST(T TIMESTAMP)"))
197196
await(conn.sendPreparedStatement("INSERT INTO TEST(T) VALUES(?)", Seq(date1)))
198197
val result = await(conn.sendPreparedStatement("SELECT T FROM TEST"))
199198
val date2 = result.rows.get.head(0)
200199

200+
date2 === date1.toDateTime(DateTimeZone.UTC).toLocalDateTime
201+
}
202+
203+
}
204+
205+
"handle sending a date with timezone and retrieving the date with the same time zone" in {
206+
207+
withTimeHandler {
208+
conn =>
209+
val date1 = new DateTime(2190319)
210+
211+
await(conn.sendPreparedStatement("CREATE TEMP TABLE TEST(T TIMESTAMP WITH TIME ZONE)"))
212+
await(conn.sendPreparedStatement("INSERT INTO TEST(T) VALUES(?)", Seq(date1)))
213+
val result = await(conn.sendPreparedStatement("SELECT T FROM TEST"))
214+
val date2 = result.rows.get.head(0)
215+
201216
date2 === date1
202217
}
203218
}

project/Build.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ object Configuration {
5555
"org.slf4j" % "slf4j-api" % "1.7.5",
5656
"joda-time" % "joda-time" % "2.2",
5757
"org.joda" % "joda-convert" % "1.3.1",
58-
"org.scala-lang" % "scala-library" % "2.10.2",
58+
"org.scala-lang" % "scala-library" % "2.10.3",
5959
"io.netty" % "netty-all" % "4.0.11.Final",
6060
"org.javassist" % "javassist" % "3.18.1-GA",
6161
specs2Dependency,

script/prepare_build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ echo "preparing postgresql configs"
88

99
psql -c 'create database netty_driver_test;' -U postgres
1010
psql -c 'create database netty_driver_time_test;' -U postgres
11+
psql -c "alter database netty_driver_time_test set timezone to 'GMT'" -U postgres
1112
psql -c "CREATE USER postgres_md5 WITH PASSWORD 'postgres_md5'; GRANT ALL PRIVILEGES ON DATABASE netty_driver_test to postgres_md5;" -U postgres
1213
psql -c "CREATE USER postgres_cleartext WITH PASSWORD 'postgres_cleartext'; GRANT ALL PRIVILEGES ON DATABASE netty_driver_test to postgres_cleartext;" -U postgres
1314
psql -c "CREATE USER postgres_kerberos WITH PASSWORD 'postgres_kerberos'; GRANT ALL PRIVILEGES ON DATABASE netty_driver_test to postgres_kerberos;" -U postgres

0 commit comments

Comments
 (0)
0