Created
November 12, 2021 22:11
-
-
Save XuPuPG/6ba3ff59510fa01b716cc0a82112cfa7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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