[jOOQ/jOOQ#9806] Add Batch.executeAsync() methods
This commit is contained in:
parent
92de670f5d
commit
fb2c0cc910
@ -39,6 +39,8 @@ package org.jooq;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Statement;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.jooq.exception.DataAccessException;
|
||||
|
||||
@ -73,6 +75,27 @@ public interface Batch extends Serializable {
|
||||
*/
|
||||
int[] execute() throws DataAccessException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute the batch operation in a new {@link CompletionStage}.
|
||||
* <p>
|
||||
* The result is asynchronously completed by a task running in an
|
||||
* {@link Executor} provided by the underlying
|
||||
* {@link Configuration#executorProvider()}.
|
||||
*
|
||||
* @see Statement#executeBatch()
|
||||
*/
|
||||
CompletionStage<int[]> executeAsync();
|
||||
|
||||
/**
|
||||
* Execute the query in a new {@link CompletionStage} that is asynchronously
|
||||
* completed by a task running in the given executor.
|
||||
*/
|
||||
CompletionStage<int[]> executeAsync(Executor executor);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of executed queries in this batch operation
|
||||
*/
|
||||
|
||||
81
jOOQ/src/main/java/org/jooq/impl/AbstractBatch.java
Normal file
81
jOOQ/src/main/java/org/jooq/impl/AbstractBatch.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Tools.blocking;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.jooq.Batch;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
abstract class AbstractBatch implements Batch {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = 5898924458502836002L;
|
||||
final Configuration configuration;
|
||||
final DSLContext dsl;
|
||||
|
||||
AbstractBatch(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.dsl = DSL.using(configuration);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final CompletionStage<int[]> executeAsync() {
|
||||
return executeAsync(configuration.executorProvider().provide());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CompletionStage<int[]> executeAsync(Executor executor) {
|
||||
return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::execute), executor), () -> executor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -46,10 +46,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jooq.Batch;
|
||||
import org.jooq.BatchBindStep;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.TableRecord;
|
||||
@ -60,21 +58,19 @@ import org.jooq.exception.DataAccessException;
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class BatchCRUD implements Batch {
|
||||
final class BatchCRUD extends AbstractBatch {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -2935544935267715011L;
|
||||
|
||||
private final DSLContext create;
|
||||
private final Configuration configuration;
|
||||
private final TableRecord<?>[] records;
|
||||
private final Action action;
|
||||
|
||||
BatchCRUD(Configuration configuration, Action action, TableRecord<?>[] records) {
|
||||
this.create = DSL.using(configuration);
|
||||
this.configuration = configuration;
|
||||
super(configuration);
|
||||
|
||||
this.action = action;
|
||||
this.records = records;
|
||||
}
|
||||
@ -89,12 +85,10 @@ final class BatchCRUD implements Batch {
|
||||
|
||||
// [#1180] Run batch queries with BatchMultiple, if no bind variables
|
||||
// should be used...
|
||||
if (executeStaticStatements(configuration.settings())) {
|
||||
if (executeStaticStatements(configuration.settings()))
|
||||
return executeStatic();
|
||||
}
|
||||
else {
|
||||
else
|
||||
return executePrepared();
|
||||
}
|
||||
}
|
||||
|
||||
private final int[] executePrepared() {
|
||||
@ -146,22 +140,19 @@ final class BatchCRUD implements Batch {
|
||||
// The order is preserved as much as possible
|
||||
List<Integer> result = new ArrayList<>();
|
||||
for (Entry<String, List<Query>> entry : queries.entrySet()) {
|
||||
BatchBindStep batch = create.batch(entry.getValue().get(0));
|
||||
BatchBindStep batch = dsl.batch(entry.getValue().get(0));
|
||||
|
||||
for (Query query : entry.getValue()) {
|
||||
for (Query query : entry.getValue())
|
||||
batch.bind(query.getBindValues().toArray());
|
||||
}
|
||||
|
||||
int[] array = batch.execute();
|
||||
for (int i : array) {
|
||||
for (int i : array)
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
int[] array = new int[result.size()];
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
for (int i = 0; i < result.size(); i++)
|
||||
array[i] = result.get(i);
|
||||
}
|
||||
|
||||
updateChangedFlag();
|
||||
return array;
|
||||
@ -186,9 +177,8 @@ final class BatchCRUD implements Batch {
|
||||
catch (QueryCollectorSignal e) {
|
||||
Query query = e.getQuery();
|
||||
|
||||
if (query.isExecutable()) {
|
||||
if (query.isExecutable())
|
||||
queries.add(query);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
records[i].attach(previous);
|
||||
@ -196,7 +186,7 @@ final class BatchCRUD implements Batch {
|
||||
}
|
||||
|
||||
// Resulting statements can be batch executed in their requested order
|
||||
int[] result = create.batch(queries).execute();
|
||||
int[] result = dsl.batch(queries).execute();
|
||||
updateChangedFlag();
|
||||
return result;
|
||||
}
|
||||
@ -227,9 +217,8 @@ final class BatchCRUD implements Batch {
|
||||
|
||||
// [#3362] If new records (fetched = false) are batch-stored twice in a row, the second
|
||||
// batch-store needs to generate an UPDATE statement.
|
||||
if (record instanceof AbstractRecord) {
|
||||
if (record instanceof AbstractRecord)
|
||||
((AbstractRecord) record).fetched = action != Action.DELETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,6 @@ package org.jooq.impl;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jooq.Batch;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteListener;
|
||||
@ -51,18 +50,18 @@ import org.jooq.exception.ControlFlowSignal;
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class BatchMultiple implements Batch {
|
||||
final class BatchMultiple extends AbstractBatch {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -7337667281292354043L;
|
||||
|
||||
private final Configuration configuration;
|
||||
private final Query[] queries;
|
||||
|
||||
public BatchMultiple(Configuration configuration, Query... queries) {
|
||||
this.configuration = configuration;
|
||||
super(configuration);
|
||||
|
||||
this.queries = queries;
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,6 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.jooq.BatchBindStep;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteListener;
|
||||
@ -67,7 +66,7 @@ import org.jooq.tools.JooqLogger;
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class BatchSingle implements BatchBindStep {
|
||||
final class BatchSingle extends AbstractBatch implements BatchBindStep {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
@ -75,21 +74,19 @@ final class BatchSingle implements BatchBindStep {
|
||||
private static final long serialVersionUID = 3793967258181493207L;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(BatchSingle.class);
|
||||
|
||||
private final DSLContext create;
|
||||
private final Configuration configuration;
|
||||
private final Query query;
|
||||
private final Map<String, List<Integer>> nameToIndexMapping;
|
||||
private final List<Object[]> allBindValues;
|
||||
private final int expectedBindValues;
|
||||
|
||||
public BatchSingle(Configuration configuration, Query query) {
|
||||
super(configuration);
|
||||
|
||||
int i = 0;
|
||||
|
||||
ParamCollector collector = new ParamCollector(configuration, false);
|
||||
collector.visit(query);
|
||||
|
||||
this.create = DSL.using(configuration);
|
||||
this.configuration = configuration;
|
||||
this.query = query;
|
||||
this.allBindValues = new ArrayList<>();
|
||||
this.nameToIndexMapping = new LinkedHashMap<>();
|
||||
@ -132,7 +129,7 @@ final class BatchSingle implements BatchBindStep {
|
||||
@SafeVarargs
|
||||
|
||||
public final BatchSingle bind(Map<String, Object>... namedBindValues) {
|
||||
List<Object> defaultValues = create.extractBindValues(query);
|
||||
List<Object> defaultValues = dsl.extractBindValues(query);
|
||||
|
||||
Object[][] bindValues = new Object[namedBindValues.length][];
|
||||
for (int row = 0; row < bindValues.length; row++) {
|
||||
@ -210,7 +207,7 @@ final class BatchSingle implements BatchBindStep {
|
||||
|
||||
listener.renderStart(ctx);
|
||||
// [#1520] TODO: Should the number of bind values be checked, here?
|
||||
ctx.sql(create.render(query));
|
||||
ctx.sql(dsl.render(query));
|
||||
listener.renderEnd(ctx);
|
||||
|
||||
listener.prepareStart(ctx);
|
||||
@ -275,9 +272,9 @@ final class BatchSingle implements BatchBindStep {
|
||||
for (int i = 0; i < bindValues.length; i++)
|
||||
query.bind(i + 1, bindValues[i]);
|
||||
|
||||
queries.add(create.query(query.getSQL(INLINED)));
|
||||
queries.add(dsl.query(query.getSQL(INLINED)));
|
||||
}
|
||||
|
||||
return create.batch(queries).execute();
|
||||
return dsl.batch(queries).execute();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user