Compare commits

...

3 commits

Author SHA1 Message Date
fdc3fcd3e2 add java.time.LocalTime 2025-03-18 21:07:25 +01:00
5a1c5af6a5 remove java.time.Instant 2025-03-18 20:29:12 +01:00
d01695aff4 remove ZonedDateTime 2025-03-18 20:10:04 +01:00
22 changed files with 309 additions and 404 deletions
gradle.properties
jdbc-mariadb/src/main/java/org/xbib/jdbc/mariadb
jdbc-oracle/src/main/java/org/xbib/jdbc/oracle
jdbc-postgresql/src/main/java/org/xbib/jdbc/postgresql
jdbc-query/src
jdbc-test/src/main/java/org/xbib/jdbc/test

View file

@ -1,3 +1,3 @@
group = org.xbib group = org.xbib
name = database name = database
version = 2.4.0 version = 2.5.0

View file

@ -117,11 +117,6 @@ public class MariaDB implements Flavor {
return "datetime(3)"; // 3 = millisecond resolution return "datetime(3)"; // 3 = millisecond resolution
} }
@Override
public String typeZonedDateTime() {
return "datetime(3)"; // 3 = millisecond resolution
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
return "date"; return "date";

View file

@ -96,11 +96,6 @@ public class Oracle implements Flavor {
return "timestamp with time zone"; return "timestamp with time zone";
} }
@Override
public String typeZonedDateTime() {
return "timestamp with time zone";
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
// well, this is a full blown timestamp in Oracle // well, this is a full blown timestamp in Oracle

View file

@ -114,11 +114,6 @@ public class Postgresql implements Flavor {
return "timestamp with time zone"; return "timestamp with time zone";
} }
@Override
public String typeZonedDateTime() {
return "timestamp with time zone";
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
return "date"; return "date";

View file

@ -12,6 +12,8 @@ import java.sql.Timestamp;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -477,6 +479,7 @@ public class DatabaseImpl implements Database {
case Boolean b -> sql.argBoolean(k, b); case Boolean b -> sql.argBoolean(k, b);
case LocalDate localDate -> sql.argLocalDate(k, localDate); case LocalDate localDate -> sql.argLocalDate(k, localDate);
case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime); case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime);
case OffsetDateTime offsetDateTime -> sql.argOffsetDateTime(k, offsetDateTime);
case null, default -> case null, default ->
throw new DatabaseException("unknown type for param: " + (v != null ? v.getClass() : "null")); throw new DatabaseException("unknown type for param: " + (v != null ? v.getClass() : "null"));
} }
@ -495,7 +498,9 @@ public class DatabaseImpl implements Database {
case Long l -> sql.argLong(k, l); case Long l -> sql.argLong(k, l);
case Boolean b -> sql.argBoolean(k, b); case Boolean b -> sql.argBoolean(k, b);
case LocalDate localDate -> sql.argLocalDate(k, localDate); case LocalDate localDate -> sql.argLocalDate(k, localDate);
case LocalTime localTime -> sql.argLocalTime(k, localTime);
case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime); case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime);
case OffsetDateTime offsetDateTime -> sql.argOffsetDateTime(k, offsetDateTime);
case null -> sql.argNull(k); case null -> sql.argNull(k);
default -> throw new DatabaseException("unknown type for param: " + v.getClass()); default -> throw new DatabaseException("unknown type for param: " + v.getClass());
} }
@ -514,7 +519,9 @@ public class DatabaseImpl implements Database {
case Long l -> sql.argLong(k, l); case Long l -> sql.argLong(k, l);
case Boolean b -> sql.argBoolean(k, b); case Boolean b -> sql.argBoolean(k, b);
case LocalDate localDate -> sql.argLocalDate(k, localDate); case LocalDate localDate -> sql.argLocalDate(k, localDate);
case LocalTime localTime -> sql.argLocalTime(k, localTime);
case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime); case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime);
case OffsetDateTime offsetDateTime -> sql.argOffsetDateTime(k, offsetDateTime);
case null -> sql.argNull(k); case null -> sql.argNull(k);
default -> throw new DatabaseException("unknown type for param: " + v.getClass()); default -> throw new DatabaseException("unknown type for param: " + v.getClass());
} }
@ -538,6 +545,7 @@ public class DatabaseImpl implements Database {
case "java.lang.Boolean" -> row.add(rows.getBooleanOrFalse(i + 1)); case "java.lang.Boolean" -> row.add(rows.getBooleanOrFalse(i + 1));
case "java.sql.Clob", "oracle.jdbc.OracleClob" -> row.add(rows.getClobStringOrEmpty(i + 1)); case "java.sql.Clob", "oracle.jdbc.OracleClob" -> row.add(rows.getClobStringOrEmpty(i + 1));
case "java.sql.Date" -> row.add(rows.getLocalDateOrNull(i + 1)); case "java.sql.Date" -> row.add(rows.getLocalDateOrNull(i + 1));
case "java.sql.Time" -> row.add(rows.getLocalTimeOrNull(i + 1));
case "oracle.sql.TIMESTAMPTZ" -> row.add(rows.getOffsetDateTimeOrNull(i + 1)); case "oracle.sql.TIMESTAMPTZ" -> row.add(rows.getOffsetDateTimeOrNull(i + 1));
case "java.sql.Timestamp", "oracle.sql.TIMESTAMP" -> row.add(rows.getLocalDateTimeOrNull(i + 1)); case "java.sql.Timestamp", "oracle.sql.TIMESTAMP" -> row.add(rows.getLocalDateTimeOrNull(i + 1));
case "java.math.BigDecimal" -> row.add(rows.getBigDecimalOrNull(i + 1)); case "java.math.BigDecimal" -> row.add(rows.getBigDecimalOrNull(i + 1));

View file

@ -44,8 +44,6 @@ public interface Flavor {
String typeOffsetDateTime(); String typeOffsetDateTime();
String typeZonedDateTime();
String typeLocalDate(); String typeLocalDate();
boolean useStringForClob(); boolean useStringForClob();

View file

@ -4,12 +4,10 @@ import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
/** /**
* Interface for reading results from a database query. * Interface for reading results from a database query.
@ -358,11 +356,17 @@ public interface Row {
InputStream getBlobInputStreamOrEmpty(String columnName); InputStream getBlobInputStreamOrEmpty(String columnName);
Instant getInstantOrNull(); LocalDate getLocalDateOrNull();
Instant getInstantOrNull(int columnOneBased); LocalDate getLocalDateOrNull(int columnOneBased);
Instant getInstantOrNull(String columnName); LocalDate getLocalDateOrNull(String columnName);
LocalTime getLocalTimeOrNull();
LocalTime getLocalTimeOrNull(int columnOneBased);
LocalTime getLocalTimeOrNull(String columnName);
LocalDateTime getLocalDateTimeOrNull(); LocalDateTime getLocalDateTimeOrNull();
@ -375,35 +379,4 @@ public interface Row {
OffsetDateTime getOffsetDateTimeOrNull(int columnOneBase); OffsetDateTime getOffsetDateTimeOrNull(int columnOneBase);
OffsetDateTime getOffsetDateTimeOrNull(String columnName); OffsetDateTime getOffsetDateTimeOrNull(String columnName);
ZonedDateTime getZonedDateTimeOrNull();
ZonedDateTime getZonedDateTimeOrNull(int columnOneBase);
ZonedDateTime getZonedDateTimeOrNull(String columnName);
/**
* Retrieve column as LocalDate, .i.e, date with no time.
*
* @return LocalDate of the database column value
*/
LocalDate getLocalDateOrNull();
/**
* Get the Date field, with no timestamp
*
* @param columnOneBased column number starting at 1, not 0
* @return LocalDate of the column value
*/
LocalDate getLocalDateOrNull(int columnOneBased);
/**
* Get the Date field, with no timestamp
*
* @param columnName column name to retrieve
* @return LocalDate of the column value
*/
LocalDate getLocalDateOrNull(String columnName);
} }

