#1819 - ENH: For DB Migration support dbMigration.setAddForeignKeySkipCheck(true);

This commit is contained in:
rob bygrave
2019-09-12 20:34:37 +12:00
parent 5d89897bbd
commit 2fb533a606
15 changed files with 97 additions and 20 deletions
@@ -136,6 +136,14 @@ public interface DbMigration {
*/
void setGeneratePendingDrop(String generatePendingDrop);
/**
* Set to true if ALTER TABLE ADD FOREIGN KEY should be generated with an option to skip validation.
* <p>
* Currently this is only useful for Postgres DDL adding the <code>NOT VALID</code> option.
* </p>
*/
void setAddForeignKeySkipCheck(boolean addForeignKeySkipCheck);
/**
* Add an additional platform to write the migration DDL.
* <p>
@@ -198,6 +206,7 @@ public interface DbMigration {
* An "init" migration can only be executed and used on a database that has had no
* prior migrations run on it.
* </p>
*
* @return the version of the generated migration
*/
String generateInitMigration() throws IOException;
@@ -26,6 +26,7 @@ import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
import io.ebean.dbmigration.DbMigration;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.Migration;
import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlWriter;
@@ -106,6 +107,7 @@ public class DefaultDbMigration implements DbMigration {
protected String version;
protected String name;
protected String generatePendingDrop;
private boolean addForeignKeySkipCheck;
protected boolean includeBuiltInPartitioning = true;
@@ -180,6 +182,11 @@ public class DefaultDbMigration implements DbMigration {
this.name = name;
}
@Override
public void setAddForeignKeySkipCheck(boolean addForeignKeySkipCheck) {
this.addForeignKeySkipCheck = addForeignKeySkipCheck;
}
@Override
public void setGeneratePendingDrop(String generatePendingDrop) {
this.generatePendingDrop = generatePendingDrop;
@@ -565,7 +572,8 @@ public class DefaultDbMigration implements DbMigration {
} else if (databasePlatform != null) {
// writer needs the current model to provide table/column details for
// history ddl generation (triggers, history tables etc)
DdlWrite write = new DdlWrite(new MConfiguration(), request.current);
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
DdlWrite write = new DdlWrite(new MConfiguration(), request.current, options);
PlatformDdlWriter writer = createDdlWriter(databasePlatform);
writer.processMigration(dbMigration, write, request.migrationDir, fullVersion);
}
@@ -623,8 +631,9 @@ public class DefaultDbMigration implements DbMigration {
*/
private void writeExtraPlatformDdl(String fullVersion, CurrentModel currentModel, Migration dbMigration, File writePath) throws IOException {
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
for (Pair pair : platforms) {
DdlWrite platformBuffer = new DdlWrite(new MConfiguration(), currentModel.read());
DdlWrite platformBuffer = new DdlWrite(new MConfiguration(), currentModel.read(), options);
PlatformDdlWriter platformWriter = createDdlWriter(pair.platform);
File subPath = platformWriter.subPath(writePath, pair.prefix);
platformWriter.processMigration(dbMigration, platformBuffer, subPath, fullVersion);
@@ -0,0 +1,31 @@
package io.ebeaninternal.dbmigration.ddlgeneration;
/**
* Options used when generated DDL.
*/
public class DdlOptions {
private boolean foreignKeySkipCheck;
public DdlOptions(boolean foreignKeySkipCheck) {
this.foreignKeySkipCheck = foreignKeySkipCheck;
}
public DdlOptions() {
}
/**
* Return true if ADD FOREIGN KEY should use a skip check option.
*/
public boolean isForeignKeySkipCheck() {
return foreignKeySkipCheck;
}
/**
* Set to true if ADD FOREIGN KEY should use a skip check option.
*/
public void setForeignKeySkipCheck(boolean foreignKeySkipCheck) {
this.foreignKeySkipCheck = foreignKeySkipCheck;
}
}
@@ -26,17 +26,19 @@ public class DdlWrite {
private final DdlBuffer dropAll;
private final DdlOptions options;
/**
* Create without any configuration or current model (no history support).
*/
public DdlWrite() {
this(new MConfiguration(), new ModelContainer());
this(new MConfiguration(), new ModelContainer(), new DdlOptions());
}
/**
* Create with a configuration.
*/
public DdlWrite(MConfiguration configuration, ModelContainer currentModel) {
public DdlWrite(MConfiguration configuration, ModelContainer currentModel, DdlOptions options) {
this.currentModel = currentModel;
this.applyDropDependencies = new BaseDdlBuffer(configuration);
this.apply = new BaseDdlBuffer(configuration);
@@ -45,6 +47,14 @@ public class DdlWrite {
this.applyHistoryTrigger = new BaseDdlBuffer(configuration);
this.dropAllForeignKeys = new BaseDdlBuffer(configuration);
this.dropAll = new BaseDdlBuffer(configuration);
this.options = options;
}
/**
* Return the DDL options.
*/
public DdlOptions getOptions() {
return options;
}
/**
@@ -7,6 +7,7 @@ import io.ebean.config.dbplatform.DbHistorySupport;
import io.ebean.config.dbplatform.IdType;
import io.ebean.util.StringHelper;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.ddlgeneration.TableDdl;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.IndexSet;
@@ -31,7 +32,6 @@ import io.ebeaninternal.dbmigration.model.MTable;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -462,7 +462,7 @@ public class BaseTableDdl implements TableDdl {
fkeyBuffer.appendStatement(platformDdl.createIndex(request.indexName(), tableName, request.cols()));
}
alterTableAddForeignKey(fkeyBuffer, request);
alterTableAddForeignKey(write.getOptions(), fkeyBuffer, request);
fkeyBuffer.end();
write.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
@@ -473,9 +473,9 @@ public class BaseTableDdl implements TableDdl {
write.dropAllForeignKeys().end();
}
protected void alterTableAddForeignKey(DdlBuffer buffer, WriteForeignKey request) throws IOException {
protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) throws IOException {
buffer.appendStatement(platformDdl.alterTableAddForeignKey(request));
buffer.appendStatement(platformDdl.alterTableAddForeignKey(options, request));
}
protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException {
@@ -635,7 +635,7 @@ public class BaseTableDdl implements TableDdl {
if (DdlHelp.isDropForeignKey(alterForeignKey.getColumnNames())) {
writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
} else {
writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(new WriteForeignKey(alterForeignKey)));
writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
}
}
@@ -899,7 +899,7 @@ public class BaseTableDdl implements TableDdl {
protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) throws IOException {
alterTableAddForeignKey(writer.apply(), new WriteForeignKey(alterColumn));
alterTableAddForeignKey(writer.getOptions(), writer.apply(), new WriteForeignKey(alterColumn));
}
protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException {
@@ -4,6 +4,7 @@ import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import java.io.IOException;
@@ -40,7 +41,7 @@ public class ClickHouseDdl extends PlatformDdl {
}
@Override
public String alterTableAddForeignKey(WriteForeignKey request) {
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
return null;
}
@@ -11,6 +11,7 @@ import io.ebean.util.StringHelper;
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
@@ -106,6 +107,8 @@ public class PlatformDdl {
protected String dropColumnSuffix = "";
protected String addForeignKeySkipCheck = "";
/**
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
*/
@@ -405,7 +408,7 @@ public class PlatformDdl {
/**
* Add foreign key.
*/
public String alterTableAddForeignKey(WriteForeignKey request) {
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
StringBuilder buffer = new StringBuilder(90);
buffer
@@ -418,6 +421,9 @@ public class PlatformDdl {
.append(lowerTableName(request.refTable()));
appendColumns(request.refCols(), buffer);
appendForeignKeySuffix(request, buffer);
if (options.isForeignKeySkipCheck()) {
buffer.append(addForeignKeySkipCheck);
}
return buffer.toString();
}
@@ -17,6 +17,7 @@ public class PostgresDdl extends PlatformDdl {
this.columnSetType = "type ";
this.alterTableIfExists = "if exists ";
this.columnSetNull = "drop not null";
this.addForeignKeySkipCheck = " not valid";
}
@Override
@@ -2,6 +2,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
/**
* DB2 platform specific DDL.
@@ -25,7 +26,7 @@ public class SQLiteDdl extends PlatformDdl {
}
@Override
public String alterTableAddForeignKey(WriteForeignKey request) {
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
// not supported
return null;
}
@@ -3,6 +3,7 @@ package io.ebeaninternal.dbmigration.model;
import io.ebean.config.DbConstraintNaming;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DefaultConstraintMaxLength;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
@@ -37,6 +38,8 @@ public class CurrentModel {
private DdlWrite write;
private DdlOptions ddlOptions = new DdlOptions();
/**
* Construct with a given EbeanServer instance for DDL create all generation, not migration.
*/
@@ -63,6 +66,10 @@ public class CurrentModel {
this.jaxbPresent = server.getServerConfig().getClassLoadConfig().isJavaxJAXBPresent();
}
public DdlOptions getDdlOptions() {
return ddlOptions;
}
/**
* Return true if the model contains tables that are partitioned.
*/
@@ -183,7 +190,7 @@ public class CurrentModel {
if (write == null) {
ChangeSet createChangeSet = getChangeSet();
write = new DdlWrite(new MConfiguration(), model);
write = new DdlWrite(new MConfiguration(), model, ddlOptions);
DdlHandler handler = handler();
handler.generateProlog(write);