[#3547] DSLContext.batch(String) doesn't accept bind variables

This commit is contained in:
Lukas Eder 2014-08-13 12:47:45 +02:00
parent 00e6fdd2b8
commit 30ae346d14
3 changed files with 41 additions and 18 deletions

View File

@ -150,6 +150,29 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
testBatchAuthors("Gamma", "Helm", "Johnson");
}
public void testBatchSinglePlainSQL() throws Exception {
jOOQAbstractTest.reset = false;
String author = TAuthor().getName();
String id = TAuthor_ID().getName();
String last_name = TAuthor_LAST_NAME().getName();
int[] r1 =
create().batch(String.format("insert into %s (%s, %s) values (?, ?)", author, id, last_name))
.bind(3, "X")
.bind(4, "Y")
.execute();
assertEquals(2, r1.length);
Result<A> authors = create().fetch(TAuthor()).sortAsc(TAuthor_ID());
assertEquals(4, authors.size());
assertEquals(3, (int) authors.get(2).getValue(TAuthor_ID()));
assertEquals(4, (int) authors.get(3).getValue(TAuthor_ID()));
assertEquals("X", authors.get(2).getValue(TAuthor_LAST_NAME()));
assertEquals("Y", authors.get(3).getValue(TAuthor_LAST_NAME()));
}
public void testBatchSingleWithNulls() throws Exception {
Batch batch = create().batch(insertInto(TDates(), TDates_ID(), TDates_D(), TDates_T(), TDates_TS())
.values(1, null, null, null))

View File

@ -2796,6 +2796,11 @@ public abstract class jOOQAbstractTest<
new BatchTests(this).testBatchSingle();
}
@Test
public void testBatchSinglePlainSQL() throws Exception {
new BatchTests(this).testBatchSinglePlainSQL();
}
@Test
public void testBatchSingleWithNulls() throws Exception {
new BatchTests(this).testBatchSingleWithNulls();

View File

@ -43,6 +43,8 @@ package org.jooq.impl;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.conf.SettingsTools.executeStaticStatements;
import static org.jooq.impl.Utils.consumeWarnings;
import static org.jooq.impl.Utils.fields;
import static org.jooq.impl.Utils.getDataTypes;
import static org.jooq.impl.Utils.visitAll;
import java.sql.Connection;
@ -53,9 +55,10 @@ import java.util.List;
import org.jooq.BatchBindStep;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.DataType;
import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener;
import org.jooq.Param;
import org.jooq.Field;
import org.jooq.Query;
/**
@ -119,12 +122,7 @@ class BatchSingle implements BatchBindStep {
Connection connection = ctx.connection();
// [#1371] fetch bind variables to restore them again, later
List<Param<?>> params = new ArrayList<Param<?>>(query.getParams().values());
List<Object> previous = new ArrayList<Object>();
for (Param<?> param : params) {
previous.add(param.getValue());
}
DataType<?>[] paramTypes = getDataTypes(query.getParams().values().toArray(new Field[0]));
try {
listener.renderStart(ctx);
@ -139,12 +137,14 @@ class BatchSingle implements BatchBindStep {
for (Object[] bindValues : allBindValues) {
listener.bindStart(ctx);
// [#1371] [#2139] Don't bind variables directly onto statement,
// bind them through the collected params list to preserve type
// information
for (int i = 0; i < params.size(); i++) {
params.get(i).setConverted(bindValues[i]);
}
// [#1371] [#2139] Don't bind variables directly onto statement, bind them through the collected params
// list to preserve type information
// [#3547] The original query may have no Params specified - e.g. when it was constructed with
// plain SQL. In that case, infer the bind value type directly from the bind value
List<Field<?>> params = (paramTypes.length > 0)
? fields(bindValues, paramTypes)
: fields(bindValues);
visitAll(new DefaultBindContext(configuration, ctx.statement()), params);
listener.bindEnd(ctx);
@ -178,11 +178,6 @@ class BatchSingle implements BatchBindStep {
}
finally {
Utils.safeClose(listener, ctx);
// Restore bind variables to values prior to batch execution
for (int i = 0; i < params.size(); i++) {
params.get(i).setConverted(previous.get(i));
}
}
}