View file

@ -9,11 +9,10 @@ import java.math.RoundingMode;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
/** /**
* Safely wrap a ResultSet and provide access to the data it contains. * Safely wrap a ResultSet and provide access to the data it contains.
@ -657,25 +656,54 @@ class RowsAdapter implements Rows {
} }
@Override @Override
public Instant getInstantOrNull() { public LocalDate getLocalDateOrNull() {
return getInstantOrNull(column++); return getLocalDateOrNull(column++);
} }
@Override @Override
public Instant getInstantOrNull(int columnOneBased) { public LocalDate getLocalDateOrNull(int columnOneBased) {
try { try {
column = columnOneBased + 1; column = columnOneBased + 1;
return rs.getObject(columnOneBased, Instant.class); java.sql.Date val = rs.getDate(columnOneBased);
return val == null ? null : val.toLocalDate();
} catch (SQLException e) { } catch (SQLException e) {
throw new DatabaseException(e); throw new DatabaseException(e);
} }
} }
@Override @Override
public Instant getInstantOrNull(String columnName) { public LocalDate getLocalDateOrNull(String columnName) {
try { try {
column = rs.findColumn(columnName) + 1; column = rs.findColumn(columnName) + 1;
return rs.getObject(columnName, Instant.class); java.sql.Date val = rs.getDate(columnName);
return val == null ? null : val.toLocalDate();
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override
public LocalTime getLocalTimeOrNull() {
return getLocalTimeOrNull(column++);
}
@Override
public LocalTime getLocalTimeOrNull(int columnOneBased) {
try {
column = columnOneBased + 1;
java.sql.Time val = rs.getTime(columnOneBased);
return val == null ? null : val.toLocalTime();
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override
public LocalTime getLocalTimeOrNull(String columnName) {
try {
column = rs.findColumn(columnName) + 1;
java.sql.Time val = rs.getTime(columnName);
return val == null ? null : val.toLocalTime();
} catch (SQLException e) { } catch (SQLException e) {
throw new DatabaseException(e); throw new DatabaseException(e);
} }
@ -706,33 +734,6 @@ class RowsAdapter implements Rows {
} }
} }
@Override
public LocalDate getLocalDateOrNull() {
return getLocalDateOrNull(column++);
}
@Override
public LocalDate getLocalDateOrNull(int columnOneBased) {
try {
column = columnOneBased + 1;
java.sql.Date val = rs.getDate(columnOneBased);
return val == null ? null : val.toLocalDate();
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override
public LocalDate getLocalDateOrNull(String columnName) {
try {
column = rs.findColumn(columnName) + 1;
java.sql.Date val = rs.getDate(columnName);
return val == null ? null : val.toLocalDate();
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override @Override
public OffsetDateTime getOffsetDateTimeOrNull() { public OffsetDateTime getOffsetDateTimeOrNull() {
return getOffsetDateTimeOrNull(column++); return getOffsetDateTimeOrNull(column++);
@ -758,31 +759,6 @@ class RowsAdapter implements Rows {
} }
} }
@Override
public ZonedDateTime getZonedDateTimeOrNull() {
return getZonedDateTimeOrNull(column++);
}
@Override
public ZonedDateTime getZonedDateTimeOrNull(int columnOneBased) {
try {
column = columnOneBased + 1;
return rs.getObject(columnOneBased, ZonedDateTime.class);
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override
public ZonedDateTime getZonedDateTimeOrNull(String columnName) {
try {
column = rs.findColumn(columnName) + 1;
return rs.getObject(columnName, ZonedDateTime.class);
} catch (SQLException e) {
throw new DatabaseException(e);
}
}
@Override @Override
public Integer rowCount() { public Integer rowCount() {
try { try {

View file

@ -238,9 +238,6 @@ public class Schema {
case OffsetDateTime: case OffsetDateTime:
sql.append(flavor.typeOffsetDateTime()); sql.append(flavor.typeOffsetDateTime());
break; break;
case ZonedDateTime:
sql.append(flavor.typeZonedDateTime());
break;
case LocalDate: case LocalDate:
sql.append(flavor.typeLocalDate()); sql.append(flavor.typeLocalDate());
break; break;
@ -418,7 +415,6 @@ public class Schema {
Instant, Instant,
LocalDateTime, LocalDateTime,
OffsetDateTime, OffsetDateTime,
ZonedDateTime,
LocalDate, LocalDate,
Boolean Boolean
} }
@ -939,10 +935,6 @@ public class Schema {
return asType(ColumnType.OffsetDateTime); return asType(ColumnType.OffsetDateTime);
} }
public Column asZonedateTime() {
return asType(ColumnType.ZonedDateTime);
}
public Column asLocalDate() { public Column asLocalDate() {
return asType(ColumnType.LocalDate); return asType(ColumnType.LocalDate);
} }

View file

@ -8,6 +8,8 @@ import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@ -133,7 +135,28 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
invocations.add(new Invocation(ColumnType.String, argName, arg)); invocations.add(new Invocation(ColumnType.String, argName, arg));
return this; return this;
} }
public SqlArgs argLocalDate(LocalDate arg) {
invocations.add(new Invocation(ColumnType.LocalDate, null, arg));
return this;
}
public SqlArgs argLocalDate(String argName, LocalDate arg) {
invocations.add(new Invocation(ColumnType.LocalDate, argName, arg));
return this;
}
public SqlArgs argLocalTime(LocalTime arg) {
invocations.add(new Invocation(ColumnType.LocalTime, null, arg));
return this;
}
public SqlArgs argLocalTime(String argName, LocalTime arg) {
invocations.add(new Invocation(ColumnType.LocalTime, argName, arg));
return this;
}
public SqlArgs argLocalDateTime(LocalDateTime arg) { public SqlArgs argLocalDateTime(LocalDateTime arg) {
invocations.add(new Invocation(ColumnType.LocalDateTime, null, arg)); invocations.add(new Invocation(ColumnType.LocalDateTime, null, arg));
return this; return this;
@ -143,14 +166,14 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
invocations.add(new Invocation(ColumnType.LocalDateTime, argName, arg)); invocations.add(new Invocation(ColumnType.LocalDateTime, argName, arg));
return this; return this;
} }
public SqlArgs argLocalDate(LocalDate arg) { public SqlArgs argOffsetDateTime(OffsetDateTime arg) {
invocations.add(new Invocation(ColumnType.LocalDate, null, arg)); invocations.add(new Invocation(ColumnType.OffsetDateTime, null, arg));
return this; return this;
} }
public SqlArgs argLocalDate(String argName, LocalDate arg) { public SqlArgs argOffsetDateTime(String argName, OffsetDateTime arg) {
invocations.add(new Invocation(ColumnType.LocalDate, argName, arg)); invocations.add(new Invocation(ColumnType.OffsetDateTime, argName, arg));
return this; return this;
} }
@ -163,7 +186,17 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
invocations.add(new Invocation(ColumnType.LocalDateTimeNowPerDb, argName, null)); invocations.add(new Invocation(ColumnType.LocalDateTimeNowPerDb, argName, null));
return this; return this;
} }
public SqlArgs argOffsetDateTimeNowPerDb() {
invocations.add(new Invocation(ColumnType.OffsetDateTimeNowPerDb, null, null));
return this;
}
public SqlArgs argOffsetDateTimeNowPerDb(String argName) {
invocations.add(new Invocation(ColumnType.OffsetDateTimeNowPerDb, argName, null));
return this;
}
public SqlArgs argBlobBytes(byte[] arg) { public SqlArgs argBlobBytes(byte[] arg) {
invocations.add(new Invocation(ColumnType.BlobBytes, null, arg)); invocations.add(new Invocation(ColumnType.BlobBytes, null, arg));
return this; return this;
@ -283,12 +316,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
} }
break; break;
case String: case String:
if (i.argName == null) {
select.argString((String) i.arg);
} else {
select.argString(i.argName, (String) i.arg);
}
break;
case ClobString: case ClobString:
if (i.argName == null) { if (i.argName == null) {
select.argString((String) i.arg); select.argString((String) i.arg);
@ -299,7 +326,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
case ClobStream: case ClobStream:
throw new DatabaseException("Don't use Clob stream parameters with select statements"); throw new DatabaseException("Don't use Clob stream parameters with select statements");
case BlobBytes: case BlobBytes:
throw new DatabaseException("Don't use Blob parameters with select statements");
case BlobStream: case BlobStream:
throw new DatabaseException("Don't use Blob parameters with select statements"); throw new DatabaseException("Don't use Blob parameters with select statements");
case LocalDate: case LocalDate:
@ -309,6 +335,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
select.argLocalDate(i.argName, (LocalDate) i.arg); select.argLocalDate(i.argName, (LocalDate) i.arg);
} }
break; break;
case LocalTime:
if (i.argName == null) {
select.argLocalTime((LocalTime) i.arg);
} else {
select.argLocalTime(i.argName, (LocalTime) i.arg);
}
break;
case LocalDateTime: case LocalDateTime:
if (i.argName == null) { if (i.argName == null) {
select.argLocalDateTime((LocalDateTime) i.arg); select.argLocalDateTime((LocalDateTime) i.arg);
@ -316,6 +349,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
select.argLocalDateTime(i.argName, (LocalDateTime) i.arg); select.argLocalDateTime(i.argName, (LocalDateTime) i.arg);
} }
break; break;
case OffsetDateTime:
if (i.argName == null) {
select.argOffsetDateTime((OffsetDateTime) i.arg);
} else {
select.argOffsetDateTime(i.argName, (OffsetDateTime) i.arg);
}
break;
case LocalDateTimeNowPerDb: case LocalDateTimeNowPerDb:
if (i.argName == null) { if (i.argName == null) {
select.argLocalDateTimeNowPerDb(); select.argLocalDateTimeNowPerDb();
@ -323,6 +363,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
select.argLocalDateTimeNowPerDb(i.argName); select.argLocalDateTimeNowPerDb(i.argName);
} }
break; break;
case OffsetDateTimeNowPerDb:
if (i.argName == null) {
select.argOffsetDateTimeNowPerDb();
} else {
select.argOffsetDateTimeNowPerDb(i.argName);
}
break;
} }
} }
} }
@ -416,6 +463,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
insert.argLocalDate(i.argName, (LocalDate) i.arg); insert.argLocalDate(i.argName, (LocalDate) i.arg);
} }
break; break;
case LocalTime:
if (i.argName == null) {
insert.argLocalTime((LocalTime) i.arg);
} else {
insert.argLocalTime(i.argName, (LocalTime) i.arg);
}
break;
case LocalDateTime: case LocalDateTime:
if (i.argName == null) { if (i.argName == null) {
insert.argLocalDateTime((LocalDateTime) i.arg); insert.argLocalDateTime((LocalDateTime) i.arg);
@ -430,6 +484,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
insert.argLocalDateTimeNowPerDb(i.argName); insert.argLocalDateTimeNowPerDb(i.argName);
} }
break; break;
case OffsetDateTimeNowPerDb:
if (i.argName == null) {
insert.argOffsetDateTimeNowPerDb();
} else {
insert.argOffsetDateTimeNowPerDb(i.argName);
}
break;
} }
} }
} }
@ -523,6 +584,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
update.argLocalDate(i.argName, (LocalDate) i.arg); update.argLocalDate(i.argName, (LocalDate) i.arg);
} }
break; break;
case LocalTime:
if (i.argName == null) {
update.argLocalTime((LocalTime) i.arg);
} else {
update.argLocalTime(i.argName, (LocalTime) i.arg);
}
break;
case LocalDateTime: case LocalDateTime:
if (i.argName == null) { if (i.argName == null) {
update.argLocalDateTime((LocalDateTime) i.arg); update.argLocalDateTime((LocalDateTime) i.arg);
@ -537,6 +605,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
update.argLocalDateTimeNowPerDb(i.argName); update.argLocalDateTimeNowPerDb(i.argName);
} }
break; break;
case OffsetDateTimeNowPerDb:
if (i.argName == null) {
update.argOffsetDateTimeNowPerDb();
} else {
update.argOffsetDateTimeNowPerDb(i.argName);
}
break;
} }
} }
} }
@ -572,8 +647,11 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
BlobBytes, BlobBytes,
BlobStream, BlobStream,
LocalDate, LocalDate,
LocalTime,
LocalDateTime, LocalDateTime,
LocalDateTimeNowPerDb LocalDateTimeNowPerDb,
OffsetDateTime,
OffsetDateTimeNowPerDb
} }
private static class Invocation { private static class Invocation {
@ -691,15 +769,15 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
args.argLocalDate(names[i], r.getLocalDateOrNull()); args.argLocalDate(names[i], r.getLocalDateOrNull());
break; break;
case Types.TIMESTAMP: case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
if (this.scale[i] == 0) { if (this.scale[i] == 0) {
// If the scale is 0, this is a LocalDate (no time/timezone).
// Anything with a time will have a non-zero scale
args.argLocalDate(names[i], r.getLocalDateOrNull()); args.argLocalDate(names[i], r.getLocalDateOrNull());
} else { } else {
args.argLocalDateTime(names[i], r.getLocalDateTimeOrNull()); args.argLocalDateTime(names[i], r.getLocalDateTimeOrNull());
} }
break; break;
case Types.TIMESTAMP_WITH_TIMEZONE:
args.argOffsetDateTime(names[i], r.getOffsetDateTimeOrNull());
break;
case Types.NVARCHAR: case Types.NVARCHAR:
case Types.VARCHAR: case Types.VARCHAR:
case Types.CHAR: case Types.CHAR:

View file

@ -3,12 +3,10 @@ package org.xbib.jdbc.query;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
/** /**
* Interface for configuring (setting parameters) and executing a chunk of SQL. * Interface for configuring (setting parameters) and executing a chunk of SQL.
@ -43,9 +41,13 @@ public interface SqlInsert {
SqlInsert argString( String argName, String arg); SqlInsert argString( String argName, String arg);
SqlInsert argInstant(Instant arg); SqlInsert argLocalDate(LocalDate arg);
SqlInsert argInstant(String argName, Instant arg); SqlInsert argLocalDate(String argName, LocalDate arg);
SqlInsert argLocalTime(LocalTime arg);
SqlInsert argLocalTime(String argName, LocalTime arg);
SqlInsert argLocalDateTime(LocalDateTime arg); SqlInsert argLocalDateTime(LocalDateTime arg);
@ -55,18 +57,14 @@ public interface SqlInsert {
SqlInsert argOffsetDateTime(String argName, OffsetDateTime arg); SqlInsert argOffsetDateTime(String argName, OffsetDateTime arg);
SqlInsert argZonedDateTime(ZonedDateTime arg);
SqlInsert argZonedDateTime(String argName, ZonedDateTime arg);
SqlInsert argLocalDate(LocalDate arg);
SqlInsert argLocalDate( String argName, LocalDate arg);
SqlInsert argLocalDateTimeNowPerDb(); SqlInsert argLocalDateTimeNowPerDb();
SqlInsert argLocalDateTimeNowPerDb(String argName); SqlInsert argLocalDateTimeNowPerDb(String argName);
SqlInsert argOffsetDateTimeNowPerDb();
SqlInsert argOffsetDateTimeNowPerDb(String argName);
SqlInsert argBlobBytes(byte[] arg); SqlInsert argBlobBytes(byte[] arg);
SqlInsert argBlobBytes(String argName, byte[] arg); SqlInsert argBlobBytes(String argName, byte[] arg);

View file

@ -1,6 +1,7 @@
package org.xbib.jdbc.query; package org.xbib.jdbc.query;
import java.sql.Types; import java.sql.Types;
import java.time.LocalTime;
import org.xbib.jdbc.query.util.DebugSql; import org.xbib.jdbc.query.util.DebugSql;
import org.xbib.jdbc.query.util.InternalStringReader; import org.xbib.jdbc.query.util.InternalStringReader;
import org.xbib.jdbc.query.util.Metric; import org.xbib.jdbc.query.util.Metric;
@ -13,11 +14,9 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -143,16 +142,6 @@ public class SqlInsertImpl implements SqlInsert {
return namedArg(argName, adaptor.nullString(arg)); return namedArg(argName, adaptor.nullString(arg));
} }
@Override
public SqlInsert argInstant(Instant arg) {
return positionalArg(adaptor.nullInstant(arg));
}
@Override
public SqlInsert argInstant(String argName, Instant arg) {
return namedArg(argName, adaptor.nullInstant(arg));
}
@Override @Override
public SqlInsert argLocalDateTime(LocalDateTime arg) { public SqlInsert argLocalDateTime(LocalDateTime arg) {
return positionalArg(adaptor.nullLocalDateTime(arg)); return positionalArg(adaptor.nullLocalDateTime(arg));
@ -164,13 +153,23 @@ public class SqlInsertImpl implements SqlInsert {
} }
@Override @Override
public SqlInsert argLocalDate( String argName, LocalDate arg) { public SqlInsert argLocalDate(LocalDate arg) {
return positionalArg(adaptor.nullLocalDate(arg));
}
@Override
public SqlInsert argLocalDate(String argName, LocalDate arg) {
return namedArg(argName, adaptor.nullLocalDate(arg)); return namedArg(argName, adaptor.nullLocalDate(arg));
} }
@Override @Override
public SqlInsert argLocalDate(LocalDate arg) { public SqlInsert argLocalTime(LocalTime arg) {
return positionalArg(adaptor.nullLocalDate(arg)); return positionalArg(adaptor.nullLocalTime(arg));
}
@Override
public SqlInsert argLocalTime(String argName, LocalTime arg) {
return namedArg(argName, adaptor.nullLocalTime(arg));
} }
@Override @Override
@ -183,16 +182,6 @@ public class SqlInsertImpl implements SqlInsert {
return namedArg(argName, adaptor.nullOffsetDateTime(arg)); return namedArg(argName, adaptor.nullOffsetDateTime(arg));
} }
@Override
public SqlInsert argZonedDateTime(ZonedDateTime arg) {
return positionalArg(adaptor.nullZonedDateTime(arg));
}
@Override
public SqlInsert argZonedDateTime(String argName, ZonedDateTime arg) {
return namedArg(argName, adaptor.nullZonedDateTime(arg));
}
@Override @Override
public SqlInsert argLocalDateTimeNowPerDb() { public SqlInsert argLocalDateTimeNowPerDb() {
if (options.useClientClock()) { if (options.useClientClock()) {
@ -209,6 +198,22 @@ public class SqlInsertImpl implements SqlInsert {
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis())); return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
} }
@Override
public SqlInsert argOffsetDateTimeNowPerDb() {
if (options.useClientClock()) {
return positionalArg(adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override
public SqlInsert argOffsetDateTimeNowPerDb(String argName) {
if (options.useClientClock()) {
return namedArg(argName, adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override @Override
public SqlInsert argBlobBytes(byte[] arg) { public SqlInsert argBlobBytes(byte[] arg) {
return positionalArg(adaptor.nullBytes(arg)); return positionalArg(adaptor.nullBytes(arg));

View file

@ -1,11 +1,10 @@
package org.xbib.jdbc.query; package org.xbib.jdbc.query;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
/** /**
@ -41,9 +40,13 @@ public interface SqlSelect {
SqlSelect argString( String argName, String arg); SqlSelect argString( String argName, String arg);
SqlSelect argInstant(Instant arg); SqlSelect argLocalDate(LocalDate arg);
SqlSelect argInstant(String argName, Instant arg); SqlSelect argLocalDate(String argName, LocalDate arg);
SqlSelect argLocalTime(LocalTime arg);
SqlSelect argLocalTime(String argName, LocalTime arg);
SqlSelect argLocalDateTime(LocalDateTime arg); SqlSelect argLocalDateTime(LocalDateTime arg);
@ -53,22 +56,14 @@ public interface SqlSelect {
SqlSelect argOffsetDateTime(String argName, OffsetDateTime arg); SqlSelect argOffsetDateTime(String argName, OffsetDateTime arg);
SqlSelect argZonedDateTime(ZonedDateTime arg);
SqlSelect argZonedDateTime(String argName, ZonedDateTime arg);
SqlSelect argLocalDate(LocalDate arg);
SqlSelect argLocalDate(String argName, LocalDate arg);
SqlSelect argInstantNowPerDb();
SqlSelect argInstantNowPerDb(String argName);
SqlSelect argLocalDateTimeNowPerDb(); SqlSelect argLocalDateTimeNowPerDb();
SqlSelect argLocalDateTimeNowPerDb(String argName); SqlSelect argLocalDateTimeNowPerDb(String argName);
SqlSelect argOffsetDateTimeNowPerDb();
SqlSelect argOffsetDateTimeNowPerDb(String argName);
SqlSelect withTimeoutSeconds(int seconds); SqlSelect withTimeoutSeconds(int seconds);
SqlSelect withMaxRows(int rows); SqlSelect withMaxRows(int rows);
@ -131,17 +126,13 @@ public interface SqlSelect {
*/ */
List<String> queryStrings(); List<String> queryStrings();
Instant queryInstantOrNull();
List<Instant> queryInstants();
LocalDateTime queryLocalDateTimeOrNull(); LocalDateTime queryLocalDateTimeOrNull();
List<LocalDateTime> queryLocalDateTimes(); List<LocalDateTime> queryLocalDateTimes();
ZonedDateTime queryZonedDateTimeOrNull(); OffsetDateTime queryOffsetDateTimeOrNull();
List<ZonedDateTime> queryZonedDateTimes(); List<OffsetDateTime> queryOffsetDateTimes();
LocalDate queryLocalDateOrNull(); LocalDate queryLocalDateOrNull();

