Files
ebean/src/test/java/io/ebeaninternal/dbmigration/DbMigrationTest.java
T
Roland PramlandRob Bygrave 41a31c1aa0 trigger based history will recreate view properly and handle default … (#1370)
* trigger based history will recreate view properly and handle default value also for history view

* HistoryTriggers are generated at the end

* Reference Script

* MYSQL: lock all tables at once
2018-05-20 17:19:10 +12:00

217 lines
8.4 KiB
Java

package io.ebeaninternal.dbmigration;
import io.ebean.BaseTestCase;
import io.ebean.SqlQuery;
import io.ebean.SqlRow;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.annotation.IgnorePlatform;
import io.ebean.annotation.Platform;
import io.ebean.migration.ddl.DdlRunner;
import io.ebeaninternal.dbmigration.ddlgeneration.Helper;
import org.junit.Test;
import javax.persistence.PersistenceException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class DbMigrationTest extends BaseTestCase {
private int runScript(boolean expectErrors, String scriptName) throws IOException {
String ddl = Helper.asText(this, "/dbmigration/migrationtest/" + server().getPluginApi().getDatabasePlatform().getName()+"/" + scriptName);
return runScript(expectErrors, ddl, scriptName);
}
private int runScript(boolean expectErrors, String content, String scriptName) {
DdlRunner runner = new DdlRunner(expectErrors, scriptName);
Transaction transaction = server().createTransaction();
Connection connection = transaction.getConnection();
try {
if (expectErrors) {
connection.setAutoCommit(true);
}
int count = runner.runAll(content, connection);
if (expectErrors) {
connection.setAutoCommit(false);
}
transaction.commit();
return count;
} catch (SQLException e) {
throw new PersistenceException("Failed to run script", e);
} finally {
transaction.end();
}
}
@IgnorePlatform(Platform.ORACLE)
@Test
public void testRunMigration() throws IOException {
// first clean up previously created objects
cleanup("migtest_ckey_assoc",
"migtest_ckey_detail",
"migtest_ckey_parent",
"migtest_e_basic",
"migtest_e_history",
"migtest_e_history2",
"migtest_e_history3",
"migtest_e_history4",
"migtest_e_history5",
"migtest_e_history6",
"migtest_e_ref",
"migtest_e_softdelete",
"migtest_e_user",
"migtest_fk_cascade",
"migtest_fk_cascade_one",
"migtest_fk_none",
"migtest_fk_none_via_join",
"migtest_fk_one",
"migtest_fk_set_null",
"migtest_mtm_c",
"migtest_mtm_m",
"migtest_mtm_c_migtest_mtm_m",
"migtest_mtm_m_migtest_mtm_c",
"migtest_oto_child",
"migtest_oto_master");
runScript(false, "1.0__initial.sql");
if (isOracle()) {
SqlUpdate update = server().createSqlUpdate("insert into migtest_e_basic (id, old_boolean, user_id) values (1, :false, 1)");
update.setParameter("false", false);
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_basic (id, old_boolean, user_id) values (2, :true, 1)");
update.setParameter("true", true);
assertThat(server().execute(update)).isEqualTo(1);
} else {
SqlUpdate update = server().createSqlUpdate("insert into migtest_e_basic (id, old_boolean, user_id) values (1, :false, 1), (2, :true, 1)");
update.setParameter("false", false);
update.setParameter("true", true);
assertThat(server().execute(update)).isEqualTo(2);
}
createHistoryEntities();
// Run migration
runScript(false, "1.1.sql");
SqlQuery select = server().createSqlQuery("select * from migtest_e_basic order by id");
List<SqlRow> result = select.findList();
assertThat(result).hasSize(2);
SqlRow row = result.get(0);
assertThat(row.keySet()).contains("old_boolean", "old_boolean2");
assertThat(row.getInteger("id")).isEqualTo(1);
assertThat(row.getBoolean("old_boolean")).isFalse();
assertThat(row.getBoolean("new_boolean_field")).isFalse(); // test if update old_boolean -> new_boolean_field works well
assertThat(row.getString("new_string_field")).isEqualTo("foo'bar");
assertThat(row.getBoolean("new_boolean_field2")).isTrue();
assertThat(row.getTimestamp("some_date")).isEqualTo(new Timestamp(100, 0, 1, 0, 0, 0, 0)); // = 2000-01-01T00:00:00
row = result.get(1);
assertThat(row.getInteger("id")).isEqualTo(2);
assertThat(row.getBoolean("old_boolean")).isTrue();
assertThat(row.getBoolean("new_boolean_field")).isTrue(); // test if update old_boolean -> new_boolean_field works well
assertThat(row.getString("new_string_field")).isEqualTo("foo'bar");
assertThat(row.getBoolean("new_boolean_field2")).isTrue();
assertThat(row.getTimestamp("some_date")).isEqualTo(new Timestamp(100, 0, 1, 0, 0, 0, 0)); // = 2000-01-01T00:00:00
// Run migration & drops
if (isMySql()) {
return; // TODO: mysql cannot drop table (need stored procedure for drop column)
}
runScript(false, "1.2__dropsFor_1.1.sql");
// Oracle caches the statement and does not detect schema change. It fails with
// an ORA-01007
if (isOracle()) {
select = server().createSqlQuery("select * from migtest_e_basic order by id,id");
} else {
select = server().createSqlQuery("select * from migtest_e_basic order by id");
}
result = select.findList();
assertThat(result).hasSize(2);
row = result.get(0);
assertThat(row.keySet()).doesNotContain("old_boolean", "old_boolean2");
runScript(false, "1.3.sql");
runScript(false, "1.4__dropsFor_1.3.sql");
// now DB structure shoud be the same as v1_0
select = server().createSqlQuery("select * from migtest_e_basic order by id");
result = select.findList();
assertThat(result).hasSize(2);
row = result.get(0);
assertThat(row.keySet()).contains("old_boolean", "old_boolean2");
}
/**
*
*/
private void createHistoryEntities() {
SqlUpdate update = server().createSqlUpdate("insert into migtest_e_history (id, test_string) values (1, '42')");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history set test_string = '45' where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_history2 (id, test_string, obsolete_string1, obsolete_string2) values (1, 'foo', 'bar', null)");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history2 set test_string = 'baz' where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_history3 (id, test_string) values (1, '42')");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history3 set test_string = '45' where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_history4 (id, test_number) values (1, 42)");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history4 set test_number = 45 where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_history5 (id, test_number) values (1, 42)");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history5 set test_number = 45 where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("insert into migtest_e_history6 (id, test_number2) values (1, 7)");
assertThat(server().execute(update)).isEqualTo(1);
update = server().createSqlUpdate("update migtest_e_history6 set test_number2 = 45 where id = 1");
assertThat(server().execute(update)).isEqualTo(1);
}
private void cleanup(String ... tables) {
StringBuilder sb = new StringBuilder();
for (String table : tables) {
// simple and stupid try to execute all commands on all dialects.
sb.append("alter table ").append(table).append(" set ( system_versioning = OFF );\n");
sb.append("drop table ").append(table).append(";\n");
sb.append("drop table ").append(table).append(" cascade;\n");
sb.append("drop table ").append(table).append("_history;\n");
sb.append("drop table ").append(table).append("_history cascade;\n");
sb.append("drop view ").append(table).append("_with_history;\n");
sb.append("drop sequence ").append(table).append("_seq;\n");
}
runScript(true, sb.toString(), "cleanup");
runScript(true, sb.toString(), "cleanup");
}
}