|
40 | 40 | import java.util.List; |
41 | 41 | import java.util.Map; |
42 | 42 | import java.util.Objects; |
| 43 | +import java.util.function.Function; |
43 | 44 | import java.util.logging.Level; |
44 | 45 | import java.util.logging.Logger; |
45 | 46 | import org.jetbrains.annotations.NotNull; |
46 | 47 | import org.jetbrains.annotations.Nullable; |
| 48 | +import org.reactivestreams.Publisher; |
47 | 49 | import reactor.core.publisher.Flux; |
48 | 50 | import reactor.core.publisher.Mono; |
49 | 51 |
|
@@ -212,31 +214,32 @@ protected Configuration getConfiguration() { |
212 | 214 | @SuppressWarnings("unchecked") |
213 | 215 | @Override |
214 | 216 | public Flux<T> fetch() { |
215 | | - return getConnection() |
216 | | - .flatMapMany( |
217 | | - conn -> { |
218 | | - var expr = (Expression<T>) queryMixin.getMetadata().getProjection(); |
219 | | - var serializer = serialize(false); |
220 | | - var mapper = createMapper(expr); |
221 | | - |
222 | | - var constants = serializer.getConstants(); |
223 | | - var originalSql = serializer.toString(); |
224 | | - var sql = |
225 | | - R2dbcUtils.replaceBindingArguments( |
226 | | - configuration.getBindMarkerFactory().create(), constants, originalSql); |
227 | | - |
228 | | - var statement = conn.createStatement(sql); |
229 | | - BindTarget bindTarget = new StatementWrapper(statement); |
230 | | - |
231 | | - setParameters( |
232 | | - bindTarget, |
233 | | - configuration.getBindMarkerFactory().create(), |
234 | | - constants, |
235 | | - serializer.getConstantPaths(), |
236 | | - getMetadata().getParams()); |
237 | | - |
238 | | - return Flux.from(statement.execute()).flatMap(result -> result.map(mapper::map)); |
239 | | - }); |
| 217 | + Function<Connection, Publisher<T>> work = |
| 218 | + connection -> { |
| 219 | + var expr = (Expression<T>) queryMixin.getMetadata().getProjection(); |
| 220 | + var serializer = serialize(false); |
| 221 | + var mapper = createMapper(expr); |
| 222 | + |
| 223 | + var constants = serializer.getConstants(); |
| 224 | + var originalSql = serializer.toString(); |
| 225 | + var sql = |
| 226 | + R2dbcUtils.replaceBindingArguments( |
| 227 | + configuration.getBindMarkerFactory().create(), constants, originalSql); |
| 228 | + |
| 229 | + var statement = connection.createStatement(sql); |
| 230 | + BindTarget bindTarget = new StatementWrapper(statement); |
| 231 | + |
| 232 | + setParameters( |
| 233 | + bindTarget, |
| 234 | + configuration.getBindMarkerFactory().create(), |
| 235 | + constants, |
| 236 | + serializer.getConstantPaths(), |
| 237 | + getMetadata().getParams()); |
| 238 | + |
| 239 | + return Flux.from(statement.execute()).flatMap(result -> result.map(mapper::map)); |
| 240 | + }; |
| 241 | + |
| 242 | + return usingConnectionMany(work); |
240 | 243 | } |
241 | 244 |
|
242 | 245 | private Mapper<T> createMapper(Expression<T> expr) { |
@@ -322,32 +325,53 @@ private Mono<Long> unsafeCount() { |
322 | 325 |
|
323 | 326 | logQuery(sql, constants); |
324 | 327 |
|
325 | | - return getConnection() |
326 | | - .flatMap( |
327 | | - connection -> { |
328 | | - var statement = getStatement(connection, sql); |
329 | | - BindTarget bindTarget = new StatementWrapper(statement); |
330 | | - |
331 | | - setParameters( |
332 | | - bindTarget, |
333 | | - configuration.getBindMarkerFactory().create(), |
334 | | - constants, |
335 | | - serializer.getConstantPaths(), |
336 | | - getMetadata().getParams()); |
337 | | - |
338 | | - return Mono.from(statement.execute()) |
339 | | - .flatMap(result -> Mono.from(result.map((row, rowMetadata) -> row.get(0)))) |
340 | | - .map( |
341 | | - o -> { |
342 | | - if (Integer.class.isAssignableFrom(o.getClass())) { |
343 | | - return ((Integer) o).longValue(); |
344 | | - } |
345 | | - |
346 | | - return (Long) o; |
347 | | - }) |
348 | | - .defaultIfEmpty(0L) |
349 | | - .doOnError(e -> Mono.error(configuration.translate(sql, constants, e))); |
350 | | - }); |
| 328 | + Function<Connection, Mono<Long>> work = |
| 329 | + connection -> { |
| 330 | + var statement = getStatement(connection, sql); |
| 331 | + BindTarget bindTarget = new StatementWrapper(statement); |
| 332 | + |
| 333 | + setParameters( |
| 334 | + bindTarget, |
| 335 | + configuration.getBindMarkerFactory().create(), |
| 336 | + constants, |
| 337 | + serializer.getConstantPaths(), |
| 338 | + getMetadata().getParams()); |
| 339 | + |
| 340 | + return Mono.from(statement.execute()) |
| 341 | + .flatMap(result -> Mono.from(result.map((row, rowMetadata) -> row.get(0)))) |
| 342 | + .map( |
| 343 | + o -> { |
| 344 | + if (Integer.class.isAssignableFrom(o.getClass())) { |
| 345 | + return ((Integer) o).longValue(); |
| 346 | + } |
| 347 | + |
| 348 | + return (Long) o; |
| 349 | + }) |
| 350 | + .defaultIfEmpty(0L) |
| 351 | + .doOnError(e -> Mono.error(configuration.translate(sql, constants, e))); |
| 352 | + }; |
| 353 | + |
| 354 | + return usingConnection(work); |
| 355 | + } |
| 356 | + |
| 357 | + private <R> Flux<R> usingConnectionMany(Function<Connection, Publisher<R>> callback) { |
| 358 | + if (connProvider != null) { |
| 359 | + return connProvider.withConnectionMany(callback); |
| 360 | + } |
| 361 | + if (conn != null) { |
| 362 | + return Flux.defer(() -> Flux.from(callback.apply(conn))); |
| 363 | + } |
| 364 | + return Flux.error(new IllegalStateException("No connection provided")); |
| 365 | + } |
| 366 | + |
| 367 | + private <R> Mono<R> usingConnection(Function<Connection, Mono<R>> callback) { |
| 368 | + if (connProvider != null) { |
| 369 | + return connProvider.withConnection(callback); |
| 370 | + } |
| 371 | + if (conn != null) { |
| 372 | + return Mono.defer(() -> callback.apply(conn)); |
| 373 | + } |
| 374 | + return Mono.error(new IllegalStateException("No connection provided")); |
351 | 375 | } |
352 | 376 |
|
353 | 377 | protected void logQuery(String queryString, Collection<Object> parameters) { |
|
0 commit comments