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;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
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.
|
||||
*/
|
||||
Date nowPerApp();
|
||||
LocalDateTime nowPerApp();
|
||||
|
||||
/**
|
||||
* 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.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -90,7 +91,7 @@ public class DatabaseImpl implements Database {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date nowPerApp() {
|
||||
public LocalDateTime nowPerApp() {
|
||||
return options.currentDate();
|
||||
}
|
||||
|
||||
|
@ -249,25 +250,26 @@ public class DatabaseImpl implements Database {
|
|||
public void assertTimeSynchronized(long millisToWarn, long millisToError) {
|
||||
toSelect("select ?" + flavor().fromAny())
|
||||
.argDateNowPerDb().queryFirstOrNull(r -> {
|
||||
Date appDate = nowPerApp();
|
||||
Date dbDate = r.getDateOrNull();
|
||||
LocalDateTime appDate = nowPerApp();
|
||||
LocalDateTime dbDate = r.getLocalDateTimeOrNull();
|
||||
if (dbDate == null) {
|
||||
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: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||
+ 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: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||
+ 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: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate.toInstant()) + " db: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate.toInstant()));
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(appDate) + " db: "
|
||||
+ DateTimeFormatter.ISO_INSTANT.format(dbDate));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package org.xbib.jdbc.query;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Enumeration of supported databases with various compatibility settings.
|
||||
|
@ -131,8 +132,8 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
dateFormat.setCalendar(calendar);
|
||||
return "timestamp('" + dateFormat.format(date) + "')";
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@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");
|
||||
dateFormat.setCalendar(calendar);
|
||||
return "cast('" + dateFormat.format(date) + "' as datetime2(3))";
|
||||
|
@ -425,7 +426,7 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@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");
|
||||
dateFormat.setCalendar(calendar);
|
||||
return "timestamp '" + dateFormat.format(date) + "'";
|
||||
|
@ -568,7 +569,7 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@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");
|
||||
dateFormat.setCalendar(calendar);
|
||||
return "'" + dateFormat.format(date) + " GMT'::timestamp";
|
||||
|
@ -711,7 +712,7 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@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");
|
||||
dateFormat.setCalendar(calendar);
|
||||
return "cast(timestamp '" + dateFormat.format(date) + "' as timestamp without time zone)";
|
||||
|
@ -855,7 +856,7 @@ public enum Flavor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String dateAsSqlFunction(Date date, Calendar calendar) {
|
||||
public String dateAsSqlFunction(Timestamp date, Calendar calendar) {
|
||||
// Construct a datetime literal
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000");
|
||||
dateFormat.setCalendar(calendar);
|
||||
|
@ -980,7 +981,7 @@ public enum Flavor {
|
|||
* Return a SQL function representing the specified date. For example, in PostgreSQL this
|
||||
* 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.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.xbib.jdbc.query;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.xbib.jdbc.query;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
@ -63,8 +64,8 @@ public class OptionsDefault implements Options {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date currentDate() {
|
||||
return new Date();
|
||||
public LocalDateTime currentDate() {
|
||||
return LocalDateTime.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.xbib.jdbc.query;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -87,7 +88,7 @@ public class OptionsOverride implements Options {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date currentDate() {
|
||||
public LocalDateTime currentDate() {
|
||||
return parent.currentDate();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.io.Reader;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Interface for reading results from a database query.
|
||||
|
@ -386,33 +386,20 @@ public interface Row {
|
|||
|
||||
|
||||
InputStream getBlobInputStreamOrEmpty(int columnOneBased);
|
||||
|
||||
|
||||
InputStream getBlobInputStreamOrEmpty(String columnName);
|
||||
|
||||
/**
|
||||
* Return the millisecond precision Date, which should be represented as a TIMESTAMP
|
||||
* in the database. The nanoseconds are truncated.
|
||||
*/
|
||||
LocalDateTime getLocalDateTimeOrNull();
|
||||
|
||||
Date getDateOrNull();
|
||||
|
||||
/**
|
||||
* Return the millisecond precision Date, which should be represented as a TIMESTAMP
|
||||
* in the database. The nanoseconds are truncated.
|
||||
*/
|
||||
LocalDateTime getLocalDateTimeOrNull(int columnOneBased);
|
||||
|
||||
Date getDateOrNull(int columnOneBased);
|
||||
|
||||
|
||||
Date getDateOrNull(String columnName);
|
||||
LocalDateTime getLocalDateTimeOrNull(String columnName);
|
||||
|
||||
/**
|
||||
* Retrieve column as LocalDate, .i.e, date with no time.
|
||||
*
|
||||
* @return LocalDate of the database column value
|
||||
*/
|
||||
|
||||
LocalDate getLocalDateOrNull();
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.sql.ResultSetMetaData;
|
|||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Safely wrap a ResultSet and provide access to the data it contains.
|
||||
|
@ -52,7 +52,6 @@ class RowsAdaptor implements Rows {
|
|||
throw new DatabaseException("Unable to retrieve metadata from ResultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResultSetMetaData getMetadata() {
|
||||
|
@ -62,13 +61,11 @@ class RowsAdaptor implements Rows {
|
|||
throw new DatabaseException("Unable to retrieve metadata from ResultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean getBooleanOrNull() {
|
||||
return getBooleanOrNull(column++);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean getBooleanOrNull(int columnOneBased) {
|
||||
|
@ -79,7 +76,6 @@ class RowsAdaptor implements Rows {
|
|||
throw new DatabaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean getBooleanOrNull(String columnName) {
|
||||
|
@ -660,36 +656,32 @@ class RowsAdaptor implements Rows {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull() {
|
||||
return getDateOrNull(column++);
|
||||
public LocalDateTime getLocalDateTimeOrNull() {
|
||||
return getLocalDateTimeOrNull(column++);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull(int columnOneBased) {
|
||||
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||
try {
|
||||
column = columnOneBased + 1;
|
||||
return toDate(rs, columnOneBased);
|
||||
return toLocalDateTime(rs, columnOneBased);
|
||||
} catch (SQLException e) {
|
||||
throw new DatabaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull(String columnName) {
|
||||
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||
try {
|
||||
column = rs.findColumn(columnName) + 1;
|
||||
return toDate(rs, columnName);
|
||||
return toLocalDateTime(rs, columnName);
|
||||
} catch (SQLException e) {
|
||||
throw new DatabaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LocalDate getLocalDateOrNull() {
|
||||
return getLocalDateOrNull(column++);
|
||||
|
@ -720,31 +712,21 @@ class RowsAdaptor implements Rows {
|
|||
@Override
|
||||
public Integer rowCount() {
|
||||
try {
|
||||
//rs.last();
|
||||
rs.last();
|
||||
return rs.getRow();
|
||||
} catch (SQLException e) {
|
||||
throw new DatabaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the Timestamp will return getTime() accurate to the millisecond
|
||||
* (if possible) and truncate away nanoseconds.
|
||||
*/
|
||||
private Date timestampToDate(Timestamp ts) {
|
||||
long millis = ts.getTime();
|
||||
int nanos = ts.getNanos();
|
||||
return new Date(millis / 1000 * 1000 + nanos / 1000000);
|
||||
private LocalDateTime toLocalDateTime(ResultSet rs, int col) throws SQLException {
|
||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
||||
return val == null ? null : val.toLocalDateTime();
|
||||
}
|
||||
|
||||
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());
|
||||
return val == null ? null : timestampToDate(val);
|
||||
}
|
||||
|
||||
private Date toDate(ResultSet rs, String col) throws SQLException {
|
||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
||||
return val == null ? null : timestampToDate(val);
|
||||
return val == null ? null : val.toLocalDateTime();
|
||||
}
|
||||
|
||||
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.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
|
@ -309,15 +309,14 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
|||
sqlArgs.argString(argName, arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Sql argDate(Date arg) {
|
||||
public Sql argDate(LocalDateTime arg) {
|
||||
sqlArgs.argDate(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Sql argDate( String argName, Date arg) {
|
||||
public Sql argDate( String argName, LocalDateTime arg) {
|
||||
sqlArgs.argDate(argName, arg);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import java.sql.ResultSetMetaData;
|
|||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -20,7 +20,6 @@ import java.util.Set;
|
|||
*/
|
||||
public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
||||
private final List<Invocation> invocations = new ArrayList<>();
|
||||
|
||||
|
||||
public static Builder fromMetadata(Row 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
|
||||
invocations.add(new Invocation(ColumnType.Date, null, arg));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public SqlArgs argDate( String argName, Date arg) {
|
||||
public SqlArgs argDate( String argName, LocalDateTime arg) {
|
||||
// date argument with a time on it
|
||||
invocations.add(new Invocation(ColumnType.Date, argName, arg));
|
||||
return this;
|
||||
|
@ -347,7 +346,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
|||
case BlobStream:
|
||||
throw new DatabaseException("Don't use Blob parameters with select statements");
|
||||
case LocalDate:
|
||||
// date argument with no time on it
|
||||
if (i.argName == null) {
|
||||
select.argLocalDate((LocalDate) i.arg);
|
||||
} else {
|
||||
|
@ -355,11 +353,10 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
|||
}
|
||||
break;
|
||||
case Date:
|
||||
// date argument with a time on it
|
||||
if (i.argName == null) {
|
||||
select.argDate((Date) i.arg);
|
||||
select.argDate((LocalDateTime) i.arg);
|
||||
} else {
|
||||
select.argDate(i.argName, (Date) i.arg);
|
||||
select.argDate(i.argName, (LocalDateTime) i.arg);
|
||||
}
|
||||
break;
|
||||
case DateNowPerApp:
|
||||
|
@ -473,9 +470,9 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
|||
case Date:
|
||||
// date argument with a time on it
|
||||
if (i.argName == null) {
|
||||
insert.argDate((Date) i.arg);
|
||||
insert.argDate((LocalDateTime) i.arg);
|
||||
} else {
|
||||
insert.argDate(i.argName, (Date) i.arg);
|
||||
insert.argDate(i.argName, (LocalDateTime) i.arg);
|
||||
}
|
||||
break;
|
||||
case DateNowPerApp:
|
||||
|
@ -579,7 +576,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
|||
}
|
||||
break;
|
||||
case LocalDate:
|
||||
// date argument with no time on it
|
||||
if (i.argName == null) {
|
||||
update.argLocalDate((LocalDate) i.arg);
|
||||
} else {
|
||||
|
@ -587,11 +583,10 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
|||
}
|
||||
break;
|
||||
case Date:
|
||||
// date argument with a time on it
|
||||
if (i.argName == null) {
|
||||
update.argDate((Date) i.arg);
|
||||
update.argDate((LocalDateTime) i.arg);
|
||||
} else {
|
||||
update.argDate(i.argName, (Date) i.arg);
|
||||
update.argDate(i.argName, (LocalDateTime) i.arg);
|
||||
}
|
||||
break;
|
||||
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
|
||||
args.argLocalDate(names[i], r.getLocalDateOrNull());
|
||||
} else {
|
||||
args.argDate(names[i], r.getDateOrNull());
|
||||
args.argDate(names[i], r.getLocalDateTimeOrNull());
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.io.InputStream;
|
|||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
||||
|
@ -33,15 +33,15 @@ public interface SqlInsert {
|
|||
|
||||
SqlInsert argBigDecimal(BigDecimal arg);
|
||||
|
||||
SqlInsert argBigDecimal( String argName, BigDecimal arg);
|
||||
SqlInsert argBigDecimal(String argName, BigDecimal arg);
|
||||
|
||||
SqlInsert argString(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
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -125,43 +125,36 @@ public class SqlInsertImpl implements SqlInsert {
|
|||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argBigDecimal( String argName, BigDecimal arg) {
|
||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argString(String arg) {
|
||||
return positionalArg(adaptor.nullString(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argString( String argName, String arg) {
|
||||
return namedArg(argName, adaptor.nullString(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argDate(Date arg) {
|
||||
public SqlInsert argDate(LocalDateTime arg) {
|
||||
return positionalArg(adaptor.nullDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argDate( String argName, Date arg) {
|
||||
public SqlInsert argDate( String argName, LocalDateTime arg) {
|
||||
return namedArg(argName, adaptor.nullDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argLocalDate( String argName, LocalDate arg) {
|
||||
return namedArg(argName, adaptor.nullLocalDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argLocalDate(LocalDate arg) {
|
||||
return positionalArg(adaptor.nullLocalDate(arg));
|
||||
}
|
||||
|
@ -173,11 +166,9 @@ public class SqlInsertImpl implements SqlInsert {
|
|||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlInsert argDateNowPerApp( String argName) {
|
||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqlInsert argDateNowPerDb() {
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.xbib.jdbc.query;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
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, Date arg); // Date with time
|
||||
SqlSelect argDate(String argName, LocalDateTime 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.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -140,14 +140,14 @@ public class SqlSelectImpl implements SqlSelect {
|
|||
|
||||
|
||||
@Override
|
||||
public SqlSelect argDate(Date arg) {
|
||||
public SqlSelect argDate(LocalDateTime arg) {
|
||||
// Date with time
|
||||
return positionalArg(adaptor.nullDate(arg));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqlSelect argDate( String argName, Date arg) {
|
||||
public SqlSelect argDate( String argName, LocalDateTime arg) {
|
||||
// Date with time
|
||||
return namedArg(argName, adaptor.nullDate(arg));
|
||||
}
|
||||
|
@ -467,21 +467,21 @@ public class SqlSelectImpl implements SqlSelect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date queryDateOrNull() {
|
||||
public LocalDateTime queryDateOrNull() {
|
||||
return queryWithTimeout(rs -> {
|
||||
if (rs.next()) {
|
||||
return rs.getDateOrNull(1);
|
||||
return rs.getLocalDateTimeOrNull(1);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Date> queryDates() {
|
||||
public List<LocalDateTime> queryDates() {
|
||||
return queryWithTimeout(rs -> {
|
||||
List<Date> result = new ArrayList<>();
|
||||
List<LocalDateTime> result = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
Date value = rs.getDateOrNull(1);
|
||||
LocalDateTime value = rs.getLocalDateTimeOrNull(1);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
|
@ -619,7 +619,9 @@ public class SqlSelectImpl implements SqlSelect {
|
|||
|
||||
if (connection != null) {
|
||||
synchronized (cancelLock) {
|
||||
ps = connection.prepareStatement(executeSql);
|
||||
ps = connection.prepareStatement(executeSql,
|
||||
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
}
|
||||
|
||||
if (timeoutSeconds >= 0) {
|
||||
|
|
|
@ -4,137 +4,74 @@ import java.io.InputStream;
|
|||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
||||
*/
|
||||
public interface SqlUpdate {
|
||||
|
||||
|
||||
SqlUpdate argBoolean(Boolean arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBoolean( String argName, Boolean arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argInteger(Integer arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argInteger( String argName, Integer arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argLong(Long arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argLong( String argName, Long arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argFloat(Float arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argFloat( String argName, Float arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDouble(Double arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDouble( String argName, Double arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBigDecimal(BigDecimal arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBigDecimal( String argName, BigDecimal arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argString(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( String argName, LocalDate arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argLocalDate(LocalDate arg); // Date only - no timestamp
|
||||
|
||||
|
||||
|
||||
SqlUpdate argLocalDate( String argName, LocalDate arg); // Date only - no timestamp
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDateNowPerApp();
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDateNowPerApp( String argName);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDateNowPerDb();
|
||||
|
||||
|
||||
|
||||
SqlUpdate argDateNowPerDb( String argName);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBlobBytes(byte[] arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBlobBytes( String argName, byte[] arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBlobStream(InputStream arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argBlobStream( String argName, InputStream arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argClobString(String arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argClobString( String argName, String arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argClobReader(Reader arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate argClobReader( String argName, Reader arg);
|
||||
|
||||
|
||||
|
||||
SqlUpdate withArgs(SqlArgs args);
|
||||
|
||||
|
||||
|
||||
SqlUpdate apply(Apply apply);
|
||||
|
||||
|
@ -151,14 +88,6 @@ public interface SqlUpdate {
|
|||
*/
|
||||
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 {
|
||||
void apply(SqlUpdate update);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ import java.math.BigDecimal;
|
|||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -131,32 +131,27 @@ public class SqlUpdateImpl implements SqlUpdate {
|
|||
|
||||
@Override
|
||||
|
||||
public SqlUpdate argDate(Date arg) {
|
||||
// Date with time
|
||||
public SqlUpdate argDate(LocalDateTime arg) {
|
||||
return positionalArg(adaptor.nullDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlUpdate argDate(String argName, Date arg) {
|
||||
// Date with time
|
||||
public SqlUpdate argDate(String argName, LocalDateTime arg) {
|
||||
return namedArg(argName, adaptor.nullDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlUpdate argLocalDate(LocalDate arg) {
|
||||
// Date with no time
|
||||
return positionalArg(adaptor.nullLocalDate(arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SqlUpdate argLocalDate(String argName, LocalDate arg) {
|
||||
// Date with no time
|
||||
return namedArg(argName, adaptor.nullLocalDate(arg));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqlUpdate argDateNowPerApp() {
|
||||
|
@ -169,7 +164,6 @@ public class SqlUpdateImpl implements SqlUpdate {
|
|||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqlUpdate argDateNowPerDb() {
|
||||
if (options.useDatePerAppOnly()) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.Statement;
|
|||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Scanner;
|
||||
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) {
|
||||
return new SqlNull(Types.TIMESTAMP);
|
||||
}
|
||||
return new Timestamp(arg.getTime());
|
||||
return Timestamp.valueOf(arg);
|
||||
}
|
||||
|
||||
// Processes a true date without time information.
|
||||
|
|
|
@ -6,8 +6,8 @@ import org.xbib.jdbc.query.SqlNull;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -77,9 +77,9 @@ public class DebugSql {
|
|||
} else if (argToPrint instanceof SqlNull || argToPrint == null) {
|
||||
buf.append("null");
|
||||
} 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) {
|
||||
buf.append(options.flavor().localDateAsSqlFunction((Date) argToPrint));
|
||||
buf.append(options.flavor().localDateAsSqlFunction((java.sql.Date) argToPrint));
|
||||
} else if (argToPrint instanceof Number) {
|
||||
buf.append(argToPrint);
|
||||
} else if (argToPrint instanceof Boolean) {
|
||||
|
|
|
@ -25,15 +25,23 @@ import java.io.Reader;
|
|||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
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.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -50,6 +58,8 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public abstract class CommonTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CommonTest.class.getName());
|
||||
|
||||
final static String TEST_TABLE_NAME = "dbtest";
|
||||
|
||||
/**
|
||||
|
@ -60,7 +70,7 @@ public abstract class CommonTest {
|
|||
|
||||
protected Database db;
|
||||
|
||||
protected Date now = new Date();
|
||||
protected LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
|
||||
protected LocalDate localDateNow = LocalDate.now();
|
||||
|
||||
|
@ -68,7 +78,7 @@ public abstract class CommonTest {
|
|||
public void setupJdbc() throws Exception {
|
||||
dbp = createDatabaseProvider(new OptionsOverride() {
|
||||
@Override
|
||||
public Date currentDate() {
|
||||
public LocalDateTime currentDate() {
|
||||
return now;
|
||||
}
|
||||
|
||||
|
@ -197,8 +207,8 @@ public abstract class CommonTest {
|
|||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen(9));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen("bin_blob"));
|
||||
assertEquals(now, rs.getDateOrNull(10));
|
||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -217,7 +227,7 @@ public abstract class CommonTest {
|
|||
assertEquals("T", rs.getStringOrNull());
|
||||
assertEquals("World", rs.getClobStringOrNull());
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull());
|
||||
assertEquals(now, rs.getDateOrNull());
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull());
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull());
|
||||
return null;
|
||||
});
|
||||
|
@ -350,8 +360,8 @@ public abstract class CommonTest {
|
|||
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||
assertNull(rs.getBlobBytesOrNull(9));
|
||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertNull(rs.getDateOrNull(10));
|
||||
assertNull(rs.getDateOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateOrNull(11));
|
||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -381,8 +391,8 @@ public abstract class CommonTest {
|
|||
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertEquals(now, rs.getDateOrNull(10));
|
||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -457,8 +467,8 @@ public abstract class CommonTest {
|
|||
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||
assertNull(rs.getBlobBytesOrNull(9));
|
||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertNull(rs.getDateOrNull(10));
|
||||
assertNull(rs.getDateOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateOrNull(11));
|
||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -491,8 +501,8 @@ public abstract class CommonTest {
|
|||
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
||||
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertEquals(now, rs.getDateOrNull(10));
|
||||
assertEquals(now, rs.getDateOrNull("date_millis"));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
||||
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
||||
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -560,8 +570,8 @@ public abstract class CommonTest {
|
|||
assertNull(rs.getClobStringOrNull("str_lob"));
|
||||
assertNull(rs.getBlobBytesOrNull(9));
|
||||
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
||||
assertNull(rs.getDateOrNull(10));
|
||||
assertNull(rs.getDateOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateTimeOrNull(10));
|
||||
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
||||
assertNull(rs.getLocalDateOrNull(11));
|
||||
assertNull(rs.getLocalDateOrNull("local_date"));
|
||||
return null;
|
||||
|
@ -1324,10 +1334,9 @@ public abstract class CommonTest {
|
|||
@Test
|
||||
public void argBigDecimal38Precision38() {
|
||||
new Schema().addTable("dbtest").addColumn("i").asBigDecimal(38, 38).schema().execute(db);
|
||||
|
||||
BigDecimal value = new BigDecimal("0.99999999999999999999999999999999999999"); // 38 digits
|
||||
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,
|
||||
db.toSelect("select i from dbtest where i=?").argBigDecimal(value).queryBigDecimalOrNull());
|
||||
}
|
||||
|
@ -1379,7 +1388,7 @@ public abstract class CommonTest {
|
|||
.insertReturning("dbtest", "pk", rs -> {
|
||||
assertTrue(rs.next());
|
||||
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
||||
assertThat(rs.getDateOrNull(2), equalTo(now));
|
||||
assertThat(rs.getLocalDateTimeOrNull(2), equalTo(now));
|
||||
assertFalse(rs.next());
|
||||
return null;
|
||||
}, "d");
|
||||
|
@ -1511,13 +1520,13 @@ public abstract class CommonTest {
|
|||
.addColumn("d").asDate().table().schema()
|
||||
.addSequence("dbtest_seq").schema()
|
||||
.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")
|
||||
.argDateNowPerDb(":d")
|
||||
.insertReturning("dbtest", "pk", rs -> {
|
||||
assertTrue(rs.next());
|
||||
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
||||
Date dbDate = rs.getDateOrNull(2);
|
||||
LocalDateTime dbDate = rs.getLocalDateTimeOrNull(2);
|
||||
assertFalse(rs.next());
|
||||
return dbDate;
|
||||
}, "d");
|
||||
|
@ -1583,11 +1592,11 @@ public abstract class CommonTest {
|
|||
db.toInsert("insert into dbtest (d) values (?)")
|
||||
.argDateNowPerDb()
|
||||
.insert(1);
|
||||
Date dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||
if (dbNow != null && dbNow.getTime() % 10 != 0) {
|
||||
LocalDateTime dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||
if (dbNow != null && dbNow.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() % 10 != 0) {
|
||||
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);
|
||||
}
|
||||
fail("Timestamp had zero in the least significant digit");
|
||||
|
@ -1605,7 +1614,7 @@ public abstract class CommonTest {
|
|||
.argDateNowPerDb()
|
||||
.insert(1);
|
||||
// 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=?")
|
||||
.argDate(dbNow)
|
||||
.update(1);
|
||||
|
@ -1619,21 +1628,23 @@ public abstract class CommonTest {
|
|||
.addTable("dbtest")
|
||||
.addColumn("d").asDate().table().schema()
|
||||
.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();
|
||||
try {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
||||
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
||||
assertEquals(date, 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(
|
||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
||||
db.toInsert("insert into dbtest (d) values (?)").argDate(dateMinus).insert(1);
|
||||
LocalDateTime localDateTimeMinus = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||
assertEquals(dateMinus, localDateTimeMinus);
|
||||
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(dateMinus).update(1);
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
||||
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
||||
assertEquals(date, 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(
|
||||
db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
||||
db.toInsert("insert into dbtest (d) values (?)").argDate(datePlus).insert(1);
|
||||
LocalDateTime localDateTimePlus = db.toSelect("select d from dbtest").queryDateOrNull();
|
||||
assertEquals(datePlus, localDateTimePlus);
|
||||
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(datePlus).update(1);
|
||||
} finally {
|
||||
TimeZone.setDefault(defaultTZ);
|
||||
}
|
||||
|
@ -1647,30 +1658,30 @@ public abstract class CommonTest {
|
|||
*/
|
||||
@Test
|
||||
public void stringDateFunctions() {
|
||||
Date date = new Date(166656789L);
|
||||
System.out.println("Date: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(date));
|
||||
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)));
|
||||
logger.info("LocalDateTime: " + dateMinus + " " + datePlus);
|
||||
TimeZone defaultTZ = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
||||
new Schema()
|
||||
.addTable("dbtest")
|
||||
.addColumn("d").asDate().schema().execute(db);
|
||||
new Schema().addTable("dbtest").addColumn("d").asDate().schema().execute(db);
|
||||
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);
|
||||
assertEquals("1970-01-02 18:17:36.789000-0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
||||
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(db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||
// Now do some client operations in a different time zone
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
||||
// 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.flavor().dateAsSqlFunction(date, db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
||||
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
||||
.insert(1);
|
||||
assertEquals("1970-01-03 02:17:36.789000+0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
||||
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(db.toSelect("select d from dbtest").queryDateOrNull()));
|
||||
// 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);
|
||||
} finally {
|
||||
TimeZone.setDefault(defaultTZ);
|
||||
|
|
|
@ -10,11 +10,10 @@ import java.io.StringReader;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.Types;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -628,20 +627,20 @@ public class RowStub {
|
|||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull() {
|
||||
public LocalDateTime getLocalDateTimeOrNull() {
|
||||
return toDate(rows.get(row)[++col]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull(int columnOneBased) {
|
||||
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||
col = columnOneBased;
|
||||
return toDate(rows.get(row)[columnOneBased - 1]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date getDateOrNull(String columnName) {
|
||||
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||
col = columnIndexByName(columnName) + 1;
|
||||
return toDate(rows.get(row)[columnIndexByName(columnName)]);
|
||||
}
|
||||
|
@ -759,29 +758,18 @@ public class RowStub {
|
|||
return (String) o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a java.util.Date. It may be used for dates or times.
|
||||
*/
|
||||
private Date toDate(Object o) {
|
||||
private LocalDateTime toDate(Object o) {
|
||||
if (o instanceof String) {
|
||||
String s = (String) o;
|
||||
if (s.length() == "yyyy-MM-dd".length()) {
|
||||
try {
|
||||
return new SimpleDateFormat("yyyy-MM-dd").parse(s);
|
||||
} catch (ParseException e) {
|
||||
throw new DatabaseException("Could not parse date as yyyy-MM-dd for " + s);
|
||||
}
|
||||
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
}
|
||||
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
|
||||
try {
|
||||
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);
|
||||
}
|
||||
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"));
|
||||
}
|
||||
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;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Simple bean for use with SampleDao.
|
||||
|
@ -13,7 +13,7 @@ public class Sample {
|
|||
|
||||
private Integer updateSequence;
|
||||
|
||||
private Date updateTime;
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
public Long getSampleId() {
|
||||
return sampleId;
|
||||
|
@ -39,11 +39,11 @@ public class Sample {
|
|||
this.updateSequence = updateSequence;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
public LocalDateTime getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
public void setUpdateTime(LocalDateTime updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.jdbc.query.test.example;
|
|||
|
||||
import org.xbib.jdbc.query.Database;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class SampleDao {
|
|||
public void createSample(final Sample sample, Long userIdMakingChange) {
|
||||
Database db = dbp.get();
|
||||
|
||||
Date updateTime = db.nowPerApp();
|
||||
LocalDateTime updateTime = db.nowPerApp();
|
||||
Long sampleId = db.toInsert(
|
||||
"insert into sample (sample_id, sample_name, update_sequence, update_time) values (?,?,0,?)")
|
||||
.argPkSeq("id_seq")
|
||||
|
@ -49,7 +50,7 @@ public class SampleDao {
|
|||
result.setSampleId(sampleId);
|
||||
result.setName(r.getStringOrNull());
|
||||
result.setUpdateSequence(r.getIntegerOrNull());
|
||||
result.setUpdateTime(r.getDateOrNull());
|
||||
result.setUpdateTime(r.getLocalDateTimeOrNull());
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
@ -60,7 +61,7 @@ public class SampleDao {
|
|||
// 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.
|
||||
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,"
|
||||
+ " is_deleted) values (?,?,?,?,?,'N')")
|
||||
.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)
|
||||
// if someone else modified the row. This is an optimistic locking strategy.
|
||||
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,"
|
||||
+ " is_deleted) values (?,?,?,?,?,'Y')")
|
||||
.argLong(sample.getSampleId())
|
||||
|
|
Loading…
Reference in a new issue