Skip to content

Commit

Permalink
dev & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
buckelieg committed Jul 15, 2024
1 parent ea2ec28 commit 815cad5
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 54 deletions.
3 changes: 2 additions & 1 deletion src/main/java/buckelieg/jdbc/AbstractQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ public Q skipWarnings(boolean skipWarnings) {
@Nonnull
@Override
public Q print(Consumer<String> printer) {
if (null == printer) throw new NullPointerException("Printer must be provided");
if (null == printer)
throw new NullPointerException("Printer must be provided");
printer.accept(asSQL());
return (Q) this;
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/buckelieg/jdbc/BatchSpliterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ public int characteristics() {
public boolean tryAdvance(Consumer<? super T> action) {
if (!init()) return false;
if (batchCount.get() > 0) {
for (T item : next()) {
for (T item : next())
action.accept(item);
}
return true;
} else return false;
}
Expand All @@ -130,8 +129,10 @@ void close() {
do {
next(); // TODO are there any chances to short circuit these out?
} while (!submittedTasks.stream().allMatch(Future::isDone));
selectQuery.finisher.run();
selectQuery.close();
if (null != exception.get()) throw newSQLRuntimeException(exception.get());
if (null != exception.get())
throw newSQLRuntimeException(exception.get());
}
}

Expand Down
20 changes: 7 additions & 13 deletions src/main/java/buckelieg/jdbc/DefaultConnectionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,13 @@ public Connection getConnection() throws SQLException {
if (isShuttingDown.get()) throw new SQLException("Connection pool is shutting down");
Connection connection;
try {
if (size.getAndIncrement() < maxConnections) {
if (size.get() < maxConnections) {
size.incrementAndGet();
connection = connectionSupplier.get();
if (null == connection) throw new NullPointerException("Provided connection is null");
if (obtainedConnections.contains(connection)) {
connection = pool.take();
} else obtainedConnections.add(connection);
} else {
connection = pool.take();
}
if (obtainedConnections.contains(connection)) connection = pool.take();
else obtainedConnections.add(connection);
} else connection = pool.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new SQLException(e);
Expand All @@ -76,9 +74,7 @@ public Connection getConnection() throws SQLException {
public void close(@Nullable Connection connection) throws SQLException {
if (null == connection) return;
connection.setAutoCommit(true);
if (!pool.offer(connection)) {
throw new SQLException("Connection pool is full");
}
if (!pool.offer(connection)) throw new SQLException("Connection pool is full");
}

@Override
Expand All @@ -95,8 +91,6 @@ public void close() throws SQLException {
}
}
obtainedConnections.clear();
if (null != exception) {
throw exception;
}
if (null != exception) throw exception;
}
}
6 changes: 2 additions & 4 deletions src/main/java/buckelieg/jdbc/JDBCDefaults.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,12 @@ public Map<String, Object> apply(ValueReader valueReader) throws SQLException {
Metadata meta = valueReader.meta();
int columnCount = meta.count();
colReaders = new ArrayList<>(columnCount);
for (int col = 1; col <= columnCount; col++) {
for (int col = 1; col <= columnCount; col++)
colReaders.add(entry(entry(meta.getLabel(col), col), reader(meta.getSQLType(col))));
}
instance = getter -> {
Map<String, Object> result = new LinkedHashMap<>(columnCount);
for (Map.Entry<Map.Entry<String, Integer>, TryBiFunction<ValueReader, Integer, ?, SQLException>> e : colReaders) {
for (Map.Entry<Map.Entry<String, Integer>, TryBiFunction<ValueReader, Integer, ?, SQLException>> e : colReaders)
result.put(e.getKey().getKey(), e.getValue().apply(getter, e.getKey().getValue()));
}
return result;
};
}
Expand Down
22 changes: 13 additions & 9 deletions src/main/java/buckelieg/jdbc/RSMeta.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ private List<Column> getColumns() {
if (null == columns) {
List<Column> buffer = new ArrayList<>();
try {
for (int col = 1; col <= rsMeta.get().getColumnCount(); col++) {
for (int col = 1; col <= rsMeta.get().getColumnCount(); col++)
buffer.add(getColumn(col));
}
columns = buffer;
} catch (SQLException e) {
throw newSQLRuntimeException(e);
Expand Down Expand Up @@ -150,7 +149,8 @@ public List<String> names() {
@Nonnull
@Override
public String getName(int columnIndex) {
if (columnIndex < 1) throw new IllegalArgumentException("Column index must start at 1");
if (columnIndex < 1)
throw new IllegalArgumentException("Column index must start at 1");
List<Column> columns = getColumns();
if (columnIndex > columns.size())
throw new IllegalArgumentException(format("No column exists under provided index %s", columnIndex));
Expand All @@ -162,9 +162,8 @@ public int indexOf(String columnName) {
if (requireNonNull(columnName, "Column name must be provided").trim().isEmpty())
throw new IllegalArgumentException("Column name must not be blank");
List<Column> columns = getColumns();
for (int index = 0; index < columns.size(); index++) {
for (int index = 0; index < columns.size(); index++)
if (columnName.equalsIgnoreCase(columns.get(index).name)) return index + 1;
}
return -1;
}

Expand Down Expand Up @@ -318,7 +317,10 @@ private boolean isNullable(Table table, String column) {
private boolean isNullable(String catalog, String schema, String table, String column) {
return getColumn(catalog, schema, table, column, c -> {
if (c.nullable == null)
c.nullable = listResultSet(dbMeta.get().getColumns(catalog, schema, table, column), rs -> rs.getInt(NULLABLE)).stream().anyMatch(mode -> mode == DatabaseMetaData.columnNullable);
c.nullable = listResultSet(
dbMeta.get().getColumns(catalog, schema, table, column),
rs -> rs.getInt(NULLABLE)
).stream().anyMatch(mode -> mode == DatabaseMetaData.columnNullable);
}).nullable;
}

Expand All @@ -329,7 +331,10 @@ private SQLType getSQLType(Table table, String column) {
private SQLType getSQLType(String catalog, String schema, String table, String column) {
return getColumn(catalog, schema, table, column, c -> {
if (c.sqlType == null)
c.sqlType = JDBCType.valueOf(listResultSet(dbMeta.get().getColumns(catalog, schema, table, column), rs -> rs.getInt(DATA_TYPE)).stream().findFirst().orElse(Types.OTHER));
c.sqlType = JDBCType.valueOf(listResultSet(
dbMeta.get().getColumns(catalog, schema, table, column),
rs -> rs.getInt(DATA_TYPE)
).stream().findFirst().orElse(Types.OTHER));
}).sqlType;
}

Expand All @@ -345,8 +350,7 @@ private Column getColumn(int columnIndex, @Nullable TryConsumer<Column, Exceptio
c.index = columnIndex;
if (c.nullable == null) c.nullable = meta.isNullable(columnIndex) == ResultSetMetaData.columnNullable;
if (c.sqlType == null) c.sqlType = JDBCType.valueOf(meta.getColumnType(columnIndex));
if (c.javaType == null)
c.javaType = Class.forName(meta.getColumnClassName(columnIndex), false, ClassLoader.getSystemClassLoader());
if (c.javaType == null) c.javaType = Class.forName(meta.getColumnClassName(columnIndex), false, ClassLoader.getSystemClassLoader());
getEnricher(enricher).accept(c);
}
);
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/buckelieg/jdbc/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,7 @@ public StoredProcedure procedure(String query, P<?>... parameters) {
@Nonnull
public Select select(String query, Object... parameters) {
requireNonNull(query, "SQL query must be provided");
if (isProcedure(query)) {
throw new IllegalArgumentException(format("Query '%s' is not valid select statement", query));
}
if (isProcedure(query)) throw new IllegalArgumentException(format("Query '%s' is not valid select statement", query));
return new SelectQuery(metaCache, connectionSupplier, connectionCloser, executorServiceSupplier, checkAnonymous(checkSingle(query)), parameters);
}

Expand Down Expand Up @@ -287,9 +285,7 @@ public Update update(String query, Map<String, ?>... batch) {
@Nonnull
public Update update(String query, Object[]... batch) {
requireNonNull(query, "SQL query must be provided");
if (isProcedure(query)) {
throw new IllegalArgumentException(format("Query '%s' is not valid DML statement", query));
}
if (isProcedure(query)) throw new IllegalArgumentException(format("Query '%s' is not valid DML statement", query));
return new UpdateQuery(connectionSupplier, connectionCloser, executorServiceSupplier, checkAnonymous(checkSingle(query)), batch);
}

Expand Down
60 changes: 46 additions & 14 deletions src/main/java/buckelieg/jdbc/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ static Entry<String, Object[]> prepareQuery(String query, Iterable<? extends Ent
Matcher matcher = NAMED_PARAMETER.matcher(query);
int idx = 0;
while (matcher.find())
for (Object o : asIterable(transformedParams.getOrDefault(matcher.group(), empty()))) indicesToValues.put(++idx, o);
for (Object o : asIterable(transformedParams.getOrDefault(matcher.group(), empty())))
indicesToValues.put(++idx, o);
for (Entry<String, Optional<?>> e : transformedParams.entrySet()) {
query = query.replaceAll(
format("(%s\\b)%s", e.getKey(), QUOTATION_ESCAPE),
Expand Down Expand Up @@ -106,7 +107,8 @@ static boolean isProcedure(String query) {
}

static String checkAnonymous(String query) {
if (!isAnonymous(query)) throw new IllegalArgumentException(format("Named parameters mismatch for query: '%s'", query));
if (!isAnonymous(query))
throw new IllegalArgumentException(format("Named parameters mismatch for query: '%s'", query));
return query;
}

Expand All @@ -117,12 +119,25 @@ static boolean isAnonymous(String query) {
static SQLRuntimeException newSQLRuntimeException(Throwable... throwables) {
StringBuilder messages = new StringBuilder();
for (Throwable throwable : throwables) {
Throwable t = throwable;
StringBuilder message = ofNullable(t).map(Throwable::getMessage).map(msg -> new StringBuilder(format("%s ", msg.trim()))).orElse(new StringBuilder());
Optional<Throwable> t = ofNullable(throwable);
StringBuilder message = t
.map(Throwable::getMessage)
.map(String::trim)
.map(StringBuilder::new)
.map(msg -> msg.append(" "))
.orElse(new StringBuilder());
AtomicReference<String> prevMsg = new AtomicReference<>();
while ((t = t.getCause()) != null) {
ofNullable(t.getMessage()).map(msg -> format("%s ", msg.trim())).filter(msg -> prevMsg.get() != null && prevMsg.get().equals(msg)).ifPresent(message::append);
prevMsg.set(t.getMessage() != null ? t.getMessage().trim() : null);
while ((t = t.map(Throwable::getCause)).orElse(null) != null) {
t.map(Throwable::getMessage)
.map(msg -> format("%s ", msg.trim()))
.filter(msg -> prevMsg.get() != null && prevMsg.get().equals(msg))
.ifPresentOrElse(
msg -> {
message.append(msg);
prevMsg.set(msg);
},
() -> prevMsg.set(null)
);
}
messages.append(message);
}
Expand Down Expand Up @@ -203,10 +218,25 @@ static String wipeComments(String query) {
}
}
if (multiLineCommentStartIndices.size() != multiLineCommentsEndIndices.size()) {
throw new SQLRuntimeException(format("Multiline comments open/close tags count mismatch (%s/%s) for query:\r\n%s", multiLineCommentStartIndices.size(), multiLineCommentsEndIndices.size(), query), true);
throw new SQLRuntimeException(
format(
"Multiline comments open/close tags count mismatch (%s/%s) for query:\r\n%s",
multiLineCommentStartIndices.size(),
multiLineCommentsEndIndices.size(),
query
),
true
);
}
if (!multiLineCommentStartIndices.isEmpty() && (multiLineCommentStartIndices.get(0) > multiLineCommentsEndIndices.get(0))) {
throw new SQLRuntimeException(format("Unmatched start multiline comment at %s for query:\r\n%s", multiLineCommentStartIndices.get(0), query), true);
throw new SQLRuntimeException(
format(
"Unmatched start multiline comment at %s for query:\r\n%s",
multiLineCommentStartIndices.get(0),
query
),
true
);
}
replaced = replaceChars(replaced, singleLineCommentStartIndices, singleLineCommentEndIndices);
replaced = replaceChars(replaced, multiLineCommentStartIndices, multiLineCommentsEndIndices);
Expand All @@ -216,7 +246,10 @@ static String wipeComments(String query) {
private static String replaceChars(String source, List<Integer> startIndices, List<Integer> endIndices) {
String replaced = source;
for (int i = 0; i < startIndices.size(); i++)
replaced = replaced.replace(replaced.substring(startIndices.get(i), endIndices.get(i)), format("%" + (endIndices.get(i) - startIndices.get(i)) + "s", " "));
replaced = replaced.replace(
replaced.substring(startIndices.get(i), endIndices.get(i)),
format("%" + (endIndices.get(i) - startIndices.get(i)) + "s", " ")
);
return replaced;
}

Expand Down Expand Up @@ -280,9 +313,8 @@ static Object proxy(Object stream) {
return proxy(stream, getAllInterfaces(stream.getClass()), (instance, proxy, method, args) -> {
if (BaseStream.class.equals(method.getDeclaringClass())) {
if (!BaseStream.class.isAssignableFrom(method.getReturnType())) {
if ("iterator".equals(method.getName()) || "spliterator".equals(method.getName())) {
throw new UnsupportedOperationException("not supported");
}
if ("iterator".equals(method.getName()) || "spliterator".equals(method.getName()))
throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
return method.invoke(instance, args);
} else return proxy(method.invoke(instance, args));
}
Expand All @@ -291,7 +323,7 @@ static Object proxy(Object stream) {
try (AutoCloseable proxied = (BaseStream<?, ?>) instance) {
return method.invoke(proxied, args);
} catch (Throwable t) {
throw Utils.newSQLRuntimeException(t.getCause(), t);
throw newSQLRuntimeException(t.getCause(), t);
}
} else return proxy(method.invoke(instance, args));
}
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/buckelieg/jdbc/ValueSetters.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ private <T, S extends PreparedStatement, R extends RowSet> void setValue(
TryTriConsumer<R, Integer, T, SQLException> rowSetSetter
) throws SQLException {
if (null != preparedStatement) statementSetter.accept((S) preparedStatement, index, value);
else if (null != callableStatement) ((TryTriConsumer<CallableStatement, Integer, T, SQLException>) statementSetter).accept(callableStatement, index, value);
else if (null != callableStatement)
((TryTriConsumer<CallableStatement, Integer, T, SQLException>) statementSetter)
.accept(callableStatement, index, value);
else if (null != resultSet) resultSetSetter.accept(resultSet, index, value);
else if (null != rowSet) rowSetSetter.accept((R) rowSet, index, value);
}
Expand Down Expand Up @@ -110,7 +112,9 @@ private <T, S extends PreparedStatement, N> void setValue(
TryQuadConsumer<RowSet, Integer, T, N, SQLException> rowSetSetter
) throws SQLException {
if (null != preparedStatement) statementSetter.accept((S) preparedStatement, index, value1, value2);
else if (null != callableStatement) ((TryQuadConsumer<CallableStatement, Integer, T, N, SQLException>) statementSetter).accept(callableStatement, index, value1, value2);
else if (null != callableStatement)
((TryQuadConsumer<CallableStatement, Integer, T, N, SQLException>) statementSetter)
.accept(callableStatement, index, value1, value2);
else if (null != resultSet) resultSetSetter.accept(resultSet, index, value1, value2);
else if (null != rowSet) rowSetSetter.accept(rowSet, index, value1, value2);
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/buckelieg/jdbc/DBTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ public void testTransactionException() {
try {
db1.transaction().isolation(Transaction.Isolation.SERIALIZABLE).execute(session -> {
session.update("INSERT INTO test(name) VALUES(?)", "name").execute();
Long countAfter = session.select("SELECT COUNT(*) FROM TEST").print(s -> log.info("WTF")).single(rs -> rs.getLong(1)).orElse(null);
Long countAfter = session.select("SELECT COUNT(*) FROM TEST").single(rs -> rs.getLong(1)).orElse(null);
assertEquals(countBefore + 1, (long) countAfter);
throw new SQLException("Rollback!");
});
Expand Down Expand Up @@ -838,7 +838,7 @@ public void testSelectForBatch() throws Exception {
log.info("{} batch processing called!", index);
batch.forEach(map -> map.put("someKey" + index, "someValue" + index));
batch.add(new HashMap<String, Object>() {{
put("WTF_KEY", "WTF_VALUE");
put("ANY_KEY", "ANY_VALUE");
}});
session.select(
"SELECT * FROM TEST WHERE id IN (:ids)",
Expand Down

0 comments on commit 815cad5

Please sign in to comment.