/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* 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.
*/
package org.seasar.extension.jdbc.query;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import javax.persistence.EntityExistsException;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import junit.framework.TestCase;
import org.seasar.extension.jdbc.JdbcContext;
import org.seasar.extension.jdbc.SqlLogRegistry;
import org.seasar.extension.jdbc.SqlLogRegistryLocator;
import org.seasar.extension.jdbc.dialect.StandardDialect;
import org.seasar.extension.jdbc.exception.QueryTwiceExecutionRuntimeException;
import org.seasar.extension.jdbc.manager.JdbcManagerImpl;
import org.seasar.extension.jdbc.parameter.LobParameter;
import org.seasar.extension.jdbc.parameter.Parameter;
import org.seasar.extension.jdbc.parameter.TemporalParameter;
import org.seasar.extension.jdbc.types.ValueTypes;
import org.seasar.extension.jta.TransactionManagerImpl;
import org.seasar.extension.jta.TransactionSynchronizationRegistryImpl;
import org.seasar.extension.sql.VariableSqlNotAllowedRuntimeException;
import org.seasar.framework.exception.ResourceNotFoundRuntimeException;
import org.seasar.framework.mock.sql.MockDataSource;
import org.seasar.framework.mock.sql.MockPreparedStatement;
import org.seasar.framework.util.tiger.CollectionsUtil;
import static java.util.Arrays.*;
import static org.seasar.extension.jdbc.parameter.Parameter.*;
/**
* @author taedium
*
*/
public class SqlFileBatchUpdateImplTest extends TestCase {
private static final String PATH_SIMPLE = SqlFileBatchUpdateImplTest.class
.getName()
+ "_update_simpleType";
private static final String PATH_DTO = SqlFileBatchUpdateImplTest.class
.getName()
+ "_update_dto";
private static final String PATH_VARIABLE = SqlFileBatchUpdateImplTest.class
.getName()
+ "_update_variable";
private JdbcManagerImpl manager;
private int addedBatch;
private int executedBatch;
private boolean preparedBindVariables;
@Override
protected void setUp() throws Exception {
manager = new JdbcManagerImpl();
manager.setSyncRegistry(new TransactionSynchronizationRegistryImpl(
new TransactionManagerImpl()));
manager.setDataSource(new MockDataSource());
manager.setDialect(new StandardDialect());
}
@Override
protected void tearDown() throws Exception {
SqlLogRegistry regisry = SqlLogRegistryLocator.getInstance();
regisry.clear();
manager = null;
}
/**
*
*/
public void testCallerClass() {
SqlFileBatchUpdateImpl<Object> query = new SqlFileBatchUpdateImpl<Object>(
manager, "aaa.sql", new ArrayList<Object>());
assertSame(query, query.callerClass(getClass()));
assertEquals(getClass(), query.callerClass);
}
/**
*
*/
public void testCallerMethodName() {
SqlFileBatchUpdateImpl<Object> query = new SqlFileBatchUpdateImpl<Object>(
manager, "aaa.sql", new ArrayList<Object>());
assertSame(query, query.callerMethodName("hoge"));
assertEquals("hoge", query.callerMethodName);
}
/**
*
*/
public void testQueryTimeout() {
SqlFileBatchUpdateImpl<Object> query = new SqlFileBatchUpdateImpl<Object>(
manager, "aaa.sql", new ArrayList<Object>());
assertSame(query, query.queryTimeout(100));
assertEquals(100, query.queryTimeout);
}
/**
*
*/
public void testParameterList() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, "aaa.sql", asList("hoge", "hoge2"));
assertEquals(2, query.parameterList.size());
Object param = query.parameterList.get(0);
assertEquals("hoge", param);
param = query.parameterList.get(1);
assertEquals("hoge2", param);
}
/**
*
*/
public void testPrepareNode() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("foo", "bar"));
query.prepareCallerClassAndMethodName("execute");
query.prepareNode();
assertNotNull(query.node);
}
/**
*
*/
public void testPrepareNode_resourceNotFound() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, "xxx", asList("foo", "bar"));
query.prepareCallerClassAndMethodName("execute");
try {
query.prepareNode();
fail();
} catch (ResourceNotFoundRuntimeException e) {
System.out.println(e);
assertEquals("xxx", e.getPath());
}
}
/**
*
*/
public void testPrepareNode_disallowVariableSqlForBatch() {
manager.setAllowVariableSqlForBatchUpdate(false);
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_VARIABLE, asList("foo", "bar"));
query.prepareCallerClassAndMethodName("execute");
try {
query.prepareNode();
fail();
} catch (VariableSqlNotAllowedRuntimeException expected) {
expected.printStackTrace();
}
}
/**
*
*/
public void testExecuteBatch_simpleType() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("foo", "bar")) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
int[] ret = query.execute();
assertEquals(2, ret.length);
assertEquals(2, addedBatch);
assertEquals(1, executedBatch);
assertTrue(preparedBindVariables);
assertEquals("update aaa set name = ? where id = 1", query.sqlContext
.getSql());
SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance();
assertEquals(2, sqlLogRegistry.getSize());
assertEquals("update aaa set name = 'foo' where id = 1", sqlLogRegistry
.get(0).getCompleteSql());
assertEquals("update aaa set name = 'bar' where id = 1", sqlLogRegistry
.get(1).getCompleteSql());
try {
query.execute();
fail();
} catch (QueryTwiceExecutionRuntimeException expected) {
}
}
/**
*
*/
public void testExecuteBatch_simpleType_clob() {
SqlFileBatchUpdateImpl<LobParameter> query = new SqlFileBatchUpdateImpl<LobParameter>(
manager, PATH_SIMPLE, asList(lob("hoge"), lob("foo"))) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(1, getParamSize());
assertEquals(ValueTypes.CLOB, getParam(0).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
* @throws Exception
*/
public void testExecuteBatch_simpleType_date() throws Exception {
Date date = new SimpleDateFormat("HH:mm:dd").parse("12:11:10");
SqlFileBatchUpdateImpl<TemporalParameter> query = new SqlFileBatchUpdateImpl<TemporalParameter>(
manager, PATH_SIMPLE, asList(time(date), time(date))) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(1, getParamSize());
assertEquals(ValueTypes.DATE_TIME, getParam(0).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
*/
public void testExecuteBatch_simpleType_bindNull() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("foo", "bar")) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
try {
query.prepareParameter(null);
fail();
} catch (NullPointerException ignore) {
}
}
/**
*
*/
public void testExecuteBatch_dto() {
MyDto dto = new MyDto();
dto.id = 1;
dto.name = "foo";
MyDto dto2 = new MyDto();
dto2.id = 2;
dto2.name = "bar";
SqlFileBatchUpdateImpl<MyDto> query = new SqlFileBatchUpdateImpl<MyDto>(
manager, PATH_DTO, asList(dto, dto2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
int[] ret = query.execute();
assertEquals(2, ret.length);
assertEquals(1, executedBatch);
assertEquals(2, addedBatch);
assertTrue(preparedBindVariables);
assertEquals("update aaa set name = ? where id = ?", query.sqlContext
.getSql());
SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance();
assertEquals(2, sqlLogRegistry.getSize());
assertEquals("update aaa set name = 'foo' where id = 1", sqlLogRegistry
.get(0).getCompleteSql());
assertEquals("update aaa set name = 'bar' where id = 2", sqlLogRegistry
.get(1).getCompleteSql());
}
/**
*
*/
public void testExecuteBatch_dto_clob() {
MyDto2 dto = new MyDto2();
dto.id = 1;
dto.name = "foo";
MyDto2 dto2 = new MyDto2();
dto2.id = 2;
dto2.name = "bar";
SqlFileBatchUpdateImpl<MyDto2> query = new SqlFileBatchUpdateImpl<MyDto2>(
manager, PATH_DTO, asList(dto, dto2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(2, getParamSize());
assertEquals(ValueTypes.CLOB, getParam(0).valueType);
assertEquals(ValueTypes.INTEGER, getParam(1).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
* @throws Exception
*/
public void testExecuteBatch_dto_date() throws Exception {
Date date = new SimpleDateFormat("HH:mm:dd").parse("12:11:10");
MyDto3 dto = new MyDto3();
dto.id = 1;
dto.name = date;
MyDto3 dto2 = new MyDto3();
dto2.id = 2;
dto2.name = date;
SqlFileBatchUpdateImpl<MyDto3> query = new SqlFileBatchUpdateImpl<MyDto3>(
manager, PATH_DTO, asList(dto, dto2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(2, getParamSize());
assertEquals(ValueTypes.DATE_TIME, getParam(0).valueType);
assertEquals(ValueTypes.INTEGER, getParam(1).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
*/
public void testExecuteBatch_map() {
Map<String, Object> map1 = CollectionsUtil.newHashMap();
map1.put("id", 1);
map1.put("name", "foo");
Map<String, Object> map2 = CollectionsUtil.newHashMap();
map2.put("id", 2);
map2.put("name", "bar");
@SuppressWarnings("unchecked")
SqlFileBatchUpdateImpl<Map<String, Object>> query = new SqlFileBatchUpdateImpl<Map<String, Object>>(
manager, PATH_DTO, asList(map1, map2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
int[] ret = query.execute();
assertEquals(2, ret.length);
assertEquals(1, executedBatch);
assertEquals(2, addedBatch);
assertTrue(preparedBindVariables);
assertEquals("update aaa set name = ? where id = ?", query.sqlContext
.getSql());
SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance();
assertEquals(2, sqlLogRegistry.getSize());
assertEquals("update aaa set name = 'foo' where id = 1", sqlLogRegistry
.get(0).getCompleteSql());
assertEquals("update aaa set name = 'bar' where id = 2", sqlLogRegistry
.get(1).getCompleteSql());
}
/**
*
*/
public void testExecuteBatch_map_clob() {
Map<String, Object> map1 = CollectionsUtil.newHashMap();
map1.put("id", 1);
map1.put("name", Parameter.lob("foo"));
Map<String, Object> map2 = CollectionsUtil.newHashMap();
map2.put("id", 2);
map2.put("name", Parameter.lob("bar"));
@SuppressWarnings("unchecked")
SqlFileBatchUpdateImpl<Map<String, Object>> query = new SqlFileBatchUpdateImpl<Map<String, Object>>(
manager, PATH_DTO, asList(map1, map2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(2, getParamSize());
assertEquals(ValueTypes.CLOB, getParam(0).valueType);
assertEquals(ValueTypes.INTEGER, getParam(1).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
* @throws Exception
*/
public void testExecuteBatch_map_date() throws Exception {
Date date = new SimpleDateFormat("HH:mm:dd").parse("12:11:10");
Map<String, Object> map1 = CollectionsUtil.newHashMap();
map1.put("id", 1);
map1.put("name", Parameter.time(date));
Map<String, Object> map2 = CollectionsUtil.newHashMap();
map2.put("id", 2);
map2.put("name", Parameter.time(date));
@SuppressWarnings("unchecked")
SqlFileBatchUpdateImpl<Map<String, Object>> query = new SqlFileBatchUpdateImpl<Map<String, Object>>(
manager, PATH_DTO, asList(map1, map2)) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
return new int[] { 1, 1 };
}
};
return ps;
}
@Override
protected void resetParams() {
assertEquals(2, getParamSize());
assertEquals(ValueTypes.DATE_TIME, getParam(0).valueType);
assertEquals(ValueTypes.INTEGER, getParam(1).valueType);
super.resetParams();
}
};
query.execute();
}
/**
*
*/
public void testExecuteBatch_entityExists() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("foo", "bar")) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public int[] executeBatch() throws SQLException {
throw new SQLException("hoge", "23");
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
try {
query.execute();
fail();
} catch (EntityExistsException expected) {
expected.printStackTrace();
}
}
/**
*
*/
public void testExecuteBatch_batchSize1() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("foo", "bar", "baz")) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return executedBatch == 1 ? new int[] { 1, 2 }
: new int[] { 3 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
int[] ret = query.batchSize(2).execute();
assertEquals(3, addedBatch);
assertEquals(2, executedBatch);
assertEquals(3, ret.length);
assertEquals(1, ret[0]);
assertEquals(2, ret[1]);
assertEquals(3, ret[2]);
assertTrue(preparedBindVariables);
assertEquals("update aaa set name = ? where id = 1", query.sqlContext
.getSql());
SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance();
assertEquals(3, sqlLogRegistry.getSize());
assertEquals("update aaa set name = 'foo' where id = 1", sqlLogRegistry
.get(0).getCompleteSql());
assertEquals("update aaa set name = 'bar' where id = 1", sqlLogRegistry
.get(1).getCompleteSql());
assertEquals("update aaa set name = 'baz' where id = 1", sqlLogRegistry
.get(2).getCompleteSql());
}
/**
*
*/
public void testExecuteBatch_batchSize2() {
SqlFileBatchUpdateImpl<String> query = new SqlFileBatchUpdateImpl<String>(
manager, PATH_SIMPLE, asList("hoge", "foo", "bar", "baz")) {
@Override
protected PreparedStatement getPreparedStatement(
JdbcContext jdbcContext) {
assertNotNull(executedSql);
MockPreparedStatement ps = new MockPreparedStatement(null, null) {
@Override
public void addBatch() throws SQLException {
++addedBatch;
super.addBatch();
}
@Override
public int[] executeBatch() throws SQLException {
++executedBatch;
return executedBatch == 1 ? new int[] { 1, 2 }
: new int[] { 3, 4 };
}
};
return ps;
}
@Override
protected void prepareInParams(PreparedStatement ps) {
preparedBindVariables = true;
super.prepareInParams(ps);
}
};
int[] ret = query.batchSize(2).execute();
assertEquals(4, addedBatch);
assertEquals(2, executedBatch);
assertEquals(4, ret.length);
assertEquals(1, ret[0]);
assertEquals(2, ret[1]);
assertEquals(3, ret[2]);
assertEquals(4, ret[3]);
assertTrue(preparedBindVariables);
assertEquals("update aaa set name = ? where id = 1", query.sqlContext
.getSql());
SqlLogRegistry sqlLogRegistry = SqlLogRegistryLocator.getInstance();
assertEquals(3, sqlLogRegistry.getSize());
assertEquals("update aaa set name = 'foo' where id = 1", sqlLogRegistry
.get(0).getCompleteSql());
assertEquals("update aaa set name = 'bar' where id = 1", sqlLogRegistry
.get(1).getCompleteSql());
assertEquals("update aaa set name = 'baz' where id = 1", sqlLogRegistry
.get(2).getCompleteSql());
}
private static class MyDto {
/**
*
*/
public Integer id;
/**
*
*/
public String name;
}
private static class MyDto2 {
/**
*
*/
public Integer id;
/**
*
*/
@Lob
public String name;
}
private static class MyDto3 {
/**
*
*/
public Integer id;
/**
*
*/
@Temporal(TemporalType.TIME)
public Date name;
}
}