diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Config.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Config.java index 6bd33d2..62fbbf6 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/Config.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Config.java @@ -15,12 +15,10 @@ public interface Config extends Function, Supplier { * * @return a builder for specifying from where configuration should be loaded */ - static ConfigFrom from() { - return new ConfigFromImpl(); + static ConfigSupplier from() { + return new ConfigSupplierImpl(); } - // TODO add: String originalKey(String key) to find out the key before prefixing or other manipulation - /** * @return a trimmed, non-empty string, or null */ @@ -47,59 +45,27 @@ public interface Config extends Function, Supplier { default Config get() { return this; } - Integer getInteger(String key); int getInteger(String key, int defaultValue); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - int getIntegerOrThrow(String key); - - Long getLong(String key); long getLong(String key, long defaultValue); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - long getLongOrThrow(String key); - - Float getFloat(String key); float getFloat(String key, float defaultValue); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - float getFloatOrThrow(String key); - - Double getDouble(String key); double getDouble(String key, double defaultValue); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - double getDoubleOrThrow(String key); - - BigDecimal getBigDecimal(String key); - BigDecimal getBigDecimal(String key, BigDecimal defaultValue); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - - BigDecimal getBigDecimalOrThrow(String key); - /** * Read a boolean value from the configuration. The value is not case-sensitivie, * and may be either true/false or yes/no. If no value was provided or an invalid @@ -114,11 +80,6 @@ public interface Config extends Function, Supplier { */ boolean getBooleanOrTrue(String key); - /** - * @throws ConfigMissingException if no value could be read for the specified key - */ - boolean getBooleanOrThrow(String key); - /** * Show where configuration is coming from. This is useful to drop in your logs * for troubleshooting. diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigImpl.java index 9d44e7e..b7ea96b 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigImpl.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigImpl.java @@ -13,7 +13,7 @@ import java.util.logging.Logger; */ public class ConfigImpl implements Config { - private static final Logger log = Logger.getLogger(ConfigFromImpl.class.getName()); + private static final Logger log = Logger.getLogger(ConfigSupplierImpl.class.getName()); private final Function provider; @@ -71,12 +71,6 @@ public class ConfigImpl implements Config { Integer value = getInteger(key); return value == null ? defaultValue : value; } - - @Override - public int getIntegerOrThrow(String key) { - return nonnull(key, getInteger(key)); - } - @Override public Long getLong(String key) { @@ -97,12 +91,6 @@ public class ConfigImpl implements Config { Long value = getLong(key); return value == null ? defaultValue : value; } - - @Override - public long getLongOrThrow(String key) { - return nonnull(key, getLong(key)); - } - @Override public Float getFloat(String key) { @@ -123,12 +111,6 @@ public class ConfigImpl implements Config { Float value = getFloat(key); return value == null ? defaultValue : value; } - - @Override - public float getFloatOrThrow(String key) { - return nonnull(key, getFloat(key)); - } - @Override public Double getDouble(String key) { @@ -149,12 +131,6 @@ public class ConfigImpl implements Config { Double value = getDouble(key); return value == null ? defaultValue : value; } - - @Override - public double getDoubleOrThrow(String key) { - return nonnull(key, getDouble(key)); - } - @Override public BigDecimal getBigDecimal(String key) { @@ -176,11 +152,6 @@ public class ConfigImpl implements Config { return value == null ? defaultValue : value; } - @Override - public BigDecimal getBigDecimalOrThrow(String key) { - return nonnull(key, getBigDecimal(key)); - } - @Override public boolean getBooleanOrFalse(String key) { return parseBoolean(cleanString(key), false); @@ -191,19 +162,6 @@ public class ConfigImpl implements Config { return parseBoolean(cleanString(key), true); } - @Override - public boolean getBooleanOrThrow(String key) { - String value = nonnull(key, cleanString(key)); - value = value.toLowerCase(); - if (value.equals("yes") || value.equals("true")) { - return true; - } - if (value.equals("no") || value.equals("false")) { - return false; - } - throw new ConfigMissingException("Unrecognized boolean value for config key: " + key); - } - @Override public String sources() { return sources; diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFrom.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplier.java similarity index 50% rename from jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFrom.java rename to jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplier.java index ae8ebf0..e89fdb8 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFrom.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplier.java @@ -9,36 +9,36 @@ import java.util.function.Supplier; /** * Pull configuration properties from various sources and filter/manipulate them. */ -public interface ConfigFrom extends Supplier { +public interface ConfigSupplier extends Supplier { /** * Convenience method for fluent syntax. * * @return a builder for specifying from where configuration should be loaded */ - static ConfigFrom firstOf() { - return new ConfigFromImpl(); + static ConfigSupplier of() { + return new ConfigSupplierImpl(); } static Config other(Function other) { if (other instanceof Config) { return (Config) other; } - return new ConfigFromImpl().custom(other::apply).get(); + return new ConfigSupplierImpl().custom(other::apply).get(); } - ConfigFrom custom(Function keyValueLookup); + ConfigSupplier custom(Function keyValueLookup); - ConfigFrom value(String key, String value); + ConfigSupplier value(String key, String value); - ConfigFrom systemProperties(); + ConfigSupplier systemProperties(); - ConfigFrom env(); + ConfigSupplier env(); - ConfigFrom properties(Properties properties); + ConfigSupplier properties(Properties properties); - ConfigFrom config(Config config); + ConfigSupplier config(Config config); - ConfigFrom config(Supplier config); + ConfigSupplier config(Supplier config); /** * Adds a set of properties files to read from, which can be overridden by a system property "properties". @@ -47,7 +47,7 @@ public interface ConfigFrom extends Supplier { * defaultPropertyFiles("properties", "conf/app.properties", "local.properties", "sample.properties") * */ - ConfigFrom defaultProperties(); + ConfigSupplier defaultProperties(); /** * Adds a set of properties files to read from, which can be overridden by a specified system property. @@ -56,7 +56,7 @@ public interface ConfigFrom extends Supplier { * defaultPropertyFiles(systemPropertyKey, Charset.defaultCharset().newDecoder(), filenames) * */ - ConfigFrom defaultProperties(String systemPropertyKey, String... filenames); + ConfigSupplier defaultProperties(String systemPropertyKey, String... filenames); /** * Adds a set of properties files to read from, which can be overridden by a specified system property. @@ -67,36 +67,35 @@ public interface ConfigFrom extends Supplier { * .split(File.pathSeparator)); * */ - ConfigFrom defaultProperties(String systemPropertyKey, CharsetDecoder decoder, String... filenames); + ConfigSupplier defaultProperties(String systemPropertyKey, CharsetDecoder decoder, String... filenames); - ConfigFrom properties(String... filenames); + ConfigSupplier properties(String... filenames); - ConfigFrom properties(CharsetDecoder decoder, String... filenames); + ConfigSupplier properties(CharsetDecoder decoder, String... filenames); - ConfigFrom properties(InputStream... inputStreams); + ConfigSupplier properties(InputStream... inputStreams); - ConfigFrom properties(CharsetDecoder decoder, InputStream... inputStreams); + ConfigSupplier properties(CharsetDecoder decoder, InputStream... inputStreams); - ConfigFrom rename(String key, String newKey); + ConfigSupplier rename(String key, String newKey); - ConfigFrom includeKeys(String... keys); + ConfigSupplier includeKeys(String... keys); - ConfigFrom includePrefix(String... prefixes); + ConfigSupplier includePrefix(String... prefixes); - ConfigFrom includeRegex(String regex); + ConfigSupplier includeRegex(String regex); - ConfigFrom excludeKeys(String... keys); + ConfigSupplier excludeKeys(String... keys); - ConfigFrom excludePrefix(String... prefixes); + ConfigSupplier excludePrefix(String... prefixes); - ConfigFrom excludeRegex(String regex); + ConfigSupplier excludeRegex(String regex); - ConfigFrom removePrefix(String... prefixes); + ConfigSupplier removePrefix(String... prefixes); - ConfigFrom addPrefix(String prefix); + ConfigSupplier addPrefix(String prefix); - ConfigFrom substitutions(Config config); + ConfigSupplier substitutions(Config config); Config get(); - } diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFromImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplierImpl.java similarity index 76% rename from jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFromImpl.java rename to jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplierImpl.java index 966834c..da13199 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigFromImpl.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/ConfigSupplierImpl.java @@ -15,8 +15,6 @@ import java.util.List; import java.util.Properties; import java.util.function.Function; import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -24,86 +22,84 @@ import java.util.regex.Pattern; * Access configuration properties from a variety of standard sources, * and provide some basic filtering and mapping of property keys. */ -public class ConfigFromImpl implements ConfigFrom { - - private static final Logger logger = Logger.getLogger(ConfigFromImpl.class.getName()); +public class ConfigSupplierImpl implements ConfigSupplier { private static final String SEPARATOR = FileSystems.getDefault().getSeparator(); private final List searchPath = new ArrayList<>(); - public ConfigFromImpl() { + public ConfigSupplierImpl() { super(); } - public ConfigFromImpl(Config first) { + public ConfigSupplierImpl(Config first) { searchPath.add(first); } @Override - public ConfigFrom custom(Function keyValueLookup) { + public ConfigSupplier custom(Function keyValueLookup) { return custom(keyValueLookup, "custom()"); } - private ConfigFrom custom(Function keyValueLookup, String source) { + private ConfigSupplier custom(Function keyValueLookup, String source) { searchPath.add(new ConfigImpl(keyValueLookup, source)); return this; } @Override - public ConfigFrom value(String key, String value) { + public ConfigSupplier value(String key, String value) { return custom(k -> k.equals(key) ? value : null, "value(" + key + ")"); } @Override - public ConfigFrom config(Config config) { + public ConfigSupplier config(Config config) { searchPath.add(config); return this; } @Override - public ConfigFrom config(Supplier config) { + public ConfigSupplier config(Supplier config) { return config(config.get()); } @Override - public ConfigFrom systemProperties() { + public ConfigSupplier systemProperties() { return custom(System::getProperty, "systemProperties()"); } @Override - public ConfigFrom env() { + public ConfigSupplier env() { return custom(System::getenv, "env()"); } @Override - public ConfigFrom properties(Properties properties) { + public ConfigSupplier properties(Properties properties) { return custom(properties::getProperty, "properties()"); } @Override - public ConfigFrom defaultProperties() { + public ConfigSupplier defaultProperties() { return defaultProperties("properties", "conf/app.properties", "local.properties", "sample.properties"); } @Override - public ConfigFrom defaultProperties(String systemPropertyKey, String... filenames) { + public ConfigSupplier defaultProperties(String systemPropertyKey, String... filenames) { return defaultProperties(systemPropertyKey, Charset.defaultCharset().newDecoder(), filenames); } @Override - public ConfigFrom defaultProperties(String systemPropertyKey, CharsetDecoder decoder, String... filenames) { + public ConfigSupplier defaultProperties(String systemPropertyKey, CharsetDecoder decoder, String... filenames) { String properties = System.getProperty(systemPropertyKey, String.join(SEPARATOR, filenames)); return properties(Charset.defaultCharset().newDecoder(), properties.split(SEPARATOR)); } @Override - public ConfigFrom properties(String... filenames) { + public ConfigSupplier properties(String... filenames) { return properties(Charset.defaultCharset().newDecoder(), filenames); } @Override - public ConfigFrom properties(CharsetDecoder decoder, String... filenames) { + public ConfigSupplier properties(CharsetDecoder decoder, String... filenames) { for (String filename : filenames) { if (filename != null) { Path path = Paths.get(filename); @@ -122,12 +118,12 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom properties(InputStream... inputStreams) { + public ConfigSupplier properties(InputStream... inputStreams) { return properties(Charset.defaultCharset().newDecoder(), inputStreams); } @Override - public ConfigFrom properties(CharsetDecoder decoder, InputStream... inputStreams) { + public ConfigSupplier properties(CharsetDecoder decoder, InputStream... inputStreams) { for (InputStream inputStream : inputStreams) { Properties properties = new Properties(); try (InputStreamReader reader = new InputStreamReader(inputStream, decoder)) { @@ -141,8 +137,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom rename(String configKey, String newKey) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier rename(String configKey, String newKey) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { if (key.equals(configKey)) { return null; } @@ -154,8 +150,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom includeKeys(String... keys) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier includeKeys(String... keys) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { for (String k : keys) { if (key.equals(k)) { return lookup(key); @@ -166,8 +162,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom includePrefix(String... prefixes) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier includePrefix(String... prefixes) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { for (String prefix : prefixes) { if (key.startsWith(prefix)) { return lookup(key); @@ -178,8 +174,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom includeRegex(String regex) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier includeRegex(String regex) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { if (key.matches(regex)) { return lookup(key); } @@ -188,8 +184,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom excludeKeys(String... keys) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier excludeKeys(String... keys) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { for (String k : keys) { if (key.equals(k)) { return null; @@ -200,8 +196,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom excludePrefix(String... prefixes) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier excludePrefix(String... prefixes) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { for (String prefix : prefixes) { if (key.startsWith(prefix)) { return null; @@ -212,8 +208,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom excludeRegex(String regex) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier excludeRegex(String regex) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { if (key.matches(regex)) { return null; } @@ -222,8 +218,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom removePrefix(String... prefixes) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier removePrefix(String... prefixes) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { // Give precedence to ones that already lacked the prefix, // do an include*() first if you don't want that String value = lookup(key); @@ -242,8 +238,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom addPrefix(String prefix) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier addPrefix(String prefix) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { if (key.startsWith(prefix)) { return lookup(key.substring(prefix.length())); } else { @@ -253,8 +249,8 @@ public class ConfigFromImpl implements ConfigFrom { } @Override - public ConfigFrom substitutions(Config config) { - return new ConfigFromImpl(new ConfigImpl(key -> { + public ConfigSupplier substitutions(Config config) { + return new ConfigSupplierImpl(new ConfigImpl(key -> { String value = lookup(key); if (value != null) { // matches ${ENV_VAR_NAME} or $ENV_VAR_NAME diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Database.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Database.java index 7dbbbbe..6138778 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/Database.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Database.java @@ -2,6 +2,7 @@ package org.xbib.jdbc.query; import java.sql.Connection; import java.sql.SQLException; +import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; @@ -87,7 +88,7 @@ public interface Database extends Supplier { * Read the next value from a sequence. This method helps smooth over the * syntax differences across databases. */ - Long nextSequenceValue( String sequenceName); + Long nextSequenceValue(String sequenceName); /** * Cause the underlying connection to commit its transaction immediately. This @@ -159,7 +160,7 @@ public interface Database extends Supplier { * @param tableName the table to be checked * @return true if the table or view exists */ - boolean tableExists( String tableName); + boolean tableExists(String tableName); /** * Convenience method to check whether a table or view exists or not. @@ -171,7 +172,7 @@ public interface Database extends Supplier { * @param schemaName the schema expected to contain the table * @return true if the table or view exists */ - boolean tableExists( String tableName, String schemaName); + boolean tableExists(String tableName, String schemaName); /** * Convenience method to get all column sizes from a table. @@ -213,6 +214,32 @@ public interface Database extends Supplier { */ void assertTimeSynchronized(); + Table getPagedRows(Table table); + + long getRowsCount(Table table); + + long countRows(String statement, Map params); + + Table getSingleRow(String statement, Map params); + + Table getUnlimitedRows(String statement, Map params); + + Table getLimitedRows(String statement, Map params, int limit, int fetchSize, int timeoutSeconds); + + void insert(String statement, Map params); + + void insert(String statement, List> params); + + void update(String statement, Map params); + + void update(String statement, List> params); + + void upsert(String insertStatement, String updateStatement, Map params); + + void delete(String statement, Map params); + + void delete(String statement, List> params); + /** * Write data into a queue table, select a channel, and consume the returned primary keys. * diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java index d532271..f4b0682 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java @@ -1,5 +1,6 @@ package org.xbib.jdbc.query; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; @@ -9,10 +10,15 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.time.Duration; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Consumer; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -276,6 +282,253 @@ public class DatabaseImpl implements Database { assertTimeSynchronized(10000, 30000); } + @Override + public Table getPagedRows(Table table) { + if (table == null) { + return table; + } + Map params = table.getParams() != null ? + new HashMap<>(table.getParams()) : new HashMap<>(); + if (table.getOffset() != null && table.getSize() != null) { + params.put("offset", table.getOffset()); + params.put("limit", table.getSize()); + } + String where = table.getWhereClause() != null ? table.getWhereClause() : ""; + String groupby = table.getGroupByClause() != null ? table.getGroupByClause() : ""; + String orderby = !table.getSort().isEmpty() ? "order by " + table.getSort() : ""; + String statement = table.getStatement() + " " + where + " " + groupby + " " + orderby; + if (table.getOffset() != null && table.getSize() != null) { + statement = statement + " offset :offset rows fetch next :limit rows only"; + } + return getUnlimitedRows(statement, params); + } + + @Override + public long getRowsCount(Table table) { + Map params = new HashMap<>(table.getParams()); + String statement = table.getStatement() + " " + table.getWhereClause(); + return countRows(statement, params); + } + + @Override + public long countRows(String statement, Map params) { + String countStatament = "select count(*) as \"cnt\" from (" + statement + ")"; + Table table = getSingleRow(countStatament, params); + if (!table.isEmpty()) { + BigDecimal bigDecimal = table.getValue(0,"cnt"); + return bigDecimal.longValue(); + } else { + return -1L; + } + } + + @Override + public Table getSingleRow(String statement, Map params) { + return getLimitedRows(statement, params, 1, options().fetchSize(), options().timeoutSeconds()); + } + + @Override + public Table getUnlimitedRows(String statement, Map params) { + return getLimitedRows(statement, params, 0, options().fetchSize(), options().timeoutSeconds()); + } + + @Override + public Table getLimitedRows(String statement, Map params, + int limit, int fetchSize, int timeoutSeconds) { + SqlSelect sql = toSelect(statement).fetchSize(fetchSize).withTimeoutSeconds(timeoutSeconds); + selectParams(sql, params); + Table table = new Table(); + sql.query(rows -> { + ResultSetMetaData md = rows.getMetadata(); + List columnNames = new ArrayList<>(); + List classNames = new ArrayList<>(); + for (int i = 1; i <= md.getColumnCount(); i++) { + columnNames.add(md.getColumnName(i).toLowerCase(Locale.ROOT)); + classNames.add(md.getColumnClassName(i)); + } + table.add(columnNames); + table.add(classNames); + int i = 0; + while (rows.next() && (limit <= 0 || i++ < limit)) { + table.add(getRow(rows, classNames)); + } + table.setTotal(rows.rowCount()); + return true; + }); + return table; + } + + @Override + public void insert(String statement, Map params) { + SqlInsert sql = toInsert(statement); + insertParams(sql, params); + sql.insert(1); + } + + @Override + public void insert(String statement, List> params) { + SqlInsert sqlInsert = toInsert(statement); + for (Map param : params) { + insertParams(sqlInsert, param); + sqlInsert.batch(); + } + sqlInsert.insertBatch(); + } + + @Override + public void update(String statement, Map params) { + SqlUpdate sql = toUpdate(statement); + updateParams(sql, params); + sql.update(); + } + + @Override + public void update(String statement, List> params) { + SqlUpdate sqlUpdate = toUpdate(statement); + for (Map param : params) { + updateParams(sqlUpdate, param); + sqlUpdate.update(); + } + } + + @Override + public void upsert(String insertStatement, String updateStatement, Map params) { + // try insert then update if error + try { + SqlInsert sql = toInsert(insertStatement); + insertParams(sql, params); + sql.insert(1); + } catch (Exception e) { + logger.log(Level.WARNING, e.getMessage(), e); + SqlUpdate sql = toUpdate(updateStatement); + updateParams(sql, params); + sql.update(); + } + } + + @Override + public void delete(String statement, Map params) { + SqlUpdate sql = toDelete(statement); + updateParams(sql, params); + sql.update(); + } + + @Override + public void delete(String statement, List> params) { + SqlUpdate sqlUpdate = toDelete(statement); + for (Map param : params) { + updateParams(sqlUpdate, param); + sqlUpdate.update(); + } + } + + private void selectParams(SqlSelect sql, Map params) { + if (params == null) { + return; + } + params.forEach((k, v) -> { + if (v instanceof String) { + sql.argString(k, (String) v); + } else if (v instanceof Integer) { + sql.argInteger(k, (Integer) v); + } else if (v instanceof Long) { + sql.argLong(k, (Long) v); + } else if (v instanceof Boolean) { + sql.argBoolean(k, (Boolean) v); + } else if (v instanceof LocalDate) { + sql.argLocalDate(k, (LocalDate) v); + } else if (v instanceof LocalDateTime) { + sql.argLocalDateTime(k, (LocalDateTime) v); + } else { + throw new DatabaseException("unknown type for param: " + (v != null ? v.getClass() : "null")); + } + }); + } + + private void insertParams(SqlInsert sql, Map params) { + if (params == null) { + return; + } + params.forEach((k, v) -> { + if (v instanceof String) { + sql.argString(k, (String) v); + } else if (v instanceof Integer) { + sql.argInteger(k, (Integer) v); + } else if (v instanceof Long) { + sql.argLong(k, (Long) v); + } else if (v instanceof Boolean) { + sql.argBoolean(k, (Boolean) v); + } else if (v instanceof LocalDate) { + sql.argLocalDate(k, (LocalDate) v); + } else if (v instanceof LocalDateTime) { + sql.argLocalDateTime(k, (LocalDateTime) v); + } else { + throw new DatabaseException("unknown type for param: " + (v != null ? v.getClass() : "null")); + } + }); + } + + private void updateParams(SqlUpdate sql, Map params) { + if (params == null) { + return; + } + params.forEach((k, v) -> { + if (v instanceof String) { + sql.argString(k, (String) v); + } else if (v instanceof Integer) { + sql.argInteger(k, (Integer) v); + } else if (v instanceof Long) { + sql.argLong(k, (Long) v); + } else if (v instanceof Boolean) { + sql.argBoolean(k, (Boolean) v); + } else if (v instanceof LocalDate) { + sql.argLocalDate(k, (LocalDate) v); + } else if (v instanceof LocalDateTime) { + sql.argLocalDateTime(k, (LocalDateTime) v); + } else { + throw new DatabaseException("unknown type for param: " + (v != null ? v.getClass() : "null")); + } + }); + } + + private List getRow(Rows rows, List classNames) { + List row = new ArrayList<>(); + for (int i = 0; i < classNames.size(); i++) { + String className = classNames.get(i).toString(); + switch (className) { + case "java.lang.String": + row.add(rows.getStringOrEmpty(i + 1)); + break; + case "java.lang.Integer": + row.add(rows.getIntegerOrNull(i + 1)); + break; + case "java.lang.Long": + row.add(rows.getLongOrNull(i + 1)); + break; + case "java.lang.Boolean": + row.add(rows.getBooleanOrFalse(i + 1)); + break; + case "java.sql.Clob": + case "oracle.jdbc.OracleClob": + row.add(rows.getClobStringOrEmpty(i + 1)); + break; + case "java.sql.Date": + row.add(rows.getLocalDateOrNull(i + 1)); + break; + case "java.sql.Timestamp": + case "oracle.sql.TIMESTAMP": + row.add(rows.getLocalDateTimeOrNull(i + 1)); + break; + case "java.math.BigDecimal": + row.add(rows.getBigDecimalOrNull(i + 1)); + break; + default: + throw new DatabaseException("unexpected column class name: " + className); + } + } + return row; + } + @Override public void writeQueue(String table, String channel, String data, Consumer consumer) throws SQLException { writeNextIntoQueue(connection, table, channel, data, consumer); diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/MixedParameterSql.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/MixedParameterSql.java index 2737c5c..d1f3fda 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/MixedParameterSql.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/MixedParameterSql.java @@ -29,7 +29,6 @@ public class MixedParameterSql { if (nameToArg == null) { nameToArg = new HashMap<>(); } - StringBuilder newSql = new StringBuilder(sql.length()); List argNamesList = new ArrayList<>(); List rewrittenArgs = new ArrayList<>(); @@ -39,26 +38,19 @@ public class MixedParameterSql { while (searchIndex < sql.length()) { int nextColonIndex = sql.indexOf(':', searchIndex); int nextQmIndex = sql.indexOf('?', searchIndex); - if (nextColonIndex < 0 && nextQmIndex < 0) { newSql.append(sql.substring(searchIndex)); break; } - if (nextColonIndex >= 0 && (nextQmIndex == -1 || nextColonIndex < nextQmIndex)) { - // The next parameter we found is a named parameter (":foo") if (nextColonIndex > sql.length() - 2) { - // Probably illegal sql, but handle boundary condition break; } - - // Allow :: as escape for : if (sql.charAt(nextColonIndex + 1) == ':') { newSql.append(sql, searchIndex, nextColonIndex + 1); searchIndex = nextColonIndex + 2; continue; } - int endOfNameIndex = nextColonIndex + 1; while (endOfNameIndex < sql.length() && Character.isJavaIdentifierPart(sql.charAt(endOfNameIndex))) { endOfNameIndex++; @@ -83,15 +75,11 @@ public class MixedParameterSql { } searchIndex = endOfNameIndex; } else { - // The next parameter we found is a positional parameter ("?") - - // Allow ?? as escape for ? if (nextQmIndex < sql.length() - 1 && sql.charAt(nextQmIndex + 1) == '?') { newSql.append(sql, searchIndex, nextQmIndex + 1); searchIndex = nextQmIndex + 2; continue; } - newSql.append(sql, searchIndex, nextQmIndex); if (currentPositionalArg >= positionalArgs.size()) { throw new DatabaseException("Not enough positional parameters (" + positionalArgs.size() + ") were provided"); @@ -108,8 +96,6 @@ public class MixedParameterSql { } this.sqlToExecute = newSql.toString(); args = argsList.toArray(new Object[argsList.size()]); - - // Sanity check number of arguments to provide a better error message if (currentPositionalArg != positionalArgs.size()) { throw new DatabaseException("Wrong number of positional parameters were provided (expected: " + currentPositionalArg + ", actual: " + positionalArgs.size() + ")"); @@ -131,5 +117,4 @@ public class MixedParameterSql { public Object[] getArgs() { return args; } - } diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Options.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Options.java index 6560394..353a6d5 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/Options.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Options.java @@ -4,9 +4,14 @@ package org.xbib.jdbc.query; * Control various optional behavior for the database interactions. */ public interface Options { + + int fetchSize(); + + int timeoutSeconds(); + /** - * Control whether the Database object will allow calls to commitNow() - * and rollbackNow(). By default it will throw exceptions if you try to + * Control whether the Database object will allow calls to commit() + * and rollback(). By default it will throw exceptions if you try to * call those. */ boolean allowTransactionControl(); diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsDefault.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsDefault.java index 905a153..d598c57 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsDefault.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsDefault.java @@ -13,6 +13,16 @@ public class OptionsDefault implements Options { this.flavor = flavor; } + @Override + public int fetchSize() { + return 10; + } + + @Override + public int timeoutSeconds() { + return 5; + } + @Override public boolean allowTransactionControl() { return false; diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsOverride.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsOverride.java index 03f623c..dcb3951 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsOverride.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/OptionsOverride.java @@ -2,7 +2,6 @@ package org.xbib.jdbc.query; import org.xbib.jdbc.query.flavor.Postgresql; - /** * Base class for selectively overriding another Options object. */ @@ -41,6 +40,16 @@ public class OptionsOverride implements Options { return this; } + @Override + public int fetchSize() { + return parent.fetchSize(); + } + + @Override + public int timeoutSeconds() { + return parent.timeoutSeconds(); + } + @Override public boolean allowTransactionControl() { return parent.allowTransactionControl(); diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdaptor.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java similarity index 82% rename from jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdaptor.java rename to jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java index b3088e7..b09428a 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdaptor.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java @@ -16,7 +16,7 @@ import java.time.ZoneId; /** * Safely wrap a ResultSet and provide access to the data it contains. */ -class RowsAdaptor implements Rows { +class RowsAdapter implements Rows { private final ResultSet rs; @@ -24,7 +24,7 @@ class RowsAdaptor implements Rows { private int column = 1; - public RowsAdaptor(ResultSet rs, Options options) { + public RowsAdapter(ResultSet rs, Options options) { this.rs = rs; this.options = options; } @@ -71,7 +71,16 @@ class RowsAdaptor implements Rows { public Boolean getBooleanOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toBoolean(rs, columnOneBased); + String val = rs.getString(columnOneBased); + if (val == null) { + return null; + } else if (val.equals("Y") || val.equals("1")) { + return Boolean.TRUE; + } else if (val.equals("N") || val.equals("0")) { + return Boolean.FALSE; + } else { + throw new DatabaseException("Reading boolean from column " + columnOneBased + " but the value was not 'Y' or 'N'"); + } } catch (SQLException e) { throw new DatabaseException(e); } @@ -81,7 +90,16 @@ class RowsAdaptor implements Rows { public Boolean getBooleanOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toBoolean(rs, columnName); + String val = rs.getString(columnName); + if (val == null) { + return null; + } else if (val.equals("Y") || val.equals("1")) { + return Boolean.TRUE; + } else if (val.equals("N") || val.equals("0")) { + return Boolean.FALSE; + } else { + throw new DatabaseException("Reading boolean from column \"" + columnName + "\" but the value was not 'Y' or 'N'"); + } } catch (SQLException e) { throw new DatabaseException(e); } @@ -133,7 +151,6 @@ class RowsAdaptor implements Rows { return result; } - @Override public Integer getIntegerOrNull() { return getIntegerOrNull(column++); @@ -143,7 +160,8 @@ class RowsAdaptor implements Rows { public Integer getIntegerOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toInteger(rs, columnOneBased); + int val = rs.getInt(columnOneBased); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -153,7 +171,8 @@ class RowsAdaptor implements Rows { public Integer getIntegerOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toInteger(rs, columnName); + int val = rs.getInt(columnName); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -181,7 +200,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public Long getLongOrNull() { @@ -192,7 +210,8 @@ class RowsAdaptor implements Rows { public Long getLongOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toLong(rs, columnOneBased); + long val = rs.getLong(columnOneBased); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -202,7 +221,8 @@ class RowsAdaptor implements Rows { public Long getLongOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toLong(rs, columnName); + long val = rs.getLong(columnName); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -230,7 +250,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public Float getFloatOrNull() { @@ -241,7 +260,8 @@ class RowsAdaptor implements Rows { public Float getFloatOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toFloat(rs, columnOneBased); + float val = rs.getFloat(columnOneBased); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -251,7 +271,8 @@ class RowsAdaptor implements Rows { public Float getFloatOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toFloat(rs, columnName); + float val = rs.getFloat(columnName); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -279,7 +300,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public Double getDoubleOrNull() { @@ -290,7 +310,8 @@ class RowsAdaptor implements Rows { public Double getDoubleOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toDouble(rs, columnOneBased); + double val = rs.getDouble(columnOneBased); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -300,7 +321,8 @@ class RowsAdaptor implements Rows { public Double getDoubleOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toDouble(rs, columnName); + double val = rs.getDouble(columnName); + return rs.wasNull() ? null : val; } catch (SQLException e) { throw new DatabaseException(e); } @@ -328,7 +350,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public BigDecimal getBigDecimalOrNull() { @@ -339,7 +360,8 @@ class RowsAdaptor implements Rows { public BigDecimal getBigDecimalOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toBigDecimal(rs, columnOneBased); + BigDecimal val = rs.getBigDecimal(columnOneBased); + return val == null ? null : fixBigDecimal(val); } catch (SQLException e) { throw new DatabaseException(e); } @@ -349,18 +371,17 @@ class RowsAdaptor implements Rows { public BigDecimal getBigDecimalOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toBigDecimal(rs, columnName); + BigDecimal val = rs.getBigDecimal(columnName); + return val == null ? null : fixBigDecimal(val); } catch (SQLException e) { throw new DatabaseException(e); } } - @Override public BigDecimal getBigDecimalOrZero() { return getBigDecimalOrZero(column++); } - @Override public BigDecimal getBigDecimalOrZero(int columnOneBased) { @@ -370,7 +391,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public BigDecimal getBigDecimalOrZero(String columnName) { @@ -380,7 +400,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public String getStringOrNull() { @@ -414,13 +433,11 @@ class RowsAdaptor implements Rows { throw new DatabaseException(e); } } - @Override public String getStringOrEmpty() { return getStringOrEmpty(column++); } - @Override public String getStringOrEmpty(int columnOneBased) { @@ -430,7 +447,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public String getStringOrEmpty(String columnName) { @@ -440,7 +456,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public String getClobStringOrNull() { @@ -475,13 +490,11 @@ class RowsAdaptor implements Rows { } } - @Override public String getClobStringOrEmpty() { return getClobStringOrEmpty(column++); } - @Override public String getClobStringOrEmpty(int columnOneBased) { String result = getClobStringOrNull(columnOneBased); @@ -490,7 +503,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public String getClobStringOrEmpty(String columnName) { @@ -500,7 +512,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public Reader getClobReaderOrNull() { @@ -526,13 +537,11 @@ class RowsAdaptor implements Rows { throw new DatabaseException(e); } } - @Override public Reader getClobReaderOrEmpty() { return getClobReaderOrEmpty(column++); } - @Override public Reader getClobReaderOrEmpty(int columnOneBased) { @@ -542,7 +551,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public Reader getClobReaderOrEmpty(String columnName) { @@ -552,7 +560,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public byte[] getBlobBytesOrNull() { @@ -578,13 +585,11 @@ class RowsAdaptor implements Rows { throw new DatabaseException(e); } } - @Override public byte[] getBlobBytesOrZeroLen() { return getBlobBytesOrZeroLen(column++); } - @Override public byte[] getBlobBytesOrZeroLen(int columnOneBased) { @@ -594,7 +599,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public byte[] getBlobBytesOrZeroLen(String columnName) { @@ -604,7 +608,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public InputStream getBlobInputStreamOrNull() { @@ -630,13 +633,11 @@ class RowsAdaptor implements Rows { throw new DatabaseException(e); } } - @Override public InputStream getBlobInputStreamOrEmpty() { return getBlobInputStreamOrEmpty(column++); } - @Override public InputStream getBlobInputStreamOrEmpty(int columnOneBased) { @@ -646,7 +647,6 @@ class RowsAdaptor implements Rows { } return result; } - @Override public InputStream getBlobInputStreamOrEmpty(String columnName) { @@ -718,7 +718,8 @@ class RowsAdaptor implements Rows { public LocalDate getLocalDateOrNull(int columnOneBased) { try { column = columnOneBased + 1; - return toLocalDate(rs, columnOneBased); + java.sql.Date val = rs.getDate(columnOneBased); + return val == null ? null : val.toLocalDate(); } catch (SQLException e) { throw new DatabaseException(e); } @@ -728,7 +729,8 @@ class RowsAdaptor implements Rows { public LocalDate getLocalDateOrNull(String columnName) { try { column = rs.findColumn(columnName) + 1; - return toLocalDate(rs, columnName); + java.sql.Date val = rs.getDate(columnName); + return val == null ? null : val.toLocalDate(); } catch (SQLException e) { throw new DatabaseException(e); } @@ -744,82 +746,6 @@ class RowsAdaptor implements Rows { } } - private LocalDate toLocalDate(ResultSet rs, int col) throws SQLException { - java.sql.Date val = rs.getDate(col); - return val == null ? null : val.toLocalDate(); - } - - private LocalDate toLocalDate(ResultSet rs, String col) throws SQLException { - java.sql.Date val = rs.getDate(col); - return val == null ? null : val.toLocalDate(); - } - - private Boolean toBoolean(ResultSet rs, int col) throws SQLException { - String val = rs.getString(col); - if (val == null) { - return null; - } else if (val.equals("Y") || val.equals("1")) { - return Boolean.TRUE; - } else if (val.equals("N") || val.equals("0")) { - return Boolean.FALSE; - } else { - throw new DatabaseException("Reading boolean from column " + col + " but the value was not 'Y' or 'N'"); - } - } - - private Boolean toBoolean(ResultSet rs, String col) throws SQLException { - String val = rs.getString(col); - if (val == null) { - return null; - } else if (val.equals("Y") || val.equals("1")) { - return Boolean.TRUE; - } else if (val.equals("N") || val.equals("0")) { - return Boolean.FALSE; - } else { - throw new DatabaseException("Reading boolean from column \"" + col + "\" but the value was not 'Y' or 'N'"); - } - } - - private Integer toInteger(ResultSet rs, int col) throws SQLException { - int val = rs.getInt(col); - return rs.wasNull() ? null : val; - } - - private Integer toInteger(ResultSet rs, String col) throws SQLException { - int val = rs.getInt(col); - return rs.wasNull() ? null : val; - } - - private Long toLong(ResultSet rs, int col) throws SQLException { - long val = rs.getLong(col); - return rs.wasNull() ? null : val; - } - - private Long toLong(ResultSet rs, String col) throws SQLException { - long val = rs.getLong(col); - return rs.wasNull() ? null : val; - } - - private Float toFloat(ResultSet rs, int col) throws SQLException { - float val = rs.getFloat(col); - return rs.wasNull() ? null : val; - } - - private Float toFloat(ResultSet rs, String col) throws SQLException { - float val = rs.getFloat(col); - return rs.wasNull() ? null : val; - } - - private Double toDouble(ResultSet rs, int col) throws SQLException { - double val = rs.getDouble(col); - return rs.wasNull() ? null : val; - } - - private Double toDouble(ResultSet rs, String col) throws SQLException { - double val = rs.getDouble(col); - return rs.wasNull() ? null : val; - } - private BigDecimal fixBigDecimal(BigDecimal val) { if (val.scale() > 0) { val = val.stripTrailingZeros(); @@ -829,14 +755,4 @@ class RowsAdaptor implements Rows { } return val; } - - private BigDecimal toBigDecimal(ResultSet rs, int col) throws SQLException { - BigDecimal val = rs.getBigDecimal(col); - return val == null ? null : fixBigDecimal(val); - } - - private BigDecimal toBigDecimal(ResultSet rs, String col) throws SQLException { - BigDecimal val = rs.getBigDecimal(col); - return val == null ? null : fixBigDecimal(val); - } } diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Sql.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Sql.java index 1ec0465..ff217fb 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/Sql.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Sql.java @@ -14,9 +14,13 @@ import java.util.Stack; * various arg*() calls and replay them later via the apply(sqlArgs) methods. */ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { + private final StringBuilder sql = new StringBuilder(); + private final Stack listFirstItem = new Stack<>(); + private List batched; + private SqlArgs sqlArgs = new SqlArgs(); public Sql() { @@ -207,7 +211,6 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { } } - public Sql listEnd(String sql) { listFirstItem.pop(); return append(sql); @@ -220,6 +223,7 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { /** * Same as sql(), provided for drop-in compatibility with StringBuilder. */ + @Override public String toString() { return sql(); } @@ -313,13 +317,11 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { sqlArgs.argLocalDateTimeNowPerDb(argName); return this; } - public Sql argBlobBytes(byte[] arg) { sqlArgs.argBlobBytes(arg); return this; } - public Sql argBlobBytes(String argName, byte[] arg) { sqlArgs.argBlobBytes(argName, arg); @@ -350,7 +352,6 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { sqlArgs.argClobReader(arg); return this; } - public Sql argClobReader( String argName, Reader arg) { sqlArgs.argClobReader(argName, arg); @@ -385,9 +386,4 @@ public class Sql implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Apply { } sqlArgs.apply(update); } - - public enum ColumnType { - Integer, Long, Float, Double, BigDecimal, String, ClobString, ClobStream, - BlobBytes, BlobStream, Date, DateNowPerApp, DateNowPerDb, Boolean - } } diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java index 22acf51..0d68f15 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java @@ -140,7 +140,7 @@ public interface SqlInsert { * unable to return the value from the insert (such as Derby) this will be simulated * first issuing a select to read the sequence, then an insert. */ - SqlInsert argPkSeq( String argName, String sequenceName); + SqlInsert argPkSeq(String argName, String sequenceName); SqlInsert argPkLong(Long pkValue); diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java index 6f26d40..b9010ff 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java @@ -602,7 +602,7 @@ public class SqlInsertImpl implements SqlInsert { } rs = ps.getGeneratedKeys(); final ResultSet finalRs = rs; - T result = handler.process(new RowsAdaptor(finalRs, options)); + T result = handler.process(new RowsAdapter(finalRs, options)); metric.checkpoint("read"); isSuccess = true; return result; diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java index d72f594..065690c 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java @@ -608,7 +608,7 @@ public class SqlSelectImpl implements SqlSelect { rs = ps.executeQuery(); metric.checkpoint("exec"); final ResultSet finalRs = rs; - T result = handler.process(new RowsAdaptor(finalRs, options)); + T result = handler.process(new RowsAdapter(finalRs, options)); metric.checkpoint("read"); isSuccess = true; return result; diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Table.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Table.java new file mode 100644 index 0000000..551bc27 --- /dev/null +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Table.java @@ -0,0 +1,202 @@ +package org.xbib.jdbc.query; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@SuppressWarnings("serial") +public class Table extends ArrayList> implements List> { + + private String statement; + + private Map params; + + private String search; + + private LocalDateTime from; + + private LocalDateTime to; + + private Integer offset; + + private Integer size; + + private List where; + + private String whereClause; + + private String groupByClause; + + private final List> sort = new ArrayList<>(); + + private long total; + + public Table() { + } + + public void setStatement(String statement) { + this.statement = statement; + } + + public String getStatement() { + return statement; + } + + public void setParams(Map params) { + this.params = params; + } + + public Map getParams() { + return params; + } + + public void setSearch(String search) { + this.search = search; + } + + public String getSearch() { + return search; + } + + public void setFromDate(LocalDateTime from) { + this.from = from; + } + + public LocalDateTime getFromDate() { + return from; + } + + public void setToDate(LocalDateTime to) { + this.to = to; + } + + public LocalDateTime getToDate() { + return to; + } + + public void setOffset(Integer offset) { + this.offset = offset; + } + + public Integer getOffset() { + return offset; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Integer getSize() { + return size; + } + + public void setWhere(List where) { + this.where = where; + } + + public List getWhere() { + return where; + } + + public void setWhereClause(String whereClause) { + this.whereClause = whereClause; + } + + public String getWhereClause() { + return whereClause; + } + + public void setGroupByClause(String groupByClause) { + this.groupByClause = groupByClause; + } + + public String getGroupByClause() { + return groupByClause; + } + + public void addSort(String sort) { + addSort(sort, true); + } + + public void addSort(String sort, Boolean asc) { + this.sort.add(Map.entry(sort, asc)); + } + + public String getSort() { + return sort.stream().map(e -> "\"" + e.getKey() + "\"" + " " + (e.getValue() ? "asc" : "desc")) + .collect(Collectors.joining(",")); + } + + public List getColumnNames() { + return get(0).stream().map(Object::toString).collect(Collectors.toList()); + } + + public int getColumn(String columnName) { + return get(0).indexOf(columnName); + } + + public List getColumnClassNames() { + return get(1).stream().map(Object::toString).collect(Collectors.toList()); + } + + public String getColumnName(int i) { + return (String) get(0).get(i); + } + + public String getColumnClassName(int i) { + return (String) get(1).get(i); + } + + public int getRowCount() { + return size() - 2; + } + + public int getColumnCount() { + return get(0).size(); + } + + public List getRow(int i) { + return get(i + 2); + } + + public void getRow(Map map, int i) { + List row = getRow(i); + for (int c = 0; c < getColumnCount(); c++) { + map.put(getColumnName(c), row.get(c)); + } + } + + public Object getObject(int row, int col) { + return get(row + 2).get(col); + } + + public Object getObject(int row, String columnName) { + int col = getColumn(columnName); + return col >= 0 ? get(row + 2).get(col) : null; + } + + @SuppressWarnings("unchecked") + public T getValue(int row, int col) { + return (T) getObject(row, col); + } + + @SuppressWarnings("unchecked") + public T getValue(int row, String columnName) { + return (T) getObject(row, columnName); + } + + public void setTotal(long total) { + this.total = total; + } + + public long getTotal() { + return total; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() || size() <= 2; + } +} diff --git a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/ConfigTest.java b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/ConfigTest.java index ead771d..980e840 100644 --- a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/ConfigTest.java +++ b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/ConfigTest.java @@ -2,7 +2,7 @@ package org.xbib.jdbc.query.test; import org.junit.jupiter.api.Test; import org.xbib.jdbc.query.Config; -import org.xbib.jdbc.query.ConfigFrom; +import org.xbib.jdbc.query.ConfigSupplier; import java.io.FileWriter; import java.math.BigDecimal; @@ -21,7 +21,7 @@ public class ConfigTest { @Test public void testSystemProperties() { System.setProperty("foo", "bar"); - Config config = ConfigFrom.firstOf().systemProperties().get(); + Config config = ConfigSupplier.of().systemProperties().get(); assertEquals("bar", config.getString("foo")); assertNull(config.getString("unknown")); assertEquals("default", config.getString("unknown", "default")); @@ -32,7 +32,7 @@ public class ConfigTest { Properties properties = new Properties(); properties.setProperty("foo", "bar"); - Config config = ConfigFrom.firstOf().properties(properties).get(); + Config config = ConfigSupplier.of().properties(properties).get(); assertEquals("bar", config.getString("foo")); assertNull(config.getString("unknown")); @@ -53,7 +53,7 @@ public class ConfigTest { properties.store(new FileWriter(filename2), null); // Throw a null in here just to make sure it doesn't blow up - Config config = ConfigFrom.firstOf().properties(filename1, null, filename2).get(); + Config config = ConfigSupplier.of().properties(filename1, null, filename2).get(); assertEquals(Integer.valueOf(1), config.getInteger("foo")); assertEquals(Integer.valueOf(-2), config.getInteger("foo2")); @@ -61,12 +61,12 @@ public class ConfigTest { assertEquals(5, config.getInteger("unknown", 5)); // Now flip the order and verify precedence works - config = ConfigFrom.firstOf().properties(filename2, null, filename1).get(); + config = ConfigSupplier.of().properties(filename2, null, filename1).get(); assertEquals(Integer.valueOf(2), config.getInteger("foo")); assertEquals(Integer.valueOf(-2), config.getInteger("foo2")); // Same as above tests, but using File version rather than filename String - config = ConfigFrom.firstOf().properties(filename1, "does not exist", filename2).get(); + config = ConfigSupplier.of().properties(filename1, "does not exist", filename2).get(); assertEquals(Integer.valueOf(1), config.getInteger("foo")); assertEquals(Integer.valueOf(-2), config.getInteger("foo2")); @@ -74,44 +74,44 @@ public class ConfigTest { assertEquals(5, config.getInteger("unknown", 5)); // Now flip the order and verify precedence works - config = ConfigFrom.firstOf().properties(filename2, null, filename1).get(); + config = ConfigSupplier.of().properties(filename2, null, filename1).get(); assertEquals(Integer.valueOf(2), config.getInteger("foo")); assertEquals(Integer.valueOf(-2), config.getInteger("foo2")); } @Test public void testNested() { - Config config = ConfigFrom.firstOf() - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "a" : null)) - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "b" : null)).get(); + Config config = ConfigSupplier.of() + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "a" : null)) + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "b" : null)).get(); assertEquals("a", config.getString("foo")); // Re-mapping prefix in nested config - config = ConfigFrom.firstOf() - .config(ConfigFrom.firstOf().custom(key -> key.equals("a.foo") ? "a" : null).removePrefix("a.")) - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "b" : null)).get(); + config = ConfigSupplier.of() + .config(ConfigSupplier.of().custom(key -> key.equals("a.foo") ? "a" : null).removePrefix("a.")) + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "b" : null)).get(); assertEquals("a", config.getString("foo")); // Excluding nested config, should skip to next - config = ConfigFrom.firstOf() - .config(ConfigFrom.firstOf().custom(key -> key.equals("a.foo") ? "a" : null).removePrefix("a.").excludeRegex("fo{2}")) - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "b" : null)).get(); + config = ConfigSupplier.of() + .config(ConfigSupplier.of().custom(key -> key.equals("a.foo") ? "a" : null).removePrefix("a.").excludeRegex("fo{2}")) + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "b" : null)).get(); assertEquals("b", config.getString("foo")); assertNull(config.getString("foooo")); - config = ConfigFrom.firstOf() - .config(ConfigFrom.firstOf().custom(key -> key.equals("a.foo") ? "a" : null).excludePrefix("a.", "other.")) - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "b" : null).addPrefix("a.")).get(); + config = ConfigSupplier.of() + .config(ConfigSupplier.of().custom(key -> key.equals("a.foo") ? "a" : null).excludePrefix("a.", "other.")) + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "b" : null).addPrefix("a.")).get(); assertEquals("b", config.getString("a.foo")); assertNull(config.getString("foo")); - config = ConfigFrom.firstOf() - .config(ConfigFrom.firstOf().custom(key -> key.equals("a.foo") ? "a" : null).includePrefix("other.")) - .config(ConfigFrom.firstOf().custom(key -> key.equals("foo") ? "b" : null).addPrefix("a.").includeRegex("a.*f.*")).get(); + config = ConfigSupplier.of() + .config(ConfigSupplier.of().custom(key -> key.equals("a.foo") ? "a" : null).includePrefix("other.")) + .config(ConfigSupplier.of().custom(key -> key.equals("foo") ? "b" : null).addPrefix("a.").includeRegex("a.*f.*")).get(); assertEquals("b", config.getString("a.foo")); assertNull(config.getString("foo")); @@ -120,14 +120,14 @@ public class ConfigTest { @Test public void testStripPrefixConflict() { - Config config = ConfigFrom.firstOf().value("a.foo", "a").value("foo", "bar").removePrefix("a.").get(); + Config config = ConfigSupplier.of().value("a.foo", "a").value("foo", "bar").removePrefix("a.").get(); assertEquals("bar", config.getString("foo")); } @Test public void testException() { - Config config = ConfigFrom.firstOf().custom(key -> { + Config config = ConfigSupplier.of().custom(key -> { throw new SecurityException("Pretending security policy is in place"); }).get(); @@ -138,12 +138,12 @@ public class ConfigTest { @Test public void testTidyValues() { - Config config = ConfigFrom.firstOf().value("foo", " a ").get(); + Config config = ConfigSupplier.of().value("foo", " a ").get(); // Strip whitespace assertEquals("a", config.getString("foo")); - config = ConfigFrom.firstOf().value("foo", " ").value("foo", "").value("foo", null).value("foo", "a").get(); + config = ConfigSupplier.of().value("foo", " ").value("foo", "").value("foo", null).value("foo", "a").get(); // Skip over the garbage ones assertEquals("a", config.getString("foo")); @@ -152,35 +152,35 @@ public class ConfigTest { @Test public void testBoolean() { // Case insensitive, allow either true/false or yes/no - Config config = ConfigFrom.firstOf().value("foo", "tRuE").get(); + Config config = ConfigSupplier.of().value("foo", "tRuE").get(); assertTrue(config.getBooleanOrFalse("foo")); assertTrue(config.getBooleanOrTrue("foo")); assertFalse(config.getBooleanOrFalse("unknown")); assertTrue(config.getBooleanOrTrue("unknown")); - config = ConfigFrom.firstOf().value("foo", "yEs").get(); + config = ConfigSupplier.of().value("foo", "yEs").get(); assertTrue(config.getBooleanOrFalse("foo")); assertTrue(config.getBooleanOrTrue("foo")); assertFalse(config.getBooleanOrFalse("unknown")); assertTrue(config.getBooleanOrTrue("unknown")); - config = ConfigFrom.firstOf().value("foo", "fAlSe").get(); + config = ConfigSupplier.of().value("foo", "fAlSe").get(); assertFalse(config.getBooleanOrFalse("foo")); assertFalse(config.getBooleanOrTrue("foo")); assertFalse(config.getBooleanOrFalse("unknown")); assertTrue(config.getBooleanOrTrue("unknown")); - config = ConfigFrom.firstOf().value("foo", "nO").get(); + config = ConfigSupplier.of().value("foo", "nO").get(); assertFalse(config.getBooleanOrFalse("foo")); assertFalse(config.getBooleanOrTrue("foo")); assertFalse(config.getBooleanOrFalse("unknown")); assertTrue(config.getBooleanOrTrue("unknown")); - config = ConfigFrom.firstOf().value("foo", "bad value").get(); + config = ConfigSupplier.of().value("foo", "bad value").get(); assertFalse(config.getBooleanOrFalse("foo")); assertTrue(config.getBooleanOrTrue("foo")); @@ -190,7 +190,7 @@ public class ConfigTest { @Test public void testInteger() { - Config config = ConfigFrom.firstOf().value("good", "123").value("bad", "hi").get(); + Config config = ConfigSupplier.of().value("good", "123").value("bad", "hi").get(); assertEquals(Integer.valueOf(123), config.getInteger("good")); assertNull(config.getInteger("bad")); assertNull(config.getInteger("missing")); @@ -201,7 +201,7 @@ public class ConfigTest { @Test public void testLong() { - Config config = ConfigFrom.firstOf().value("good", "123").value("bad", "hi").get(); + Config config = ConfigSupplier.of().value("good", "123").value("bad", "hi").get(); assertEquals(Long.valueOf(123), config.getLong("good")); assertNull(config.getLong("bad")); @@ -213,7 +213,7 @@ public class ConfigTest { @Test public void testFloat() { - Config config = ConfigFrom.firstOf().value("good", "123.45").value("bad", "hi").get(); + Config config = ConfigSupplier.of().value("good", "123.45").value("bad", "hi").get(); assertEquals(Float.valueOf(123.45f), config.getFloat("good")); assertNull(config.getFloat("bad")); @@ -225,7 +225,7 @@ public class ConfigTest { @Test public void testDouble() { - Config config = ConfigFrom.firstOf().value("good", "123.45").value("bad", "hi").get(); + Config config = ConfigSupplier.of().value("good", "123.45").value("bad", "hi").get(); assertEquals(Double.valueOf(123.45), config.getDouble("good")); assertNull(config.getDouble("bad")); @@ -237,7 +237,7 @@ public class ConfigTest { @Test public void testBigDecimal() { - Config config = ConfigFrom.firstOf().value("good", "123.45").value("bad", "hi").get(); + Config config = ConfigSupplier.of().value("good", "123.45").value("bad", "hi").get(); assertEquals(new BigDecimal("123.45"), config.getBigDecimal("good")); assertNull(config.getBigDecimal("bad")); diff --git a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/HsqldbTest.java b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/HsqldbTest.java index 39eae75..1381be4 100644 --- a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/HsqldbTest.java +++ b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/HsqldbTest.java @@ -4,7 +4,7 @@ import java.util.logging.Logger; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.xbib.jdbc.query.Config; -import org.xbib.jdbc.query.ConfigFrom; +import org.xbib.jdbc.query.ConfigSupplier; import org.xbib.jdbc.query.DatabaseProvider; import org.xbib.jdbc.query.OptionsOverride; import org.xbib.jdbc.query.Schema; @@ -28,7 +28,7 @@ public class HsqldbTest extends CommonTest { @Override protected DatabaseProvider createDatabaseProvider(OptionsOverride options) throws Exception { String propertiesFile = "hsqldb.properties"; - Config config = ConfigFrom.firstOf() + Config config = ConfigSupplier.of() .properties(getClass().getResourceAsStream(propertiesFile)) .get(); return DatabaseProvider.builder(config) diff --git a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/RowStub.java b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/RowStub.java index 230083e..0023d2b 100644 --- a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/RowStub.java +++ b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/RowStub.java @@ -237,24 +237,21 @@ public class RowStub { return i == null || i; } - @Override public Integer getIntegerOrNull() { - return toInteger(rows.get(row)[++col]); + return (Integer) (rows.get(row)[++col]); } - @Override public Integer getIntegerOrNull(int columnOneBased) { col = columnOneBased; - return toInteger(rows.get(row)[columnOneBased - 1]); + return (Integer) (rows.get(row)[columnOneBased - 1]); } - @Override public Integer getIntegerOrNull(String columnName) { col = columnIndexByName(columnName) + 1; - return toInteger(rows.get(row)[columnIndexByName(columnName)]); + return (Integer) (rows.get(row)[columnIndexByName(columnName)]); } @Override @@ -275,20 +272,17 @@ public class RowStub { return i == null ? 0 : i; } - @Override public Long getLongOrNull() { return toLong(rows.get(row)[++col]); } - @Override public Long getLongOrNull(int columnOneBased) { col = columnOneBased; return toLong(rows.get(row)[columnOneBased - 1]); } - @Override public Long getLongOrNull(String columnName) { col = columnIndexByName(columnName) + 1; @@ -313,20 +307,17 @@ public class RowStub { return i == null ? 0 : i; } - @Override public Float getFloatOrNull() { return toFloat(rows.get(row)[++col]); } - @Override public Float getFloatOrNull(int columnOneBased) { col = columnOneBased; return toFloat(rows.get(row)[columnOneBased - 1]); } - @Override public Float getFloatOrNull(String columnName) { col = columnIndexByName(columnName) + 1; @@ -351,20 +342,17 @@ public class RowStub { return i == null ? 0 : i; } - @Override public Double getDoubleOrNull() { return toDouble(rows.get(row)[++col]); } - @Override public Double getDoubleOrNull(int columnOneBased) { col = columnOneBased; return toDouble(rows.get(row)[columnOneBased - 1]); } - @Override public Double getDoubleOrNull(String columnName) { col = columnIndexByName(columnName) + 1; @@ -389,250 +377,212 @@ public class RowStub { return i == null ? 0 : i; } - @Override public BigDecimal getBigDecimalOrNull() { return toBigDecimal(rows.get(row)[++col]); } - @Override public BigDecimal getBigDecimalOrNull(int columnOneBased) { col = columnOneBased; return toBigDecimal(rows.get(row)[columnOneBased - 1]); } - @Override public BigDecimal getBigDecimalOrNull(String columnName) { col = columnIndexByName(columnName) + 1; return toBigDecimal(rows.get(row)[columnIndexByName(columnName)]); } - @Override public BigDecimal getBigDecimalOrZero() { BigDecimal i = getBigDecimalOrNull(); return i == null ? new BigDecimal(0) : i; } - @Override public BigDecimal getBigDecimalOrZero(int columnOneBased) { BigDecimal i = getBigDecimalOrNull(columnOneBased); return i == null ? new BigDecimal(0) : i; } - @Override public BigDecimal getBigDecimalOrZero(String columnName) { BigDecimal i = getBigDecimalOrNull(columnName); return i == null ? new BigDecimal(0) : i; } - @Override public String getStringOrNull() { - return toString(rows.get(row)[++col]); + return (String) rows.get(row)[++col]; } - @Override public String getStringOrNull(int columnOneBased) { col = columnOneBased; - return toString(rows.get(row)[columnOneBased - 1]); + return (String) rows.get(row)[columnOneBased - 1]; } - @Override public String getStringOrNull(String columnName) { col = columnIndexByName(columnName) + 1; - return toString(rows.get(row)[columnIndexByName(columnName)]); + return (String) rows.get(row)[columnIndexByName(columnName)]; } - @Override public String getStringOrEmpty() { String i = getStringOrNull(); return i == null ? "" : i; } - @Override public String getStringOrEmpty(int columnOneBased) { String i = getStringOrNull(columnOneBased); return i == null ? "" : i; } - @Override public String getStringOrEmpty(String columnName) { String i = getStringOrNull(columnName); return i == null ? "" : i; } - @Override public String getClobStringOrNull() { return getStringOrNull(); } - @Override public String getClobStringOrNull(int columnOneBased) { return getStringOrNull(columnOneBased); } - @Override public String getClobStringOrNull(String columnName) { return getStringOrNull(columnName); } - @Override public String getClobStringOrEmpty() { return getStringOrEmpty(); } - @Override public String getClobStringOrEmpty(int columnOneBased) { return getStringOrEmpty(columnOneBased); } - @Override public String getClobStringOrEmpty(String columnName) { return getStringOrEmpty(columnName); } - @Override public Reader getClobReaderOrNull() { String s = getStringOrNull(); return s == null ? null : new StringReader(s); } - @Override public Reader getClobReaderOrNull(int columnOneBased) { String s = getStringOrNull(columnOneBased); return s == null ? null : new StringReader(s); } - @Override public Reader getClobReaderOrNull(String columnName) { String s = getStringOrNull(columnName); return s == null ? null : new StringReader(s); } - @Override public Reader getClobReaderOrEmpty() { return new StringReader(getStringOrEmpty()); } - @Override public Reader getClobReaderOrEmpty(int columnOneBased) { return new StringReader(getStringOrEmpty(columnOneBased)); } - @Override public Reader getClobReaderOrEmpty(String columnName) { return new StringReader(getStringOrEmpty(columnName)); } - @Override public byte[] getBlobBytesOrNull() { - return toBytes(rows.get(row)[++col]); + return (byte []) (rows.get(row)[++col]); } - @Override public byte[] getBlobBytesOrNull(int columnOneBased) { col = columnOneBased; - return toBytes(rows.get(row)[columnOneBased - 1]); + return (byte []) (rows.get(row)[columnOneBased - 1]); } - @Override public byte[] getBlobBytesOrNull(String columnName) { col = columnIndexByName(columnName) + 1; - return toBytes(rows.get(row)[columnIndexByName(columnName)]); + return (byte []) (rows.get(row)[columnIndexByName(columnName)]); } - @Override public byte[] getBlobBytesOrZeroLen() { byte[] a = getBlobBytesOrNull(); return a == null ? new byte[0] : a; } - @Override public byte[] getBlobBytesOrZeroLen(int columnOneBased) { byte[] a = getBlobBytesOrNull(columnOneBased); return a == null ? new byte[0] : a; } - @Override public byte[] getBlobBytesOrZeroLen(String columnName) { byte[] a = getBlobBytesOrNull(columnName); return a == null ? new byte[0] : a; } - @Override public InputStream getBlobInputStreamOrNull() { byte[] a = getBlobBytesOrNull(); return a == null ? null : new ByteArrayInputStream(a); } - @Override public InputStream getBlobInputStreamOrNull(int columnOneBased) { byte[] a = getBlobBytesOrNull(columnOneBased); return a == null ? null : new ByteArrayInputStream(a); } - @Override public InputStream getBlobInputStreamOrNull(String columnName) { byte[] a = getBlobBytesOrNull(columnName); return a == null ? null : new ByteArrayInputStream(a); } - @Override public InputStream getBlobInputStreamOrEmpty() { return new ByteArrayInputStream(getBlobBytesOrZeroLen()); } - @Override public InputStream getBlobInputStreamOrEmpty(int columnOneBased) { return new ByteArrayInputStream(getBlobBytesOrZeroLen(columnOneBased)); } - @Override public InputStream getBlobInputStreamOrEmpty(String columnName) { return new ByteArrayInputStream(getBlobBytesOrZeroLen(columnName)); } - @Override public LocalDateTime getLocalDateTimeOrNull() { return toLocalDateTime(rows.get(row)[++col]); } - @Override public LocalDateTime getLocalDateTimeOrNull(int columnOneBased) { col = columnOneBased; @@ -645,7 +595,6 @@ public class RowStub { return toLocalDateTime(rows.get(row)[columnOneBased - 1], zoneId); } - @Override public LocalDateTime getLocalDateTimeOrNull(String columnName) { col = columnIndexByName(columnName) + 1; @@ -718,10 +667,6 @@ public class RowStub { return (Boolean) o; } - private Integer toInteger(Object o) { - return (Integer) o; - } - private Long toLong(Object o) { if (o instanceof Integer) { return ((Integer) o).longValue(); @@ -762,14 +707,6 @@ public class RowStub { return (BigDecimal) o; } - private byte[] toBytes(Object o) { - return (byte[]) o; - } - - private String toString(Object o) { - return (String) o; - } - private LocalDateTime toLocalDateTime(Object o) { return toLocalDateTime(o, ZoneId.systemDefault()); } @@ -800,7 +737,6 @@ public class RowStub { if (o instanceof String) { return LocalDate.parse((String) o); } - return (LocalDate) o; } }; diff --git a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/SqlServerTest.java b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/SqlServerTest.java index 0b93794..a21c163 100644 --- a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/SqlServerTest.java +++ b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/SqlServerTest.java @@ -3,7 +3,7 @@ package org.xbib.jdbc.query.test; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.xbib.jdbc.query.Config; -import org.xbib.jdbc.query.ConfigFrom; +import org.xbib.jdbc.query.ConfigSupplier; import org.xbib.jdbc.query.DatabaseProvider; import org.xbib.jdbc.query.OptionsOverride; import org.xbib.jdbc.query.Schema; @@ -18,7 +18,7 @@ public class SqlServerTest extends CommonTest { @Override protected DatabaseProvider createDatabaseProvider(OptionsOverride options) throws Exception { String propertiesFile = System.getProperty("local.properties", "local.properties"); - Config config = ConfigFrom.firstOf() + Config config = ConfigSupplier.of() .systemProperties() .properties(propertiesFile) .excludePrefix("database.")