package jef.orm.onetable;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import jef.common.log.LogUtil;
import jef.database.Condition.Operator;
import jef.database.DbClient;
import jef.database.DbMetaData;
import jef.database.IQueryableEntity;
import jef.database.jdbc.result.ResultSets;
import jef.database.meta.ITableMetadata;
import jef.database.meta.MetaHolder;
import jef.database.meta.TableInfo;
import jef.database.test.DataSource;
import jef.database.test.DataSourceContext;
import jef.database.test.DatabaseInit;
import jef.database.test.JefJUnit4DatabaseTestRunner;
import jef.orm.onetable.model.TestEntity;
import jef.tools.Assert;
import jef.tools.ThreadUtils;
import jef.tools.string.RandomData;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* 自动创建的序列的起始值取值问题(Trac #56111)单元测试类
* <p>
* @see SequenceKeyHolder
*
* @Date 2012-8-28
*/
@RunWith(JefJUnit4DatabaseTestRunner.class)
@DataSourceContext({
// @DataSource(name="oracle",url="${oracle.url}",user="${oracle.user}",password="${oracle.password}"),
// @DataSource(name = "postgresql", url = "${postgresql.url}", user = "${postgresql.user}", password = "${postgresql.password}"),
@DataSource(name = "hsqldb", url = "jdbc:hsqldb:mem:testhsqldb", user = "sa", password = "")
})
public class SequenceCreationTest extends org.junit.Assert{
private DbClient db;
private static String seqName;
@DatabaseInit
public void truncatTable() {
try {
db.dropTable(TestEntity.class);
db.createTable(TestEntity.class);
ThreadUtils.doSleep(500);
} catch (SQLException e) {
LogUtil.exception(e);
}
}
@Test
public void testCase() throws SQLException{
testSequenceStartValueOnEmptyTable();
testSequenceStartValueOnNotEmptyTable();
}
/**
* 测试表中无数据的情况下的起始值,应为1.
*
* @throws SQLException
*/
private void testSequenceStartValueOnEmptyTable() throws SQLException {
Assert.notNull(db);
// 单个插入
TestEntity t1 = RandomData.newInstance(TestEntity.class);
db.insert(t1);
assertEquals(1, t1.getLongField());
db.truncate(TestEntity.class);
}
/**
* 测试表中已有数据的情况下的起始值,应为max+1.
* <p>
* 注:需单独运行。通过{@code SequenceCreationTest} 运行,由于{@code SequenceKeyHolder}
* 被缓存,故序列不会被自动创建。
* </p>
*
* @throws SQLException
*/
private void testSequenceStartValueOnNotEmptyTable() throws SQLException {
insertRecords(3);
dropSequence();
// 批量插入
TestEntity t1 = RandomData.newInstance(TestEntity.class);
TestEntity t2 = RandomData.newInstance(TestEntity.class);
TestEntity t3 = RandomData.newInstance(TestEntity.class);
TestEntity t4 = RandomData.newInstance(TestEntity.class);
db.batchInsert(Arrays.asList(t1,t2,t3,t4));
assertEquals(5, t1.getLongField());
assertEquals(8, t4.getLongField());
}
/**
* 由于调用 DbClient.insert 或 DbClient.startBatchInsert 方法会引起 SequenceKeyHolder
* 缓存, 在insert后drop sequence,sequence不会重建,所以需通过直接JDBC方式插入数据。
*
* @throws SQLException
*/
private void insertRecords(int num) throws SQLException {
for(int i=0;i<num;i++){
TestEntity t= RandomData.newInstance(TestEntity.class);
db.insert(t);
}
}
private void dropSequence() throws SQLException {
seqName = getSeqNameByTable(TestEntity.class);
db.getMetaData(null).dropSequence(seqName);
db.getSequenceManager().clearHolders();
}
// 根据表名称计算SequenceName
public String getSeqNameByTable(Class<? extends IQueryableEntity> table) {
ITableMetadata meta = MetaHolder.getMeta(table);
return meta.getFirstAutoincrementDef().getSequenceName(db.getProfile());
}
}