Mercurial > hg > monetdb-java
comparison src/main/java/org/monetdb/jdbc/MonetResultSet.java @ 820:4c35009cd59c
In ResultSet.getObject() method added support for retrieving
TIMESTAMP WITH TIME ZONE data as java.time.OffsetDateTime object and
TIME WITH TIME ZONE as java.time.OffsetTime object.
Also methods ResultSetMetaData.getColumnClassName() and ParameterMetaData.getParameterClassName() now return
java.time.OffsetDateTime.class for columns of type TIMESTAMP WITH TIME ZONE and
java.time.OffsetTime.class for columns of type TIME WITH TIME ZONE.
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 14 Dec 2023 14:58:21 +0100 (16 months ago) |
parents | e029af7551b7 |
children | 7eb05cbf67dc |
comparison
equal
deleted
inserted
replaced
819:726a1d7b168c | 820:4c35009cd59c |
---|---|
36 import java.sql.Statement; | 36 import java.sql.Statement; |
37 import java.sql.Time; | 37 import java.sql.Time; |
38 import java.sql.Timestamp; | 38 import java.sql.Timestamp; |
39 import java.sql.Types; | 39 import java.sql.Types; |
40 import java.text.SimpleDateFormat; | 40 import java.text.SimpleDateFormat; |
41 import java.time.OffsetDateTime; | |
42 import java.time.OffsetTime; | |
41 import java.util.Calendar; | 43 import java.util.Calendar; |
42 import java.util.Map; | 44 import java.util.Map; |
43 import java.util.TimeZone; | 45 import java.util.TimeZone; |
44 | 46 |
45 /** | 47 /** |
1424 case Types.BLOB: | 1426 case Types.BLOB: |
1425 return new MonetBlob(val); | 1427 return new MonetBlob(val); |
1426 case Types.DATE: | 1428 case Types.DATE: |
1427 return getDate(columnIndex, null); | 1429 return getDate(columnIndex, null); |
1428 case Types.TIME: | 1430 case Types.TIME: |
1431 return getTime(columnIndex, null); | |
1429 case Types.TIME_WITH_TIMEZONE: | 1432 case Types.TIME_WITH_TIMEZONE: |
1430 return getTime(columnIndex, null); | 1433 return getOffsetTime(columnIndex); |
1431 case Types.TIMESTAMP: | 1434 case Types.TIMESTAMP: |
1435 return getTimestamp(columnIndex, null); | |
1432 case Types.TIMESTAMP_WITH_TIMEZONE: | 1436 case Types.TIMESTAMP_WITH_TIMEZONE: |
1433 return getTimestamp(columnIndex, null); | 1437 return getOffsetDateTime(columnIndex); |
1434 case Types.BINARY: | 1438 case Types.BINARY: |
1435 case Types.VARBINARY: | 1439 case Types.VARBINARY: |
1436 /* case Types.LONGVARBINARY: // MonetDB doesn't use type LONGVARBINARY */ | 1440 /* case Types.LONGVARBINARY: // MonetDB doesn't use type LONGVARBINARY */ |
1437 return getBytes(columnIndex); | 1441 return getBytes(columnIndex); |
1438 case Types.OTHER: | 1442 case Types.OTHER: |
1509 type = MonetDriver.getClassForType(JdbcSQLTypes[columnIndex - 1]); | 1513 type = MonetDriver.getClassForType(JdbcSQLTypes[columnIndex - 1]); |
1510 } | 1514 } |
1511 | 1515 |
1512 if (type == null || type == String.class) { | 1516 if (type == null || type == String.class) { |
1513 return val; | 1517 return val; |
1514 } else if (type == BigDecimal.class) { | 1518 } |
1519 if (type == BigDecimal.class) { | |
1515 return getBigDecimal(columnIndex); | 1520 return getBigDecimal(columnIndex); |
1516 } else if (type == Boolean.class) { | 1521 } |
1522 if (type == Boolean.class) { | |
1517 return Boolean.valueOf(getBoolean(columnIndex)); | 1523 return Boolean.valueOf(getBoolean(columnIndex)); |
1518 } else if (type == Short.class) { | 1524 } |
1525 if (type == Integer.class) { | |
1526 return Integer.valueOf(getInt(columnIndex)); | |
1527 } | |
1528 if (type == Long.class) { | |
1529 return Long.valueOf(getLong(columnIndex)); | |
1530 } | |
1531 if (type == Short.class) { | |
1519 return Short.valueOf(getShort(columnIndex)); | 1532 return Short.valueOf(getShort(columnIndex)); |
1520 } else if (type == Integer.class) { | 1533 } |
1521 return Integer.valueOf(getInt(columnIndex)); | 1534 if (type == Double.class) { |
1522 } else if (type == Long.class) { | 1535 return Double.valueOf(getDouble(columnIndex)); |
1523 return Long.valueOf(getLong(columnIndex)); | 1536 } |
1524 } else if (type == Float.class) { | 1537 if (type == Float.class) { |
1525 return Float.valueOf(getFloat(columnIndex)); | 1538 return Float.valueOf(getFloat(columnIndex)); |
1526 } else if (type == Double.class) { | 1539 } |
1527 return Double.valueOf(getDouble(columnIndex)); | 1540 if (type == Date.class) { |
1528 } else if (type == byte[].class) { | 1541 return getDate(columnIndex, null); |
1542 } | |
1543 if (type == Time.class) { | |
1544 return getTime(columnIndex, null); | |
1545 } | |
1546 if (type == Timestamp.class) { | |
1547 return getTimestamp(columnIndex, null); | |
1548 } | |
1549 if (type == OffsetTime.class) { | |
1550 return getOffsetTime(columnIndex); | |
1551 } | |
1552 if (type == OffsetDateTime.class) { | |
1553 return getOffsetDateTime(columnIndex); | |
1554 } | |
1555 if (type == Clob.class) { | |
1556 return getClob(columnIndex); | |
1557 } | |
1558 if (type == Blob.class) { | |
1559 return getBlob(columnIndex); | |
1560 } | |
1561 if (type == byte[].class) { | |
1529 return getBytes(columnIndex); | 1562 return getBytes(columnIndex); |
1530 } else if (type == Date.class) { | 1563 } |
1531 return getDate(columnIndex, null); | 1564 if (classImplementsSQLData(type)) { |
1532 } else if (type == Time.class) { | |
1533 return getTime(columnIndex, null); | |
1534 } else if (type == Timestamp.class) { | |
1535 return getTimestamp(columnIndex, null); | |
1536 } else if (type == Clob.class) { | |
1537 return getClob(columnIndex); | |
1538 } else if (type == Blob.class) { | |
1539 return getBlob(columnIndex); | |
1540 } else if (classImplementsSQLData(type)) { | |
1541 final SQLData x; | 1565 final SQLData x; |
1542 try { | 1566 try { |
1543 final java.lang.reflect.Constructor<? extends SQLData> ctor = | 1567 final java.lang.reflect.Constructor<? extends SQLData> ctor = |
1544 ((Class)type).getConstructor(); | 1568 ((Class)type).getConstructor(); |
1545 x = ctor.newInstance(); | 1569 x = ctor.newInstance(); |
1692 return getRowId(colnum); | 1716 return getRowId(colnum); |
1693 } | 1717 } |
1694 }; | 1718 }; |
1695 x.readSQL(input, MonetDBtype); | 1719 x.readSQL(input, MonetDBtype); |
1696 return x; | 1720 return x; |
1697 } else { | 1721 } |
1698 return val; | 1722 return val; |
1699 } | |
1700 } | 1723 } |
1701 | 1724 |
1702 /** | 1725 /** |
1703 * Gets the value of the designated column in the current row of this | 1726 * Gets the value of the designated column in the current row of this |
1704 * ResultSet object as an Object in the Java programming language. | 1727 * ResultSet object as an Object in the Java programming language. |
3252 return type.cast(getTime(columnIndex, null)); | 3275 return type.cast(getTime(columnIndex, null)); |
3253 } | 3276 } |
3254 if (type == Timestamp.class) { | 3277 if (type == Timestamp.class) { |
3255 return type.cast(getTimestamp(columnIndex, null)); | 3278 return type.cast(getTimestamp(columnIndex, null)); |
3256 } | 3279 } |
3280 if (type == OffsetTime.class) { | |
3281 return type.cast(getOffsetTime(columnIndex)); | |
3282 } | |
3283 if (type == OffsetDateTime.class) { | |
3284 return type.cast(getOffsetDateTime(columnIndex)); | |
3285 } | |
3257 if (type == java.util.Date.class) { | 3286 if (type == java.util.Date.class) { |
3258 final Timestamp timestamp = getTimestamp(columnIndex, null); | 3287 final Timestamp timestamp = getTimestamp(columnIndex, null); |
3259 return type.cast(new java.util.Date(timestamp.getTime())); | 3288 return type.cast(new java.util.Date(timestamp.getTime())); |
3260 } | 3289 } |
3261 if (type == Calendar.class) { | 3290 if (type == Calendar.class) { |
3360 if (isClosed()) | 3389 if (isClosed()) |
3361 throw new SQLException("ResultSet is closed", "M1M20"); | 3390 throw new SQLException("ResultSet is closed", "M1M20"); |
3362 } | 3391 } |
3363 | 3392 |
3364 /** | 3393 /** |
3394 * Retrieves the value of the designated column in the current row | |
3395 * of this ResultSet object and will convert to OffsetTime. | |
3396 * If the conversion is not supported a SQLException is thrown. | |
3397 * | |
3398 * @param columnIndex the first column is 1, the second is 2, ... | |
3399 * @return OffsetTime object or null | |
3400 * @throws SQLException if conversion is not supported | |
3401 */ | |
3402 private OffsetTime getOffsetTime(final int columnIndex) throws SQLException { | |
3403 final String val; | |
3404 try { | |
3405 val = tlp.values[columnIndex - 1]; | |
3406 if (val == null) { | |
3407 lastReadWasNull = true; | |
3408 return null; | |
3409 } | |
3410 lastReadWasNull = false; | |
3411 return OffsetTime.parse(val, java.time.format.DateTimeFormatter.ISO_TIME); | |
3412 } catch (IndexOutOfBoundsException e) { | |
3413 throw newSQLInvalidColumnIndexException(columnIndex); | |
3414 } catch (java.time.format.DateTimeParseException e) { | |
3415 throw new SQLException("Failed to convert to OffsetTime: " + e.getMessage(), "22M36"); | |
3416 } | |
3417 } | |
3418 | |
3419 /** | |
3420 * Retrieves the value of the designated column in the current row | |
3421 * of this ResultSet object and will convert to OffsetDateTime. | |
3422 * If the conversion is not supported a SQLException is thrown. | |
3423 * | |
3424 * @param columnIndex the first column is 1, the second is 2, ... | |
3425 * @return OffsetDateTime object or null | |
3426 * @throws SQLException if conversion is not supported | |
3427 */ | |
3428 private OffsetDateTime getOffsetDateTime(final int columnIndex) throws SQLException { | |
3429 final String val; | |
3430 try { | |
3431 val = tlp.values[columnIndex - 1]; | |
3432 if (val == null) { | |
3433 lastReadWasNull = true; | |
3434 return null; | |
3435 } | |
3436 lastReadWasNull = false; | |
3437 | |
3438 // ISO_OFFSET_DATE_TIME format expects a 'T' instead of a space between date and time parts | |
3439 // replace the space between date and time parts with 'T' | |
3440 String val_new = val; | |
3441 final int space = val.indexOf(' ', 4); | |
3442 if (space > 4 && space < 16) { | |
3443 val_new = val.substring(0, space) + "T" + val.substring(space + 1); | |
3444 } | |
3445 // System.out.println("getOffsetDateTime() changed " + val + " into " + val_new); | |
3446 return OffsetDateTime.parse(val_new, java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME); | |
3447 } catch (IndexOutOfBoundsException e) { | |
3448 throw newSQLInvalidColumnIndexException(columnIndex); | |
3449 } catch (java.time.format.DateTimeParseException e) { | |
3450 throw new SQLException("Failed to convert to OffsetDateTime: " + e.getMessage(), "22M37"); | |
3451 } | |
3452 } | |
3453 | |
3454 /** | |
3365 * Small helper method that formats the "Invalid Column Index number ..." message | 3455 * Small helper method that formats the "Invalid Column Index number ..." message |
3366 * and creates a new SQLDataException object whose SQLState is set | 3456 * and creates a new SQLDataException object whose SQLState is set |
3367 * to "22010": invalid indicator parameter value. | 3457 * to "22010": invalid indicator parameter value. |
3368 * | 3458 * |
3369 * @param colIdx the column index number | 3459 * @param colIdx the column index number |