DB migration initial

This commit is contained in:
Robin Bygrave
2015-08-04 17:37:16 +12:00
parent 30c3a435d6
commit 3bd281bea0
93 changed files with 8350 additions and 34 deletions
@@ -0,0 +1,131 @@
package com.avaje.ebean.dbmigration.ddlgeneration;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.config.dbplatform.DbTypeMap;
import com.avaje.ebean.config.dbplatform.H2Platform;
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.DdlNamingConvention;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.H2Ddl;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl;
import com.avaje.ebean.dbmigration.migration.ChangeSet;
import com.avaje.ebean.dbmigration.model.CurrentModel;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class BaseDdlHandlerTest extends BaseTestCase {
private BaseDdlHandler h2Handler() {
DbTypeMap types = new H2Platform().getDbTypeMap();
return new BaseDdlHandler(new DdlNamingConvention(), new H2Ddl(types));
}
private BaseDdlHandler postgresHandler() {
DbTypeMap pgTypes = new PostgresPlatform().getDbTypeMap();
PostgresDdl pgDdl = new PostgresDdl(pgTypes);
return new BaseDdlHandler(new DdlNamingConvention(), pgDdl);
}
@Test
public void addColumn_nullable_noConstraint() throws Exception {
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = h2Handler();
handler.generate(write, Helper.getAddColumn());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column added_to_foo varchar(20);\n\n");
assertThat(write.rollback().getBuffer()).isEqualTo("alter table foo drop column added_to_foo;\n\n");
}
@Test
public void dropColumn() throws Exception {
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = h2Handler();
handler.generate(write, Helper.getDropColumn());
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo drop column col2;\n\n");
assertThat(write.rollback().getBuffer()).isEqualTo("");
}
@Test
public void createTable() throws Exception {
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = h2Handler();
handler.generate(write, Helper.getCreateTable());
String createTableDDL = Helper.asText(this, "/assert/create-table.txt");
assertThat(write.apply().getBuffer()).isEqualTo(createTableDDL);
assertThat(write.rollback().getBuffer()).isEqualTo("drop table foo;\n\n");
}
@Test
public void generateChangeSet() throws Exception {
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = h2Handler();
handler.generate(write, Helper.getChangeSet());
String apply = Helper.asText(this, "/assert/BaseDdlHandlerTest/apply.sql");
String rollbackLast = Helper.asText(this, "/assert/BaseDdlHandlerTest/rollback.sql");
assertThat(write.apply().getBuffer()).isEqualTo(apply);
assertThat(write.rollback().getBuffer()).isEqualTo(rollbackLast);
}
@Test
public void generateChangeSetFromModel() throws Exception {
SpiEbeanServer defaultServer = (SpiEbeanServer) Ebean.getDefaultServer();
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = h2Handler();
handler.generate(write, createChangeSet);
String apply = Helper.asText(this, "/assert/changeset-apply.txt");
String rollbackLast = Helper.asText(this, "/assert/changeset-rollback.txt");
assertThat(write.apply().getBuffer()).isEqualTo(apply);
assertThat(write.rollback().getBuffer()).isEqualTo(rollbackLast);
}
@Test
public void generateChangeSetFromModel_given_postgresTypes() throws Exception {
SpiEbeanServer defaultServer = (SpiEbeanServer) Ebean.getDefaultServer();
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
DdlWrite write = new DdlWrite();
BaseDdlHandler handler = postgresHandler();
handler.generate(write, createChangeSet);
String apply = Helper.asText(this, "/assert/changeset-pg-apply.sql");
String applyLast = Helper.asText(this, "/assert/changeset-pg-applyLast.sql");
String rollbackFirst = Helper.asText(this, "/assert/changeset-pg-rollbackFirst.sql");
String rollbackLast = Helper.asText(this, "/assert/changeset-pg-rollbackLast.sql");
assertThat(write.apply().getBuffer()).isEqualTo(apply);
assertThat(write.applyForeignKeys().getBuffer()).isEqualTo(applyLast);
assertThat(write.rollbackForeignKeys().getBuffer()).isEqualTo(rollbackFirst);
assertThat(write.rollback().getBuffer()).isEqualTo(rollbackLast);
}
}
@@ -0,0 +1,76 @@
package com.avaje.ebean.dbmigration.ddlgeneration;
import com.avaje.ebean.dbmigration.migration.AddColumn;
import com.avaje.ebean.dbmigration.migration.ChangeSet;
import com.avaje.ebean.dbmigration.migration.CreateTable;
import com.avaje.ebean.dbmigration.migration.DropColumn;
import com.avaje.ebean.dbmigration.migration.Migration;
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.List;
/**
* Helper for testing to return some basic migration objects.
*/
public class Helper {
static Migration migration = MigrationXmlReader.read("/container/test-create-table.xml");
static ChangeSet changeSet;
static List<Object> changeSetChildren;
static {
List<ChangeSet> changeSets = migration.getChangeSet();
changeSet = changeSets.get(0);
changeSetChildren = changeSet.getChangeSetChildren();
}
public static ChangeSet getChangeSet() {
return changeSet;
}
public static CreateTable getCreateTable() {
return (CreateTable) changeSetChildren.get(0);
}
public static AddColumn getAddColumn() {
return (AddColumn) changeSetChildren.get(1);
}
public static DropColumn getDropColumn() {
return (DropColumn) changeSetChildren.get(2);
}
public static String asText(Object instance, String relativePath) throws IOException {
InputStream is = instance.getClass().getResourceAsStream(relativePath);
if (is == null) {
throw new IllegalArgumentException("resource "+relativePath+" not found");
}
return asText(is);
}
public static String asText(InputStream in) throws IOException {
try {
InputStreamReader reader = new InputStreamReader(in);
LineNumberReader lineNumberReader = new LineNumberReader(reader);
StringBuilder builder = new StringBuilder(400);
String line;
while ((line = lineNumberReader.readLine()) != null) {
builder.append(line).append("\n");
}
return builder.toString();
} finally {
in.close();
}
}
}
@@ -0,0 +1,70 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
import com.avaje.ebean.config.dbplatform.DbTypeMap;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlWrite;
import com.avaje.ebean.dbmigration.ddlgeneration.Helper;
import com.avaje.ebean.dbmigration.migration.Column;
import com.avaje.ebean.dbmigration.migration.CreateTable;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class BaseTableDdlTest {
@Test
public void testGenerate() throws Exception {
BaseTableDdl ddlGen = new BaseTableDdl(new DdlNamingConvention(), new H2Ddl(new DbTypeMap()));
DdlWrite write = new DdlWrite();
ddlGen.generate(write, createTable());
String apply = write.apply().getBuffer();
String applyLast = write.applyForeignKeys().getBuffer();
String rollbackFirst = write.rollbackForeignKeys().getBuffer();
String rollbackLast = write.rollback().getBuffer();
assertThat(apply).isEqualTo( Helper.asText(this, "/assert/BaseTableDdlTest/createTable-apply.txt"));
assertThat(applyLast).isEqualTo( Helper.asText(this, "/assert/BaseTableDdlTest/createTable-applyLast.txt"));
assertThat(rollbackFirst).isEqualTo( Helper.asText(this, "/assert/BaseTableDdlTest/createTable-rollbackFirst.txt"));
assertThat(rollbackLast).isEqualTo( Helper.asText(this, "/assert/BaseTableDdlTest/createTable-rollback.txt"));
}
private CreateTable createTable() {
CreateTable createTable = new CreateTable();
createTable.setName("mytable");
List<Column> columns = createTable.getColumn();
Column col = new Column();
col.setName("id");
col.setType("integer");
col.setPrimaryKey(true);
columns.add(col);
Column col2 = new Column();
col2.setName("status");
col2.setType("varchar(1)");
col2.setNotnull(true);
col2.setCheckConstraint("check (status in ('A','B'))");
columns.add(col2);
Column col3 = new Column();
col3.setName("order_id");
col3.setType("integer");
col3.setNotnull(true);
col3.setReferences("orders.id");
columns.add(col3);
return createTable;
}
}
@@ -0,0 +1,29 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
import org.junit.Test;
import static org.assertj.core.api.StrictAssertions.assertThat;
public class DbNameNormaliseTest {
DbNameNormalise normalise = new DbNameNormalise();
@Test
public void testNormalise() throws Exception {
assertThat(normalise.normalise("cat.sch.foo_bar]")).isEqualTo("foo_bar");
assertThat(normalise.normalise("sch.foo_bar]")).isEqualTo("foo_bar");
assertThat(normalise.normalise("foo_bar]")).isEqualTo("foo_bar");
}
@Test
public void testTrimQuotes() throws Exception {
assertThat(normalise.trimQuotes("[foo]")).isEqualTo("foo");
assertThat(normalise.trimQuotes("'foo'")).isEqualTo("foo");
assertThat(normalise.trimQuotes("\"foo\"")).isEqualTo("foo");
assertThat(normalise.trimQuotes("`foo`")).isEqualTo("foo");
assertThat(normalise.trimQuotes("`fo_o`")).isEqualTo("fo_o");
}
}
@@ -0,0 +1,43 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class DdlNamingConventionTest {
DdlNamingConvention defaultNaming = new DdlNamingConvention();
@Test
public void testPrimaryKeyName() throws Exception {
List<String> cols = new ArrayList<String>();
cols.add("[jim]");
cols.add("`jack`");
assertThat(defaultNaming.primaryKeyName("[cat].[sce].[foo_bar]", cols)).isEqualTo("pk_foo_bar");
}
@Test
public void testUniqueConstraintName() throws Exception {
assertThat(defaultNaming.uniqueConstraintName("[foo_bar]", "[jim]")).isEqualTo("uq_foo_bar_jim");
}
@Test
public void testCheckConstraintName() throws Exception {
assertThat(defaultNaming.checkConstraintName("[foo_bar]", "[jim]")).isEqualTo("ck_foo_bar_jim");
}
@Test
public void testNormalise() throws Exception {
assertThat(defaultNaming.normalise("cat.sch.foo_bar]")).isEqualTo("foo_bar");
assertThat(defaultNaming.normalise("sch.foo_bar]")).isEqualTo("foo_bar");
assertThat(defaultNaming.normalise("foo_bar]")).isEqualTo("foo_bar");
}
}
@@ -0,0 +1,80 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform;
import com.avaje.ebean.config.dbplatform.DbTypeMap;
import com.avaje.ebean.config.dbplatform.H2Platform;
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class PlatformTypeConverterTest {
@Test
public void testConvert_given_postgres() throws Exception {
PostgresPlatform pg = new PostgresPlatform();
DbTypeMap dbTypeMap = pg.getDbTypeMap();
PlatformTypeConverter converter = new PlatformTypeConverter(dbTypeMap);
assertThat(converter.convert("varchar(10)")).isEqualTo("varchar(10)");
assertThat(converter.convert("decimal(10,2)")).isEqualTo("decimal(10,2)");
assertThat(converter.convert("clob")).isEqualTo("text");
assertThat(converter.convert("blob")).isEqualTo("bytea");
assertThat(converter.convert("tinyint")).isEqualTo("smallint");
assertThat(converter.convert("funky")).isEqualTo("funky"); // unknown
assertThat(converter.convert("integer(8)")).isEqualTo("integer"); // removes scale
assertThat(converter.convert("funky(")).isEqualTo("funky(");
assertThat(converter.convert("funky()")).isEqualTo("funky()");
assertThat(converter.convert("funky)")).isEqualTo("funky)");
}
@Test
public void testConvert_given_h2() throws Exception {
H2Platform platform = new H2Platform();
DbTypeMap dbTypeMap = platform.getDbTypeMap();
PlatformTypeConverter converter = new PlatformTypeConverter(dbTypeMap);
assertThat(converter.convert("varchar(10)")).isEqualTo("varchar(10)");
assertThat(converter.convert("decimal(10,2)")).isEqualTo("decimal(10,2)");
assertThat(converter.convert("clob")).isEqualTo("clob");
assertThat(converter.convert("blob")).isEqualTo("blob");
assertThat(converter.convert("tinyint")).isEqualTo("tinyint");
assertThat(converter.convert("integer(8)")).isEqualTo("integer(8)");
assertThat(converter.convert("funky")).isEqualTo("funky"); // unknown
}
@Test
public void testConvertJsonTypes_given_postgres() {
PostgresPlatform platform = new PostgresPlatform();
DbTypeMap dbTypeMap = platform.getDbTypeMap();
PlatformTypeConverter converter = new PlatformTypeConverter(dbTypeMap);
assertThat(converter.convert("jsonblob")).isEqualTo("bytea");
assertThat(converter.convert("jsonclob")).isEqualTo("text");
assertThat(converter.convert("jsonvarchar(200)")).isEqualTo("varchar(200)");
assertThat(converter.convert("json")).isEqualTo("json");
assertThat(converter.convert("jsonb")).isEqualTo("jsonb");
}
@Test
public void testConvertJsonTypes_given_h2() {
H2Platform platform = new H2Platform();
DbTypeMap dbTypeMap = platform.getDbTypeMap();
PlatformTypeConverter converter = new PlatformTypeConverter(dbTypeMap);
assertThat(converter.convert("jsonblob")).isEqualTo("blob");
assertThat(converter.convert("jsonclob")).isEqualTo("clob");
assertThat(converter.convert("jsonvarchar(200)")).isEqualTo("varchar(200)");
assertThat(converter.convert("json")).isEqualTo("clob");
assertThat(converter.convert("jsonb")).isEqualTo("clob");
}
}
@@ -0,0 +1,26 @@
package com.avaje.ebean.dbmigration.migrationreader;
import com.avaje.ebean.dbmigration.migration.Migration;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
public class MigrationXmlWriterTest {
Logger logger = LoggerFactory.getLogger(MigrationXmlWriterTest.class);
@Test
public void testWrite() throws Exception {
Migration migration = MigrationXmlReader.read("/test/container/test-create-table.xml");
File temp = File.createTempFile("migrationWrite",".xml");
MigrationXmlWriter writer = new MigrationXmlWriter();
writer.write(migration, temp);
logger.info("wrote migration file: "+temp.getAbsolutePath());
}
}
@@ -0,0 +1,41 @@
package com.avaje.ebean.dbmigration.model;
import com.avaje.ebean.dbmigration.migration.AddColumn;
import com.avaje.ebean.dbmigration.migration.ChangeSet;
import com.avaje.ebean.dbmigration.migration.CreateTable;
import com.avaje.ebean.dbmigration.migration.DropColumn;
import com.avaje.ebean.dbmigration.migration.Migration;
import com.avaje.ebean.dbmigration.migrationreader.MigrationXmlReader;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelContainerApplyTest {
@Test
public void testApply() throws Exception {
Migration migration = MigrationXmlReader.read("/test/container/test-create-table.xml");
List<ChangeSet> changeSets = migration.getChangeSet();
ChangeSet changeSet = changeSets.get(0);
List<Object> changeSetChildren = changeSet.getChangeSetChildren();
assertThat(changeSetChildren).hasSize(3);
assertThat(changeSetChildren.get(0)).isInstanceOf(CreateTable.class);
assertThat(changeSetChildren.get(1)).isInstanceOf(AddColumn.class);
assertThat(changeSetChildren.get(2)).isInstanceOf(DropColumn.class);
ModelContainer model = new ModelContainer();
model.apply(migration);
MTable foo = model.getTable("foo");
assertThat(foo.getRemarks()).isEqualTo("comment");
assertThat(foo.getTablespace()).isEqualTo("fooSpace");
assertThat(foo.getIndexTablespace()).isEqualTo("fooIndexSpace");
assertThat(foo.getWithHistory()).isEqualTo(true);
assertThat(foo.getColumns()).containsKeys("col1", "col3", "added_to_foo");
}
}
@@ -0,0 +1,33 @@
package com.avaje.ebean.dbmigration.model.build;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebean.dbmigration.model.MTable;
import com.avaje.ebean.dbmigration.model.ModelContainer;
import com.avaje.ebean.dbmigration.model.visitor.VisitAllUsing;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelBuildBeanVisitorTest extends BaseTestCase {
@Test
public void test() {
SpiEbeanServer defaultServer = (SpiEbeanServer)Ebean.getDefaultServer();
ModelContainer model = new ModelContainer();
ModelBuildContext ctx = new ModelBuildContext(model);
ModelBuildBeanVisitor addTable = new ModelBuildBeanVisitor(ctx);
new VisitAllUsing(addTable, defaultServer).visitAllBeans();
MTable customer = model.getTable("o_customer");
assertThat(customer).isNotNull();
}
}
@@ -0,0 +1,51 @@
package com.avaje.ebean.dbmigration.model.build;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.dbmigration.model.CurrentModel;
import com.avaje.ebean.dbmigration.model.MTable;
import com.avaje.ebean.dbmigration.model.ModelContainer;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.tests.model.basic.CKeyAssoc;
import com.avaje.tests.model.basic.CKeyDetail;
import com.avaje.tests.model.basic.CKeyParent;
import com.avaje.tests.model.basic.CKeyParentId;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ModelBuild_compoundKeyTest extends BaseTestCase {
@Test
public void test() {
ServerConfig config = new ServerConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("h2other");
config.setDdlGenerate(false);
config.setDdlRun(false);
config.setDefaultServer(false);
config.setRegister(false);
config.addClass(CKeyDetail.class);
config.addClass(CKeyParent.class);
config.addClass(CKeyAssoc.class);
config.addClass(CKeyParentId.class);
SpiEbeanServer ebeanServer = (SpiEbeanServer)EbeanServerFactory.create(config);
CurrentModel currentModel = new CurrentModel(ebeanServer);
ModelContainer model = currentModel.read();
MTable parent = model.getTable("ckey_parent");
MTable detail = model.getTable("ckey_detail");
assertThat(parent).isNotNull();
assertThat(detail).isNotNull();
}
}
@@ -4,7 +4,7 @@ import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class CKeyAssoc {
public class CKeyAssoc {
@Id
Integer id;