Playing around with SqlUpdate and bind expansion for ?1 etc

This commit is contained in:
rob bygrave
2019-02-04 14:24:47 +13:00
parent a02673359d
commit 37a66f1ee2
2 changed files with 131 additions and 3 deletions
@@ -9,6 +9,7 @@ import io.ebeaninternal.api.SpiSqlUpdate;
import io.ebeaninternal.api.SpiTransaction;
import java.io.Serializable;
import java.util.Collection;
/**
* A SQL Update Delete or Insert statement that can be executed. For the times
@@ -66,6 +67,8 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
*/
private int addPos;
private int bindExpansion;
private boolean getGeneratedKeys;
private Object generatedKey;
@@ -253,21 +256,46 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
return this;
}
private SqlUpdate setParamWithBindExpansion(int position, Collection values, String bindLiteral) {
StringBuilder sqlExpand = new StringBuilder(values.size() * 2);
int offset = 0;
for (Object val : values) {
if (offset > 0) {
sqlExpand.append(",");
}
sqlExpand.append("?");
bindParams.setParameter(position + offset++, val);
}
bindExpansion += offset;
generatedSql = generatedSql.replace(bindLiteral, sqlExpand.toString());
return this;
}
@Override
public SqlUpdate setParameter(int position, Object value) {
bindParams.setParameter(position, value);
if (value instanceof Collection) {
String bindLiteral = "?" + position;
int pos = sql.indexOf(bindLiteral);
if (pos > -1) {
return setParamWithBindExpansion(position, (Collection) value, bindLiteral);
}
}
bindParams.setParameter(bindExpansion + position, value);
return this;
}
@Override
public SqlUpdate setNull(int position, int jdbcType) {
bindParams.setNullParameter(position, jdbcType);
bindParams.setNullParameter(bindExpansion + position, jdbcType);
return this;
}
@Override
public SqlUpdate setNullParameter(int position, int jdbcType) {
bindParams.setNullParameter(position, jdbcType);
bindParams.setNullParameter(bindExpansion + position, jdbcType);
return this;
}
@@ -1,8 +1,10 @@
package org.tests.update;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.Ebean;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import org.junit.Test;
import static java.util.Arrays.asList;
@@ -26,6 +28,104 @@ public class TestSqlUpdateBindMultipleLists extends BaseTestCase {
}
@Test
public void positionParamsExpansion() {
SqlUpdate sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id in (?1)");
sqlUpdate.setParameter(1, asList(9991, 9992, 9993));
sqlUpdate.execute();
assertEquals("delete from o_customer where id in (?,?,?)", sqlUpdate.getGeneratedSql());
sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id in (?1)");
sqlUpdate.setParameter(1, asList(9991, 9993));
sqlUpdate.execute();
assertEquals("delete from o_customer where id in (?,?)", sqlUpdate.getGeneratedSql());
sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id in (?1)");
sqlUpdate.setParameter(1, asList(9993));
sqlUpdate.execute();
assertEquals("delete from o_customer where id in (?)", sqlUpdate.getGeneratedSql());
}
@Test
public void positionParamsExpansion_withPrePost() {
SqlUpdate sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id > ? and id in (?2) and id < ?");
sqlUpdate.setParameter(1, 90);
sqlUpdate.setParameter(2, asList(9991, 9992, 9993));
sqlUpdate.setParameter(3, 91);
sqlUpdate.execute();
assertEquals("delete from o_customer where id > ? and id in (?,?,?) and id < ?", sqlUpdate.getGeneratedSql());
}
@Test
public void positionParamsExpansion_withPrePost_usingParam() {
SqlUpdate sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id > ? and id in (?2) and id < ?");
sqlUpdate.setParams(90, asList(9991, 9992, 9993), 91);
sqlUpdate.execute();
assertEquals("delete from o_customer where id > ? and id in (?,?,?) and id < ?", sqlUpdate.getGeneratedSql());
}
@Test
public void positionParamsExpansion_withPre() {
SqlUpdate sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where name = ? and id in (?2)");
sqlUpdate.setParameter(1, "Foo");
sqlUpdate.setParameter(2, asList(9991, 9992, 9993));
sqlUpdate.execute();
assertEquals("delete from o_customer where name = ? and id in (?,?,?)", sqlUpdate.getGeneratedSql());
}
@Test
public void positionParamsExpansion_withPost() {
SqlUpdate sqlUpdate = Ebean.createSqlUpdate("delete from o_customer where id in (?1) and name = ?");
sqlUpdate.setParameter(1, asList(9991, 9992, 9993));
sqlUpdate.setParameter(2, "Foo");
sqlUpdate.execute();
assertEquals("delete from o_customer where id in (?,?,?) and name = ?", sqlUpdate.getGeneratedSql());
}
@Test
public void positionParamsExpansion_withPost_andBatch() {
SqlUpdate upd = Ebean.createSqlUpdate("delete from o_customer where id in (:ids) and name = :name");
try (Transaction transaction = DB.beginTransaction()) {
transaction.setBatchMode(true);
upd.setParameter("ids", asList(9991, 9992, 9993));
upd.setParameter("name", "Foo");
upd.execute();
upd.setParameter("ids", asList(9991, 9992));
upd.setParameter("name", "Bar");
upd.execute();
upd.setParameter("ids", asList(9991, 9992, 9999));
upd.setParameter("name", "Baz");
upd.execute();
transaction.commit();
}
}
@Test
public void test_multipleLists() {