replace Date by LocalDateTime
This commit is contained in:
parent
436ae935b8
commit
d35071b910
22 changed files with 181 additions and 298 deletions
|
@ -1,7 +1,7 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +90,7 @@ public interface Database extends Supplier<Database> {
|
||||||
/**
|
/**
|
||||||
* Get the value that would be used if you specify an argNowPerApp() parameter.
|
* Get the value that would be used if you specify an argNowPerApp() parameter.
|
||||||
*/
|
*/
|
||||||
Date nowPerApp();
|
LocalDateTime nowPerApp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cause the underlying connection to commit its transaction immediately. This
|
* Cause the underlying connection to commit its transaction immediately. This
|
||||||
|
|
|
@ -5,8 +5,9 @@ import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +91,7 @@ public class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date nowPerApp() {
|
public LocalDateTime nowPerApp() {
|
||||||
return options.currentDate();
|
return options.currentDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,25 +250,26 @@ public class DatabaseImpl implements Database {
|
||||||
public void assertTimeSynchronized(long millisToWarn, long millisToError) {
|
public void assertTimeSynchronized(long millisToWarn, long millisToError) {
|
||||||
toSelect("select ?" + flavor().fromAny())
|
toSelect("select ?" + flavor().fromAny())
|
||||||
.argDateNowPerDb().queryFirstOrNull(r -> {
|
.argDateNowPerDb().queryFirstOrNull(r -> {
|
||||||
Date appDate = nowPerApp();
|
LocalDateTime appDate = nowPerApp();
|
||||||
Date dbDate = r.getDateOrNull();
|
LocalDateTime dbDate = r.getLocalDateTimeOrNull();
|
||||||
if (dbDate == null) {
|
if (dbDate == null) {
|
||||||
throw new DatabaseException("Expecting a date in the result");
|
throw new DatabaseException("Expecting a date in the result");
|
||||||
}
|
}
|
||||||
if (Math.abs(appDate.getTime() - dbDate.getTime()) > 3600000) {
|
Duration duration = Duration.between(appDate, dbDate).abs();
|
||||||
|
if (duration.getSeconds() > 3600) {
|
||||||
throw new DatabaseException("App and db time are over an hour apart (check your timezones) app: "
|
throw new DatabaseException("App and db time are over an hour apart (check your timezones) app: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
+ DateTimeFormatter.ISO_INSTANT.format(dbDate));
|
||||||
}
|
}
|
||||||
if (Math.abs(appDate.getTime() - dbDate.getTime()) > millisToError) {
|
if (duration.getSeconds() * 1000 > millisToError) {
|
||||||
throw new DatabaseException("App and db time over " + millisToError + " millis apart (check your clocks) app: "
|
throw new DatabaseException("App and db time over " + millisToError + " millis apart (check your clocks) app: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
+ DateTimeFormatter.ISO_INSTANT.format(dbDate));
|
||||||
}
|
}
|
||||||
if (Math.abs(appDate.getTime() - dbDate.getTime()) > millisToWarn) {
|
if (duration.getSeconds() * 1000 > millisToWarn) {
|
||||||
log.warning("App and db time are over " + millisToWarn + " millis apart (check your clocks) app: "
|
log.warning("App and db time are over " + millisToWarn + " millis apart (check your clocks) app: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
+ DateTimeFormatter.ISO_INSTANT.format(dbDate));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of supported databases with various compatibility settings.
|
* Enumeration of supported databases with various compatibility settings.
|
||||||
|
@ -131,8 +132,8 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
return "timestamp('" + dateFormat.format(date) + "')";
|
return "timestamp('" + dateFormat.format(date) + "')";
|
||||||
}
|
}
|
||||||
|
@ -279,7 +280,7 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
return "cast('" + dateFormat.format(date) + "' as datetime2(3))";
|
return "cast('" + dateFormat.format(date) + "' as datetime2(3))";
|
||||||
|
@ -425,7 +426,7 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
return "timestamp '" + dateFormat.format(date) + "'";
|
return "timestamp '" + dateFormat.format(date) + "'";
|
||||||
|
@ -568,7 +569,7 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
return "'" + dateFormat.format(date) + " GMT'::timestamp";
|
return "'" + dateFormat.format(date) + " GMT'::timestamp";
|
||||||
|
@ -711,7 +712,7 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000XXX");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000XXX");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
return "cast(timestamp '" + dateFormat.format(date) + "' as timestamp without time zone)";
|
return "cast(timestamp '" + dateFormat.format(date) + "' as timestamp without time zone)";
|
||||||
|
@ -855,7 +856,7 @@ public enum Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||||
// Construct a datetime literal
|
// Construct a datetime literal
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||||
dateFormat.setCalendar(calendar);
|
dateFormat.setCalendar(calendar);
|
||||||
|
@ -980,7 +981,7 @@ public enum Flavor {
|
||||||
* Return a SQL function representing the specified date. For example, in PostgreSQL this
|
* Return a SQL function representing the specified date. For example, in PostgreSQL this
|
||||||
* looks like "'1970-01-02 02:17:36.789000 GMT'::timestamp".
|
* looks like "'1970-01-02 02:17:36.789000 GMT'::timestamp".
|
||||||
*/
|
*/
|
||||||
public abstract String dateAsSqlFunction(Date date, Calendar calendar);
|
public abstract String dateAsSqlFunction(Timestamp timestamp, Calendar calendar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a SQL function representing the specified date without time.
|
* Return a SQL function representing the specified date without time.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control various optional behavior for the database interactions.
|
* Control various optional behavior for the database interactions.
|
||||||
|
@ -98,7 +98,7 @@ public interface Options {
|
||||||
* The value returned by this method will be used for argDateNowPerApp() calls. It
|
* The value returned by this method will be used for argDateNowPerApp() calls. It
|
||||||
* may also be used for argDateNowPerDb() calls if you have enabled that.
|
* may also be used for argDateNowPerDb() calls if you have enabled that.
|
||||||
*/
|
*/
|
||||||
Date currentDate();
|
LocalDateTime currentDate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wherever argDateNowPerDb() is specified, use argDateNowPerApp() instead. This is
|
* Wherever argDateNowPerDb() is specified, use argDateNowPerApp() instead. This is
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
@ -63,8 +64,8 @@ public class OptionsDefault implements Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date currentDate() {
|
public LocalDateTime currentDate() {
|
||||||
return new Date();
|
return LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ public class OptionsOverride implements Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date currentDate() {
|
public LocalDateTime currentDate() {
|
||||||
return parent.currentDate();
|
return parent.currentDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for reading results from a database query.
|
* Interface for reading results from a database query.
|
||||||
|
@ -387,32 +387,19 @@ public interface Row {
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrEmpty(int columnOneBased);
|
InputStream getBlobInputStreamOrEmpty(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrEmpty(String columnName);
|
InputStream getBlobInputStreamOrEmpty(String columnName);
|
||||||
|
|
||||||
/**
|
LocalDateTime getLocalDateTimeOrNull();
|
||||||
* Return the millisecond precision Date, which should be represented as a TIMESTAMP
|
|
||||||
* in the database. The nanoseconds are truncated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Date getDateOrNull();
|
LocalDateTime getLocalDateTimeOrNull(int columnOneBased);
|
||||||
|
|
||||||
/**
|
LocalDateTime getLocalDateTimeOrNull(String columnName);
|
||||||
* Return the millisecond precision Date, which should be represented as a TIMESTAMP
|
|
||||||
* in the database. The nanoseconds are truncated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Date getDateOrNull(int columnOneBased);
|
|
||||||
|
|
||||||
|
|
||||||
Date getDateOrNull(String columnName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve column as LocalDate, .i.e, date with no time.
|
* Retrieve column as LocalDate, .i.e, date with no time.
|
||||||
*
|
*
|
||||||
* @return LocalDate of the database column value
|
* @return LocalDate of the database column value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LocalDate getLocalDateOrNull();
|
LocalDate getLocalDateOrNull();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely wrap a ResultSet and provide access to the data it contains.
|
* Safely wrap a ResultSet and provide access to the data it contains.
|
||||||
|
@ -53,7 +53,6 @@ class RowsAdaptor implements Rows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetMetaData getMetadata() {
|
public ResultSetMetaData getMetadata() {
|
||||||
try {
|
try {
|
||||||
|
@ -63,13 +62,11 @@ class RowsAdaptor implements Rows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean getBooleanOrNull() {
|
public Boolean getBooleanOrNull() {
|
||||||
return getBooleanOrNull(column++);
|
return getBooleanOrNull(column++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean getBooleanOrNull(int columnOneBased) {
|
public Boolean getBooleanOrNull(int columnOneBased) {
|
||||||
try {
|
try {
|
||||||
|
@ -80,7 +77,6 @@ class RowsAdaptor implements Rows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean getBooleanOrNull(String columnName) {
|
public Boolean getBooleanOrNull(String columnName) {
|
||||||
try {
|
try {
|
||||||
|
@ -661,35 +657,31 @@ class RowsAdaptor implements Rows {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull() {
|
public LocalDateTime getLocalDateTimeOrNull() {
|
||||||
return getDateOrNull(column++);
|
return getLocalDateTimeOrNull(column++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull(int columnOneBased) {
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||||
try {
|
try {
|
||||||
column = columnOneBased + 1;
|
column = columnOneBased + 1;
|
||||||
return toDate(rs, columnOneBased);
|
return toLocalDateTime(rs, columnOneBased);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull(String columnName) {
|
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||||
try {
|
try {
|
||||||
column = rs.findColumn(columnName) + 1;
|
column = rs.findColumn(columnName) + 1;
|
||||||
return toDate(rs, columnName);
|
return toLocalDateTime(rs, columnName);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDate getLocalDateOrNull() {
|
public LocalDate getLocalDateOrNull() {
|
||||||
return getLocalDateOrNull(column++);
|
return getLocalDateOrNull(column++);
|
||||||
|
@ -720,31 +712,21 @@ class RowsAdaptor implements Rows {
|
||||||
@Override
|
@Override
|
||||||
public Integer rowCount() {
|
public Integer rowCount() {
|
||||||
try {
|
try {
|
||||||
//rs.last();
|
rs.last();
|
||||||
return rs.getRow();
|
return rs.getRow();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private LocalDateTime toLocalDateTime(ResultSet rs, int col) throws SQLException {
|
||||||
* Make sure the Timestamp will return getTime() accurate to the millisecond
|
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
||||||
* (if possible) and truncate away nanoseconds.
|
return val == null ? null : val.toLocalDateTime();
|
||||||
*/
|
|
||||||
private Date timestampToDate(Timestamp ts) {
|
|
||||||
long millis = ts.getTime();
|
|
||||||
int nanos = ts.getNanos();
|
|
||||||
return new Date(millis / 1000 * 1000 + nanos / 1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date toDate(ResultSet rs, int col) throws SQLException {
|
private LocalDateTime toLocalDateTime(ResultSet rs, String col) throws SQLException {
|
||||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
||||||
return val == null ? null : timestampToDate(val);
|
return val == null ? null : val.toLocalDateTime();
|
||||||
}
|
|
||||||
|
|
||||||
private Date toDate(ResultSet rs, String col) throws SQLException {
|
|
||||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
|
||||||
return val == null ? null : timestampToDate(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate toLocalDate(ResultSet rs, int col) throws SQLException {
|
private LocalDate toLocalDate(ResultSet rs, int col) throws SQLException {
|
||||||
|
|
|
@ -3,9 +3,9 @@ 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.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
@ -310,14 +310,13 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Sql argDate(LocalDateTime arg) {
|
||||||
public Sql argDate(Date arg) {
|
|
||||||
sqlArgs.argDate(arg);
|
sqlArgs.argDate(arg);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Sql argDate( String argName, Date arg) {
|
public Sql argDate( String argName, LocalDateTime arg) {
|
||||||
sqlArgs.argDate(argName, arg);
|
sqlArgs.argDate(argName, arg);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
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.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -21,7 +21,6 @@ import java.util.Set;
|
||||||
public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
||||||
private final List<Invocation> invocations = new ArrayList<>();
|
private final List<Invocation> invocations = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
public static Builder fromMetadata(Row r) {
|
public static Builder fromMetadata(Row r) {
|
||||||
return new Builder(r);
|
return new Builder(r);
|
||||||
}
|
}
|
||||||
|
@ -147,14 +146,14 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDate(Date arg) {
|
public SqlArgs argDate(LocalDateTime arg) {
|
||||||
// date argument with a time on it
|
// date argument with a time on it
|
||||||
invocations.add(new Invocation(ColumnType.Date, null, arg));
|
invocations.add(new Invocation(ColumnType.Date, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDate( String argName, Date arg) {
|
public SqlArgs argDate( String argName, LocalDateTime arg) {
|
||||||
// date argument with a time on it
|
// date argument with a time on it
|
||||||
invocations.add(new Invocation(ColumnType.Date, argName, arg));
|
invocations.add(new Invocation(ColumnType.Date, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
|
@ -347,7 +346,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
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:
|
||||||
// date argument with no time on it
|
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
select.argLocalDate((LocalDate) i.arg);
|
select.argLocalDate((LocalDate) i.arg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -355,11 +353,10 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Date:
|
case Date:
|
||||||
// date argument with a time on it
|
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
select.argDate((Date) i.arg);
|
select.argDate((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
select.argDate(i.argName, (Date) i.arg);
|
select.argDate(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case DateNowPerApp:
|
||||||
|
@ -473,9 +470,9 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
case Date:
|
case Date:
|
||||||
// date argument with a time on it
|
// date argument with a time on it
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
insert.argDate((Date) i.arg);
|
insert.argDate((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
insert.argDate(i.argName, (Date) i.arg);
|
insert.argDate(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case DateNowPerApp:
|
||||||
|
@ -579,7 +576,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LocalDate:
|
case LocalDate:
|
||||||
// date argument with no time on it
|
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
update.argLocalDate((LocalDate) i.arg);
|
update.argLocalDate((LocalDate) i.arg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -587,11 +583,10 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Date:
|
case Date:
|
||||||
// date argument with a time on it
|
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
update.argDate((Date) i.arg);
|
update.argDate((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
update.argDate(i.argName, (Date) i.arg);
|
update.argDate(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case DateNowPerApp:
|
||||||
|
@ -748,7 +743,7 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
// Anything with a time will have a non-zero scale
|
// 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.argDate(names[i], r.getDateOrNull());
|
args.argDate(names[i], r.getLocalDateTimeOrNull());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
||||||
|
@ -33,15 +33,15 @@ public interface SqlInsert {
|
||||||
|
|
||||||
SqlInsert argBigDecimal(BigDecimal arg);
|
SqlInsert argBigDecimal(BigDecimal arg);
|
||||||
|
|
||||||
SqlInsert argBigDecimal( String argName, BigDecimal arg);
|
SqlInsert argBigDecimal(String argName, BigDecimal arg);
|
||||||
|
|
||||||
SqlInsert argString(String arg);
|
SqlInsert argString(String arg);
|
||||||
|
|
||||||
SqlInsert argString( String argName, String arg);
|
SqlInsert argString( String argName, String arg);
|
||||||
|
|
||||||
SqlInsert argDate(Date arg); // date with time
|
SqlInsert argDate(LocalDateTime arg); // date with time
|
||||||
|
|
||||||
SqlInsert argDate( String argName, Date arg); // date with time
|
SqlInsert argDate(String argName, LocalDateTime arg); // date with time
|
||||||
|
|
||||||
SqlInsert argLocalDate(LocalDate arg); // date only - no timestamp
|
SqlInsert argLocalDate(LocalDate arg); // date only - no timestamp
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -125,43 +125,36 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argBigDecimal( String argName, BigDecimal arg) {
|
public SqlInsert argBigDecimal( String argName, BigDecimal arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argString(String arg) {
|
public SqlInsert argString(String arg) {
|
||||||
return positionalArg(adaptor.nullString(arg));
|
return positionalArg(adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argString( String argName, String arg) {
|
public SqlInsert argString( String argName, String arg) {
|
||||||
return namedArg(argName, adaptor.nullString(arg));
|
return namedArg(argName, adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlInsert argDate(LocalDateTime arg) {
|
||||||
public SqlInsert argDate(Date arg) {
|
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
return positionalArg(adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlInsert argDate( String argName, LocalDateTime arg) {
|
||||||
public SqlInsert argDate( String argName, Date arg) {
|
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
return namedArg(argName, adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argLocalDate( String argName, LocalDate arg) {
|
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 argLocalDate(LocalDate arg) {
|
||||||
return positionalArg(adaptor.nullLocalDate(arg));
|
return positionalArg(adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
@ -173,12 +166,10 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argDateNowPerApp( String argName) {
|
public SqlInsert argDateNowPerApp( String argName) {
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert argDateNowPerDb() {
|
public SqlInsert argDateNowPerDb() {
|
||||||
if (options.useDatePerAppOnly()) {
|
if (options.useDatePerAppOnly()) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,11 +67,9 @@ public interface SqlSelect {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argDate(Date arg); // Date with time
|
SqlSelect argDate(LocalDateTime arg); // Date with time
|
||||||
|
|
||||||
|
SqlSelect argDate(String argName, LocalDateTime arg); // Date with time
|
||||||
|
|
||||||
SqlSelect argDate( String argName, Date arg); // Date with time
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -207,11 +205,11 @@ public interface SqlSelect {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Date queryDateOrNull(); // Date with time
|
LocalDateTime queryDateOrNull(); // Date with time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Date> queryDates(); // Date with time
|
List<LocalDateTime> queryDates(); // Date with time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -140,14 +140,14 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDate(Date arg) {
|
public SqlSelect argDate(LocalDateTime arg) {
|
||||||
// Date with time
|
// Date with time
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
return positionalArg(adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDate( String argName, Date arg) {
|
public SqlSelect argDate( String argName, LocalDateTime arg) {
|
||||||
// Date with time
|
// Date with time
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
return namedArg(argName, adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
@ -467,21 +467,21 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date queryDateOrNull() {
|
public LocalDateTime queryDateOrNull() {
|
||||||
return queryWithTimeout(rs -> {
|
return queryWithTimeout(rs -> {
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
return rs.getDateOrNull(1);
|
return rs.getLocalDateTimeOrNull(1);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Date> queryDates() {
|
public List<LocalDateTime> queryDates() {
|
||||||
return queryWithTimeout(rs -> {
|
return queryWithTimeout(rs -> {
|
||||||
List<Date> result = new ArrayList<>();
|
List<LocalDateTime> result = new ArrayList<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
Date value = rs.getDateOrNull(1);
|
LocalDateTime value = rs.getLocalDateTimeOrNull(1);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
|
@ -619,7 +619,9 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
synchronized (cancelLock) {
|
synchronized (cancelLock) {
|
||||||
ps = connection.prepareStatement(executeSql);
|
ps = connection.prepareStatement(executeSql,
|
||||||
|
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||||
|
ResultSet.CONCUR_READ_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeoutSeconds >= 0) {
|
if (timeoutSeconds >= 0) {
|
||||||
|
|
|
@ -4,138 +4,75 @@ import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
||||||
*/
|
*/
|
||||||
public interface SqlUpdate {
|
public interface SqlUpdate {
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBoolean(Boolean arg);
|
SqlUpdate argBoolean(Boolean arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBoolean( String argName, Boolean arg);
|
SqlUpdate argBoolean( String argName, Boolean arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argInteger(Integer arg);
|
SqlUpdate argInteger(Integer arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argInteger( String argName, Integer arg);
|
SqlUpdate argInteger( String argName, Integer arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argLong(Long arg);
|
SqlUpdate argLong(Long arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argLong( String argName, Long arg);
|
SqlUpdate argLong( String argName, Long arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argFloat(Float arg);
|
SqlUpdate argFloat(Float arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argFloat( String argName, Float arg);
|
SqlUpdate argFloat( String argName, Float arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDouble(Double arg);
|
SqlUpdate argDouble(Double arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDouble( String argName, Double arg);
|
SqlUpdate argDouble( String argName, Double arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBigDecimal(BigDecimal arg);
|
SqlUpdate argBigDecimal(BigDecimal arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBigDecimal( String argName, BigDecimal arg);
|
SqlUpdate argBigDecimal( String argName, BigDecimal arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argString(String arg);
|
SqlUpdate argString(String arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argString( String argName, String arg);
|
SqlUpdate argString( String argName, String arg);
|
||||||
|
|
||||||
|
SqlUpdate argDate(LocalDateTime arg);
|
||||||
|
|
||||||
|
SqlUpdate argDate( String argName, LocalDateTime arg);
|
||||||
|
|
||||||
SqlUpdate argDate(Date arg); // Date with timestamp
|
SqlUpdate argLocalDate(LocalDate arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDate( String argName, Date arg); // Date with timestamp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argLocalDate(LocalDate arg); // Date only - no timestamp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argLocalDate( String argName, LocalDate arg); // Date only - no timestamp
|
|
||||||
|
|
||||||
|
|
||||||
|
SqlUpdate argLocalDate( String argName, LocalDate arg);
|
||||||
|
|
||||||
SqlUpdate argDateNowPerApp();
|
SqlUpdate argDateNowPerApp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDateNowPerApp( String argName);
|
SqlUpdate argDateNowPerApp( String argName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDateNowPerDb();
|
SqlUpdate argDateNowPerDb();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argDateNowPerDb( String argName);
|
SqlUpdate argDateNowPerDb( String argName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBlobBytes(byte[] arg);
|
SqlUpdate argBlobBytes(byte[] arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBlobBytes( String argName, byte[] arg);
|
SqlUpdate argBlobBytes( String argName, byte[] arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBlobStream(InputStream arg);
|
SqlUpdate argBlobStream(InputStream arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argBlobStream( String argName, InputStream arg);
|
SqlUpdate argBlobStream( String argName, InputStream arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argClobString(String arg);
|
SqlUpdate argClobString(String arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argClobString( String argName, String arg);
|
SqlUpdate argClobString( String argName, String arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argClobReader(Reader arg);
|
SqlUpdate argClobReader(Reader arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate argClobReader( String argName, Reader arg);
|
SqlUpdate argClobReader( String argName, Reader arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate withArgs(SqlArgs args);
|
SqlUpdate withArgs(SqlArgs args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlUpdate apply(Apply apply);
|
SqlUpdate apply(Apply apply);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,14 +88,6 @@ public interface SqlUpdate {
|
||||||
*/
|
*/
|
||||||
void update(int expectedRowsUpdated);
|
void update(int expectedRowsUpdated);
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this between setting rows of parameters for a SQL statement. You may call it before
|
|
||||||
* setting any parameters, after setting all, or multiple times between rows.
|
|
||||||
*/
|
|
||||||
// SqlUpdate batch();
|
|
||||||
|
|
||||||
// SqlUpdate withTimeoutSeconds(int seconds);
|
|
||||||
|
|
||||||
interface Apply {
|
interface Apply {
|
||||||
void apply(SqlUpdate update);
|
void apply(SqlUpdate update);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import java.math.BigDecimal;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -131,33 +131,28 @@ public class SqlUpdateImpl implements SqlUpdate {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argDate(Date arg) {
|
public SqlUpdate argDate(LocalDateTime arg) {
|
||||||
// Date with time
|
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
return positionalArg(adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argDate(String argName, Date arg) {
|
public SqlUpdate argDate(String argName, LocalDateTime arg) {
|
||||||
// Date with time
|
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
return namedArg(argName, adaptor.nullDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argLocalDate(LocalDate arg) {
|
public SqlUpdate argLocalDate(LocalDate arg) {
|
||||||
// Date with no time
|
|
||||||
return positionalArg(adaptor.nullLocalDate(arg));
|
return positionalArg(adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argLocalDate(String argName, LocalDate arg) {
|
public SqlUpdate argLocalDate(String argName, LocalDate arg) {
|
||||||
// Date with no time
|
|
||||||
return namedArg(argName, adaptor.nullLocalDate(arg));
|
return namedArg(argName, adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlUpdate argDateNowPerApp() {
|
public SqlUpdate argDateNowPerApp() {
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
return positionalArg(adaptor.nullDate(options.currentDate()));
|
||||||
|
@ -169,7 +164,6 @@ public class SqlUpdateImpl implements SqlUpdate {
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlUpdate argDateNowPerDb() {
|
public SqlUpdate argDateNowPerDb() {
|
||||||
if (options.useDatePerAppOnly()) {
|
if (options.useDatePerAppOnly()) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -142,11 +143,11 @@ public class StatementAdaptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object nullDate(Date arg) {
|
public Object nullDate(LocalDateTime arg) {
|
||||||
if (arg == null) {
|
if (arg == null) {
|
||||||
return new SqlNull(Types.TIMESTAMP);
|
return new SqlNull(Types.TIMESTAMP);
|
||||||
}
|
}
|
||||||
return new Timestamp(arg.getTime());
|
return Timestamp.valueOf(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Processes a true date without time information.
|
// Processes a true date without time information.
|
||||||
|
|
|
@ -6,8 +6,8 @@ import org.xbib.jdbc.query.SqlNull;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -77,9 +77,9 @@ public class DebugSql {
|
||||||
} else if (argToPrint instanceof SqlNull || argToPrint == null) {
|
} else if (argToPrint instanceof SqlNull || argToPrint == null) {
|
||||||
buf.append("null");
|
buf.append("null");
|
||||||
} else if (argToPrint instanceof java.sql.Timestamp) {
|
} else if (argToPrint instanceof java.sql.Timestamp) {
|
||||||
buf.append(options.flavor().dateAsSqlFunction((Date) argToPrint, options.calendarForTimestamps()));
|
buf.append(options.flavor().dateAsSqlFunction((Timestamp) argToPrint, options.calendarForTimestamps()));
|
||||||
} else if (argToPrint instanceof java.sql.Date) {
|
} else if (argToPrint instanceof java.sql.Date) {
|
||||||
buf.append(options.flavor().localDateAsSqlFunction((Date) argToPrint));
|
buf.append(options.flavor().localDateAsSqlFunction((java.sql.Date) argToPrint));
|
||||||
} else if (argToPrint instanceof Number) {
|
} else if (argToPrint instanceof Number) {
|
||||||
buf.append(argToPrint);
|
buf.append(argToPrint);
|
||||||
} else if (argToPrint instanceof Boolean) {
|
} else if (argToPrint instanceof Boolean) {
|
||||||
|
|
|
@ -25,15 +25,23 @@ 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.sql.Timestamp;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
@ -50,6 +58,8 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
*/
|
*/
|
||||||
public abstract class CommonTest {
|
public abstract class CommonTest {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(CommonTest.class.getName());
|
||||||
|
|
||||||
final static String TEST_TABLE_NAME = "dbtest";
|
final static String TEST_TABLE_NAME = "dbtest";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +70,7 @@ public abstract class CommonTest {
|
||||||
|
|
||||||
protected Database db;
|
protected Database db;
|
||||||
|
|
||||||
protected Date now = new Date();
|
protected LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
||||||
|
|
||||||
protected LocalDate localDateNow = LocalDate.now();
|
protected LocalDate localDateNow = LocalDate.now();
|
||||||
|
|
||||||
|
@ -68,7 +78,7 @@ public abstract class CommonTest {
|
||||||
public void setupJdbc() throws Exception {
|
public void setupJdbc() throws Exception {
|
||||||
dbp = createDatabaseProvider(new OptionsOverride() {
|
dbp = createDatabaseProvider(new OptionsOverride() {
|
||||||
@Override
|
@Override
|
||||||
public Date currentDate() {
|
public LocalDateTime currentDate() {
|
||||||
return now;
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,8 +207,8 @@ public abstract class CommonTest {
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen(9));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen(9));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen("bin_blob"));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen("bin_blob"));
|
||||||
assertEquals(now, rs.getDateOrNull(10));
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -217,7 +227,7 @@ public abstract class CommonTest {
|
||||||
assertEquals("T", rs.getStringOrNull());
|
assertEquals("T", rs.getStringOrNull());
|
||||||
assertEquals("World", rs.getClobStringOrNull());
|
assertEquals("World", rs.getClobStringOrNull());
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull());
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull());
|
||||||
assertEquals(now, rs.getDateOrNull());
|
assertEquals(now, rs.getLocalDateTimeOrNull());
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull());
|
assertEquals(localDateNow, rs.getLocalDateOrNull());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -350,8 +360,8 @@ public abstract class CommonTest {
|
||||||
assertNull(rs.getClobStringOrNull("str_lob"));
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||||
assertNull(rs.getBlobBytesOrNull(9));
|
assertNull(rs.getBlobBytesOrNull(9));
|
||||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertNull(rs.getDateOrNull(10));
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||||
assertNull(rs.getDateOrNull("date_millis"));
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertNull(rs.getLocalDateOrNull(11));
|
assertNull(rs.getLocalDateOrNull(11));
|
||||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -381,8 +391,8 @@ public abstract class CommonTest {
|
||||||
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertEquals(now, rs.getDateOrNull(10));
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -457,8 +467,8 @@ public abstract class CommonTest {
|
||||||
assertNull(rs.getClobStringOrNull("str_lob"));
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||||
assertNull(rs.getBlobBytesOrNull(9));
|
assertNull(rs.getBlobBytesOrNull(9));
|
||||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertNull(rs.getDateOrNull(10));
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||||
assertNull(rs.getDateOrNull("date_millis"));
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertNull(rs.getLocalDateOrNull(11));
|
assertNull(rs.getLocalDateOrNull(11));
|
||||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -491,8 +501,8 @@ public abstract class CommonTest {
|
||||||
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
||||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertEquals(now, rs.getDateOrNull(10));
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -560,8 +570,8 @@ public abstract class CommonTest {
|
||||||
assertNull(rs.getClobStringOrNull("str_lob"));
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||||
assertNull(rs.getBlobBytesOrNull(9));
|
assertNull(rs.getBlobBytesOrNull(9));
|
||||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||||
assertNull(rs.getDateOrNull(10));
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||||
assertNull(rs.getDateOrNull("date_millis"));
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||||
assertNull(rs.getLocalDateOrNull(11));
|
assertNull(rs.getLocalDateOrNull(11));
|
||||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||||
return null;
|
return null;
|
||||||
|
@ -1324,10 +1334,9 @@ public abstract class CommonTest {
|
||||||
@Test
|
@Test
|
||||||
public void argBigDecimal38Precision38() {
|
public void argBigDecimal38Precision38() {
|
||||||
new Schema().addTable("dbtest").addColumn("i").asBigDecimal(38, 38).schema().execute(db);
|
new Schema().addTable("dbtest").addColumn("i").asBigDecimal(38, 38).schema().execute(db);
|
||||||
|
|
||||||
BigDecimal value = new BigDecimal("0.99999999999999999999999999999999999999"); // 38 digits
|
BigDecimal value = new BigDecimal("0.99999999999999999999999999999999999999"); // 38 digits
|
||||||
db.toInsert("insert into dbtest (i) values (?)").argBigDecimal(value).insert(1);
|
db.toInsert("insert into dbtest (i) values (?)").argBigDecimal(value).insert(1);
|
||||||
System.out.println(db.toSelect("select i from dbtest").queryBigDecimalOrNull());
|
logger.info(db.toSelect("select i from dbtest").queryBigDecimalOrNull().toString());
|
||||||
assertEquals(value,
|
assertEquals(value,
|
||||||
db.toSelect("select i from dbtest where i=?").argBigDecimal(value).queryBigDecimalOrNull());
|
db.toSelect("select i from dbtest where i=?").argBigDecimal(value).queryBigDecimalOrNull());
|
||||||
}
|
}
|
||||||
|
@ -1379,7 +1388,7 @@ public abstract class CommonTest {
|
||||||
.insertReturning("dbtest", "pk", rs -> {
|
.insertReturning("dbtest", "pk", rs -> {
|
||||||
assertTrue(rs.next());
|
assertTrue(rs.next());
|
||||||
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
||||||
assertThat(rs.getDateOrNull(2), equalTo(now));
|
assertThat(rs.getLocalDateTimeOrNull(2), equalTo(now));
|
||||||
assertFalse(rs.next());
|
assertFalse(rs.next());
|
||||||
return null;
|
return null;
|
||||||
}, "d");
|
}, "d");
|
||||||
|
@ -1511,13 +1520,13 @@ public abstract class CommonTest {
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d").asDate().table().schema()
|
||||||
.addSequence("dbtest_seq").schema()
|
.addSequence("dbtest_seq").schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
Date dbNow = db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
LocalDateTime dbNow = db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
||||||
.argPkSeq(":seq", "dbtest_seq")
|
.argPkSeq(":seq", "dbtest_seq")
|
||||||
.argDateNowPerDb(":d")
|
.argDateNowPerDb(":d")
|
||||||
.insertReturning("dbtest", "pk", rs -> {
|
.insertReturning("dbtest", "pk", rs -> {
|
||||||
assertTrue(rs.next());
|
assertTrue(rs.next());
|
||||||
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
||||||
Date dbDate = rs.getDateOrNull(2);
|
LocalDateTime dbDate = rs.getLocalDateTimeOrNull(2);
|
||||||
assertFalse(rs.next());
|
assertFalse(rs.next());
|
||||||
return dbDate;
|
return dbDate;
|
||||||
}, "d");
|
}, "d");
|
||||||
|
@ -1583,11 +1592,11 @@ public abstract class CommonTest {
|
||||||
db.toInsert("insert into dbtest (d) values (?)")
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
.argDateNowPerDb()
|
.argDateNowPerDb()
|
||||||
.insert(1);
|
.insert(1);
|
||||||
Date dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
LocalDateTime dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||||
if (dbNow != null && dbNow.getTime() % 10 != 0) {
|
if (dbNow != null && dbNow.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() % 10 != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Zero in least significant digit (attempt " + attempts + ")");
|
logger.info("Zero in least significant digit (attempt " + attempts + ")");
|
||||||
db.dropTableQuietly(TEST_TABLE_NAME);
|
db.dropTableQuietly(TEST_TABLE_NAME);
|
||||||
}
|
}
|
||||||
fail("Timestamp had zero in the least significant digit");
|
fail("Timestamp had zero in the least significant digit");
|
||||||
|
@ -1605,7 +1614,7 @@ public abstract class CommonTest {
|
||||||
.argDateNowPerDb()
|
.argDateNowPerDb()
|
||||||
.insert(1);
|
.insert(1);
|
||||||
// Now pull it out, put it back in, and verify it matches in the database
|
// Now pull it out, put it back in, and verify it matches in the database
|
||||||
Date dbNow = db.toSelect("select d1 from dbtest").queryDateOrNull();
|
LocalDateTime dbNow = db.toSelect("select d1 from dbtest").queryDateOrNull();
|
||||||
db.toUpdate("update dbtest set d2=?")
|
db.toUpdate("update dbtest set d2=?")
|
||||||
.argDate(dbNow)
|
.argDate(dbNow)
|
||||||
.update(1);
|
.update(1);
|
||||||
|
@ -1619,21 +1628,23 @@ public abstract class CommonTest {
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d").asDate().table().schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
Date date = new Date(166656789L);
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
||||||
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
||||||
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
||||||
TimeZone defaultTZ = TimeZone.getDefault();
|
TimeZone defaultTZ = TimeZone.getDefault();
|
||||||
try {
|
try {
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
||||||
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
db.toInsert("insert into dbtest (d) values (?)").argDate(dateMinus).insert(1);
|
||||||
assertEquals(date, db.toSelect("select d from dbtest").queryDateOrNull());
|
LocalDateTime localDateTimeMinus = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||||
assertEquals("1970-01-02 18:17:36.789000-0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
assertEquals(dateMinus, localDateTimeMinus);
|
||||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
assertEquals("1970-01-02 18:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimeMinus));
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
db.toDelete("delete from dbtest where d=?").argDate(dateMinus).update(1);
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
||||||
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
db.toInsert("insert into dbtest (d) values (?)").argDate(datePlus).insert(1);
|
||||||
assertEquals(date, db.toSelect("select d from dbtest").queryDateOrNull());
|
LocalDateTime localDateTimePlus = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||||
assertEquals("1970-01-03 02:17:36.789000+0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
assertEquals(datePlus, localDateTimePlus);
|
||||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
assertEquals("1970-01-03 02:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimePlus));
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
||||||
} finally {
|
} finally {
|
||||||
TimeZone.setDefault(defaultTZ);
|
TimeZone.setDefault(defaultTZ);
|
||||||
}
|
}
|
||||||
|
@ -1647,30 +1658,30 @@ public abstract class CommonTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void stringDateFunctions() {
|
public void stringDateFunctions() {
|
||||||
Date date = new Date(166656789L);
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
||||||
System.out.println("Date: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(date));
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
||||||
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
||||||
|
logger.info("LocalDateTime: " + dateMinus + " " + datePlus);
|
||||||
TimeZone defaultTZ = TimeZone.getDefault();
|
TimeZone defaultTZ = TimeZone.getDefault();
|
||||||
try {
|
try {
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
||||||
new Schema()
|
new Schema().addTable("dbtest").addColumn("d").asDate().schema().execute(db);
|
||||||
.addTable("dbtest")
|
|
||||||
.addColumn("d").asDate().schema().execute(db);
|
|
||||||
db.toInsert("insert into dbtest (d) values ("
|
db.toInsert("insert into dbtest (d) values ("
|
||||||
+ db.flavor().dateAsSqlFunction(date, db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(dateMinus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
||||||
.insert(1);
|
.insert(1);
|
||||||
assertEquals("1970-01-02 18:17:36.789000-0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
assertEquals("1970-01-02 18:17:36.789",
|
||||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||||
// Now do some client operations in a different time zone
|
// Now do some client operations in a different time zone
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
||||||
// Verify regular arg maps date the same way even though our TimeZone is now different
|
// Verify regular arg maps date the same way even though our TimeZone is now different
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
||||||
db.toInsert("insert into dbtest (d) values ("
|
db.toInsert("insert into dbtest (d) values ("
|
||||||
+ db.flavor().dateAsSqlFunction(date, db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
||||||
.insert(1);
|
.insert(1);
|
||||||
assertEquals("1970-01-03 02:17:36.789000+0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
assertEquals("1970-01-03 02:17:36.789",
|
||||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||||
// Verify the function maps correctly for equals operations as well
|
// Verify the function maps correctly for equals operations as well
|
||||||
db.toDelete("delete from dbtest where d=" + db.flavor().dateAsSqlFunction(date,
|
db.toDelete("delete from dbtest where d=" + db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus),
|
||||||
db.options().calendarForTimestamps()).replace(":", "::")).update(1);
|
db.options().calendarForTimestamps()).replace(":", "::")).update(1);
|
||||||
} finally {
|
} finally {
|
||||||
TimeZone.setDefault(defaultTZ);
|
TimeZone.setDefault(defaultTZ);
|
||||||
|
|
|
@ -10,11 +10,10 @@ 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.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -628,20 +627,20 @@ public class RowStub {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull() {
|
public LocalDateTime getLocalDateTimeOrNull() {
|
||||||
return toDate(rows.get(row)[++col]);
|
return toDate(rows.get(row)[++col]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull(int columnOneBased) {
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||||
col = columnOneBased;
|
col = columnOneBased;
|
||||||
return toDate(rows.get(row)[columnOneBased - 1]);
|
return toDate(rows.get(row)[columnOneBased - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDateOrNull(String columnName) {
|
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||||
col = columnIndexByName(columnName) + 1;
|
col = columnIndexByName(columnName) + 1;
|
||||||
return toDate(rows.get(row)[columnIndexByName(columnName)]);
|
return toDate(rows.get(row)[columnIndexByName(columnName)]);
|
||||||
}
|
}
|
||||||
|
@ -759,29 +758,18 @@ public class RowStub {
|
||||||
return (String) o;
|
return (String) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private LocalDateTime toDate(Object o) {
|
||||||
* Returns a java.util.Date. It may be used for dates or times.
|
|
||||||
*/
|
|
||||||
private Date toDate(Object o) {
|
|
||||||
if (o instanceof String) {
|
if (o instanceof String) {
|
||||||
String s = (String) o;
|
String s = (String) o;
|
||||||
if (s.length() == "yyyy-MM-dd".length()) {
|
if (s.length() == "yyyy-MM-dd".length()) {
|
||||||
try {
|
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
return new SimpleDateFormat("yyyy-MM-dd").parse(s);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new DatabaseException("Could not parse date as yyyy-MM-dd for " + s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
|
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
|
||||||
try {
|
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"));
|
||||||
return new SimpleDateFormat("yyyy-MM-ddThh:mm:ss").parse(s);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new DatabaseException("Could not parse date as yyyy-MM-ddThh:mm:ss for " + s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new DatabaseException("Didn't understand date string: " + s);
|
throw new DatabaseException("Didn't understand date string: " + s);
|
||||||
}
|
}
|
||||||
return (Date) o;
|
return (LocalDateTime) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.xbib.jdbc.query.test.example;
|
package org.xbib.jdbc.query.test.example;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple bean for use with SampleDao.
|
* Simple bean for use with SampleDao.
|
||||||
|
@ -13,7 +13,7 @@ public class Sample {
|
||||||
|
|
||||||
private Integer updateSequence;
|
private Integer updateSequence;
|
||||||
|
|
||||||
private Date updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
public Long getSampleId() {
|
public Long getSampleId() {
|
||||||
return sampleId;
|
return sampleId;
|
||||||
|
@ -39,11 +39,11 @@ public class Sample {
|
||||||
this.updateSequence = updateSequence;
|
this.updateSequence = updateSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getUpdateTime() {
|
public LocalDateTime getUpdateTime() {
|
||||||
return updateTime;
|
return updateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpdateTime(Date updateTime) {
|
public void setUpdateTime(LocalDateTime updateTime) {
|
||||||
this.updateTime = updateTime;
|
this.updateTime = updateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.jdbc.query.test.example;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Database;
|
import org.xbib.jdbc.query.Database;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ public class SampleDao {
|
||||||
public void createSample(final Sample sample, Long userIdMakingChange) {
|
public void createSample(final Sample sample, Long userIdMakingChange) {
|
||||||
Database db = dbp.get();
|
Database db = dbp.get();
|
||||||
|
|
||||||
Date updateTime = db.nowPerApp();
|
LocalDateTime updateTime = db.nowPerApp();
|
||||||
Long sampleId = db.toInsert(
|
Long sampleId = db.toInsert(
|
||||||
"insert into sample (sample_id, sample_name, update_sequence, update_time) values (?,?,0,?)")
|
"insert into sample (sample_id, sample_name, update_sequence, update_time) values (?,?,0,?)")
|
||||||
.argPkSeq("id_seq")
|
.argPkSeq("id_seq")
|
||||||
|
@ -49,7 +50,7 @@ public class SampleDao {
|
||||||
result.setSampleId(sampleId);
|
result.setSampleId(sampleId);
|
||||||
result.setName(r.getStringOrNull());
|
result.setName(r.getStringOrNull());
|
||||||
result.setUpdateSequence(r.getIntegerOrNull());
|
result.setUpdateSequence(r.getIntegerOrNull());
|
||||||
result.setUpdateTime(r.getDateOrNull());
|
result.setUpdateTime(r.getLocalDateTimeOrNull());
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -60,7 +61,7 @@ public class SampleDao {
|
||||||
// Insert the history row first, so it will fail (non-unique sample_id + update_sequence)
|
// Insert the history row first, so it will fail (non-unique sample_id + update_sequence)
|
||||||
// if someone else modified the row. This is an optimistic locking strategy.
|
// if someone else modified the row. This is an optimistic locking strategy.
|
||||||
int newUpdateSequence = sample.getUpdateSequence() + 1;
|
int newUpdateSequence = sample.getUpdateSequence() + 1;
|
||||||
Date newUpdateTime = db.nowPerApp();
|
LocalDateTime newUpdateTime = db.nowPerApp();
|
||||||
db.toInsert("insert into sample_history (sample_id, sample_name, update_sequence, update_time, update_user_id,"
|
db.toInsert("insert into sample_history (sample_id, sample_name, update_sequence, update_time, update_user_id,"
|
||||||
+ " is_deleted) values (?,?,?,?,?,'N')")
|
+ " is_deleted) values (?,?,?,?,?,'N')")
|
||||||
.argLong(sample.getSampleId())
|
.argLong(sample.getSampleId())
|
||||||
|
@ -88,7 +89,7 @@ public class SampleDao {
|
||||||
// Insert the history row first, so it will fail (non-unique sample_id + update_sequence)
|
// Insert the history row first, so it will fail (non-unique sample_id + update_sequence)
|
||||||
// if someone else modified the row. This is an optimistic locking strategy.
|
// if someone else modified the row. This is an optimistic locking strategy.
|
||||||
int newUpdateSequence = sample.getUpdateSequence() + 1;
|
int newUpdateSequence = sample.getUpdateSequence() + 1;
|
||||||
Date newUpdateTime = db.nowPerApp();
|
LocalDateTime newUpdateTime = db.nowPerApp();
|
||||||
db.toInsert("insert into sample_history (sample_id, sample_name, update_sequence, update_time, update_user_id,"
|
db.toInsert("insert into sample_history (sample_id, sample_name, update_sequence, update_time, update_user_id,"
|
||||||
+ " is_deleted) values (?,?,?,?,?,'Y')")
|
+ " is_deleted) values (?,?,?,?,?,'Y')")
|
||||||
.argLong(sample.getSampleId())
|
.argLong(sample.getSampleId())
|
||||||
|
|
Loading…
Reference in a new issue