Skip to content

Instantly share code, notes, and snippets.

@XuPuPG
Created November 12, 2021 22:11
Show Gist options
  • Save XuPuPG/6ba3ff59510fa01b716cc0a82112cfa7 to your computer and use it in GitHub Desktop.
Save XuPuPG/6ba3ff59510fa01b716cc0a82112cfa7 to your computer and use it in GitHub Desktop.
static class MyRSI<T> implements ResultIterator<T> {
private final ResultSet results;
private final RowMapper<T> mapper;
private final StatementContext context;
private volatile boolean alreadyAdvanced = false;
private volatile boolean hasNext = false;
private volatile boolean closed = false;
MyRSI(ResultSet results,
RowMapper<T> mapper,
StatementContext context) throws SQLException {
this.results = requireNonNull(results);
this.mapper = mapper.specialize(results, context);
this.context = context;
this.context.addCleanable(results::close);
}
@Override
public void close() {
closed = true;
//context.close();
}
@Override
public boolean hasNext() {
if (closed) {
return false;
}
if (alreadyAdvanced) {
return hasNext;
}
hasNext = safeNext();
if (hasNext) {
alreadyAdvanced = true;
} else {
close();
}
return hasNext;
}
@Override
public T next() {
if (closed) {
throw new IllegalStateException("iterator is closed");
}
if (!hasNext()) {
close();
throw new NoSuchElementException("No element to advance to");
}
try {
return mapper.map(results, context);
} catch (SQLException e) {
throw new ResultSetException("Error thrown mapping result set into return type", e, context);
} finally {
alreadyAdvanced = safeNext();
if (!alreadyAdvanced) {
close();
}
}
}
@Override
public StatementContext getContext() {
return context;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Deleting from a result set iterator is not yet supported");
}
private boolean safeNext() {
try {
return results.next();
} catch (SQLException e) {
throw new ResultSetException("Unable to advance result set", e, context);
}
}
}
static <T> ResultIterable<T> of2(Supplier<ResultSet> supplier, RowMapper<T> mapper, StatementContext ctx) {
return () -> {
try {
return new MyRSI<>(supplier.get(), mapper, ctx);
} catch (SQLException e) {
try {
ctx.close();
} catch (Exception e1) {
e.addSuppressed(e1);
}
throw new ResultSetException("Unable to iterator result set", e, ctx);
}
};
}
static class JdbiMapper<K,V>{
private K rowMapper;
private V resultConsumer;
Integer i;
public JdbiMapper(K rowMapper, V resultConsumer, int i) {
this.rowMapper = rowMapper;
this.resultConsumer = resultConsumer;
this.i=i;
}
public K getRowMapper() {
return rowMapper;
}
public void setRowMapper(K rowMapper) {
this.rowMapper = rowMapper;
}
public V getResultConsumer() {
return resultConsumer;
}
public void setResultConsumer(V resultConsumer) {
this.resultConsumer = resultConsumer;
}
}
public static <T> ResultProducer<Void> mappedResultProducer(
Map<Integer, Integer> updates,
JdbiMapper<RowMapper<?>, Consumer<ResultIterable<?>>>... fdf) {
return (statementSupplier, ctx) -> {
PreparedStatement preparedStatement = statementSupplier.get();
try {
List<JdbiMapper<RowMapper<?>, Consumer<ResultIterable<?>>>> jdbiMappers = Arrays.asList(fdf);
List<Integer> keys = new ArrayList<>();
for (JdbiMapper<RowMapper<?>, Consumer<ResultIterable<?>>> jdbiMapper : jdbiMappers) {
keys.add(jdbiMapper.i);
}
Collections.sort(keys);
int position = 0;
for (Integer x : keys) {
for (; position < x; ++position) {
System.out.println(preparedStatement.getMoreResults());
}
if (preparedStatement.getUpdateCount() != -1) {
updates.replace(x, preparedStatement.getUpdateCount());
} else {
ResultSet resultSet = preparedStatement.getResultSet();
if (resultSet == null) {
throw new NoResultsException("Statement returned no results or update count", ctx);
}
jdbiMappers
.stream()
.filter(rowMapperConsumerJdbiMapper1 -> rowMapperConsumerJdbiMapper1.i.equals(x))
.forEach(rowMapperConsumerJdbiMapper -> rowMapperConsumerJdbiMapper.resultConsumer.accept(of2(() -> resultSet, rowMapperConsumerJdbiMapper.getRowMapper(), ctx)));
}
}
} finally {
preparedStatement.close();
ctx.close();
System.out.println("is closed = " + preparedStatement.isClosed());
}
return null;
};
}
public static void main(String[] args) {
init();
String sql = "insert into table (t1,t2,t3) values (34,10,1);" +
"SELECT id FROM table2 WHERE UUID='123';" +
"SELECT id FROM table3 WHERE UUID='2133';" +
"SELECT 6;\n";
jdbi.useHandle(handle -> {
//map for updates, after execute store 0:1 as count of updated rows
Map<Integer, Integer> updates = new HashMap<>(){{0,null}};
//raw cast
handle.createUpdate(sql).execute(mappedResultProducer(
updates,
new JdbiMapper<>(new MapMapper(), maps -> maps.forEach(stringObjectMap -> ((Map<String, Object>) stringObjectMap).forEach((s, o) -> System.out.println(s + o))), 1),
new JdbiMapper<>(new MapMapper(), maps -> maps.forEach(stringObjectMap -> ((Map<String, Object>) stringObjectMap).forEach((s, o) -> System.out.println(s + o))), 3)
));
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment