Skip to content

Commit

Permalink
fix: EXPOSED-122 Fix timestampWithTimeZone tests in Oracle (#1829)
Browse files Browse the repository at this point in the history
The following test fails when run on Oracle in the 3 modules:
exposed-kotlin-datetime, exposed-java-time, exposed-jodatime

DefaultsTest/testTimestampWithTimeZoneDefaults

The following tests fail when run on Oracle in exposed-jodatime only:

JodaTimeBaseTest/testTimestampWithTimeZone
JodaTimeMiscTableTest/testTimestampWithTimeZone

Issue 1:
Fails with:
ORA-01861: literal does not match format string
Because Oracle is set to use the default formatter (2023-08-09T11:26:32.7367231Z)
instead of the expected pattern (2023-08-09 11:26:32.7367231 +00:00).

Oracle now has its own datetime formatter in each module.

Issue 2:

In exposed-jodatime module only, reading a timestamp with time zone object in Oracle
then fails with a NPE. This occurs because of a read conversion error since DateTime
is sent to the DB as java.sql.Timestamp and ends up being stored as oracle.sql.TIMESTAMPTZ.

The object is instead read and retrieved as a java.sql.Timestamp.
  • Loading branch information
bog-walk authored Aug 10, 2023
1 parent 8fabb12 commit d168bd4
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ internal val MYSQL_OFFSET_DATE_TIME_FORMATTER by lazy {
)
}

// Example result: 2023-07-07 14:42:29.343789 +02:00
internal val ORACLE_OFFSET_DATE_TIME_FORMATTER by lazy {
DateTimeFormatter.ofPattern(
"yyyy-MM-dd HH:mm:ss.SSSSSS [xxx]",
Locale.ROOT
)
}

internal val DEFAULT_OFFSET_DATE_TIME_FORMATTER by lazy {
DateTimeFormatter.ISO_OFFSET_DATE_TIME.withLocale(Locale.ROOT)
}
Expand Down Expand Up @@ -272,6 +280,7 @@ class JavaOffsetDateTimeColumnType : ColumnType(), IDateColumnType {
when (currentDialect) {
is SQLiteDialect -> "'${value.format(SQLITE_OFFSET_DATE_TIME_FORMATTER)}'"
is MysqlDialect -> "'${value.format(MYSQL_OFFSET_DATE_TIME_FORMATTER)}'"
is OracleDialect -> "'${value.format(ORACLE_OFFSET_DATE_TIME_FORMATTER)}'"
else -> "'${value.format(DEFAULT_OFFSET_DATE_TIME_FORMATTER)}'"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.jetbrains.exposed.sql.IDateColumnType
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.vendors.MariaDBDialect
import org.jetbrains.exposed.sql.vendors.MysqlDialect
import org.jetbrains.exposed.sql.vendors.OracleDialect
import org.jetbrains.exposed.sql.vendors.SQLiteDialect
import org.jetbrains.exposed.sql.vendors.currentDialect
import org.joda.time.DateTime
Expand All @@ -29,6 +30,10 @@ private val MYSQL_DATE_TIME_WITH_TIME_ZONE_FORMATTER by lazy {
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSSSSZZ").withLocale(Locale.ROOT)
}

private val ORACLE_DATE_TIME_WITH_TIME_ZONE_FORMATTER by lazy {
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSSSS ZZ").withLocale(Locale.ROOT)
}

private val DEFAULT_DATE_TIME_WITH_TIME_ZONE_FORMATTER by lazy {
ISODateTimeFormat.dateTime().withLocale(Locale.ROOT)
}
Expand Down Expand Up @@ -151,6 +156,7 @@ class DateTimeWithTimeZoneColumnType : ColumnType(), IDateColumnType {
when (currentDialect) {
is SQLiteDialect -> "'${SQLITE_DATE_TIME_WITH_TIME_ZONE_FORMATTER.print(value)}'"
is MysqlDialect -> "'${MYSQL_DATE_TIME_WITH_TIME_ZONE_FORMATTER.print(value)}'"
is OracleDialect -> "'${ORACLE_DATE_TIME_WITH_TIME_ZONE_FORMATTER.print(value)}'"
else -> "'${DEFAULT_DATE_TIME_WITH_TIME_ZONE_FORMATTER.print(value)}'"
}
}
Expand All @@ -166,11 +172,13 @@ class DateTimeWithTimeZoneColumnType : ColumnType(), IDateColumnType {
DateTime.parse(value)
}
}
value is java.sql.Timestamp -> DateTime(value.time)
else -> error("Unexpected value: $value of ${value::class.qualifiedName}")
}

override fun readObject(rs: ResultSet, index: Int): Any? = when (currentDialect) {
is SQLiteDialect -> super.readObject(rs, index)
is OracleDialect -> rs.getObject(index, java.sql.Timestamp::class.java)
else -> {
if (offsetDateTimeClass != null) {
rs.getObject(index, offsetDateTimeClass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ internal val MYSQL_OFFSET_DATE_TIME_FORMATTER by lazy {
)
}

// Example result: 2023-07-07 14:42:29.343789 +02:00
internal val ORACLE_OFFSET_DATE_TIME_FORMATTER by lazy {
DateTimeFormatter.ofPattern(
"yyyy-MM-dd HH:mm:ss.SSSSSS [xxx]",
Locale.ROOT
)
}

internal val DEFAULT_OFFSET_DATE_TIME_FORMATTER by lazy {
DateTimeFormatter.ISO_OFFSET_DATE_TIME.withLocale(Locale.ROOT)
}
Expand Down Expand Up @@ -281,6 +289,7 @@ class KotlinOffsetDateTimeColumnType : ColumnType(), IDateColumnType {
when (currentDialect) {
is SQLiteDialect -> "'${value.format(SQLITE_OFFSET_DATE_TIME_FORMATTER)}'"
is MysqlDialect -> "'${value.format(MYSQL_OFFSET_DATE_TIME_FORMATTER)}'"
is OracleDialect -> "'${value.format(ORACLE_OFFSET_DATE_TIME_FORMATTER)}'"
else -> "'${value.format(DEFAULT_OFFSET_DATE_TIME_FORMATTER)}'"
}
}
Expand Down

0 comments on commit d168bd4

Please sign in to comment.