View file

@ -1,5 +1,6 @@
package org.xbib.jdbc.query; package org.xbib.jdbc.query;
import java.time.LocalTime;
import org.xbib.jdbc.query.util.DebugSql; import org.xbib.jdbc.query.util.DebugSql;
import org.xbib.jdbc.query.util.Metric; import org.xbib.jdbc.query.util.Metric;
import org.xbib.jdbc.query.util.RewriteArg; import org.xbib.jdbc.query.util.RewriteArg;
@ -9,11 +10,9 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -137,16 +136,6 @@ public class SqlSelectImpl implements SqlSelect {
return namedArg(argName, adaptor.nullString(arg)); return namedArg(argName, adaptor.nullString(arg));
} }
@Override
public SqlSelect argInstant(Instant arg) {
return positionalArg(adaptor.nullInstant(arg));
}
@Override
public SqlSelect argInstant(String argName, Instant arg) {
return namedArg(argName, adaptor.nullInstant(arg));
}
@Override @Override
public SqlSelect argLocalDateTime(LocalDateTime arg) { public SqlSelect argLocalDateTime(LocalDateTime arg) {
return positionalArg(adaptor.nullLocalDateTime(arg)); return positionalArg(adaptor.nullLocalDateTime(arg));
@ -167,16 +156,6 @@ public class SqlSelectImpl implements SqlSelect {
return namedArg(argName, adaptor.nullOffsetDateTime(arg)); return namedArg(argName, adaptor.nullOffsetDateTime(arg));
} }
@Override
public SqlSelect argZonedDateTime(ZonedDateTime arg) {
return positionalArg(adaptor.nullZonedDateTime(arg));
}
@Override
public SqlSelect argZonedDateTime(String argName, ZonedDateTime arg) {
return namedArg(argName, adaptor.nullZonedDateTime(arg));
}
@Override @Override
public SqlSelect argLocalDate(LocalDate arg) { public SqlSelect argLocalDate(LocalDate arg) {
return positionalArg(adaptor.nullLocalDate(arg)); return positionalArg(adaptor.nullLocalDate(arg));
@ -188,19 +167,13 @@ public class SqlSelectImpl implements SqlSelect {
} }
@Override @Override
public SqlSelect argInstantNowPerDb() { public SqlSelect argLocalTime(LocalTime arg) {
if (options.useClientClock()) { return positionalArg(adaptor.nullLocalTime(arg));
return positionalArg(adaptor.nullInstant(Instant.now()));
}
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
} }
@Override @Override
public SqlSelect argInstantNowPerDb(String argName) { public SqlSelect argLocalTime(String argName, LocalTime arg) {
if (options.useClientClock()) { return namedArg(argName, adaptor.nullLocalTime(arg));
return namedArg(argName, adaptor.nullInstant(Instant.now()));
}
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
} }
@Override @Override
@ -218,7 +191,23 @@ public class SqlSelectImpl implements SqlSelect {
} }
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis())); return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
} }
@Override
public SqlSelect argOffsetDateTimeNowPerDb() {
if (options.useClientClock()) {
return positionalArg(adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override
public SqlSelect argOffsetDateTimeNowPerDb(String argName) {
if (options.useClientClock()) {
return namedArg(argName, adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override @Override
public SqlSelect withTimeoutSeconds(int seconds) { public SqlSelect withTimeoutSeconds(int seconds) {
timeoutSeconds = seconds; timeoutSeconds = seconds;
@ -478,31 +467,6 @@ public class SqlSelectImpl implements SqlSelect {
}); });
} }
@Override
public Instant queryInstantOrNull() {
return queryWithTimeout(rs -> {
if (rs.next()) {
return rs.getInstantOrNull(1);
}
return null;
});
}
@Override
public List<Instant> queryInstants() {
return queryWithTimeout(rs -> {
List<Instant> result = new ArrayList<>();
while (rs.next()) {
Instant value = rs.getInstantOrNull(1);
if (value != null) {
result.add(value);
}
}
return result;
});
}
@Override @Override
public LocalDateTime queryLocalDateTimeOrNull() { public LocalDateTime queryLocalDateTimeOrNull() {
return queryWithTimeout(rs -> { return queryWithTimeout(rs -> {
@ -528,32 +492,17 @@ public class SqlSelectImpl implements SqlSelect {
} }
@Override @Override
public ZonedDateTime queryZonedDateTimeOrNull() { public OffsetDateTime queryOffsetDateTimeOrNull() {
return queryWithTimeout(rs -> { return null;
if (rs.next()) {
return rs.getZonedDateTimeOrNull(1);
}
return null;
});
} }
@Override @Override
public List<ZonedDateTime> queryZonedDateTimes() { public List<OffsetDateTime> queryOffsetDateTimes() {
return queryWithTimeout(rs -> { return List.of();
List<ZonedDateTime> result = new ArrayList<>();
while (rs.next()) {
ZonedDateTime value = rs.getZonedDateTimeOrNull(1);
if (value != null) {
result.add(value);
}
}
return result;
});
} }
@Override @Override
public LocalDate queryLocalDateOrNull() { public LocalDate queryLocalDateOrNull() {
// Date without time
return queryWithTimeout(rs -> { return queryWithTimeout(rs -> {
if (rs.next()) { if (rs.next()) {
return rs.getLocalDateOrNull(1); return rs.getLocalDateOrNull(1);
@ -564,7 +513,6 @@ public class SqlSelectImpl implements SqlSelect {
@Override @Override
public List<LocalDate> queryLocalDates() { public List<LocalDate> queryLocalDates() {
// Date without time
return queryWithTimeout(rs -> { return queryWithTimeout(rs -> {
List<LocalDate> result = new ArrayList<>(); List<LocalDate> result = new ArrayList<>();
while (rs.next()) { while (rs.next()) {

View file

@ -5,6 +5,8 @@ import java.io.Reader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
/** /**
* Interface for configuring (setting parameters) and executing a chunk of SQL. * Interface for configuring (setting parameters) and executing a chunk of SQL.
@ -38,19 +40,31 @@ public interface SqlUpdate {
SqlUpdate argString(String arg); SqlUpdate argString(String arg);
SqlUpdate argString(String argName, String arg); SqlUpdate argString(String argName, String arg);
SqlUpdate argLocalDateTime(LocalDateTime arg);
SqlUpdate argLocalDateTime(String argName, LocalDateTime arg);
SqlUpdate argLocalDate(LocalDate arg); SqlUpdate argLocalDate(LocalDate arg);
SqlUpdate argLocalDate(String argName, LocalDate arg); SqlUpdate argLocalDate(String argName, LocalDate arg);
SqlUpdate argLocalTime(LocalTime arg);
SqlUpdate argLocalTime(String argName, LocalTime arg);
SqlUpdate argLocalDateTime(LocalDateTime arg);
SqlUpdate argLocalDateTime(String argName, LocalDateTime arg);
SqlUpdate argOffsetDateTime(OffsetDateTime arg);
SqlUpdate argOffsetDateTime(String argName, OffsetDateTime arg);
SqlUpdate argLocalDateTimeNowPerDb(); SqlUpdate argLocalDateTimeNowPerDb();
SqlUpdate argLocalDateTimeNowPerDb(String argName); SqlUpdate argLocalDateTimeNowPerDb(String argName);
SqlUpdate argOffsetDateTimeNowPerDb();
SqlUpdate argOffsetDateTimeNowPerDb(String argName);
SqlUpdate argBlobBytes(byte[] arg); SqlUpdate argBlobBytes(byte[] arg);
SqlUpdate argBlobBytes(String argName, byte[] arg); SqlUpdate argBlobBytes(String argName, byte[] arg);

View file

@ -2,6 +2,8 @@ package org.xbib.jdbc.query;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import org.xbib.jdbc.query.util.DebugSql; import org.xbib.jdbc.query.util.DebugSql;
import org.xbib.jdbc.query.util.InternalStringReader; import org.xbib.jdbc.query.util.InternalStringReader;
import org.xbib.jdbc.query.util.Metric; import org.xbib.jdbc.query.util.Metric;
@ -27,7 +29,7 @@ import java.util.logging.Logger;
*/ */
public class SqlUpdateImpl implements SqlUpdate { public class SqlUpdateImpl implements SqlUpdate {
private static final Logger log = Logger.getLogger(Database.class.getName()); private static final Logger logger = Logger.getLogger(SqlUpdateImpl.class.getName());
private final Connection connection; private final Connection connection;
@ -130,6 +132,16 @@ public class SqlUpdateImpl implements SqlUpdate {
return namedArg(argName, adaptor.nullLocalDateTime(arg)); return namedArg(argName, adaptor.nullLocalDateTime(arg));
} }
@Override
public SqlUpdate argOffsetDateTime(OffsetDateTime arg) {
return positionalArg(adaptor.nullOffsetDateTime(arg));
}
@Override
public SqlUpdate argOffsetDateTime(String argName, OffsetDateTime arg) {
return namedArg(argName, adaptor.nullOffsetDateTime(arg));
}
@Override @Override
public SqlUpdate argLocalDate(LocalDate arg) { public SqlUpdate argLocalDate(LocalDate arg) {
return positionalArg(adaptor.nullLocalDate(arg)); return positionalArg(adaptor.nullLocalDate(arg));
@ -140,6 +152,16 @@ public class SqlUpdateImpl implements SqlUpdate {
return namedArg(argName, adaptor.nullLocalDate(arg)); return namedArg(argName, adaptor.nullLocalDate(arg));
} }
@Override
public SqlUpdate argLocalTime(LocalTime arg) {
return positionalArg(adaptor.nullLocalTime(arg));
}
@Override
public SqlUpdate argLocalTime(String argName, LocalTime arg) {
return namedArg(argName, adaptor.nullLocalTime(arg));
}
@Override @Override
public SqlUpdate argLocalDateTimeNowPerDb() { public SqlUpdate argLocalDateTimeNowPerDb() {
if (options.useClientClock()) { if (options.useClientClock()) {
@ -156,6 +178,22 @@ public class SqlUpdateImpl implements SqlUpdate {
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis())); return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
} }
@Override
public SqlUpdate argOffsetDateTimeNowPerDb() {
if (options.useClientClock()) {
return positionalArg(adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override
public SqlUpdate argOffsetDateTimeNowPerDb(String argName) {
if (options.useClientClock()) {
return namedArg(argName, adaptor.nullOffsetDateTime(OffsetDateTime.now()));
}
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
}
@Override @Override
public SqlUpdate argBlobBytes(byte[] arg) { public SqlUpdate argBlobBytes(byte[] arg) {
return positionalArg(adaptor.nullBytes(arg)); return positionalArg(adaptor.nullBytes(arg));
@ -258,7 +296,7 @@ public class SqlUpdateImpl implements SqlUpdate {
throw new DatabaseException("Batch insert requires parameters"); throw new DatabaseException("Batch insert requires parameters");
} }
PreparedStatement ps = null; PreparedStatement ps = null;
Metric metric = new Metric(log.isLoggable(Level.FINE)); Metric metric = new Metric(logger.isLoggable(Level.FINE));
String executeSql = sql; String executeSql = sql;
List<Object> firstRowParameters = null; List<Object> firstRowParameters = null;
List<List<Object>> parameters = new ArrayList<>(); List<List<Object>> parameters = new ArrayList<>();
@ -300,19 +338,19 @@ public class SqlUpdateImpl implements SqlUpdate {
logEx = e; logEx = e;
throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, firstRowParameters, errorCode, options), e); throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, firstRowParameters, errorCode, options), e);
} finally { } finally {
adaptor.closeQuietly(ps, log); adaptor.closeQuietly(ps, logger);
metric.done("close"); metric.done("close");
if (isSuccess) { if (isSuccess) {
DebugSql.logSuccess("Insert", log, metric, executeSql, firstRowParameters, options); DebugSql.logSuccess("Insert", logger, metric, executeSql, firstRowParameters, options);
} else { } else {
DebugSql.logError("Insert", log, metric, errorCode, executeSql, firstRowParameters, options, logEx); DebugSql.logError("Insert", logger, metric, errorCode, executeSql, firstRowParameters, options, logEx);
} }
} }
} }
private int updateInternal(int expectedNumAffectedRows) { private int updateInternal(int expectedNumAffectedRows) {
PreparedStatement ps = null; PreparedStatement ps = null;
Metric metric = new Metric(log.isLoggable(Level.FINE)); Metric metric = new Metric(logger.isLoggable(Level.FINE));
String executeSql = sql; String executeSql = sql;
List<Object> parameters = null; List<Object> parameters = null;
boolean isSuccess = false; boolean isSuccess = false;
@ -346,12 +384,12 @@ public class SqlUpdateImpl implements SqlUpdate {
logEx = e; logEx = e;
throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, parameters, errorCode, options), e); throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, parameters, errorCode, options), e);
} finally { } finally {
adaptor.closeQuietly(ps, log); adaptor.closeQuietly(ps, logger);
metric.done("close"); metric.done("close");
if (isSuccess) { if (isSuccess) {
DebugSql.logSuccess("Update", log, metric, executeSql, parameters, options); DebugSql.logSuccess("Update", logger, metric, executeSql, parameters, options);
} else { } else {
DebugSql.logError("Update", log, metric, errorCode, executeSql, parameters, options, logEx); DebugSql.logError("Update", logger, metric, errorCode, executeSql, parameters, options, logEx);
} }
} }
} }

View file

@ -11,13 +11,11 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
@ -97,18 +95,10 @@ public class StatementAdapter {
} }
} }
public Object nullInstant(Instant arg) {
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg.atOffset(ZoneOffset.UTC).toLocalDateTime());
}
public Object nullLocalDateTime(LocalDateTime arg) { public Object nullLocalDateTime(LocalDateTime arg) {
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg); return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg);
} }
public Object nullZonedDateTime(ZonedDateTime arg) {
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg.toLocalDateTime());
}
public Object nullOffsetDateTime(OffsetDateTime arg) { public Object nullOffsetDateTime(OffsetDateTime arg) {
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg.toLocalDateTime()); return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg.toLocalDateTime());
} }
@ -117,6 +107,10 @@ public class StatementAdapter {
return arg == null ? new SqlNull(Types.DATE) : java.sql.Date.valueOf(arg); return arg == null ? new SqlNull(Types.DATE) : java.sql.Date.valueOf(arg);
} }
public Object nullLocalTime(LocalTime arg) {
return arg == null ? new SqlNull(Types.TIME) : java.sql.Time.valueOf(arg);
}
public Object nullNumeric(Number arg) { public Object nullNumeric(Number arg) {
if (arg == null) { if (arg == null) {
return new SqlNull(Types.NUMERIC); return new SqlNull(Types.NUMERIC);

View file

@ -110,11 +110,6 @@ public class Derby implements Flavor {
return "timestamptz"; return "timestamptz";
} }
@Override
public String typeZonedDateTime() {
return "timestamptz";
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
return "date"; return "date";

View file

@ -110,11 +110,6 @@ public class H2 implements Flavor {
return "timestamptz"; return "timestamptz";
} }
@Override
public String typeZonedDateTime() {
return "timestamptz";
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
return "date"; return "date";

View file

@ -110,11 +110,6 @@ public class Hsql implements Flavor {
return "timestamp with time zone"; return "timestamp with time zone";
} }
@Override
public String typeZonedDateTime() {
return "timestamp with time zone";
}
@Override @Override
public String typeLocalDate() { public String typeLocalDate() {
return "date"; return "date";

View file

@ -10,12 +10,9 @@ import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.Types; import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -581,23 +578,6 @@ public class RowStub {
return new ByteArrayInputStream(getBlobBytesOrZeroLen(columnName)); return new ByteArrayInputStream(getBlobBytesOrZeroLen(columnName));
} }
@Override
public Instant getInstantOrNull() {
return toInstant(rows.get(row)[++col]);
}
@Override
public Instant getInstantOrNull(int columnOneBased) {
col = columnOneBased;
return toInstant(rows.get(row)[columnOneBased - 1]);
}
@Override
public Instant getInstantOrNull(String columnName) {
col = columnIndexByName(columnName) + 1;
return toInstant(rows.get(row)[columnIndexByName(columnName)]);
}
@Override @Override
public LocalDateTime getLocalDateTimeOrNull() { public LocalDateTime getLocalDateTimeOrNull() {
return toLocalDateTime(rows.get(row)[++col]); return toLocalDateTime(rows.get(row)[++col]);
@ -632,23 +612,6 @@ public class RowStub {
return toOffsetDateTime(rows.get(row)[columnIndexByName(columnName)]); return toOffsetDateTime(rows.get(row)[columnIndexByName(columnName)]);
} }
@Override
public ZonedDateTime getZonedDateTimeOrNull() {
return toZonedDateTime(rows.get(row)[++col]);
}
@Override
public ZonedDateTime getZonedDateTimeOrNull(int columnOneBased) {
col = columnOneBased;
return toZonedDateTime(rows.get(row)[columnOneBased - 1]);
}
@Override
public ZonedDateTime getZonedDateTimeOrNull(String columnName) {
col = columnIndexByName(columnName) + 1;
return toZonedDateTime(rows.get(row)[columnIndexByName(columnName)]);
}
@Override @Override
public LocalDate getLocalDateOrNull() { public LocalDate getLocalDateOrNull() {
return toLocalDate(rows.get(row)[++col]); return toLocalDate(rows.get(row)[++col]);
@ -735,28 +698,13 @@ public class RowStub {
return (BigDecimal) o; return (BigDecimal) o;
} }
private Instant toInstant(Object o) {
if (o instanceof String s) {
if (s.length() == "yyyy-MM-dd".length()) {
return Instant.parse(s);
}
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
return Instant.parse(s);
}
throw new DatabaseException("Didn't understand date string: " + s);
}
return (Instant) o;
}
private LocalDateTime toLocalDateTime(Object o) { private LocalDateTime toLocalDateTime(Object o) {
if (o instanceof String s) { if (o instanceof String s) {
if (s.length() == "yyyy-MM-dd".length()) { if (s.length() == "yyyy-MM-dd".length()) {
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd")) return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
.atZone(ZoneId.systemDefault()).toLocalDateTime();
} }
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) { if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss")) return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"));
.atZone(ZoneId.systemDefault()).toLocalDateTime();
} }
throw new DatabaseException("Didn't understand date string: " + s); throw new DatabaseException("Didn't understand date string: " + s);
} }
@ -776,19 +724,6 @@ public class RowStub {
return (OffsetDateTime) o; return (OffsetDateTime) o;
} }
private ZonedDateTime toZonedDateTime(Object o) {
if (o instanceof String s) {
if (s.length() == "yyyy-MM-dd".length()) {
return ZonedDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
return ZonedDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"));
}
throw new DatabaseException("Didn't understand date string: " + s);
}
return (ZonedDateTime) o;
}
private LocalDate toLocalDate(Object o) { private LocalDate toLocalDate(Object o) {
if (o instanceof String) { if (o instanceof String) {
return LocalDate.parse((String) o); return LocalDate.parse((String) o);

View file

@ -1,5 +1,6 @@
package org.xbib.jdbc.test; package org.xbib.jdbc.test;
import java.time.Instant;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -25,14 +26,12 @@ import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.Month; import java.time.Month;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
@ -70,8 +69,6 @@ public abstract class CommonTest {
protected OffsetDateTime offsetDateTimeNow; protected OffsetDateTime offsetDateTimeNow;
protected ZonedDateTime zonedDateTimeNow;
protected abstract DatabaseProvider createDatabaseProvider(OptionsOverride options) throws Exception; protected abstract DatabaseProvider createDatabaseProvider(OptionsOverride options) throws Exception;
@BeforeEach @BeforeEach
@ -79,7 +76,6 @@ public abstract class CommonTest {
localDateTimeNow = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS); localDateTimeNow = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
localDateNow = LocalDate.now(); localDateNow = LocalDate.now();
offsetDateTimeNow = OffsetDateTime.now(); offsetDateTimeNow = OffsetDateTime.now();
zonedDateTimeNow = ZonedDateTime.now();
dbp = createDatabaseProvider(new OptionsOverride() { dbp = createDatabaseProvider(new OptionsOverride() {
}); });
db = dbp.get(); db = dbp.get();
@ -153,11 +149,10 @@ public abstract class CommonTest {
.addColumn("date_millis").asLocalDateTime().table() .addColumn("date_millis").asLocalDateTime().table()
.addColumn("local_date").asLocalDate().table() .addColumn("local_date").asLocalDate().table()
.addColumn("offset_date_time").asOffsetDateTime().table() .addColumn("offset_date_time").asOffsetDateTime().table()
.addColumn("tz_date_time").asZonedateTime().table()
.schema() .schema()
.execute(db); .execute(db);
BigDecimal bigDecimal = new BigDecimal("5.3"); BigDecimal bigDecimal = new BigDecimal("5.3");
db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?,?,?)") db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?,?)")
.argInteger(1) .argInteger(1)
.argLong(2L) .argLong(2L)
.argFloat(3.2f) .argFloat(3.2f)
@ -170,10 +165,9 @@ public abstract class CommonTest {
.argLocalDateTime(localDateTimeNow) .argLocalDateTime(localDateTimeNow)
.argLocalDate(localDateNow) .argLocalDate(localDateNow)
.argOffsetDateTime(offsetDateTimeNow) .argOffsetDateTime(offsetDateTimeNow)
.argZonedDateTime(zonedDateTimeNow)
.insert(1); .insert(1);
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, " db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
+ "bin_blob, date_millis, local_date, offset_date_time, tz_date_time from dbtest") + "bin_blob, date_millis, local_date, offset_date_time from dbtest")
.query((RowsHandler<Void>) rs -> { .query((RowsHandler<Void>) rs -> {
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(Integer.valueOf(1), rs.getIntegerOrNull(1)); assertEquals(Integer.valueOf(1), rs.getIntegerOrNull(1));
@ -220,14 +214,11 @@ public abstract class CommonTest {
rs.getOffsetDateTimeOrNull(12).truncatedTo(ChronoUnit.SECONDS)); rs.getOffsetDateTimeOrNull(12).truncatedTo(ChronoUnit.SECONDS));
assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS), assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS),
rs.getOffsetDateTimeOrNull("offset_date_time").truncatedTo(ChronoUnit.SECONDS)); rs.getOffsetDateTimeOrNull("offset_date_time").truncatedTo(ChronoUnit.SECONDS));
// org.postgresql.util.PSQLException: conversion to class java.time.ZonedDateTime from timestamptz not supported
// assertEquals(zonedDateTimeNow, rs.getZonedDateTimeOrNull(13));
// assertEquals(zonedDateTimeNow, rs.getZonedDateTimeOrNull("tz_date_time"));
return null; return null;
}); });
// Repeat the above query, using the various methods that automatically infer the column // Repeat the above query, using the various methods that automatically infer the column
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, " db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
+ "bin_blob, date_millis, local_date, offset_date_time, tz_date_time from dbtest") + "bin_blob, date_millis, local_date, offset_date_time from dbtest")
.query((RowsHandler<Void>) rs -> { .query((RowsHandler<Void>) rs -> {
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(Integer.valueOf(1), rs.getIntegerOrNull()); assertEquals(Integer.valueOf(1), rs.getIntegerOrNull());
@ -242,12 +233,10 @@ public abstract class CommonTest {
assertEquals(localDateTimeNow, rs.getLocalDateTimeOrNull()); assertEquals(localDateTimeNow, rs.getLocalDateTimeOrNull());
assertEquals(localDateNow, rs.getLocalDateOrNull()); assertEquals(localDateNow, rs.getLocalDateOrNull());
assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS), rs.getOffsetDateTimeOrNull().truncatedTo(ChronoUnit.SECONDS)); assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS), rs.getOffsetDateTimeOrNull().truncatedTo(ChronoUnit.SECONDS));
// org.postgresql.util.PSQLException: conversion to class java.time.ZonedDateTime from timestamptz not supported
//assertEquals(zonedDateTimeNow, rs.getZonedDateTimeOrNull());
return null; return null;
}); });
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, " db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
+ "bin_blob, date_millis, local_date, offset_date_time, tz_date_time from dbtest") + "bin_blob, date_millis, local_date, offset_date_time from dbtest")
.query((RowsHandler<Void>) rs -> { .query((RowsHandler<Void>) rs -> {
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1, rs.getIntegerOrZero()); assertEquals(1, rs.getIntegerOrZero());
@ -262,8 +251,6 @@ public abstract class CommonTest {
assertEquals(localDateTimeNow, rs.getLocalDateTimeOrNull()); assertEquals(localDateTimeNow, rs.getLocalDateTimeOrNull());
assertEquals(localDateNow, rs.getLocalDateOrNull()); assertEquals(localDateNow, rs.getLocalDateOrNull());
assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS), rs.getOffsetDateTimeOrNull().truncatedTo(ChronoUnit.SECONDS)); assertEquals(offsetDateTimeNow.truncatedTo(ChronoUnit.SECONDS), rs.getOffsetDateTimeOrNull().truncatedTo(ChronoUnit.SECONDS));
// org.postgresql.util.PSQLException: conversion to class java.time.ZonedDateTime from timestamptz not supported
//assertEquals(zonedDateTimeNow, rs.getZonedDateTimeOrNull());
return null; return null;
}); });
db.toSelect("select str_lob, bin_blob from dbtest").query((RowsHandler<Void>) rs -> { db.toSelect("select str_lob, bin_blob from dbtest").query((RowsHandler<Void>) rs -> {