move java.util.Date to java.time
This commit is contained in:
parent
1047be8456
commit
625c8999a3
36 changed files with 796 additions and 922 deletions
|
@ -2,7 +2,6 @@ package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -90,11 +89,6 @@ public interface Database extends Supplier<Database> {
|
||||||
*/
|
*/
|
||||||
Long nextSequenceValue( String sequenceName);
|
Long nextSequenceValue( String sequenceName);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value that would be used if you specify an argNowPerApp() parameter.
|
|
||||||
*/
|
|
||||||
LocalDateTime nowPerApp();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cause the underlying connection to commit its transaction immediately. This
|
* Cause the underlying connection to commit its transaction immediately. This
|
||||||
* must be explicitly enabled (see {@link Options},
|
* must be explicitly enabled (see {@link Options},
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -95,11 +94,6 @@ public class DatabaseImpl implements Database {
|
||||||
return toSelect(flavor().sequenceSelectNextVal(sequenceName)).queryLongOrNull();
|
return toSelect(flavor().sequenceSelectNextVal(sequenceName)).queryLongOrNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalDateTime nowPerApp() {
|
|
||||||
return options.currentDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commitNow() {
|
public void commitNow() {
|
||||||
if (options.ignoreTransactionControl()) {
|
if (options.ignoreTransactionControl()) {
|
||||||
|
@ -250,8 +244,9 @@ public class DatabaseImpl implements Database {
|
||||||
@Override
|
@Override
|
||||||
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 -> {
|
.argLocalDateTimeNowPerDb()
|
||||||
LocalDateTime appDate = nowPerApp();
|
.queryFirstOrNull(r -> {
|
||||||
|
LocalDateTime appDate = LocalDateTime.now();
|
||||||
LocalDateTime dbDate = r.getLocalDateTimeOrNull();
|
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");
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ public final class DatabaseProvider implements Supplier<Database> {
|
||||||
public Builder withDatePerAppOnly() {
|
public Builder withDatePerAppOnly() {
|
||||||
return new BuilderImpl(ds, connectionProvider, new OptionsOverride() {
|
return new BuilderImpl(ds, connectionProvider, new OptionsOverride() {
|
||||||
@Override
|
@Override
|
||||||
public boolean useDatePerAppOnly() {
|
public boolean useLocalDateTimeOnly() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}.withParent(this.options));
|
}.withParent(this.options));
|
||||||
|
|
|
@ -30,13 +30,11 @@ public class DdlImpl implements Ddl {
|
||||||
private void updateInternal(boolean quiet) {
|
private void updateInternal(boolean quiet) {
|
||||||
CallableStatement ps = null;
|
CallableStatement ps = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
Exception logEx = null;
|
Exception logEx = null;
|
||||||
try {
|
try {
|
||||||
ps = connection.prepareCall(sql);
|
ps = connection.prepareCall(sql);
|
||||||
|
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
ps.execute();
|
ps.execute();
|
||||||
metric.checkpoint("exec");
|
metric.checkpoint("exec");
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
public interface Flavor {
|
public interface Flavor {
|
||||||
|
@ -39,7 +36,7 @@ public interface Flavor {
|
||||||
|
|
||||||
String typeBlob();
|
String typeBlob();
|
||||||
|
|
||||||
String typeDate();
|
String typeLocalDateTime();
|
||||||
|
|
||||||
String typeLocalDate();
|
String typeLocalDate();
|
||||||
|
|
||||||
|
@ -72,17 +69,6 @@ public interface Flavor {
|
||||||
*/
|
*/
|
||||||
String fromAny();
|
String fromAny();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a SQL function representing the specified date. For example, in PostgreSQL this
|
|
||||||
* looks like "'1970-01-02 02:17:36.789000 GMT'::timestamp".
|
|
||||||
*/
|
|
||||||
String dateAsSqlFunction(Timestamp timestamp, Calendar calendar);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a SQL function representing the specified date without time.
|
|
||||||
*/
|
|
||||||
String localDateAsSqlFunction(Date date);
|
|
||||||
|
|
||||||
String sequenceOptions();
|
String sequenceOptions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control various optional behavior for the database interactions.
|
* Control various optional behavior for the database interactions.
|
||||||
*/
|
*/
|
||||||
|
@ -95,27 +92,10 @@ public interface Options {
|
||||||
Flavor flavor();
|
Flavor flavor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value returned by this method will be used for argDateNowPerApp() calls. It
|
* This is useful for testing purposes as you can use OptionsOverride to provide your
|
||||||
* may also be used for argDateNowPerDb() calls if you have enabled that.
|
* own clock that will be used.
|
||||||
*/
|
*/
|
||||||
LocalDateTime currentDate();
|
boolean useLocalDateTimeOnly();
|
||||||
|
|
||||||
/**
|
|
||||||
* Wherever argDateNowPerDb() is specified, use argDateNowPerApp() instead. This is
|
|
||||||
* useful for testing purposes as you can use OptionsOverride to provide your
|
|
||||||
* own system clock that will be used for time travel.
|
|
||||||
*/
|
|
||||||
boolean useDatePerAppOnly();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calendar will be used for conversions when storing and retrieving timestamps
|
|
||||||
* from the database. By default this is the JVM default with TimeZone explicitly set
|
|
||||||
* to GMT (so timestamps will be stored in the database as GMT).
|
|
||||||
*
|
|
||||||
* <p>It is strongly recommended to always run your database in GMT timezone, and
|
|
||||||
* leave this set to the default.</p>
|
|
||||||
*/
|
|
||||||
Calendar calendarForTimestamps();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of characters to print in debug SQL for a given String type
|
* The maximum number of characters to print in debug SQL for a given String type
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control various optional behavior for the database interactions.
|
* Control various optional behavior for the database interactions.
|
||||||
|
@ -44,8 +40,7 @@ public class OptionsDefault implements Options {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateErrorCode() {
|
public String generateErrorCode() {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:H:m:s");
|
return LocalDateTime.now() + "-" + Math.round(Math.random() * 1000000);
|
||||||
return sdf.format(new Date()) + "-" + Math.round(Math.random() * 1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,20 +59,10 @@ public class OptionsDefault implements Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime currentDate() {
|
public boolean useLocalDateTimeOnly() {
|
||||||
return LocalDateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useDatePerAppOnly() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Calendar calendarForTimestamps() {
|
|
||||||
return Calendar.getInstance(TimeZone.getDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int maxStringLengthParam() {
|
public int maxStringLengthParam() {
|
||||||
return 4000;
|
return 4000;
|
||||||
|
|
|
@ -2,9 +2,6 @@ package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.flavor.Postgresql;
|
import org.xbib.jdbc.query.flavor.Postgresql;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for selectively overriding another Options object.
|
* Base class for selectively overriding another Options object.
|
||||||
|
@ -90,18 +87,8 @@ public class OptionsOverride implements Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime currentDate() {
|
public boolean useLocalDateTimeOnly() {
|
||||||
return parent.currentDate();
|
return parent.useLocalDateTimeOnly();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useDatePerAppOnly() {
|
|
||||||
return parent.useDatePerAppOnly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Calendar calendarForTimestamps() {
|
|
||||||
return parent.calendarForTimestamps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.math.BigDecimal;
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for reading results from a database query.
|
* Interface for reading results from a database query.
|
||||||
|
@ -228,173 +229,142 @@ public interface Row {
|
||||||
* representation. Some databases will pad the number out to "full precision". This
|
* representation. Some databases will pad the number out to "full precision". This
|
||||||
* method tries to reduce scale if there is zero padding to the right of the decimal.
|
* method tries to reduce scale if there is zero padding to the right of the decimal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrNull();
|
BigDecimal getBigDecimalOrNull();
|
||||||
|
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrNull(int columnOneBased);
|
BigDecimal getBigDecimalOrNull(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrNull(String columnName);
|
BigDecimal getBigDecimalOrNull(String columnName);
|
||||||
|
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrZero();
|
BigDecimal getBigDecimalOrZero();
|
||||||
|
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrZero(int columnOneBased);
|
BigDecimal getBigDecimalOrZero(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
BigDecimal getBigDecimalOrZero(String columnName);
|
BigDecimal getBigDecimalOrZero(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrNull();
|
String getStringOrNull();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrNull(int columnOneBased);
|
String getStringOrNull(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrNull(String columnName);
|
String getStringOrNull(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrEmpty();
|
String getStringOrEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrEmpty(int columnOneBased);
|
String getStringOrEmpty(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getStringOrEmpty(String columnName);
|
String getStringOrEmpty(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrNull();
|
String getClobStringOrNull();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrNull(int columnOneBased);
|
String getClobStringOrNull(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null; never returns the empty string
|
* @return the value, or null if it is SQL null; never returns the empty string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrNull(String columnName);
|
String getClobStringOrNull(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrEmpty();
|
String getClobStringOrEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrEmpty(int columnOneBased);
|
String getClobStringOrEmpty(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or the empty string if it is SQL null; never returns null
|
* @return the value, or the empty string if it is SQL null; never returns null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String getClobStringOrEmpty(String columnName);
|
String getClobStringOrEmpty(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null
|
* @return the value, or null if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrNull();
|
Reader getClobReaderOrNull();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null
|
* @return the value, or null if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrNull(int columnOneBased);
|
Reader getClobReaderOrNull(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or null if it is SQL null
|
* @return the value, or null if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrNull(String columnName);
|
Reader getClobReaderOrNull(String columnName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or a StringReader containing the empty string if it is SQL null
|
* @return the value, or a StringReader containing the empty string if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrEmpty();
|
Reader getClobReaderOrEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or a StringReader containing the empty string if it is SQL null
|
* @return the value, or a StringReader containing the empty string if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrEmpty(int columnOneBased);
|
Reader getClobReaderOrEmpty(int columnOneBased);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the value, or a StringReader containing the empty string if it is SQL null
|
* @return the value, or a StringReader containing the empty string if it is SQL null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Reader getClobReaderOrEmpty(String columnName);
|
Reader getClobReaderOrEmpty(String columnName);
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrNull();
|
byte[] getBlobBytesOrNull();
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrNull(int columnOneBased);
|
byte[] getBlobBytesOrNull(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrNull(String columnName);
|
byte[] getBlobBytesOrNull(String columnName);
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrZeroLen();
|
byte[] getBlobBytesOrZeroLen();
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrZeroLen(int columnOneBased);
|
byte[] getBlobBytesOrZeroLen(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
byte[] getBlobBytesOrZeroLen(String columnName);
|
byte[] getBlobBytesOrZeroLen(String columnName);
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrNull();
|
InputStream getBlobInputStreamOrNull();
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrNull(int columnOneBased);
|
InputStream getBlobInputStreamOrNull(int columnOneBased);
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrNull(String columnName);
|
InputStream getBlobInputStreamOrNull(String columnName);
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrEmpty();
|
InputStream getBlobInputStreamOrEmpty();
|
||||||
|
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrEmpty(int columnOneBased);
|
InputStream getBlobInputStreamOrEmpty(int columnOneBased);
|
||||||
|
|
||||||
InputStream getBlobInputStreamOrEmpty(String columnName);
|
InputStream getBlobInputStreamOrEmpty(String columnName);
|
||||||
|
|
||||||
LocalDateTime getLocalDateTimeOrNull();
|
LocalDateTime getLocalDateTimeOrNull();
|
||||||
|
|
||||||
LocalDateTime getLocalDateTimeOrNull(int columnOneBased);
|
LocalDateTime getLocalDateTimeOrNull(int columnOneBased);
|
||||||
|
|
||||||
|
LocalDateTime getLocalDateTimeOrNull(int columnOneBased, ZoneId zoneId);
|
||||||
|
|
||||||
LocalDateTime getLocalDateTimeOrNull(String columnName);
|
LocalDateTime getLocalDateTimeOrNull(String columnName);
|
||||||
|
|
||||||
|
LocalDateTime getLocalDateTimeOrNull(String columnName, ZoneId zoneId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve column as LocalDate, .i.e, date with no time.
|
* Retrieve column as LocalDate, .i.e, date with no time.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely wrap a ResultSet and provide access to the data it contains.
|
* Safely wrap a ResultSet and provide access to the data it contains.
|
||||||
|
@ -38,7 +39,6 @@ class RowsAdaptor implements Rows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getColumnLabels() {
|
public String[] getColumnLabels() {
|
||||||
try {
|
try {
|
||||||
|
@ -661,22 +661,49 @@ class RowsAdaptor implements Rows {
|
||||||
public LocalDateTime getLocalDateTimeOrNull() {
|
public LocalDateTime getLocalDateTimeOrNull() {
|
||||||
return getLocalDateTimeOrNull(column++);
|
return getLocalDateTimeOrNull(column++);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||||
try {
|
try {
|
||||||
column = columnOneBased + 1;
|
column = columnOneBased + 1;
|
||||||
return toLocalDateTime(rs, columnOneBased);
|
return rs.getObject(columnOneBased, LocalDateTime.class);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased, ZoneId zoneId) {
|
||||||
|
try {
|
||||||
|
column = columnOneBased + 1;
|
||||||
|
LocalDateTime localDateTime = rs.getObject(columnOneBased, LocalDateTime.class);
|
||||||
|
Timestamp timestamp = rs.getTimestamp(columnOneBased);
|
||||||
|
if (zoneId != null) {
|
||||||
|
return localDateTime != null ? localDateTime.atZone(zoneId).toLocalDateTime() : null;
|
||||||
|
} else {
|
||||||
|
return localDateTime;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DatabaseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||||
try {
|
try {
|
||||||
column = rs.findColumn(columnName) + 1;
|
column = rs.findColumn(columnName) + 1;
|
||||||
return toLocalDateTime(rs, columnName);
|
return rs.getObject(columnName, LocalDateTime.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DatabaseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime getLocalDateTimeOrNull(String columnName, ZoneId zoneId) {
|
||||||
|
try {
|
||||||
|
column = rs.findColumn(columnName) + 1;
|
||||||
|
LocalDateTime localDateTime = rs.getObject(columnName, LocalDateTime.class);
|
||||||
|
return localDateTime != null ? localDateTime.atZone(zoneId).toLocalDateTime() : null;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
|
@ -686,7 +713,6 @@ class RowsAdaptor implements Rows {
|
||||||
public LocalDate getLocalDateOrNull() {
|
public LocalDate getLocalDateOrNull() {
|
||||||
return getLocalDateOrNull(column++);
|
return getLocalDateOrNull(column++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDate getLocalDateOrNull(int columnOneBased) {
|
public LocalDate getLocalDateOrNull(int columnOneBased) {
|
||||||
|
@ -697,7 +723,6 @@ class RowsAdaptor implements Rows {
|
||||||
throw new DatabaseException(e);
|
throw new DatabaseException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDate getLocalDateOrNull(String columnName) {
|
public LocalDate getLocalDateOrNull(String columnName) {
|
||||||
|
@ -719,16 +744,6 @@ class RowsAdaptor implements Rows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDateTime toLocalDateTime(ResultSet rs, int col) throws SQLException {
|
|
||||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
|
||||||
return val == null ? null : val.toLocalDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalDateTime toLocalDateTime(ResultSet rs, String col) throws SQLException {
|
|
||||||
Timestamp val = rs.getTimestamp(col, options.calendarForTimestamps());
|
|
||||||
return val == null ? null : val.toLocalDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalDate toLocalDate(ResultSet rs, int col) throws SQLException {
|
private LocalDate toLocalDate(ResultSet rs, int col) throws SQLException {
|
||||||
java.sql.Date val = rs.getDate(col);
|
java.sql.Date val = rs.getDate(col);
|
||||||
return val == null ? null : val.toLocalDate();
|
return val == null ? null : val.toLocalDate();
|
||||||
|
|
|
@ -5,5 +5,6 @@ package org.xbib.jdbc.query;
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface RowsHandler<T> {
|
public interface RowsHandler<T> {
|
||||||
|
|
||||||
T process(Rows rs) throws Exception;
|
T process(Rows rs) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,17 +76,14 @@ public class Schema {
|
||||||
Table table = addTable(tableName);
|
Table table = addTable(tableName);
|
||||||
try {
|
try {
|
||||||
ResultSetMetaData metadata = r.getMetadata();
|
ResultSetMetaData metadata = r.getMetadata();
|
||||||
|
|
||||||
int columnCount = metadata.getColumnCount();
|
int columnCount = metadata.getColumnCount();
|
||||||
String[] names = new String[columnCount];
|
String[] names = new String[columnCount];
|
||||||
for (int i = 0; i < columnCount; i++) {
|
for (int i = 0; i < columnCount; i++) {
|
||||||
names[i] = metadata.getColumnName(i + 1);
|
names[i] = metadata.getColumnName(i + 1);
|
||||||
}
|
}
|
||||||
names = SqlArgs.tidyColumnNames(names);
|
names = SqlArgs.tidyColumnNames(names);
|
||||||
|
|
||||||
for (int i = 0; i < columnCount; i++) {
|
for (int i = 0; i < columnCount; i++) {
|
||||||
int type = metadata.getColumnType(i + 1);
|
int type = metadata.getColumnType(i + 1);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Types.SMALLINT:
|
case Types.SMALLINT:
|
||||||
case Types.INTEGER:
|
case Types.INTEGER:
|
||||||
|
@ -142,13 +139,14 @@ public class Schema {
|
||||||
// This is the type dates and times with time and time zone associated.
|
// This is the type dates and times with time and time zone associated.
|
||||||
// Note that Oracle dates are always really Timestamps.
|
// Note that Oracle dates are always really Timestamps.
|
||||||
case Types.TIMESTAMP:
|
case Types.TIMESTAMP:
|
||||||
|
case Types.TIMESTAMP_WITH_TIMEZONE:
|
||||||
// Check if we really have a LocalDate implemented by the DB as a timestamp
|
// Check if we really have a LocalDate implemented by the DB as a timestamp
|
||||||
if (metadata.getScale(i + 1) == 0) {
|
if (metadata.getScale(i + 1) == 0) {
|
||||||
// If the scale is 0, this is a LocalDate (no time/timezone).
|
// If the scale is 0, this is a LocalDate (no time/timezone).
|
||||||
// Anything with a time/timezone will have a non-zero scale
|
// Anything with a time/timezone will have a non-zero scale
|
||||||
table.addColumn(names[i]).asLocalDate();
|
table.addColumn(names[i]).asLocalDate();
|
||||||
} else {
|
} else {
|
||||||
table.addColumn(names[i]).asDate();
|
table.addColumn(names[i]).asLocalDateTime();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -229,8 +227,8 @@ public class Schema {
|
||||||
case StringFixed:
|
case StringFixed:
|
||||||
sql.append(flavor.typeStringFixed(column.scale));
|
sql.append(flavor.typeStringFixed(column.scale));
|
||||||
break;
|
break;
|
||||||
case Date:
|
case LocalDateTime:
|
||||||
sql.append(flavor.typeDate()); // Append a date with time
|
sql.append(flavor.typeLocalDateTime()); // Append a date with time
|
||||||
break;
|
break;
|
||||||
case LocalDate:
|
case LocalDate:
|
||||||
sql.append(flavor.typeLocalDate()); // Append a true date - no time
|
sql.append(flavor.typeLocalDate()); // Append a true date - no time
|
||||||
|
@ -400,7 +398,7 @@ public class Schema {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ColumnType {
|
public enum ColumnType {
|
||||||
Integer, Long, Float, Double, BigDecimal, StringVar, StringFixed, Clob, Blob, Date, LocalDate, Boolean
|
Integer, Long, Float, Double, BigDecimal, StringVar, StringFixed, Clob, Blob, LocalDateTime, LocalDate, Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sequence {
|
public class Sequence {
|
||||||
|
@ -525,13 +523,13 @@ public class Schema {
|
||||||
|
|
||||||
public Schema schema() {
|
public Schema schema() {
|
||||||
if (createTracking) {
|
if (createTracking) {
|
||||||
addColumn("create_time").asDate().table();
|
addColumn("create_time").asLocalDateTime().table();
|
||||||
}
|
}
|
||||||
if (createTrackingFkName != null) {
|
if (createTrackingFkName != null) {
|
||||||
addColumn("create_user").foreignKey(createTrackingFkName).references(createTrackingFkTable).table();
|
addColumn("create_user").foreignKey(createTrackingFkName).references(createTrackingFkTable).table();
|
||||||
}
|
}
|
||||||
if (updateTracking || updateSequence) {
|
if (updateTracking || updateSequence) {
|
||||||
addColumn("update_time").asDate().table();
|
addColumn("update_time").asLocalDateTime().table();
|
||||||
}
|
}
|
||||||
if (updateTrackingFkName != null) {
|
if (updateTrackingFkName != null) {
|
||||||
addColumn("update_user").foreignKey(updateTrackingFkName).references(updateTrackingFkTable).table();
|
addColumn("update_user").foreignKey(updateTrackingFkName).references(updateTrackingFkTable).table();
|
||||||
|
@ -868,8 +866,8 @@ public class Schema {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type is for dates that have time associated
|
// This type is for dates that have time associated
|
||||||
public Column asDate() {
|
public Column asLocalDateTime() {
|
||||||
return asType(ColumnType.Date);
|
return asType(ColumnType.LocalDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type is for true dates with no time associated
|
// This type is for true dates with no time associated
|
||||||
|
|
|
@ -295,32 +295,22 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sql argDate(LocalDateTime arg) {
|
public Sql argDate(LocalDateTime arg) {
|
||||||
sqlArgs.argDate(arg);
|
sqlArgs.argLocalDateTime(arg);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sql argDate(String argName, LocalDateTime arg) {
|
public Sql argDate(String argName, LocalDateTime arg) {
|
||||||
sqlArgs.argDate(argName, arg);
|
sqlArgs.argLocalDateTime(argName, arg);
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sql argDateNowPerApp() {
|
|
||||||
sqlArgs.argDateNowPerApp();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sql argDateNowPerApp(String argName) {
|
|
||||||
sqlArgs.argDateNowPerApp(argName);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sql argDateNowPerDb() {
|
public Sql argDateNowPerDb() {
|
||||||
sqlArgs.argDateNowPerDb();
|
sqlArgs.argLocalDateTimeNowPerDb();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sql argDateNowPerDb(String argName) {
|
public Sql argDateNowPerDb(String argName) {
|
||||||
sqlArgs.argDateNowPerDb(argName);
|
sqlArgs.argLocalDateTimeNowPerDb(argName);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,62 +63,53 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
return uniqueNames.toArray(new String[uniqueNames.size()]);
|
return uniqueNames.toArray(new String[uniqueNames.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBoolean(Boolean arg) {
|
public SqlArgs argBoolean(Boolean arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Boolean, null, arg));
|
invocations.add(new Invocation(ColumnType.Boolean, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBoolean( String argName, Boolean arg) {
|
public SqlArgs argBoolean(String argName, Boolean arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Boolean, argName, arg));
|
invocations.add(new Invocation(ColumnType.Boolean, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argInteger(Integer arg) {
|
public SqlArgs argInteger(Integer arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Integer, null, arg));
|
invocations.add(new Invocation(ColumnType.Integer, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argInteger( String argName, Integer arg) {
|
public SqlArgs argInteger(String argName, Integer arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Integer, argName, arg));
|
invocations.add(new Invocation(ColumnType.Integer, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argLong(Long arg) {
|
public SqlArgs argLong(Long arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Long, null, arg));
|
invocations.add(new Invocation(ColumnType.Long, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argLong( String argName, Long arg) {
|
public SqlArgs argLong(String argName, Long arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Long, argName, arg));
|
invocations.add(new Invocation(ColumnType.Long, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argFloat(Float arg) {
|
public SqlArgs argFloat(Float arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Float, null, arg));
|
invocations.add(new Invocation(ColumnType.Float, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argFloat( String argName, Float arg) {
|
public SqlArgs argFloat(String argName, Float arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Float, argName, arg));
|
invocations.add(new Invocation(ColumnType.Float, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDouble(Double arg) {
|
public SqlArgs argDouble(Double arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Double, null, arg));
|
invocations.add(new Invocation(ColumnType.Double, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlArgs argDouble( String argName, Double arg) {
|
public SqlArgs argDouble(String argName, Double arg) {
|
||||||
invocations.add(new Invocation(ColumnType.Double, argName, arg));
|
invocations.add(new Invocation(ColumnType.Double, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +119,7 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlArgs argBigDecimal( String argName, BigDecimal arg) {
|
public SqlArgs argBigDecimal(String argName, BigDecimal arg) {
|
||||||
invocations.add(new Invocation(ColumnType.BigDecimal, argName, arg));
|
invocations.add(new Invocation(ColumnType.BigDecimal, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -138,109 +129,80 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlArgs argString( String argName, String arg) {
|
public SqlArgs argString(String argName, String arg) {
|
||||||
invocations.add(new Invocation(ColumnType.String, argName, arg));
|
invocations.add(new Invocation(ColumnType.String, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlArgs argDate(LocalDateTime arg) {
|
public SqlArgs argLocalDateTime(LocalDateTime arg) {
|
||||||
// date argument with a time on it
|
invocations.add(new Invocation(ColumnType.LocalDateTime, null, arg));
|
||||||
invocations.add(new Invocation(ColumnType.Date, null, arg));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlArgs argDate( String argName, LocalDateTime arg) {
|
public SqlArgs argLocalDateTime(String argName, LocalDateTime arg) {
|
||||||
// date argument with a time on it
|
invocations.add(new Invocation(ColumnType.LocalDateTime, argName, arg));
|
||||||
invocations.add(new Invocation(ColumnType.Date, argName, arg));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argLocalDate(LocalDate arg) {
|
public SqlArgs argLocalDate(LocalDate arg) {
|
||||||
// date argument with no time on it
|
|
||||||
invocations.add(new Invocation(ColumnType.LocalDate, null, arg));
|
invocations.add(new Invocation(ColumnType.LocalDate, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argLocalDate( String argName, LocalDate arg) {
|
public SqlArgs argLocalDate(String argName, LocalDate arg) {
|
||||||
// date argument with no time on it
|
|
||||||
invocations.add(new Invocation(ColumnType.LocalDate, argName, arg));
|
invocations.add(new Invocation(ColumnType.LocalDate, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SqlArgs argLocalDateTimeNowPerDb() {
|
||||||
public SqlArgs argDateNowPerApp() {
|
invocations.add(new Invocation(ColumnType.LocalDateTimeNowPerDb, null, null));
|
||||||
invocations.add(new Invocation(ColumnType.DateNowPerApp, null, null));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDateNowPerApp( String argName) {
|
public SqlArgs argLocalDateTimeNowPerDb(String argName) {
|
||||||
invocations.add(new Invocation(ColumnType.DateNowPerApp, argName, null));
|
invocations.add(new Invocation(ColumnType.LocalDateTimeNowPerDb, argName, null));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDateNowPerDb() {
|
|
||||||
invocations.add(new Invocation(ColumnType.DateNowPerDb, null, null));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argDateNowPerDb( String argName) {
|
|
||||||
invocations.add(new Invocation(ColumnType.DateNowPerDb, argName, null));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBlobBytes(byte[] arg) {
|
public SqlArgs argBlobBytes(byte[] arg) {
|
||||||
invocations.add(new Invocation(ColumnType.BlobBytes, null, arg));
|
invocations.add(new Invocation(ColumnType.BlobBytes, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBlobBytes( String argName, byte[] arg) {
|
public SqlArgs argBlobBytes(String argName, byte[] arg) {
|
||||||
invocations.add(new Invocation(ColumnType.BlobBytes, argName, arg));
|
invocations.add(new Invocation(ColumnType.BlobBytes, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBlobInputStream(InputStream arg) {
|
public SqlArgs argBlobInputStream(InputStream arg) {
|
||||||
invocations.add(new Invocation(ColumnType.BlobStream, null, arg));
|
invocations.add(new Invocation(ColumnType.BlobStream, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argBlobInputStream( String argName, InputStream arg) {
|
public SqlArgs argBlobInputStream(String argName, InputStream arg) {
|
||||||
invocations.add(new Invocation(ColumnType.BlobStream, argName, arg));
|
invocations.add(new Invocation(ColumnType.BlobStream, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argClobString(String arg) {
|
public SqlArgs argClobString(String arg) {
|
||||||
invocations.add(new Invocation(ColumnType.ClobString, null, arg));
|
invocations.add(new Invocation(ColumnType.ClobString, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argClobString( String argName, String arg) {
|
public SqlArgs argClobString(String argName, String arg) {
|
||||||
invocations.add(new Invocation(ColumnType.ClobString, argName, arg));
|
invocations.add(new Invocation(ColumnType.ClobString, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argClobReader(Reader arg) {
|
public SqlArgs argClobReader(Reader arg) {
|
||||||
invocations.add(new Invocation(ColumnType.ClobStream, null, arg));
|
invocations.add(new Invocation(ColumnType.ClobStream, null, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs argClobReader( String argName, Reader arg) {
|
public SqlArgs argClobReader(String argName, Reader arg) {
|
||||||
invocations.add(new Invocation(ColumnType.ClobStream, argName, arg));
|
invocations.add(new Invocation(ColumnType.ClobStream, argName, arg));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SqlArgs makePositional() {
|
public SqlArgs makePositional() {
|
||||||
for (Invocation invocation : invocations) {
|
for (Invocation invocation : invocations) {
|
||||||
|
@ -248,7 +210,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<String> names() {
|
public List<String> names() {
|
||||||
List<String> names = new ArrayList<>();
|
List<String> names = new ArrayList<>();
|
||||||
|
@ -348,25 +309,18 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
select.argLocalDate(i.argName, (LocalDate) i.arg);
|
select.argLocalDate(i.argName, (LocalDate) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Date:
|
case LocalDateTime:
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
select.argDate((LocalDateTime) i.arg);
|
select.argLocalDateTime((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
select.argDate(i.argName, (LocalDateTime) i.arg);
|
select.argLocalDateTime(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case LocalDateTimeNowPerDb:
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
select.argDateNowPerApp();
|
select.argLocalDateTimeNowPerDb();
|
||||||
} else {
|
} else {
|
||||||
select.argDateNowPerApp(i.argName);
|
select.argLocalDateTimeNowPerDb(i.argName);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DateNowPerDb:
|
|
||||||
if (i.argName == null) {
|
|
||||||
select.argDateNowPerDb();
|
|
||||||
} else {
|
|
||||||
select.argDateNowPerDb(i.argName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -456,33 +410,24 @@ 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) {
|
||||||
insert.argLocalDate((LocalDate) i.arg);
|
insert.argLocalDate((LocalDate) i.arg);
|
||||||
} else {
|
} else {
|
||||||
insert.argLocalDate(i.argName, (LocalDate) i.arg);
|
insert.argLocalDate(i.argName, (LocalDate) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Date:
|
case LocalDateTime:
|
||||||
// date argument with a time on it
|
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
insert.argDate((LocalDateTime) i.arg);
|
insert.argLocalDateTime((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
insert.argDate(i.argName, (LocalDateTime) i.arg);
|
insert.argLocalDateTime(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case LocalDateTimeNowPerDb:
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
insert.argDateNowPerApp();
|
insert.argLocalDateTimeNowPerDb();
|
||||||
} else {
|
} else {
|
||||||
insert.argDateNowPerApp(i.argName);
|
insert.argLocalDateTimeNowPerDb(i.argName);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DateNowPerDb:
|
|
||||||
if (i.argName == null) {
|
|
||||||
insert.argDateNowPerDb();
|
|
||||||
} else {
|
|
||||||
insert.argDateNowPerDb(i.argName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -578,25 +523,18 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
update.argLocalDate(i.argName, (LocalDate) i.arg);
|
update.argLocalDate(i.argName, (LocalDate) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Date:
|
case LocalDateTime:
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
update.argDate((LocalDateTime) i.arg);
|
update.argLocalDateTime((LocalDateTime) i.arg);
|
||||||
} else {
|
} else {
|
||||||
update.argDate(i.argName, (LocalDateTime) i.arg);
|
update.argLocalDateTime(i.argName, (LocalDateTime) i.arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DateNowPerApp:
|
case LocalDateTimeNowPerDb:
|
||||||
if (i.argName == null) {
|
if (i.argName == null) {
|
||||||
update.argDateNowPerApp();
|
update.argLocalDateTimeNowPerDb();
|
||||||
} else {
|
} else {
|
||||||
update.argDateNowPerApp(i.argName);
|
update.argLocalDateTimeNowPerDb(i.argName);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DateNowPerDb:
|
|
||||||
if (i.argName == null) {
|
|
||||||
update.argDateNowPerDb();
|
|
||||||
} else {
|
|
||||||
update.argDateNowPerDb(i.argName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -622,14 +560,29 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ColumnType {
|
public enum ColumnType {
|
||||||
Integer, Long, Float, Double, BigDecimal, String, ClobString, ClobStream,
|
String,
|
||||||
BlobBytes, BlobStream, Date, LocalDate, DateNowPerApp, DateNowPerDb, Boolean
|
Boolean,
|
||||||
|
Integer,
|
||||||
|
Long,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
BigDecimal,
|
||||||
|
ClobString,
|
||||||
|
ClobStream,
|
||||||
|
BlobBytes,
|
||||||
|
BlobStream,
|
||||||
|
LocalDate,
|
||||||
|
LocalDateTime,
|
||||||
|
LocalDateTimeNowPerDb
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Invocation {
|
private static class Invocation {
|
||||||
ColumnType columnType;
|
|
||||||
String argName;
|
private final ColumnType columnType;
|
||||||
Object arg;
|
|
||||||
|
private String argName;
|
||||||
|
|
||||||
|
private final Object arg;
|
||||||
|
|
||||||
Invocation(ColumnType columnType, String argName, Object arg) {
|
Invocation(ColumnType columnType, String argName, Object arg) {
|
||||||
this.columnType = columnType;
|
this.columnType = columnType;
|
||||||
|
@ -639,8 +592,12 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Invocation that = (Invocation) o;
|
Invocation that = (Invocation) o;
|
||||||
return columnType == that.columnType &&
|
return columnType == that.columnType &&
|
||||||
Objects.equals(argName, that.argName) &&
|
Objects.equals(argName, that.argName) &&
|
||||||
|
@ -659,9 +616,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private final int[] types;
|
private final int[] types;
|
||||||
|
|
||||||
private final int[] precision;
|
private final int[] precision;
|
||||||
|
|
||||||
private final int[] scale;
|
private final int[] scale;
|
||||||
|
|
||||||
private String[] names;
|
private String[] names;
|
||||||
|
|
||||||
public Builder(Row r) {
|
public Builder(Row r) {
|
||||||
|
@ -672,14 +633,12 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
types = new int[columnCount];
|
types = new int[columnCount];
|
||||||
precision = new int[columnCount];
|
precision = new int[columnCount];
|
||||||
scale = new int[columnCount];
|
scale = new int[columnCount];
|
||||||
|
|
||||||
for (int i = 0; i < columnCount; i++) {
|
for (int i = 0; i < columnCount; i++) {
|
||||||
names[i] = metadata.getColumnLabel(i + 1);
|
names[i] = metadata.getColumnLabel(i + 1);
|
||||||
types[i] = metadata.getColumnType(i + 1);
|
types[i] = metadata.getColumnType(i + 1);
|
||||||
precision[i] = metadata.getPrecision(i + 1);
|
precision[i] = metadata.getPrecision(i + 1);
|
||||||
scale[i] = metadata.getScale(i + 1);
|
scale[i] = metadata.getScale(i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
names = tidyColumnNames(names);
|
names = tidyColumnNames(names);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DatabaseException("Unable to retrieve metadata from ResultSet", e);
|
throw new DatabaseException("Unable to retrieve metadata from ResultSet", e);
|
||||||
|
@ -727,22 +686,19 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
|
||||||
case Types.NCLOB:
|
case Types.NCLOB:
|
||||||
args.argClobString(names[i], r.getClobStringOrNull());
|
args.argClobString(names[i], r.getClobStringOrNull());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check Date before TimeStamp because SQL dates are also timestamps
|
|
||||||
case Types.DATE:
|
case Types.DATE:
|
||||||
args.argLocalDate(names[i], r.getLocalDateOrNull());
|
args.argLocalDate(names[i], r.getLocalDateOrNull());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Types.TIMESTAMP:
|
case Types.TIMESTAMP:
|
||||||
|
case Types.TIMESTAMP_WITH_TIMEZONE:
|
||||||
if (this.scale[i] == 0) {
|
if (this.scale[i] == 0) {
|
||||||
// If the scale is 0, this is a LocalDate (no time/timezone).
|
// If the scale is 0, this is a LocalDate (no time/timezone).
|
||||||
// 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.getLocalDateTimeOrNull());
|
args.argLocalDateTime(names[i], r.getLocalDateTimeOrNull());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Types.NVARCHAR:
|
case Types.NVARCHAR:
|
||||||
case Types.VARCHAR:
|
case Types.VARCHAR:
|
||||||
case Types.CHAR:
|
case Types.CHAR:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
* Interface for configuring (setting parameters) and executing a chunk of SQL.
|
||||||
|
@ -39,21 +40,19 @@ public interface SqlInsert {
|
||||||
|
|
||||||
SqlInsert argString( String argName, String arg);
|
SqlInsert argString( String argName, String arg);
|
||||||
|
|
||||||
SqlInsert argDate(LocalDateTime arg); // date with time
|
SqlInsert argLocalDateTime(LocalDateTime arg);
|
||||||
|
|
||||||
SqlInsert argDate(String argName, LocalDateTime arg); // date with time
|
SqlInsert argLocalDateTime(LocalDateTime arg, ZoneId zoneId);
|
||||||
|
|
||||||
SqlInsert argLocalDate(LocalDate arg); // date only - no timestamp
|
SqlInsert argLocalDateTime(String argName, LocalDateTime arg);
|
||||||
|
|
||||||
SqlInsert argLocalDate( String argName, LocalDate arg); // date only - no timestamp
|
SqlInsert argLocalDate(LocalDate arg);
|
||||||
|
|
||||||
SqlInsert argDateNowPerApp();
|
SqlInsert argLocalDate( String argName, LocalDate arg);
|
||||||
|
|
||||||
SqlInsert argDateNowPerApp(String argName);
|
SqlInsert argLocalDateTimeNowPerDb();
|
||||||
|
|
||||||
SqlInsert argDateNowPerDb();
|
SqlInsert argLocalDateTimeNowPerDb(String argName);
|
||||||
|
|
||||||
SqlInsert argDateNowPerDb(String argName);
|
|
||||||
|
|
||||||
SqlInsert argBlobBytes(byte[] arg);
|
SqlInsert argBlobBytes(byte[] arg);
|
||||||
|
|
||||||
|
@ -126,7 +125,6 @@ public interface SqlInsert {
|
||||||
* <p>This version of insert expects exactly one row to be inserted, and will throw
|
* <p>This version of insert expects exactly one row to be inserted, and will throw
|
||||||
* a DatabaseException if that isn't the case.</p>
|
* a DatabaseException if that isn't the case.</p>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Long insertReturningPkSeq(String primaryKeyColumnName);
|
Long insertReturningPkSeq(String primaryKeyColumnName);
|
||||||
|
|
||||||
<T> T insertReturning(String tableName, String primaryKeyColumnName, RowsHandler<T> rowsHandler,
|
<T> T insertReturning(String tableName, String primaryKeyColumnName, RowsHandler<T> rowsHandler,
|
||||||
|
|
|
@ -15,6 +15,7 @@ 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.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -40,9 +41,9 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
|
|
||||||
private List<Batch> batched;
|
private List<Batch> batched;
|
||||||
|
|
||||||
private List<Object> parameterList; // !null ==> traditional ? args
|
private List<Object> parameterList;
|
||||||
|
|
||||||
private Map<String, Object> parameterMap; // !null ==> named :abc args
|
private Map<String, Object> parameterMap;
|
||||||
|
|
||||||
private String pkArgName;
|
private String pkArgName;
|
||||||
|
|
||||||
|
@ -141,13 +142,18 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert argDate(LocalDateTime arg) {
|
public SqlInsert argLocalDateTime(LocalDateTime arg) {
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
return positionalArg(adaptor.nullLocalDateTime(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert argDate( String argName, LocalDateTime arg) {
|
public SqlInsert argLocalDateTime(LocalDateTime arg, ZoneId zoneId) {
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
return positionalArg(adaptor.nullLocalDateTime(arg, zoneId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlInsert argLocalDateTime(String argName, LocalDateTime arg) {
|
||||||
|
return namedArg(argName, adaptor.nullLocalDateTime(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -161,27 +167,17 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert argDateNowPerApp() {
|
public SqlInsert argLocalDateTimeNowPerDb() {
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
if (options.useLocalDateTimeOnly()) {
|
||||||
}
|
return positionalArg(adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlInsert argDateNowPerApp( String argName) {
|
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlInsert argDateNowPerDb() {
|
|
||||||
if (options.useDatePerAppOnly()) {
|
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
}
|
||||||
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert argDateNowPerDb( String argName) {
|
public SqlInsert argLocalDateTimeNowPerDb(String argName) {
|
||||||
if (options.useDatePerAppOnly()) {
|
if (options.useLocalDateTimeOnly()) {
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
return namedArg(argName, adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
}
|
}
|
||||||
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
@ -235,7 +231,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
public SqlInsert withArgs(SqlArgs args) {
|
public SqlInsert withArgs(SqlArgs args) {
|
||||||
return apply(args);
|
return apply(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlInsert apply(Apply apply) {
|
public SqlInsert apply(Apply apply) {
|
||||||
|
@ -312,7 +307,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
if (!hasPk()) {
|
if (!hasPk()) {
|
||||||
throw new DatabaseException("Identify a primary key with argPk*() before insertReturning()");
|
throw new DatabaseException("Identify a primary key with argPk*() before insertReturning()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.flavor().supportsInsertReturning()) {
|
if (options.flavor().supportsInsertReturning()) {
|
||||||
return updateInternal(1, primaryKeyColumnName, handler, otherColumnNames);
|
return updateInternal(1, primaryKeyColumnName, handler, otherColumnNames);
|
||||||
} else if (pkSeqName != null) {
|
} else if (pkSeqName != null) {
|
||||||
|
@ -367,7 +361,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argPkSeq( String argName, String sequenceName) {
|
public SqlInsert argPkSeq( String argName, String sequenceName) {
|
||||||
if (hasPk() && batched == null) {
|
if (hasPk() && batched == null) {
|
||||||
throw new DatabaseException("Only call one argPk*() method");
|
throw new DatabaseException("Only call one argPk*() method");
|
||||||
|
@ -381,7 +374,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argPkLong(String argName, Long arg) {
|
public SqlInsert argPkLong(String argName, Long arg) {
|
||||||
if (hasPk() && batched == null) {
|
if (hasPk() && batched == null) {
|
||||||
throw new DatabaseException("Only call one argPk*() method");
|
throw new DatabaseException("Only call one argPk*() method");
|
||||||
|
@ -395,7 +387,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlInsert argPkLong(Long arg) {
|
public SqlInsert argPkLong(Long arg) {
|
||||||
if (hasPk() && batched == null) {
|
if (hasPk() && batched == null) {
|
||||||
throw new DatabaseException("Only call one argPk*() method");
|
throw new DatabaseException("Only call one argPk*() method");
|
||||||
|
@ -415,18 +406,14 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
|
|
||||||
private int[] insertBatchInternal() {
|
private int[] insertBatchInternal() {
|
||||||
batch();
|
batch();
|
||||||
|
|
||||||
if (batched == null || batched.size() == 0) {
|
if (batched == null || batched.size() == 0) {
|
||||||
throw new DatabaseException("Batch insert requires parameters");
|
throw new DatabaseException("Batch insert requires parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
||||||
|
|
||||||
String executeSql = sql;
|
String executeSql = sql;
|
||||||
Object[] firstRowParameters = null;
|
Object[] firstRowParameters = null;
|
||||||
List<Object[]> parameters = new ArrayList<>();
|
List<Object[]> parameters = new ArrayList<>();
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
Exception logEx = null;
|
Exception logEx = null;
|
||||||
|
@ -444,7 +431,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
parameters.add(mpSql.getArgs());
|
parameters.add(mpSql.getArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
ps = connection.prepareStatement(executeSql);
|
ps = connection.prepareStatement(executeSql);
|
||||||
|
|
||||||
|
@ -452,7 +438,6 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
adaptor.addParameters(ps, params);
|
adaptor.addParameters(ps, params);
|
||||||
ps.addBatch();
|
ps.addBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
int[] numAffectedRows = ps.executeBatch();
|
int[] numAffectedRows = ps.executeBatch();
|
||||||
metric.checkpoint("execBatch", parameters.size());
|
metric.checkpoint("execBatch", parameters.size());
|
||||||
|
@ -482,13 +467,10 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
if (batched != null) {
|
if (batched != null) {
|
||||||
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
||||||
|
|
||||||
String executeSql = sql;
|
String executeSql = sql;
|
||||||
Object[] parameters = null;
|
Object[] parameters = null;
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
Exception logEx = null;
|
Exception logEx = null;
|
||||||
|
@ -496,10 +478,8 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
||||||
executeSql = mpSql.getSqlToExecute();
|
executeSql = mpSql.getSqlToExecute();
|
||||||
parameters = mpSql.getArgs();
|
parameters = mpSql.getArgs();
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
ps = connection.prepareStatement(executeSql);
|
ps = connection.prepareStatement(executeSql);
|
||||||
|
|
||||||
adaptor.addParameters(ps, parameters);
|
adaptor.addParameters(ps, parameters);
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
int numAffectedRows = ps.executeUpdate();
|
int numAffectedRows = ps.executeUpdate();
|
||||||
|
@ -536,14 +516,11 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
if (batched != null) {
|
if (batched != null) {
|
||||||
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
||||||
|
|
||||||
String executeSql = sql;
|
String executeSql = sql;
|
||||||
Object[] parameters = null;
|
Object[] parameters = null;
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
Exception logEx = null;
|
Exception logEx = null;
|
||||||
|
@ -551,10 +528,8 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
||||||
executeSql = mpSql.getSqlToExecute();
|
executeSql = mpSql.getSqlToExecute();
|
||||||
parameters = mpSql.getArgs();
|
parameters = mpSql.getArgs();
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
ps = connection.prepareStatement(executeSql, new String[]{pkToReturn});
|
ps = connection.prepareStatement(executeSql, new String[]{pkToReturn});
|
||||||
|
|
||||||
adaptor.addParameters(ps, parameters);
|
adaptor.addParameters(ps, parameters);
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
int numAffectedRows = ps.executeUpdate();
|
int numAffectedRows = ps.executeUpdate();
|
||||||
|
@ -598,14 +573,11 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
if (batched != null) {
|
if (batched != null) {
|
||||||
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
throw new DatabaseException("Call insertBatch() if you are using the batch() feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
||||||
|
|
||||||
String executeSql = sql;
|
String executeSql = sql;
|
||||||
Object[] parameters = null;
|
Object[] parameters = null;
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
Exception logEx = null;
|
Exception logEx = null;
|
||||||
|
@ -613,14 +585,11 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
||||||
executeSql = mpSql.getSqlToExecute();
|
executeSql = mpSql.getSqlToExecute();
|
||||||
parameters = mpSql.getArgs();
|
parameters = mpSql.getArgs();
|
||||||
|
|
||||||
String[] returnCols = new String[otherCols.length + 1];
|
String[] returnCols = new String[otherCols.length + 1];
|
||||||
returnCols[0] = pkToReturn;
|
returnCols[0] = pkToReturn;
|
||||||
System.arraycopy(otherCols, 0, returnCols, 1, otherCols.length);
|
System.arraycopy(otherCols, 0, returnCols, 1, otherCols.length);
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
ps = connection.prepareStatement(executeSql, returnCols);
|
ps = connection.prepareStatement(executeSql, returnCols);
|
||||||
|
|
||||||
adaptor.addParameters(ps, parameters);
|
adaptor.addParameters(ps, parameters);
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
int numAffectedRows = ps.executeUpdate();
|
int numAffectedRows = ps.executeUpdate();
|
||||||
|
@ -682,8 +651,8 @@ public class SqlInsertImpl implements SqlInsert {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Batch {
|
private static class Batch {
|
||||||
private final List<Object> parameterList; // !null ==> traditional ? args
|
private final List<Object> parameterList;
|
||||||
private final Map<String, Object> parameterMap; // !null ==> named :abc args
|
private final Map<String, Object> parameterMap;
|
||||||
|
|
||||||
public Batch(List<Object> parameterList, Map<String, Object> parameterMap) {
|
public Batch(List<Object> parameterList, Map<String, Object> parameterMap) {
|
||||||
this.parameterList = parameterList;
|
this.parameterList = parameterList;
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.jdbc.query;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,126 +11,64 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface SqlSelect {
|
public interface SqlSelect {
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argBoolean(Boolean arg);
|
SqlSelect argBoolean(Boolean arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argBoolean( String argName, Boolean arg);
|
SqlSelect argBoolean( String argName, Boolean arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argInteger(Integer arg);
|
SqlSelect argInteger(Integer arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argInteger( String argName, Integer arg);
|
SqlSelect argInteger( String argName, Integer arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argLong(Long arg);
|
SqlSelect argLong(Long arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argLong( String argName, Long arg);
|
SqlSelect argLong( String argName, Long arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argFloat(Float arg);
|
SqlSelect argFloat(Float arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argFloat( String argName, Float arg);
|
SqlSelect argFloat( String argName, Float arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argDouble(Double arg);
|
SqlSelect argDouble(Double arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argDouble( String argName, Double arg);
|
SqlSelect argDouble( String argName, Double arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argBigDecimal(BigDecimal arg);
|
SqlSelect argBigDecimal(BigDecimal arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argBigDecimal( String argName, BigDecimal arg);
|
SqlSelect argBigDecimal( String argName, BigDecimal arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argString(String arg);
|
SqlSelect argString(String arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argString( String argName, String arg);
|
SqlSelect argString( String argName, String arg);
|
||||||
|
|
||||||
|
SqlSelect argLocalDateTime(LocalDateTime arg);
|
||||||
|
|
||||||
SqlSelect argDate(LocalDateTime arg); // Date with time
|
|
||||||
|
|
||||||
SqlSelect argDate(String argName, LocalDateTime arg); // Date with time
|
SqlSelect argLocalDateTime(String argName, LocalDateTime arg);
|
||||||
|
|
||||||
|
SqlSelect argLocalDate(LocalDate arg);
|
||||||
|
|
||||||
SqlSelect argLocalDate(LocalDate arg); // Date without time
|
|
||||||
|
|
||||||
|
SqlSelect argLocalDate( String argName, LocalDate arg);
|
||||||
|
|
||||||
SqlSelect argLocalDate( String argName, LocalDate arg); // Date without time
|
|
||||||
|
|
||||||
|
SqlSelect argLocalDateTimeNowPerDb();
|
||||||
|
|
||||||
SqlSelect argDateNowPerApp();
|
|
||||||
|
|
||||||
|
SqlSelect argLocalDateTimeNowPerDb(String argName);
|
||||||
|
|
||||||
SqlSelect argDateNowPerApp( String argName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argDateNowPerDb();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect argDateNowPerDb( String argName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect withTimeoutSeconds(int seconds);
|
SqlSelect withTimeoutSeconds(int seconds);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect withMaxRows(int rows);
|
SqlSelect withMaxRows(int rows);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect withArgs(SqlArgs args);
|
SqlSelect withArgs(SqlArgs args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect apply(Apply apply);
|
SqlSelect apply(Apply apply);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SqlSelect fetchSize(int fetchSize);
|
SqlSelect fetchSize(int fetchSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Boolean queryBooleanOrNull();
|
Boolean queryBooleanOrNull();
|
||||||
|
|
||||||
|
|
||||||
boolean queryBooleanOrFalse();
|
boolean queryBooleanOrFalse();
|
||||||
|
|
||||||
|
|
||||||
boolean queryBooleanOrTrue();
|
boolean queryBooleanOrTrue();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Long queryLongOrNull();
|
Long queryLongOrNull();
|
||||||
|
|
||||||
|
|
||||||
long queryLongOrZero();
|
long queryLongOrZero();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,61 +76,34 @@ public interface SqlSelect {
|
||||||
*
|
*
|
||||||
* @return the first column values, omitting any that were null
|
* @return the first column values, omitting any that were null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
List<Long> queryLongs();
|
List<Long> queryLongs();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Integer queryIntegerOrNull();
|
Integer queryIntegerOrNull();
|
||||||
|
|
||||||
|
|
||||||
int queryIntegerOrZero();
|
int queryIntegerOrZero();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Integer> queryIntegers();
|
List<Integer> queryIntegers();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Float queryFloatOrNull();
|
Float queryFloatOrNull();
|
||||||
|
|
||||||
|
|
||||||
float queryFloatOrZero();
|
float queryFloatOrZero();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Float> queryFloats();
|
List<Float> queryFloats();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Double queryDoubleOrNull();
|
Double queryDoubleOrNull();
|
||||||
|
|
||||||
|
|
||||||
double queryDoubleOrZero();
|
double queryDoubleOrZero();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Double> queryDoubles();
|
List<Double> queryDoubles();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BigDecimal queryBigDecimalOrNull();
|
BigDecimal queryBigDecimalOrNull();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BigDecimal queryBigDecimalOrZero();
|
BigDecimal queryBigDecimalOrZero();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<BigDecimal> queryBigDecimals();
|
List<BigDecimal> queryBigDecimals();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
String queryStringOrNull();
|
String queryStringOrNull();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
String queryStringOrEmpty();
|
String queryStringOrEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,25 +111,19 @@ public interface SqlSelect {
|
||||||
*
|
*
|
||||||
* @return the first column values, omitting any that were null
|
* @return the first column values, omitting any that were null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
List<String> queryStrings();
|
List<String> queryStrings();
|
||||||
|
|
||||||
|
LocalDateTime queryLocalDateTimeOrNull();
|
||||||
|
|
||||||
LocalDateTime queryDateOrNull(); // Date with time
|
|
||||||
|
|
||||||
|
LocalDateTime queryLocalDateTimeOrNull(ZoneId zoneId);
|
||||||
|
|
||||||
List<LocalDateTime> queryDates(); // Date with time
|
|
||||||
|
|
||||||
|
List<LocalDateTime> queryLocalDateTimes();
|
||||||
|
|
||||||
LocalDate queryLocalDateOrNull(); // Date without time
|
|
||||||
|
|
||||||
|
List<LocalDateTime> queryLocalDateTimes(ZoneId zoneId);
|
||||||
|
|
||||||
|
LocalDate queryLocalDateOrNull();
|
||||||
|
|
||||||
|
List<LocalDate> queryLocalDates();
|
||||||
List<LocalDate> queryLocalDates(); // Date without time
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the most generic and low-level way to iterate the query results.
|
* This is the most generic and low-level way to iterate the query results.
|
||||||
|
|
|
@ -11,6 +11,7 @@ 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.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -23,7 +24,7 @@ import java.util.logging.Logger;
|
||||||
*/
|
*/
|
||||||
public class SqlSelectImpl implements SqlSelect {
|
public class SqlSelectImpl implements SqlSelect {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(Database.class.getName());
|
private static final Logger logger = Logger.getLogger(Database.class.getName());
|
||||||
|
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
|
|
||||||
|
@ -114,115 +115,84 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argBigDecimal(BigDecimal arg) {
|
public SqlSelect argBigDecimal(BigDecimal arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argBigDecimal( String argName, BigDecimal arg) {
|
public SqlSelect argBigDecimal( String argName, BigDecimal arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argString(String arg) {
|
public SqlSelect argString(String arg) {
|
||||||
return positionalArg(adaptor.nullString(arg));
|
return positionalArg(adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argString( String argName, String arg) {
|
public SqlSelect argString(String argName, String arg) {
|
||||||
return namedArg(argName, adaptor.nullString(arg));
|
return namedArg(argName, adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDate(LocalDateTime arg) {
|
public SqlSelect argLocalDateTime(LocalDateTime arg) {
|
||||||
// Date with time
|
return positionalArg(adaptor.nullLocalDateTime(arg));
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDate( String argName, LocalDateTime arg) {
|
public SqlSelect argLocalDateTime(String argName, LocalDateTime arg) {
|
||||||
// Date with time
|
return namedArg(argName, adaptor.nullLocalDateTime(arg));
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argLocalDate(LocalDate arg) {
|
public SqlSelect argLocalDate(LocalDate arg) {
|
||||||
// Date with no time
|
|
||||||
return positionalArg(adaptor.nullLocalDate(arg));
|
return positionalArg(adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argLocalDate( String argName, LocalDate arg) {
|
public SqlSelect argLocalDate( String argName, LocalDate arg) {
|
||||||
// Date with no time
|
|
||||||
return namedArg(argName, adaptor.nullLocalDate(arg));
|
return namedArg(argName, adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDateNowPerApp() {
|
public SqlSelect argLocalDateTimeNowPerDb() {
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
if (options.useLocalDateTimeOnly()) {
|
||||||
}
|
return positionalArg(adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlSelect argDateNowPerApp( String argName) {
|
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlSelect argDateNowPerDb() {
|
|
||||||
if (options.useDatePerAppOnly()) {
|
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
}
|
||||||
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect argDateNowPerDb( String argName) {
|
public SqlSelect argLocalDateTimeNowPerDb(String argName) {
|
||||||
if (options.useDatePerAppOnly()) {
|
if (options.useLocalDateTimeOnly()) {
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
return namedArg(argName, adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
}
|
}
|
||||||
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect withTimeoutSeconds(int seconds) {
|
public SqlSelect withTimeoutSeconds(int seconds) {
|
||||||
timeoutSeconds = seconds;
|
timeoutSeconds = seconds;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect withMaxRows(int rows) {
|
public SqlSelect withMaxRows(int rows) {
|
||||||
maxRows = rows;
|
maxRows = rows;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect withArgs(SqlArgs args) {
|
public SqlSelect withArgs(SqlArgs args) {
|
||||||
return apply(args);
|
return apply(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect apply(Apply apply) {
|
public SqlSelect apply(Apply apply) {
|
||||||
apply.apply(this);
|
apply.apply(this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlSelect fetchSize(int rows) {
|
public SqlSelect fetchSize(int rows) {
|
||||||
|
@ -253,7 +223,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public Long queryLongOrNull() {
|
public Long queryLongOrNull() {
|
||||||
return queryWithTimeout(rs -> {
|
return queryWithTimeout(rs -> {
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
|
@ -287,7 +256,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer queryIntegerOrNull() {
|
public Integer queryIntegerOrNull() {
|
||||||
|
@ -323,7 +291,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Float queryFloatOrNull() {
|
public Float queryFloatOrNull() {
|
||||||
|
@ -404,7 +371,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal queryBigDecimalOrZero() {
|
public BigDecimal queryBigDecimalOrZero() {
|
||||||
|
@ -415,7 +381,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return new BigDecimal(0);
|
return new BigDecimal(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BigDecimal> queryBigDecimals() {
|
public List<BigDecimal> queryBigDecimals() {
|
||||||
|
@ -440,7 +405,6 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String queryStringOrEmpty() {
|
public String queryStringOrEmpty() {
|
||||||
|
@ -467,21 +431,31 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime queryDateOrNull() {
|
public LocalDateTime queryLocalDateTimeOrNull() {
|
||||||
|
return queryLocalDateTimeOrNull(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime queryLocalDateTimeOrNull(ZoneId zoneId) {
|
||||||
return queryWithTimeout(rs -> {
|
return queryWithTimeout(rs -> {
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
return rs.getLocalDateTimeOrNull(1);
|
return rs.getLocalDateTimeOrNull(1, zoneId);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<LocalDateTime> queryDates() {
|
public List<LocalDateTime> queryLocalDateTimes() {
|
||||||
|
return queryLocalDateTimes(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<LocalDateTime> queryLocalDateTimes(ZoneId zoneId) {
|
||||||
return queryWithTimeout(rs -> {
|
return queryWithTimeout(rs -> {
|
||||||
List<LocalDateTime> result = new ArrayList<>();
|
List<LocalDateTime> result = new ArrayList<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
LocalDateTime value = rs.getLocalDateTimeOrNull(1);
|
LocalDateTime value = rs.getLocalDateTimeOrNull(1, zoneId);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
|
@ -489,7 +463,7 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDate queryLocalDateOrNull() {
|
public LocalDate queryLocalDateOrNull() {
|
||||||
// Date without time
|
// Date without time
|
||||||
|
@ -603,11 +577,9 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
private <T> T queryWithTimeout(RowsHandler<T> handler) {
|
private <T> T queryWithTimeout(RowsHandler<T> handler) {
|
||||||
assert ps == null;
|
assert ps == null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Metric metric = new Metric(log.isLoggable(Level.FINE));
|
Metric metric = new Metric(logger.isLoggable(Level.FINE));
|
||||||
|
|
||||||
String executeSql = sql;
|
String executeSql = sql;
|
||||||
Object[] parameters = null;
|
Object[] parameters = null;
|
||||||
|
|
||||||
boolean isWarn = false;
|
boolean isWarn = false;
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
String errorCode = null;
|
String errorCode = null;
|
||||||
|
@ -616,26 +588,21 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
MixedParameterSql mpSql = new MixedParameterSql(sql, parameterList, parameterMap);
|
||||||
executeSql = mpSql.getSqlToExecute();
|
executeSql = mpSql.getSqlToExecute();
|
||||||
parameters = mpSql.getArgs();
|
parameters = mpSql.getArgs();
|
||||||
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
synchronized (cancelLock) {
|
synchronized (cancelLock) {
|
||||||
ps = connection.prepareStatement(executeSql,
|
ps = connection.prepareStatement(executeSql,
|
||||||
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
ResultSet.CONCUR_READ_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeoutSeconds >= 0) {
|
if (timeoutSeconds >= 0) {
|
||||||
ps.setQueryTimeout(timeoutSeconds);
|
ps.setQueryTimeout(timeoutSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxRows > 0) {
|
if (maxRows > 0) {
|
||||||
ps.setMaxRows(maxRows);
|
ps.setMaxRows(maxRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fetchSize >= 0) {
|
if (fetchSize >= 0) {
|
||||||
ps.setFetchSize(fetchSize);
|
ps.setFetchSize(fetchSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
adaptor.addParameters(ps, parameters);
|
adaptor.addParameters(ps, parameters);
|
||||||
metric.checkpoint("prep");
|
metric.checkpoint("prep");
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
|
@ -662,18 +629,18 @@ public class SqlSelectImpl implements SqlSelect {
|
||||||
logEx = e;
|
logEx = e;
|
||||||
throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, parameters, errorCode, options), e);
|
throw DatabaseException.wrap(DebugSql.exceptionMessage(executeSql, parameters, errorCode, options), e);
|
||||||
} finally {
|
} finally {
|
||||||
adaptor.closeQuietly(rs, log);
|
adaptor.closeQuietly(rs, logger);
|
||||||
adaptor.closeQuietly(ps, log);
|
adaptor.closeQuietly(ps, logger);
|
||||||
synchronized (cancelLock) {
|
synchronized (cancelLock) {
|
||||||
ps = null;
|
ps = null;
|
||||||
}
|
}
|
||||||
metric.done("close");
|
metric.done("close");
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
DebugSql.logSuccess("Query", log, metric, executeSql, parameters, options);
|
DebugSql.logSuccess("Query", logger, metric, executeSql, parameters, options);
|
||||||
} else if (isWarn) {
|
} else if (isWarn) {
|
||||||
DebugSql.logWarning("Query", log, metric, "QueryTimedOutException", executeSql, parameters, options, null);
|
DebugSql.logWarning("Query", logger, metric, "QueryTimedOutException", executeSql, parameters, options, null);
|
||||||
} else {
|
} else {
|
||||||
DebugSql.logError("Query", log, metric, errorCode, executeSql, parameters, options, logEx);
|
DebugSql.logError("Query", logger, metric, errorCode, executeSql, parameters, options, logEx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,21 +39,17 @@ public interface SqlUpdate {
|
||||||
|
|
||||||
SqlUpdate argString(String argName, String arg);
|
SqlUpdate argString(String argName, String arg);
|
||||||
|
|
||||||
SqlUpdate argDate(LocalDateTime arg);
|
SqlUpdate argLocalDateTime(LocalDateTime arg);
|
||||||
|
|
||||||
SqlUpdate argDate(String argName, LocalDateTime arg);
|
SqlUpdate argLocalDateTime(String argName, LocalDateTime arg);
|
||||||
|
|
||||||
SqlUpdate argLocalDate(LocalDate arg);
|
SqlUpdate argLocalDate(LocalDate arg);
|
||||||
|
|
||||||
SqlUpdate argLocalDate(String argName, LocalDate arg);
|
SqlUpdate argLocalDate(String argName, LocalDate arg);
|
||||||
|
|
||||||
SqlUpdate argDateNowPerApp();
|
SqlUpdate argLocalDateTimeNowPerDb();
|
||||||
|
|
||||||
SqlUpdate argDateNowPerApp(String argName);
|
|
||||||
|
|
||||||
SqlUpdate argDateNowPerDb();
|
SqlUpdate argLocalDateTimeNowPerDb(String argName);
|
||||||
|
|
||||||
SqlUpdate argDateNowPerDb(String argName);
|
|
||||||
|
|
||||||
SqlUpdate argBlobBytes(byte[] arg);
|
SqlUpdate argBlobBytes(byte[] arg);
|
||||||
|
|
||||||
|
|
|
@ -49,187 +49,149 @@ public class SqlUpdateImpl implements SqlUpdate {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
adaptor = new StatementAdaptor(options);
|
adaptor = new StatementAdaptor(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlUpdate argBoolean(Boolean arg) {
|
public SqlUpdate argBoolean(Boolean arg) {
|
||||||
return positionalArg(adaptor.nullString(booleanToString(arg)));
|
return positionalArg(adaptor.nullString(booleanToString(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlUpdate argBoolean(String argName, Boolean arg) {
|
public SqlUpdate argBoolean(String argName, Boolean arg) {
|
||||||
return namedArg(argName, adaptor.nullString(booleanToString(arg)));
|
return namedArg(argName, adaptor.nullString(booleanToString(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argInteger(Integer arg) {
|
public SqlUpdate argInteger(Integer arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argInteger(String argName, Integer arg) {
|
public SqlUpdate argInteger(String argName, Integer arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argLong(Long arg) {
|
public SqlUpdate argLong(Long arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argLong(String argName, Long arg) {
|
public SqlUpdate argLong(String argName, Long arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argFloat(Float arg) {
|
public SqlUpdate argFloat(Float arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argFloat(String argName, Float arg) {
|
public SqlUpdate argFloat(String argName, Float arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argDouble(Double arg) {
|
public SqlUpdate argDouble(Double arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argDouble(String argName, Double arg) {
|
public SqlUpdate argDouble(String argName, Double arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBigDecimal(BigDecimal arg) {
|
public SqlUpdate argBigDecimal(BigDecimal arg) {
|
||||||
return positionalArg(adaptor.nullNumeric(arg));
|
return positionalArg(adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBigDecimal(String argName, BigDecimal arg) {
|
public SqlUpdate argBigDecimal(String argName, BigDecimal arg) {
|
||||||
return namedArg(argName, adaptor.nullNumeric(arg));
|
return namedArg(argName, adaptor.nullNumeric(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argString(String arg) {
|
public SqlUpdate argString(String arg) {
|
||||||
return positionalArg(adaptor.nullString(arg));
|
return positionalArg(adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argString(String argName, String arg) {
|
public SqlUpdate argString(String argName, String arg) {
|
||||||
return namedArg(argName, adaptor.nullString(arg));
|
return namedArg(argName, adaptor.nullString(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlUpdate argLocalDateTime(LocalDateTime arg) {
|
||||||
public SqlUpdate argDate(LocalDateTime arg) {
|
return positionalArg(adaptor.nullLocalDateTime(arg));
|
||||||
return positionalArg(adaptor.nullDate(arg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlUpdate argLocalDateTime(String argName, LocalDateTime arg) {
|
||||||
public SqlUpdate argDate(String argName, LocalDateTime arg) {
|
return namedArg(argName, adaptor.nullLocalDateTime(arg));
|
||||||
return namedArg(argName, adaptor.nullDate(arg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argLocalDate(LocalDate arg) {
|
public SqlUpdate argLocalDate(LocalDate arg) {
|
||||||
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) {
|
||||||
return namedArg(argName, adaptor.nullLocalDate(arg));
|
return namedArg(argName, adaptor.nullLocalDate(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlUpdate argDateNowPerApp() {
|
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlUpdate argLocalDateTimeNowPerDb() {
|
||||||
public SqlUpdate argDateNowPerApp(String argName) {
|
if (options.useLocalDateTimeOnly()) {
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
return positionalArg(adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlUpdate argDateNowPerDb() {
|
|
||||||
if (options.useDatePerAppOnly()) {
|
|
||||||
return positionalArg(adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
}
|
||||||
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
return positionalArg(new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SqlUpdate argLocalDateTimeNowPerDb(String argName) {
|
||||||
public SqlUpdate argDateNowPerDb(String argName) {
|
if (options.useLocalDateTimeOnly()) {
|
||||||
if (options.useDatePerAppOnly()) {
|
return namedArg(argName, adaptor.nullLocalDateTime(LocalDateTime.now()));
|
||||||
return namedArg(argName, adaptor.nullDate(options.currentDate()));
|
|
||||||
}
|
}
|
||||||
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
return namedArg(argName, new RewriteArg(options.flavor().dbTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBlobBytes(byte[] arg) {
|
public SqlUpdate argBlobBytes(byte[] arg) {
|
||||||
return positionalArg(adaptor.nullBytes(arg));
|
return positionalArg(adaptor.nullBytes(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBlobBytes(String argName, byte[] arg) {
|
public SqlUpdate argBlobBytes(String argName, byte[] arg) {
|
||||||
return namedArg(argName, adaptor.nullBytes(arg));
|
return namedArg(argName, adaptor.nullBytes(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBlobStream(InputStream arg) {
|
public SqlUpdate argBlobStream(InputStream arg) {
|
||||||
return positionalArg(adaptor.nullInputStream(arg));
|
return positionalArg(adaptor.nullInputStream(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argBlobStream(String argName, InputStream arg) {
|
public SqlUpdate argBlobStream(String argName, InputStream arg) {
|
||||||
return namedArg(argName, adaptor.nullInputStream(arg));
|
return namedArg(argName, adaptor.nullInputStream(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argClobString(String arg) {
|
public SqlUpdate argClobString(String arg) {
|
||||||
return positionalArg(adaptor.nullClobReader(arg == null ? null : new InternalStringReader(arg)));
|
return positionalArg(adaptor.nullClobReader(arg == null ? null : new InternalStringReader(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argClobString(String argName, String arg) {
|
public SqlUpdate argClobString(String argName, String arg) {
|
||||||
return namedArg(argName, adaptor.nullClobReader(arg == null ? null : new InternalStringReader(arg)));
|
return namedArg(argName, adaptor.nullClobReader(arg == null ? null : new InternalStringReader(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argClobReader(Reader arg) {
|
public SqlUpdate argClobReader(Reader arg) {
|
||||||
return positionalArg(adaptor.nullClobReader(arg));
|
return positionalArg(adaptor.nullClobReader(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public SqlUpdate argClobReader(String argName, Reader arg) {
|
public SqlUpdate argClobReader(String argName, Reader arg) {
|
||||||
return namedArg(argName, adaptor.nullClobReader(arg));
|
return namedArg(argName, adaptor.nullClobReader(arg));
|
||||||
}
|
}
|
||||||
|
@ -244,7 +206,6 @@ public class SqlUpdateImpl implements SqlUpdate {
|
||||||
return apply(args);
|
return apply(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlUpdate apply(Apply apply) {
|
public SqlUpdate apply(Apply apply) {
|
||||||
apply.apply(this);
|
apply.apply(this);
|
||||||
|
@ -419,8 +380,8 @@ public class SqlUpdateImpl implements SqlUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Batch {
|
private static class Batch {
|
||||||
private final List<Object> parameterList; // !null ==> traditional ? args
|
private final List<Object> parameterList;
|
||||||
private final Map<String, Object> parameterMap; // !null ==> named :abc args
|
private final Map<String, Object> parameterMap;
|
||||||
|
|
||||||
public Batch(List<Object> parameterList, Map<String, Object> parameterMap) {
|
public Batch(List<Object> parameterList, Map<String, Object> parameterMap) {
|
||||||
this.parameterList = parameterList;
|
this.parameterList = parameterList;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.xbib.jdbc.query;
|
package org.xbib.jdbc.query;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -13,75 +13,32 @@ 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.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deal with mapping parameters into prepared statements.
|
* Deal with mapping parameters into prepared statements.
|
||||||
*/
|
*/
|
||||||
public class StatementAdaptor {
|
public class StatementAdaptor {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(StatementAdaptor.class.getName());
|
||||||
|
|
||||||
private final Options options;
|
private final Options options;
|
||||||
|
|
||||||
public StatementAdaptor(Options options) {
|
public StatementAdaptor(Options options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String readerToString(Reader r) {
|
|
||||||
Scanner s = new Scanner(r).useDelimiter("\\A");
|
|
||||||
return s.hasNext() ? s.next() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] streamToBytes(InputStream is) throws SQLException {
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
|
|
||||||
try {
|
|
||||||
while ((length = is.read(buffer)) != -1) {
|
|
||||||
out.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new SQLException("Unable to convert InputStream parameter to bytes", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the java.util.Date into a java.sql.Timestamp, following the nanos/millis canonicalization
|
|
||||||
* required by the spec. If a java.sql.Timestamp is passed in (since it extends java.util.Date),
|
|
||||||
* it will be checked and canonicalized only if not already correct.
|
|
||||||
*/
|
|
||||||
private static Timestamp toSqlTimestamp(Date date) {
|
|
||||||
long millis = date.getTime();
|
|
||||||
int fractionalSecondMillis = (int) (millis % 1000); // guaranteed < 1000
|
|
||||||
|
|
||||||
if (fractionalSecondMillis == 0) { // this means it's already correct by the spec
|
|
||||||
if (date instanceof Timestamp) {
|
|
||||||
return (Timestamp) date;
|
|
||||||
} else {
|
|
||||||
return new Timestamp(millis);
|
|
||||||
}
|
|
||||||
} else { // the millis are invalid and need to be corrected
|
|
||||||
int tsNanos = fractionalSecondMillis * 1000000;
|
|
||||||
long tsMillis = millis - fractionalSecondMillis;
|
|
||||||
Timestamp timestamp = new Timestamp(tsMillis);
|
|
||||||
timestamp.setNanos(tsNanos);
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addParameters(PreparedStatement ps, Object[] parameters) throws SQLException {
|
public void addParameters(PreparedStatement ps, Object[] parameters) throws SQLException {
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
Object parameter = parameters[i];
|
Object parameter = parameters[i];
|
||||||
|
|
||||||
// Unwrap secret args here so we can use them
|
// Unwrap secret args here so we can use them
|
||||||
if (parameter instanceof SecretArg) {
|
if (parameter instanceof SecretArg) {
|
||||||
parameter = ((SecretArg) parameter).getArg();
|
parameter = ((SecretArg) parameter).getArg();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter == null) {
|
if (parameter == null) {
|
||||||
ParameterMetaData metaData;
|
ParameterMetaData metaData;
|
||||||
int parameterType;
|
int parameterType;
|
||||||
|
@ -106,57 +63,52 @@ public class StatementAdaptor {
|
||||||
} else if (parameter instanceof java.sql.Date) {
|
} else if (parameter instanceof java.sql.Date) {
|
||||||
ps.setDate(i + 1, (java.sql.Date) parameter);
|
ps.setDate(i + 1, (java.sql.Date) parameter);
|
||||||
} else if (parameter instanceof Date) {
|
} else if (parameter instanceof Date) {
|
||||||
|
Date date = (Date) parameter;
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
|
||||||
|
ps.setTimestamp(i + 1, Timestamp.valueOf(localDateTime));
|
||||||
// this will correct the millis and nanos according to the JDBC spec
|
// this will correct the millis and nanos according to the JDBC spec
|
||||||
// if a correct Timestamp is passed in, this will detect that and leave it alone
|
// if a correct Timestamp is passed in, this will detect that and leave it alone
|
||||||
ps.setTimestamp(i + 1, toSqlTimestamp((Date) parameter), options.calendarForTimestamps());
|
//ps.setTimestamp(i + 1, toSqlTimestamp((Date) parameter), options.calendarForTimestamps());
|
||||||
} else if (parameter instanceof Reader) {
|
} else if (parameter instanceof Reader) {
|
||||||
if (options.useStringForClob()) {
|
if (options.useStringForClob()) {
|
||||||
ps.setString(i + 1, readerToString((Reader) parameter));
|
try (BufferedReader reader = new BufferedReader((Reader) parameter)) {
|
||||||
|
ps.setString(i + 1, reader.lines().collect(Collectors.joining()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SQLException(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ps.setCharacterStream(i + 1, (Reader) parameter);
|
ps.setCharacterStream(i + 1, (Reader) parameter);
|
||||||
}
|
}
|
||||||
} else if (parameter instanceof InputStream) {
|
} else if (parameter instanceof InputStream) {
|
||||||
if (options.useBytesForBlob()) {
|
if (options.useBytesForBlob()) {
|
||||||
ps.setBytes(i + 1, streamToBytes((InputStream) parameter));
|
try {
|
||||||
|
ps.setBytes(i + 1, ((InputStream) parameter).readAllBytes());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SQLException(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ps.setBinaryStream(i + 1, (InputStream) parameter);
|
ps.setBinaryStream(i + 1, (InputStream) parameter);
|
||||||
}
|
}
|
||||||
} else if (parameter instanceof Float) {
|
} else if (parameter instanceof Float) {
|
||||||
//if (options.flavor() == Flavor.oracle && ps.isWrapperFor(OraclePreparedStatement.class)) {
|
ps.setFloat(i + 1, (Float) parameter);
|
||||||
// The Oracle 11 driver setDouble() first converts the double to NUMBER, causing underflow
|
|
||||||
// for small values so we need to use the proprietary mechanism
|
|
||||||
//ps.unwrap(OraclePreparedStatement.class).setBinaryFloat(i + 1, (Float) parameter);
|
|
||||||
//} else {
|
|
||||||
ps.setFloat(i + 1, (Float) parameter);
|
|
||||||
//}
|
|
||||||
} else if (parameter instanceof Double) {
|
} else if (parameter instanceof Double) {
|
||||||
//if (options.flavor() == Flavor.oracle && ps.isWrapperFor(OraclePreparedStatement.class)) {
|
ps.setDouble(i + 1, (Double) parameter);
|
||||||
// The Oracle 11 driver setDouble() first converts the double to NUMBER, causing underflow
|
|
||||||
// for small values so we need to use the proprietary mechanism
|
|
||||||
//ps.unwrap(OraclePreparedStatement.class).setBinaryDouble(i + 1, (Double) parameter);
|
|
||||||
//} else {
|
|
||||||
ps.setDouble(i + 1, (Double) parameter);
|
|
||||||
//}
|
|
||||||
} else {
|
} else {
|
||||||
ps.setObject(i + 1, parameter);
|
ps.setObject(i + 1, parameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object nullDate(LocalDateTime arg) {
|
public Object nullLocalDateTime(LocalDateTime arg) {
|
||||||
if (arg == null) {
|
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg);
|
||||||
return new SqlNull(Types.TIMESTAMP);
|
|
||||||
}
|
|
||||||
return Timestamp.valueOf(arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Processes a true date without time information.
|
public Object nullLocalDateTime(LocalDateTime arg, ZoneId zoneId) {
|
||||||
public Object nullLocalDate(LocalDate arg) {
|
return arg == null ? new SqlNull(Types.TIMESTAMP) : Timestamp.valueOf(arg.atZone(zoneId).toLocalDateTime());
|
||||||
if (arg == null) {
|
}
|
||||||
return new SqlNull(Types.DATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return java.sql.Date.valueOf(arg);
|
public Object nullLocalDate(LocalDate arg) {
|
||||||
|
return arg == null ? new SqlNull(Types.DATE) : java.sql.Date.valueOf(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object nullNumeric(Number arg) {
|
public Object nullNumeric(Number arg) {
|
||||||
|
@ -217,5 +169,4 @@ public class StatementAdaptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class BigQuery implements Flavor {
|
public class BigQuery implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,7 +76,7 @@ public class BigQuery implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "datetime";
|
return "datetime";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,20 +145,6 @@ public class BigQuery implements Flavor {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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);
|
|
||||||
return String.format("datetime '%s'", dateFormat.format(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
// Construct a datetime literal
|
|
||||||
return String.format("datetime '%s'", date.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class Derby implements Flavor {
|
public class Derby implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,7 +75,7 @@ public class Derby implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "timestamp";
|
return "timestamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,18 +144,6 @@ public class Derby implements Flavor {
|
||||||
return " from sysibm.sysdummy1";
|
return " from sysibm.sysdummy1";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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) + "')";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
return "'" + date.toString() + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
return " as bigint";
|
return " as bigint";
|
||||||
|
|
175
jdbc-query/src/main/java/org/xbib/jdbc/query/flavor/H2.java
Normal file
175
jdbc-query/src/main/java/org/xbib/jdbc/query/flavor/H2.java
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
|
public class H2 implements Flavor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "h2";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(String url) {
|
||||||
|
return url.startsWith("jdbc:h2:");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String driverClass() {
|
||||||
|
return "org.h2.Driver";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNormalizedUpperCase() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeInteger() {
|
||||||
|
return "integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBoolean() {
|
||||||
|
return "char(1)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLong() {
|
||||||
|
return "bigint";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeFloat() {
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeDouble() {
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBigDecimal(int size, int precision) {
|
||||||
|
return "numeric(" + size + "," + precision + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeStringVar(int length) {
|
||||||
|
return "varchar(" + length + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeStringFixed(int length) {
|
||||||
|
return "char(" + length + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeClob() {
|
||||||
|
return "clob(2G)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBlob() {
|
||||||
|
return "blob(2G)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLocalDateTime() {
|
||||||
|
return "timestamp(3)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLocalDate() {
|
||||||
|
return "date";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useStringForClob() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useBytesForBlob() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceNextVal(String sequenceName) {
|
||||||
|
return "next value for " + sequenceName + "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceSelectNextVal(String sequenceName) {
|
||||||
|
return "select " + sequenceNextVal(sequenceName) + fromAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceDrop(String dbtestSeq) {
|
||||||
|
return "drop sequence if exists " + dbtestSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tableDrop(String table) {
|
||||||
|
return "drop table if exists " + table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceOrderClause(boolean order) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceCycleClause(boolean cycle) {
|
||||||
|
return cycle ? " cycle" : " no cycle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fromAny() {
|
||||||
|
return " from (values(0))";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsInsertReturning() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String dbTimeMillis() {
|
||||||
|
return "localtimestamp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceCacheClause(int nbrValuesToCache) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceOptions() {
|
||||||
|
return " as bigint";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoCommitOnly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String writeNextIntoQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readNextFromQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String succeedInQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String failInQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class Hsql implements Flavor {
|
public class Hsql implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,8 +75,8 @@ public class Hsql implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "timestamp(3)";
|
return "timestamp with time zone";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,18 +144,6 @@ public class Hsql implements Flavor {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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)";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
return "'" + date.toString() + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
return " as bigint";
|
return " as bigint";
|
||||||
|
|
177
jdbc-query/src/main/java/org/xbib/jdbc/query/flavor/MySQL.java
Normal file
177
jdbc-query/src/main/java/org/xbib/jdbc/query/flavor/MySQL.java
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
|
public class MySQL implements Flavor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "mysql";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(String url) {
|
||||||
|
return url.startsWith("jdbc:mysql:");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String driverClass() {
|
||||||
|
return "com.mysql.jdbc.Driver";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNormalizedUpperCase() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeInteger() {
|
||||||
|
return "integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBoolean() {
|
||||||
|
return "char(1)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLong() {
|
||||||
|
return "bigint";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeFloat() {
|
||||||
|
return "real";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeDouble() {
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBigDecimal(int size, int precision) {
|
||||||
|
return "numeric(" + size + "," + precision + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeStringVar(int length) {
|
||||||
|
return "varchar(" + length + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeStringFixed(int length) {
|
||||||
|
return "char(" + length + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeClob() {
|
||||||
|
return "clob";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeBlob() {
|
||||||
|
return "blob";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLocalDateTime() {
|
||||||
|
return "timestamp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeLocalDate() {
|
||||||
|
return "date";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useStringForClob() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useBytesForBlob() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceNextVal(String sequenceName) {
|
||||||
|
return "next value for " + sequenceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceSelectNextVal(String sequenceName) {
|
||||||
|
return "values next value for " + sequenceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceDrop(String sequenceName) {
|
||||||
|
return "drop sequence " + sequenceName + " restrict";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tableDrop(String table) {
|
||||||
|
return "drop table " + table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsInsertReturning() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceCacheClause(int nbrValuesToCache) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceOrderClause(boolean order) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceCycleClause(boolean cycle) {
|
||||||
|
return cycle ? " cycle" : " no cycle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String dbTimeMillis() {
|
||||||
|
return "current_timestamp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fromAny() {
|
||||||
|
return " from sysibm.sysdummy1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sequenceOptions() {
|
||||||
|
return " as bigint";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoCommitOnly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String writeNextIntoQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readNextFromQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String succeedInQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String failInQueue(String table) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class Oracle implements Flavor {
|
public class Oracle implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,7 +55,7 @@ public class Oracle implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "timestamp(3)";
|
return "timestamp(3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,18 +147,6 @@ public class Oracle implements Flavor {
|
||||||
return " from dual";
|
return " from dual";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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) + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
return "to_date('" + date.toString() + "', 'yyyy-mm-dd')";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class Postgresql implements Flavor {
|
public class Postgresql implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,7 +75,7 @@ public class Postgresql implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "timestamp(3)";
|
return "timestamp(3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,18 +144,6 @@ public class Postgresql implements Flavor {
|
||||||
return " cache " + nbrValuesToCache;
|
return " cache " + nbrValuesToCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
return "'" + date.toString() + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -2,11 +2,6 @@ package org.xbib.jdbc.query.flavor;
|
||||||
|
|
||||||
import org.xbib.jdbc.query.Flavor;
|
import org.xbib.jdbc.query.Flavor;
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class SqlServer implements Flavor {
|
public class SqlServer implements Flavor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,7 +55,7 @@ public class SqlServer implements Flavor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String typeDate() {
|
public String typeLocalDateTime() {
|
||||||
return "datetime2(3)";
|
return "datetime2(3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,18 +148,6 @@ public class SqlServer implements Flavor {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
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))";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String localDateAsSqlFunction(Date date) {
|
|
||||||
return "'" + date.toString() + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sequenceOptions() {
|
public String sequenceOptions() {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -6,7 +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.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -77,9 +78,15 @@ 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((Timestamp) argToPrint, options.calendarForTimestamps()));
|
java.sql.Timestamp timestamp = (java.sql.Timestamp) argToPrint;
|
||||||
|
LocalDateTime localDateTime = timestamp.toLocalDateTime();
|
||||||
|
buf.append(localDateTime.toString());
|
||||||
|
//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((java.sql.Date) argToPrint));
|
java.sql.Date date = (java.sql.Date) argToPrint;
|
||||||
|
LocalDate localDate = date.toLocalDate();
|
||||||
|
buf.append(localDate.toString());
|
||||||
|
//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) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
org.xbib.jdbc.query.flavor.BigQuery
|
org.xbib.jdbc.query.flavor.BigQuery
|
||||||
org.xbib.jdbc.query.flavor.Derby
|
org.xbib.jdbc.query.flavor.Derby
|
||||||
org.xbib.jdbc.query.flavor.Hsql
|
org.xbib.jdbc.query.flavor.Hsql
|
||||||
|
org.xbib.jdbc.query.flavor.H2
|
||||||
|
org.xbib.jdbc.query.flavor.MySQL
|
||||||
org.xbib.jdbc.query.flavor.Oracle
|
org.xbib.jdbc.query.flavor.Oracle
|
||||||
org.xbib.jdbc.query.flavor.Postgresql
|
org.xbib.jdbc.query.flavor.Postgresql
|
||||||
org.xbib.jdbc.query.flavor.SqlServer
|
org.xbib.jdbc.query.flavor.SqlServer
|
|
@ -25,7 +25,6 @@ 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.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -36,9 +35,9 @@ import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
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.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
@ -64,22 +63,15 @@ public abstract class CommonTest {
|
||||||
|
|
||||||
protected Database db;
|
protected Database db;
|
||||||
|
|
||||||
protected LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
protected LocalDateTime now;
|
||||||
|
|
||||||
protected LocalDate localDateNow = LocalDate.now();
|
protected LocalDate localDateNow;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setupJdbc() throws Exception {
|
public void setupJdbc() throws Exception {
|
||||||
|
now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
||||||
|
localDateNow = LocalDate.now();
|
||||||
dbp = createDatabaseProvider(new OptionsOverride() {
|
dbp = createDatabaseProvider(new OptionsOverride() {
|
||||||
@Override
|
|
||||||
public LocalDateTime currentDate() {
|
|
||||||
return now;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Calendar calendarForTimestamps() {
|
|
||||||
return Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
db = dbp.get();
|
db = dbp.get();
|
||||||
db.dropTableQuietly(TEST_TABLE_NAME);
|
db.dropTableQuietly(TEST_TABLE_NAME);
|
||||||
|
@ -153,13 +145,13 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_fixed").asStringFixed(1).table()
|
.addColumn("str_fixed").asStringFixed(1).table()
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
||||||
|
|
||||||
BigDecimal bigDecimal = new BigDecimal("5.3");
|
BigDecimal bigDecimal = new BigDecimal("5.3");
|
||||||
db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?)").argInteger(1).argLong(2L).argFloat(3.2f).argDouble(4.2)
|
db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?)").argInteger(1).argLong(2L).argFloat(3.2f).argDouble(4.2)
|
||||||
.argBigDecimal(bigDecimal).argString("Hello").argString("T").argClobString("World")
|
.argBigDecimal(bigDecimal).argString("Hello").argString("T").argClobString("World")
|
||||||
.argBlobBytes("More".getBytes()).argDate(now).argLocalDate(localDateNow).insert(1);
|
.argBlobBytes("More".getBytes()).argLocalDateTime(now).argLocalDate(localDateNow).insert(1);
|
||||||
|
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest")
|
+ "bin_blob, date_millis, local_date from dbtest")
|
||||||
|
@ -286,14 +278,14 @@ public abstract class CommonTest {
|
||||||
.argBigDecimal("bd", bigDecimal)
|
.argBigDecimal("bd", bigDecimal)
|
||||||
.argString("s", "Hello")
|
.argString("s", "Hello")
|
||||||
.argString("sf", "T")
|
.argString("sf", "T")
|
||||||
.argDate("date", now)
|
.argLocalDateTime("date", now)
|
||||||
.argLocalDate("local_date", localDateNow)
|
.argLocalDate("local_date", localDateNow)
|
||||||
.queryLongOrNull());
|
.queryLongOrNull());
|
||||||
List<Long> result = db.toSelect("select count(*) from dbtest where nbr_integer=:i and nbr_long=:l and "
|
List<Long> result = db.toSelect("select count(*) from dbtest where nbr_integer=:i and nbr_long=:l and "
|
||||||
+ "abs(nbr_float-:f)<0.01 and abs(nbr_double-:d)<0.01 and nbr_big_decimal=:bd and str_varchar=:s "
|
+ "abs(nbr_float-:f)<0.01 and abs(nbr_double-:d)<0.01 and nbr_big_decimal=:bd and str_varchar=:s "
|
||||||
+ "and str_fixed=:sf and date_millis=:date and local_date=:local_date").argInteger("i", 1).argLong("l", 2L).argFloat("f", 3.2f)
|
+ "and str_fixed=:sf and date_millis=:date and local_date=:local_date").argInteger("i", 1).argLong("l", 2L).argFloat("f", 3.2f)
|
||||||
.argDouble("d", 4.2).argBigDecimal("bd", bigDecimal).argString("s", "Hello").argString("sf", "T")
|
.argDouble("d", 4.2).argBigDecimal("bd", bigDecimal).argString("s", "Hello").argString("sf", "T")
|
||||||
.argDate("date", now).argLocalDate("local_date", localDateNow).queryLongs();
|
.argLocalDateTime("date", now).argLocalDate("local_date", localDateNow).queryLongs();
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
assertEquals(Long.valueOf(1), result.get(0));
|
assertEquals(Long.valueOf(1), result.get(0));
|
||||||
}
|
}
|
||||||
|
@ -312,7 +304,7 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_fixed").asStringFixed(1).table()
|
.addColumn("str_fixed").asStringFixed(1).table()
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
||||||
|
|
||||||
BigDecimal bigDecimal = new BigDecimal("5.3");
|
BigDecimal bigDecimal = new BigDecimal("5.3");
|
||||||
|
@ -327,12 +319,12 @@ public abstract class CommonTest {
|
||||||
.argString("T")
|
.argString("T")
|
||||||
.argClobString("World")
|
.argClobString("World")
|
||||||
.argBlobBytes("More".getBytes())
|
.argBlobBytes("More".getBytes())
|
||||||
.argDate(now)
|
.argLocalDateTime(now)
|
||||||
.argLocalDate(localDateNow).insert());
|
.argLocalDate(localDateNow).insert());
|
||||||
db.toUpdate("update dbtest set nbr_integer=?, nbr_long=?, nbr_float=?, nbr_double=?, nbr_big_decimal=?, "
|
db.toUpdate("update dbtest set nbr_integer=?, nbr_long=?, nbr_float=?, nbr_double=?, nbr_big_decimal=?, "
|
||||||
+ "str_varchar=?, str_fixed=?, str_lob=?, bin_blob=?, date_millis=?, local_date=?").argInteger(null).argLong(null)
|
+ "str_varchar=?, str_fixed=?, str_lob=?, bin_blob=?, date_millis=?, local_date=?").argInteger(null).argLong(null)
|
||||||
.argFloat(null).argDouble(null).argBigDecimal(null).argString(null).argString(null).argClobString(null)
|
.argFloat(null).argDouble(null).argBigDecimal(null).argString(null).argString(null).argClobString(null)
|
||||||
.argBlobBytes(null).argDate(null).argLocalDate(null).update(1);
|
.argBlobBytes(null).argLocalDateTime(null).argLocalDate(null).update(1);
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
||||||
assertTrue(rs.next());
|
assertTrue(rs.next());
|
||||||
|
@ -363,7 +355,7 @@ public abstract class CommonTest {
|
||||||
assertEquals(1, db.toUpdate("update dbtest set nbr_integer=?, nbr_long=?, nbr_float=?, nbr_double=?, "
|
assertEquals(1, db.toUpdate("update dbtest set nbr_integer=?, nbr_long=?, nbr_float=?, nbr_double=?, "
|
||||||
+ "nbr_big_decimal=?, str_varchar=?, str_fixed=?, str_lob=?, bin_blob=?, date_millis=?, local_date=?").argInteger(1)
|
+ "nbr_big_decimal=?, str_varchar=?, str_fixed=?, str_lob=?, bin_blob=?, date_millis=?, local_date=?").argInteger(1)
|
||||||
.argLong(2L).argFloat(3.2f).argDouble(4.2).argBigDecimal(bigDecimal).argString("Hello").argString("T")
|
.argLong(2L).argFloat(3.2f).argDouble(4.2).argBigDecimal(bigDecimal).argString("Hello").argString("T")
|
||||||
.argClobString("World").argBlobBytes("More".getBytes()).argDate(now).argLocalDate(localDateNow).update());
|
.argClobString("World").argBlobBytes("More".getBytes()).argLocalDateTime(now).argLocalDate(localDateNow).update());
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
||||||
assertTrue(rs.next());
|
assertTrue(rs.next());
|
||||||
|
@ -426,20 +418,20 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_fixed").asStringFixed(1).table()
|
.addColumn("str_fixed").asStringFixed(1).table()
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
||||||
BigDecimal bigDecimal = new BigDecimal("5.3");
|
BigDecimal bigDecimal = new BigDecimal("5.3");
|
||||||
db.toInsert("insert into dbtest values (:pk,:a,:b,:c,:d,:e,:f,:sf,:g,:h,:i,:j)").argLong(":pk", 1L).argInteger(":a", 1)
|
db.toInsert("insert into dbtest values (:pk,:a,:b,:c,:d,:e,:f,:sf,:g,:h,:i,:j)").argLong(":pk", 1L).argInteger(":a", 1)
|
||||||
.argLong(":b", 2L).argFloat(":c", 3.2f).argDouble(":d", 4.2).argBigDecimal(":e", bigDecimal)
|
.argLong(":b", 2L).argFloat(":c", 3.2f).argDouble(":d", 4.2).argBigDecimal(":e", bigDecimal)
|
||||||
.argString(":f", "Hello").argString(":sf", "T")
|
.argString(":f", "Hello").argString(":sf", "T")
|
||||||
.argClobString(":g", "World").argBlobBytes(":h", "More".getBytes())
|
.argClobString(":g", "World").argBlobBytes(":h", "More".getBytes())
|
||||||
.argDate(":i", now).argLocalDate(":j", localDateNow).insert(1);
|
.argLocalDateTime(":i", now).argLocalDate(":j", localDateNow).insert(1);
|
||||||
db.toUpdate("update dbtest set nbr_integer=:a, nbr_long=:b, nbr_float=:c, nbr_double=:d, nbr_big_decimal=:e, "
|
db.toUpdate("update dbtest set nbr_integer=:a, nbr_long=:b, nbr_float=:c, nbr_double=:d, nbr_big_decimal=:e, "
|
||||||
+ "str_varchar=:f, str_fixed=:sf, str_lob=:g, bin_blob=:h, date_millis=:i, local_date=:j").argInteger(":a", null)
|
+ "str_varchar=:f, str_fixed=:sf, str_lob=:g, bin_blob=:h, date_millis=:i, local_date=:j").argInteger(":a", null)
|
||||||
.argLong(":b", null).argFloat(":c", null).argDouble(":d", null).argBigDecimal(":e", null)
|
.argLong(":b", null).argFloat(":c", null).argDouble(":d", null).argBigDecimal(":e", null)
|
||||||
.argString(":f", null).argString(":sf", null)
|
.argString(":f", null).argString(":sf", null)
|
||||||
.argClobString(":g", null).argBlobBytes(":h", null)
|
.argClobString(":g", null).argBlobBytes(":h", null)
|
||||||
.argDate(":i", null).argLocalDate(":j", null).update(1);
|
.argLocalDateTime(":i", null).argLocalDate(":j", null).update(1);
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
+ "bin_blob, date_millis, local_date from dbtest").query((RowsHandler<Void>) rs -> {
|
||||||
assertTrue(rs.next());
|
assertTrue(rs.next());
|
||||||
|
@ -472,7 +464,7 @@ public abstract class CommonTest {
|
||||||
.argLong(":b", 2L).argFloat(":c", 3.2f).argDouble(":d", 4.2).argBigDecimal(":e", bigDecimal)
|
.argLong(":b", 2L).argFloat(":c", 3.2f).argDouble(":d", 4.2).argBigDecimal(":e", bigDecimal)
|
||||||
.argString(":f", "Hello").argString(":sf", "T")
|
.argString(":f", "Hello").argString(":sf", "T")
|
||||||
.argClobString(":g", "World").argBlobBytes(":h", "More".getBytes())
|
.argClobString(":g", "World").argBlobBytes(":h", "More".getBytes())
|
||||||
.argDate(":i", now).argLocalDate(":j", localDateNow).update(1);
|
.argLocalDateTime(":i", now).argLocalDate(":j", localDateNow).update(1);
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest")
|
+ "bin_blob, date_millis, local_date from dbtest")
|
||||||
.query((RowsHandler<Void>) rs -> {
|
.query((RowsHandler<Void>) rs -> {
|
||||||
|
@ -537,11 +529,11 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_fixed").asStringFixed(1).table()
|
.addColumn("str_fixed").asStringFixed(1).table()
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
.addColumn("local_date").asLocalDate().table().schema().execute(db);
|
||||||
db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?,?)").argLong(1L).argInteger(null).argLong(null)
|
db.toInsert("insert into dbtest values (?,?,?,?,?,?,?,?,?,?,?,?)").argLong(1L).argInteger(null).argLong(null)
|
||||||
.argFloat(null).argDouble(null).argBigDecimal(null).argString(null).argString(null).argClobString(null)
|
.argFloat(null).argDouble(null).argBigDecimal(null).argString(null).argString(null).argClobString(null)
|
||||||
.argBlobBytes(null).argDate(null).argLocalDate(null).insert(1);
|
.argBlobBytes(null).argLocalDateTime(null).argLocalDate(null).insert(1);
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar, str_fixed, str_lob, "
|
||||||
+ "bin_blob, date_millis, local_date from dbtest")
|
+ "bin_blob, date_millis, local_date from dbtest")
|
||||||
.query((RowsHandler<Void>) rs -> {
|
.query((RowsHandler<Void>) rs -> {
|
||||||
|
@ -604,7 +596,7 @@ public abstract class CommonTest {
|
||||||
String dateColumnName = "local_date";
|
String dateColumnName = "local_date";
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn(timestampColumnName).asDate().table()
|
.addColumn(timestampColumnName).asLocalDateTime().table()
|
||||||
.addColumn(dateColumnName).asLocalDate().table().schema().execute(db);
|
.addColumn(dateColumnName).asLocalDate().table().schema().execute(db);
|
||||||
db.toSelect("select * from dbtest").query((RowsHandler<Void>) rs -> {
|
db.toSelect("select * from dbtest").query((RowsHandler<Void>) rs -> {
|
||||||
ResultSetMetaData metadata = rs.getMetadata();
|
ResultSetMetaData metadata = rs.getMetadata();
|
||||||
|
@ -612,8 +604,10 @@ public abstract class CommonTest {
|
||||||
String columnName = metadata.getColumnName(i);
|
String columnName = metadata.getColumnName(i);
|
||||||
String columnType = metadata.getColumnTypeName(i);
|
String columnType = metadata.getColumnTypeName(i);
|
||||||
if (columnName.equalsIgnoreCase(timestampColumnName)) {
|
if (columnName.equalsIgnoreCase(timestampColumnName)) {
|
||||||
if ("sqlserver".equals(db.flavor().toString())) {
|
if ("sqlserver".equals(db.flavor().getName())) {
|
||||||
assertEquals("DATETIME2", columnType.toUpperCase());
|
assertEquals("DATETIME2", columnType.toUpperCase());
|
||||||
|
} else if ("hsqldb".equals(db.flavor().getName())) {
|
||||||
|
assertEquals("TIMESTAMP WITH TIME ZONE", columnType.toUpperCase());
|
||||||
} else {
|
} else {
|
||||||
assertEquals("TIMESTAMP", columnType.toUpperCase());
|
assertEquals("TIMESTAMP", columnType.toUpperCase());
|
||||||
}
|
}
|
||||||
|
@ -629,11 +623,11 @@ public abstract class CommonTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void intervals() {
|
public void intervals() {
|
||||||
new Schema().addTable("dbtest").addColumn("d").asDate().schema().execute(db);
|
new Schema().addTable("dbtest").addColumn("d").asLocalDateTime().schema().execute(db);
|
||||||
db.toInsert("insert into dbtest (d) values (?)").argDate(now).insert(1);
|
db.toInsert("insert into dbtest (d) values (?)").argLocalDateTime(now).insert(1);
|
||||||
assertEquals(1, db.toSelect("select count(1) from dbtest where d - interval '1' hour * ? < ?")
|
assertEquals(1, db.toSelect("select count(1) from dbtest where d - interval '1' hour * ? < ?")
|
||||||
.argInteger(2)
|
.argInteger(2)
|
||||||
.argDate(now)
|
.argLocalDateTime(now)
|
||||||
.queryIntegerOrZero());
|
.queryIntegerOrZero());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +644,7 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("boolean_flag").asBoolean().table()
|
.addColumn("boolean_flag").asBoolean().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().schema().execute(db);
|
.addColumn("local_date").asLocalDate().schema().execute(db);
|
||||||
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
||||||
+ " str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date) values (?,?,?,?,?,?,?,?,?,?,?,?)")
|
+ " str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date) values (?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||||
|
@ -658,14 +652,16 @@ public abstract class CommonTest {
|
||||||
.argDouble(Double.MAX_VALUE).argBigDecimal(new BigDecimal("123.456"))
|
.argDouble(Double.MAX_VALUE).argBigDecimal(new BigDecimal("123.456"))
|
||||||
.argString("hello").argString("Z").argClobString("hello again")
|
.argString("hello").argString("Z").argClobString("hello again")
|
||||||
.argBlobBytes(new byte[]{'1', '2'}).argBoolean(true)
|
.argBlobBytes(new byte[]{'1', '2'}).argBoolean(true)
|
||||||
.argDateNowPerApp().argLocalDate(localDateNow).insert(1);
|
.argLocalDateTime(now)
|
||||||
|
.argLocalDate(localDateNow).insert(1);
|
||||||
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
||||||
+ " str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date) values (?,?,?,?,?,?,?,?,?,?,?,?)")
|
+ " str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date) values (?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||||
.argInteger(Integer.MIN_VALUE).argLong(Long.MIN_VALUE).argFloat(0.000001f)
|
.argInteger(Integer.MIN_VALUE).argLong(Long.MIN_VALUE).argFloat(0.000001f)
|
||||||
.argDouble(Double.MIN_VALUE).argBigDecimal(new BigDecimal("-123.456"))
|
.argDouble(Double.MIN_VALUE).argBigDecimal(new BigDecimal("-123.456"))
|
||||||
.argString("goodbye").argString("A").argClobString("bye again")
|
.argString("goodbye").argString("A").argClobString("bye again")
|
||||||
.argBlobBytes(new byte[]{'3', '4'}).argBoolean(false)
|
.argBlobBytes(new byte[]{'3', '4'}).argBoolean(false)
|
||||||
.argDateNowPerApp().argLocalDate(localDateNow).insert(1);
|
.argLocalDateTime(now)
|
||||||
|
.argLocalDate(localDateNow).insert(1);
|
||||||
String expectedSchema = new Schema().addTable("dbtest2")
|
String expectedSchema = new Schema().addTable("dbtest2")
|
||||||
.addColumn("nbr_integer").asInteger().table()
|
.addColumn("nbr_integer").asInteger().table()
|
||||||
.addColumn("nbr_long").asLong().table()
|
.addColumn("nbr_long").asLong().table()
|
||||||
|
@ -677,7 +673,7 @@ public abstract class CommonTest {
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("boolean_flag").asBoolean().table()
|
.addColumn("boolean_flag").asBoolean().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().schema().print(db.flavor());
|
.addColumn("local_date").asLocalDate().schema().print(db.flavor());
|
||||||
List<SqlArgs> args = db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
List<SqlArgs> args = db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
||||||
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest")
|
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest")
|
||||||
|
@ -719,7 +715,7 @@ public abstract class CommonTest {
|
||||||
.argClobString("str_lob", "bye again")
|
.argClobString("str_lob", "bye again")
|
||||||
.argBlobBytes("bin_blob", new byte[]{'3', '4'})
|
.argBlobBytes("bin_blob", new byte[]{'3', '4'})
|
||||||
.argString("boolean_flag", "N")//.argBoolean("boolean_flag", false)
|
.argString("boolean_flag", "N")//.argBoolean("boolean_flag", false)
|
||||||
.argDate("date_millis", now)
|
.argLocalDateTime("date_millis", now)
|
||||||
.argLocalDate("local_date", localDateNow),
|
.argLocalDate("local_date", localDateNow),
|
||||||
new SqlArgs().argInteger("nbr_integer", Integer.MAX_VALUE)
|
new SqlArgs().argInteger("nbr_integer", Integer.MAX_VALUE)
|
||||||
.argLong("nbr_long", Long.MAX_VALUE)
|
.argLong("nbr_long", Long.MAX_VALUE)
|
||||||
|
@ -731,7 +727,7 @@ public abstract class CommonTest {
|
||||||
.argClobString("str_lob", "hello again")
|
.argClobString("str_lob", "hello again")
|
||||||
.argBlobBytes("bin_blob", new byte[]{'1', '2'})
|
.argBlobBytes("bin_blob", new byte[]{'1', '2'})
|
||||||
.argString("boolean_flag", "Y")//.argBoolean("boolean_flag", true)
|
.argString("boolean_flag", "Y")//.argBoolean("boolean_flag", true)
|
||||||
.argDate("date_millis", now)
|
.argLocalDateTime("date_millis", now)
|
||||||
.argLocalDate("local_date", localDateNow)),
|
.argLocalDate("local_date", localDateNow)),
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
||||||
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest2 order by 1")
|
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest2 order by 1")
|
||||||
|
@ -1368,25 +1364,26 @@ public abstract class CommonTest {
|
||||||
@Test
|
@Test
|
||||||
public void insertReturningAppDate() {
|
public void insertReturningAppDate() {
|
||||||
db.dropSequenceQuietly("dbtest_seq");
|
db.dropSequenceQuietly("dbtest_seq");
|
||||||
|
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("pk").primaryKey().table()
|
.addColumn("pk").primaryKey().table()
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d")
|
||||||
|
.asLocalDateTime()
|
||||||
|
.table()
|
||||||
|
.schema()
|
||||||
.addSequence("dbtest_seq").schema()
|
.addSequence("dbtest_seq").schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
|
|
||||||
db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
||||||
.argPkSeq(":seq", "dbtest_seq")
|
.argPkSeq(":seq", "dbtest_seq")
|
||||||
.argDateNowPerApp(":d")
|
.argLocalDateTime(":d", now)
|
||||||
.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.getLocalDateTimeOrNull(2), equalTo(now));
|
assertThat(rs.getLocalDateTimeOrNull(2, ZoneId.systemDefault()), equalTo(now));
|
||||||
assertFalse(rs.next());
|
assertFalse(rs.next());
|
||||||
return null;
|
return null;
|
||||||
}, "d");
|
}, "d");
|
||||||
assertEquals(Long.valueOf(1L), db.toSelect("select count(*) from dbtest where d=?").argDate(now).queryLongOrNull());
|
assertEquals(Long.valueOf(1L), db.toSelect("select count(*) from dbtest where d=?").argLocalDateTime(now).queryLongOrNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1394,18 +1391,20 @@ public abstract class CommonTest {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("pk").primaryKey().table()
|
.addColumn("pk").primaryKey().table()
|
||||||
.addColumn("d").asDate().table()
|
.addColumn("d").asLocalDateTime().table()
|
||||||
.addColumn("d2").asDate().table()
|
.addColumn("d2").asLocalDateTime().table()
|
||||||
.addColumn("d3").asLocalDate().table()
|
.addColumn("d3").asLocalDate().table()
|
||||||
.addColumn("d4").asLocalDate().table()
|
.addColumn("d4").asLocalDate().table()
|
||||||
.addColumn("s").asString(5).table()
|
.addColumn("s").asString(5).table()
|
||||||
.addColumn("s2").asString(5).table()
|
.addColumn("s2").asString(5).table()
|
||||||
.addColumn("i").asInteger().table().schema()
|
.addColumn("i").asInteger().table().schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
|
|
||||||
db.toInsert("insert into dbtest (pk, d, d3, s) values (?,?,?,?)")
|
db.toInsert("insert into dbtest (pk, d, d3, s) values (?,?,?,?)")
|
||||||
.argLong(1L).argDateNowPerApp().argLocalDate(localDateNow).argString("foo").insert(1);
|
.argLong(1L)
|
||||||
|
.argLocalDateTime(now)
|
||||||
|
.argLocalDate(localDateNow)
|
||||||
|
.argString("foo")
|
||||||
|
.insert(1);
|
||||||
assertEquals(Long.valueOf(1L), db.toSelect("select pk from dbtest").queryLongOrNull());
|
assertEquals(Long.valueOf(1L), db.toSelect("select pk from dbtest").queryLongOrNull());
|
||||||
assertNull(db.toSelect("select pk from dbtest where 1=0").queryLongOrNull());
|
assertNull(db.toSelect("select pk from dbtest where 1=0").queryLongOrNull());
|
||||||
assertNull(db.toSelect("select i from dbtest").queryLongOrNull());
|
assertNull(db.toSelect("select i from dbtest").queryLongOrNull());
|
||||||
|
@ -1415,7 +1414,6 @@ public abstract class CommonTest {
|
||||||
assertEquals(1L, (long) db.toSelect("select pk from dbtest").queryLongs().get(0));
|
assertEquals(1L, (long) db.toSelect("select pk from dbtest").queryLongs().get(0));
|
||||||
assertTrue(db.toSelect("select pk from dbtest where 1=0").queryLongs().isEmpty());
|
assertTrue(db.toSelect("select pk from dbtest where 1=0").queryLongs().isEmpty());
|
||||||
assertTrue(db.toSelect("select i from dbtest").queryLongs().isEmpty());
|
assertTrue(db.toSelect("select i from dbtest").queryLongs().isEmpty());
|
||||||
|
|
||||||
assertEquals(Integer.valueOf(1), db.toSelect("select pk from dbtest").queryIntegerOrNull());
|
assertEquals(Integer.valueOf(1), db.toSelect("select pk from dbtest").queryIntegerOrNull());
|
||||||
assertNull(db.toSelect("select pk from dbtest where 1=0").queryIntegerOrNull());
|
assertNull(db.toSelect("select pk from dbtest where 1=0").queryIntegerOrNull());
|
||||||
assertNull(db.toSelect("select i from dbtest").queryIntegerOrNull());
|
assertNull(db.toSelect("select i from dbtest").queryIntegerOrNull());
|
||||||
|
@ -1425,7 +1423,6 @@ public abstract class CommonTest {
|
||||||
assertEquals(1L, (int) db.toSelect("select pk from dbtest").queryIntegers().get(0));
|
assertEquals(1L, (int) db.toSelect("select pk from dbtest").queryIntegers().get(0));
|
||||||
assertTrue(db.toSelect("select pk from dbtest where 1=0").queryIntegers().isEmpty());
|
assertTrue(db.toSelect("select pk from dbtest where 1=0").queryIntegers().isEmpty());
|
||||||
assertTrue(db.toSelect("select i from dbtest").queryIntegers().isEmpty());
|
assertTrue(db.toSelect("select i from dbtest").queryIntegers().isEmpty());
|
||||||
|
|
||||||
assertEquals("foo", db.toSelect("select s from dbtest").queryStringOrNull());
|
assertEquals("foo", db.toSelect("select s from dbtest").queryStringOrNull());
|
||||||
assertNull(db.toSelect("select s from dbtest where 1=0").queryStringOrNull());
|
assertNull(db.toSelect("select s from dbtest where 1=0").queryStringOrNull());
|
||||||
assertNull(db.toSelect("select s2 from dbtest").queryStringOrNull());
|
assertNull(db.toSelect("select s2 from dbtest").queryStringOrNull());
|
||||||
|
@ -1435,13 +1432,12 @@ public abstract class CommonTest {
|
||||||
assertEquals("foo", db.toSelect("select s from dbtest").queryStrings().get(0));
|
assertEquals("foo", db.toSelect("select s from dbtest").queryStrings().get(0));
|
||||||
assertTrue(db.toSelect("select s from dbtest where 1=0").queryStrings().isEmpty());
|
assertTrue(db.toSelect("select s from dbtest where 1=0").queryStrings().isEmpty());
|
||||||
assertTrue(db.toSelect("select s2 from dbtest").queryStrings().isEmpty());
|
assertTrue(db.toSelect("select s2 from dbtest").queryStrings().isEmpty());
|
||||||
|
assertEquals(now, db.toSelect("select d from dbtest").queryLocalDateTimeOrNull());
|
||||||
assertEquals(now, db.toSelect("select d from dbtest").queryDateOrNull());
|
assertNull(db.toSelect("select d from dbtest where 1=0").queryLocalDateTimeOrNull());
|
||||||
assertNull(db.toSelect("select d from dbtest where 1=0").queryDateOrNull());
|
assertNull(db.toSelect("select d2 from dbtest").queryLocalDateTimeOrNull());
|
||||||
assertNull(db.toSelect("select d2 from dbtest").queryDateOrNull());
|
assertEquals(db.toSelect("select d from dbtest").queryLocalDateTimes().get(0), now);
|
||||||
assertEquals(db.toSelect("select d from dbtest").queryDates().get(0), now);
|
assertTrue(db.toSelect("select d from dbtest where 1=0").queryLocalDateTimes().isEmpty());
|
||||||
assertTrue(db.toSelect("select d from dbtest where 1=0").queryDates().isEmpty());
|
assertTrue(db.toSelect("select d2 from dbtest").queryLocalDateTimes().isEmpty());
|
||||||
assertTrue(db.toSelect("select d2 from dbtest").queryDates().isEmpty());
|
|
||||||
|
|
||||||
assertEquals(localDateNow, db.toSelect("select d3 from dbtest").queryLocalDateOrNull());
|
assertEquals(localDateNow, db.toSelect("select d3 from dbtest").queryLocalDateOrNull());
|
||||||
assertNull(db.toSelect("select d3 from dbtest where 1=0").queryLocalDateOrNull());
|
assertNull(db.toSelect("select d3 from dbtest where 1=0").queryLocalDateOrNull());
|
||||||
|
@ -1511,12 +1507,12 @@ public abstract class CommonTest {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("pk").primaryKey().table()
|
.addColumn("pk").primaryKey().table()
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d").asLocalDateTime().table().schema()
|
||||||
.addSequence("dbtest_seq").schema()
|
.addSequence("dbtest_seq").schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
LocalDateTime 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")
|
.argLocalDateTimeNowPerDb(":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));
|
||||||
|
@ -1524,7 +1520,8 @@ public abstract class CommonTest {
|
||||||
assertFalse(rs.next());
|
assertFalse(rs.next());
|
||||||
return dbDate;
|
return dbDate;
|
||||||
}, "d");
|
}, "d");
|
||||||
assertEquals(Long.valueOf(1L), db.toSelect("select count(*) from dbtest where d=?").argDate(dbNow).queryLongOrNull());
|
assertEquals(Long.valueOf(1L),
|
||||||
|
db.toSelect("select count(*) from dbtest where d = ?").argLocalDateTime(dbNow).queryLongOrNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1581,12 +1578,12 @@ public abstract class CommonTest {
|
||||||
for (int attempts = 1; attempts <= 10; attempts++) {
|
for (int attempts = 1; attempts <= 10; attempts++) {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d").asLocalDateTime().table().schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
db.toInsert("insert into dbtest (d) values (?)")
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
.argDateNowPerDb()
|
.argLocalDateTimeNowPerDb()
|
||||||
.insert(1);
|
.insert(1);
|
||||||
LocalDateTime dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
LocalDateTime dbNow = db.toSelect("select d from dbtest").queryLocalDateTimeOrNull();
|
||||||
if (dbNow != null && dbNow.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() % 10 != 0) {
|
if (dbNow != null && dbNow.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() % 10 != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1600,19 +1597,17 @@ public abstract class CommonTest {
|
||||||
public void dateRoundTrip() {
|
public void dateRoundTrip() {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("d1").asDate().table()
|
.addColumn("d1").asLocalDateTime().table()
|
||||||
.addColumn("d2").asDate().table().schema()
|
.addColumn("d2").asLocalDateTime().table()
|
||||||
|
.schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
// Store current time as per the database
|
|
||||||
db.toInsert("insert into dbtest (d1) values (?)")
|
db.toInsert("insert into dbtest (d1) values (?)")
|
||||||
.argDateNowPerDb()
|
.argLocalDateTimeNowPerDb()
|
||||||
.insert(1);
|
.insert(1);
|
||||||
// Now pull it out, put it back in, and verify it matches in the database
|
LocalDateTime dbNow = db.toSelect("select d1 from dbtest").queryLocalDateTimeOrNull();
|
||||||
LocalDateTime dbNow = db.toSelect("select d1 from dbtest").queryDateOrNull();
|
db.toUpdate("update dbtest set d2 = ?")
|
||||||
db.toUpdate("update dbtest set d2=?")
|
.argLocalDateTime(dbNow)
|
||||||
.argDate(dbNow)
|
|
||||||
.update(1);
|
.update(1);
|
||||||
|
|
||||||
assertEquals(Long.valueOf(1L), db.toSelect("select count(*) from dbtest where d1=d2").queryLongOrNull());
|
assertEquals(Long.valueOf(1L), db.toSelect("select count(*) from dbtest where d1=d2").queryLongOrNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1620,66 +1615,75 @@ public abstract class CommonTest {
|
||||||
public void dateRoundTripTimezones() {
|
public void dateRoundTripTimezones() {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("d").asDate().table().schema()
|
.addColumn("d")
|
||||||
|
.asLocalDateTime()
|
||||||
|
.table()
|
||||||
|
.schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
Instant instant = Instant.ofEpochMilli(166656789L);
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
||||||
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
ZoneId dateMinusZone = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4));
|
||||||
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, dateMinusZone);
|
||||||
TimeZone defaultTZ = TimeZone.getDefault();
|
ZoneId datePlusZone = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4));
|
||||||
try {
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant,datePlusZone);
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
logger.log(Level.INFO, "dateMinus = " + dateMinus);
|
||||||
db.toInsert("insert into dbtest (d) values (?)").argDate(dateMinus).insert(1);
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
LocalDateTime localDateTimeMinus = db.toSelect("select d from dbtest").queryDateOrNull();
|
.argLocalDateTime(dateMinus)
|
||||||
assertEquals(dateMinus, localDateTimeMinus);
|
.insert(1);
|
||||||
assertEquals("1970-01-02 18:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimeMinus));
|
LocalDateTime localDateTimeMinus = db.toSelect("select d from dbtest")
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(dateMinus).update(1);
|
.queryLocalDateTimeOrNull();
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
assertEquals(dateMinus, localDateTimeMinus);
|
||||||
db.toInsert("insert into dbtest (d) values (?)").argDate(datePlus).insert(1);
|
assertEquals("1970-01-02 18:17:36.789",
|
||||||
LocalDateTime localDateTimePlus = db.toSelect("select d from dbtest").queryDateOrNull();
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimeMinus));
|
||||||
assertEquals(datePlus, localDateTimePlus);
|
db.toDelete("delete from dbtest where d = ?").argLocalDateTime(dateMinus).update(1);
|
||||||
assertEquals("1970-01-03 02:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimePlus));
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
.argLocalDateTime(datePlus)
|
||||||
} finally {
|
.insert(1);
|
||||||
TimeZone.setDefault(defaultTZ);
|
LocalDateTime localDateTimePlus = db.toSelect("select d from dbtest")
|
||||||
}
|
.queryLocalDateTimeOrNull(datePlusZone);
|
||||||
|
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 = ?").argLocalDateTime(datePlus).update(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the appropriate database flavor can correctly convert a {@code Date}
|
* Verify the appropriate database flavor can correctly convert a {@code LocalDateTime}
|
||||||
* into a SQL function representing a conversion from string to timestamp. This
|
* into a SQL function representing a conversion from string to timestamp. This
|
||||||
* function is used to write debug SQL to the log in a way that could be manually
|
* function is used to write debug SQL to the log in a way that could be manually
|
||||||
* executed if desired.
|
* executed if desired.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void stringDateFunctions() {
|
public void stringLocalDateTimeFunctions() {
|
||||||
Instant instant = Instant.ofEpochMilli(166656789L);
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
||||||
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
ZoneId dateMinusZone = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4));
|
||||||
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, dateMinusZone);
|
||||||
logger.info("LocalDateTime: " + dateMinus + " " + datePlus);
|
ZoneId datePlusZone = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4));
|
||||||
TimeZone defaultTZ = TimeZone.getDefault();
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, datePlusZone);
|
||||||
try {
|
logger.info("LocalDateTime: dateMinus=" + dateMinus + " datePlus=" + datePlus);
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
new Schema().addTable("dbtest").addColumn("d")
|
||||||
new Schema().addTable("dbtest").addColumn("d").asDate().schema().execute(db);
|
.asLocalDateTime()
|
||||||
db.toInsert("insert into dbtest (d) values ("
|
.schema()
|
||||||
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(dateMinus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
.execute(db);
|
||||||
.insert(1);
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
assertEquals("1970-01-02 18:17:36.789",
|
.argLocalDateTime(dateMinus)
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
.insert(1);
|
||||||
// Now do some client operations in a different time zone
|
LocalDateTime localDateTime = db.toSelect("select d from dbtest")
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
.queryLocalDateTimeOrNull();
|
||||||
// Verify regular arg maps date the same way even though our TimeZone is now different
|
assertEquals("1970-01-02 18:17:36.789",
|
||||||
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTime.atZone(dateMinusZone)));
|
||||||
db.toInsert("insert into dbtest (d) values ("
|
db.toDelete("delete from dbtest where d = ?")
|
||||||
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
.argLocalDateTime(dateMinus)
|
||||||
.insert(1);
|
.update(1);
|
||||||
assertEquals("1970-01-03 02:17:36.789",
|
db.toInsert("insert into dbtest (d) values (?)")
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
.argLocalDateTime(datePlus)
|
||||||
// Verify the function maps correctly for equals operations as well
|
.insert(1);
|
||||||
db.toDelete("delete from dbtest where d=" + db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus),
|
localDateTime = db.toSelect("select d from dbtest")
|
||||||
db.options().calendarForTimestamps()).replace(":", "::")).update(1);
|
.queryLocalDateTimeOrNull(datePlusZone);
|
||||||
} finally {
|
assertEquals("1970-01-03 02:17:36.789",
|
||||||
TimeZone.setDefault(defaultTZ);
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTime.atZone(datePlusZone)));
|
||||||
}
|
db.toDelete("delete from dbtest where d = ?")
|
||||||
|
.argLocalDateTime(datePlus)
|
||||||
|
.update(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1687,12 +1691,12 @@ public abstract class CommonTest {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("dbtest")
|
.addTable("dbtest")
|
||||||
.addColumn("pk").primaryKey().table()
|
.addColumn("pk").primaryKey().table()
|
||||||
.addColumn("d").asDate().table()
|
.addColumn("d").asLocalDateTime().table()
|
||||||
.addColumn("a").asInteger().table().schema()
|
.addColumn("a").asInteger().table().schema()
|
||||||
.execute(db);
|
.execute(db);
|
||||||
|
|
||||||
db.toSelect("select pk as \"time:: now??\" from dbtest where a=? and d=:now")
|
db.toSelect("select pk as \"time:: now??\" from dbtest where a=? and d=:now")
|
||||||
.argInteger(1).argDateNowPerDb("now").query(rs -> {
|
.argInteger(1).argLocalDateTimeNowPerDb("now").query(rs -> {
|
||||||
assertFalse(rs.next());
|
assertFalse(rs.next());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -57,12 +57,6 @@ public class HsqldbTest extends CommonTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Disabled("HSQLDB uses always static GMT timezone")
|
|
||||||
@Test
|
|
||||||
public void clockSync() {
|
|
||||||
db.assertTimeSynchronized();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Disabled("LocalDate implementations should be TimeZone agnostic, but HSQLDB implementation has a bug.")
|
@Disabled("LocalDate implementations should be TimeZone agnostic, but HSQLDB implementation has a bug.")
|
||||||
@Test
|
@Test
|
||||||
public void argLocalDateTimeZones() {
|
public void argLocalDateTimeZones() {
|
||||||
|
@ -89,7 +83,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("boolean_flag").asBoolean().table()
|
.addColumn("boolean_flag").asBoolean().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().schema().execute(db);
|
.addColumn("local_date").asLocalDate().schema().execute(db);
|
||||||
|
|
||||||
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
db.toInsert("insert into dbtest (nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal, str_varchar,"
|
||||||
|
@ -104,7 +98,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.argClobString("hello again")
|
.argClobString("hello again")
|
||||||
.argBlobBytes(new byte[]{'1', '2'})
|
.argBlobBytes(new byte[]{'1', '2'})
|
||||||
.argBoolean(true)
|
.argBoolean(true)
|
||||||
.argDateNowPerApp()
|
.argLocalDateTime(now)
|
||||||
.argLocalDate(localDateNow)
|
.argLocalDate(localDateNow)
|
||||||
.insert(1);
|
.insert(1);
|
||||||
|
|
||||||
|
@ -120,7 +114,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.argClobString("bye again")
|
.argClobString("bye again")
|
||||||
.argBlobBytes(new byte[]{'3', '4'})
|
.argBlobBytes(new byte[]{'3', '4'})
|
||||||
.argBoolean(false)
|
.argBoolean(false)
|
||||||
.argDateNowPerApp()
|
.argLocalDateTime(now)
|
||||||
.argLocalDate(localDateNow)
|
.argLocalDate(localDateNow)
|
||||||
.insert(1);
|
.insert(1);
|
||||||
|
|
||||||
|
@ -135,7 +129,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.addColumn("str_lob").asClob().table()
|
.addColumn("str_lob").asClob().table()
|
||||||
.addColumn("bin_blob").asBlob().table()
|
.addColumn("bin_blob").asBlob().table()
|
||||||
.addColumn("boolean_flag").asBoolean().table()
|
.addColumn("boolean_flag").asBoolean().table()
|
||||||
.addColumn("date_millis").asDate().table()
|
.addColumn("date_millis").asLocalDateTime().table()
|
||||||
.addColumn("local_date").asLocalDate().schema().print(db.flavor());
|
.addColumn("local_date").asLocalDate().schema().print(db.flavor());
|
||||||
|
|
||||||
List<SqlArgs> args = db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
List<SqlArgs> args = db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
||||||
|
@ -175,7 +169,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.argClobString("str_lob", "bye again")
|
.argClobString("str_lob", "bye again")
|
||||||
.argBlobBytes("bin_blob", new byte[]{'3', '4'})
|
.argBlobBytes("bin_blob", new byte[]{'3', '4'})
|
||||||
.argString("boolean_flag", "N")//.argBoolean("boolean_flag", false)
|
.argString("boolean_flag", "N")//.argBoolean("boolean_flag", false)
|
||||||
.argDate("date_millis", now)
|
.argLocalDateTime("date_millis", now)
|
||||||
.argLocalDate("local_date", localDateNow),
|
.argLocalDate("local_date", localDateNow),
|
||||||
new SqlArgs()
|
new SqlArgs()
|
||||||
.argInteger("nbr_integer", Integer.MAX_VALUE)
|
.argInteger("nbr_integer", Integer.MAX_VALUE)
|
||||||
|
@ -188,7 +182,7 @@ public class HsqldbTest extends CommonTest {
|
||||||
.argClobString("str_lob", "hello again")
|
.argClobString("str_lob", "hello again")
|
||||||
.argBlobBytes("bin_blob", new byte[]{'1', '2'})
|
.argBlobBytes("bin_blob", new byte[]{'1', '2'})
|
||||||
.argString("boolean_flag", "Y")//.argBoolean("boolean_flag", true)
|
.argString("boolean_flag", "Y")//.argBoolean("boolean_flag", true)
|
||||||
.argDate("date_millis", now)
|
.argLocalDateTime("date_millis", now)
|
||||||
.argLocalDate("local_date", localDateNow)),
|
.argLocalDate("local_date", localDateNow)),
|
||||||
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
db.toSelect("select nbr_integer, nbr_long, nbr_float, nbr_double, nbr_big_decimal,"
|
||||||
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest2 order by 1")
|
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest2 order by 1")
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.ResultSetMetaData;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -628,21 +629,32 @@ public class RowStub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime getLocalDateTimeOrNull() {
|
public LocalDateTime getLocalDateTimeOrNull() {
|
||||||
return toDate(rows.get(row)[++col]);
|
return toLocalDateTime(rows.get(row)[++col]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) {
|
||||||
col = columnOneBased;
|
col = columnOneBased;
|
||||||
return toDate(rows.get(row)[columnOneBased - 1]);
|
return toLocalDateTime(rows.get(row)[columnOneBased - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime getLocalDateTimeOrNull(int columnOneBased, ZoneId zoneId) {
|
||||||
|
col = columnOneBased;
|
||||||
|
return toLocalDateTime(rows.get(row)[columnOneBased - 1], zoneId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
public LocalDateTime getLocalDateTimeOrNull(String columnName) {
|
||||||
col = columnIndexByName(columnName) + 1;
|
col = columnIndexByName(columnName) + 1;
|
||||||
return toDate(rows.get(row)[columnIndexByName(columnName)]);
|
return toLocalDateTime(rows.get(row)[columnIndexByName(columnName)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime getLocalDateTimeOrNull(String columnName, ZoneId zoneId) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -758,14 +770,20 @@ public class RowStub {
|
||||||
return (String) o;
|
return (String) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDateTime toDate(Object o) {
|
private LocalDateTime toLocalDateTime(Object o) {
|
||||||
|
return toLocalDateTime(o, ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalDateTime toLocalDateTime(Object o, ZoneId zoneId) {
|
||||||
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()) {
|
||||||
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
|
||||||
|
.atZone(zoneId).toLocalDateTime();
|
||||||
}
|
}
|
||||||
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
|
if (s.length() == "yyyy-MM-ddThh:mm:ss".length()) {
|
||||||
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"));
|
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-ddThh:mm:ss"))
|
||||||
|
.atZone(zoneId).toLocalDateTime();
|
||||||
}
|
}
|
||||||
throw new DatabaseException("Didn't understand date string: " + s);
|
throw new DatabaseException("Didn't understand date string: " + s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class InsertReturning extends DerbyExample {
|
||||||
new Schema()
|
new Schema()
|
||||||
.addTable("t")
|
.addTable("t")
|
||||||
.addColumn("pk").primaryKey().table()
|
.addColumn("pk").primaryKey().table()
|
||||||
.addColumn("d").asDate().table()
|
.addColumn("d").asLocalDateTime().table()
|
||||||
.addColumn("s").asString(80).schema()
|
.addColumn("s").asString(80).schema()
|
||||||
.addSequence("pk_seq").schema().execute(db);
|
.addSequence("pk_seq").schema().execute(db);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class InsertReturning extends DerbyExample {
|
||||||
Long pk = db.toInsert(
|
Long pk = db.toInsert(
|
||||||
"insert into t (pk,d,s) values (?,?,?)")
|
"insert into t (pk,d,s) values (?,?,?)")
|
||||||
.argPkSeq("pk_seq")
|
.argPkSeq("pk_seq")
|
||||||
.argDateNowPerDb()
|
.argLocalDateTimeNowPerDb()
|
||||||
.argString("Hi")
|
.argString("Hi")
|
||||||
.insertReturningPkSeq("pk");
|
.insertReturningPkSeq("pk");
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ 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.time.LocalDateTime;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,20 +18,19 @@ 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();
|
||||||
|
LocalDateTime updateTime = LocalDateTime.now();
|
||||||
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")
|
||||||
.argString(sample.getName())
|
.argString(sample.getName())
|
||||||
.argDate(updateTime)
|
.argLocalDateTime(updateTime)
|
||||||
.insertReturningPkSeq("sample_id");
|
.insertReturningPkSeq("sample_id");
|
||||||
|
|
||||||
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 (?,?,0,?,?,'N')")
|
+ " is_deleted) values (?,?,0,?,?,'N')")
|
||||||
.argLong(sampleId)
|
.argLong(sampleId)
|
||||||
.argString(sample.getName())
|
.argString(sample.getName())
|
||||||
.argDate(updateTime)
|
.argLocalDateTime(updateTime)
|
||||||
.argLong(userIdMakingChange)
|
.argLong(userIdMakingChange)
|
||||||
.insert(1);
|
.insert(1);
|
||||||
|
|
||||||
|
@ -61,20 +59,20 @@ 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;
|
||||||
LocalDateTime newUpdateTime = db.nowPerApp();
|
LocalDateTime newUpdateTime = LocalDateTime.now();
|
||||||
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())
|
||||||
.argString(sample.getName())
|
.argString(sample.getName())
|
||||||
.argInteger(newUpdateSequence)
|
.argInteger(newUpdateSequence)
|
||||||
.argDate(newUpdateTime)
|
.argLocalDateTime(newUpdateTime)
|
||||||
.argLong(userIdMakingChange)
|
.argLong(userIdMakingChange)
|
||||||
.insert(1);
|
.insert(1);
|
||||||
|
|
||||||
db.toUpdate("update sample set sample_name=?, update_sequence=?, update_time=? where sample_id=?")
|
db.toUpdate("update sample set sample_name=?, update_sequence=?, update_time=? where sample_id=?")
|
||||||
.argString(sample.getName())
|
.argString(sample.getName())
|
||||||
.argInteger(newUpdateSequence)
|
.argInteger(newUpdateSequence)
|
||||||
.argDate(newUpdateTime)
|
.argLocalDateTime(newUpdateTime)
|
||||||
.argLong(sample.getSampleId())
|
.argLong(sample.getSampleId())
|
||||||
.update(1);
|
.update(1);
|
||||||
|
|
||||||
|
@ -89,13 +87,13 @@ 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;
|
||||||
LocalDateTime newUpdateTime = db.nowPerApp();
|
LocalDateTime newUpdateTime = LocalDateTime.now();
|
||||||
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())
|
||||||
.argString(sample.getName())
|
.argString(sample.getName())
|
||||||
.argInteger(newUpdateSequence)
|
.argInteger(newUpdateSequence)
|
||||||
.argDate(newUpdateTime)
|
.argLocalDateTime(newUpdateTime)
|
||||||
.argLong(userIdMakingChange)
|
.argLong(userIdMakingChange)
|
||||||
.insert(1);
|
.insert(1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue