create primary keys on directly on table creation instead of a seperate operation
This commit is contained in:
@@ -24,8 +24,8 @@ import java.util.List;
|
|||||||
public class MigrationBuilder {
|
public class MigrationBuilder {
|
||||||
private final List<MigrationOperation.Builder<?>> operations = new ArrayList<>();
|
private final List<MigrationOperation.Builder<?>> operations = new ArrayList<>();
|
||||||
|
|
||||||
public AddTableOperation.Builder addTable(String table, List<AddFieldOperation.Builder> fields) {
|
public AddTableOperation.Builder addTable(String table, List<AddFieldOperation.Builder> fields, AddPrimaryKeyOperation.Builder primaryKey) {
|
||||||
var op = new AddTableOperation.Builder(table, fields);
|
var op = new AddTableOperation.Builder(table, fields, primaryKey);
|
||||||
operations.add(op);
|
operations.add(op);
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,20 +14,23 @@ import java.util.List;
|
|||||||
public class AddTableOperation implements MigrationOperation {
|
public class AddTableOperation implements MigrationOperation {
|
||||||
private final String table;
|
private final String table;
|
||||||
private final List<AddFieldOperation.Builder> fields;
|
private final List<AddFieldOperation.Builder> fields;
|
||||||
|
private final AddPrimaryKeyOperation.Builder primaryKey;
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
public static class Builder implements MigrationOperation.Builder<AddTableOperation> {
|
public static class Builder implements MigrationOperation.Builder<AddTableOperation> {
|
||||||
private final String table;
|
private final String table;
|
||||||
private final List<AddFieldOperation.Builder> fields;
|
private final List<AddFieldOperation.Builder> fields;
|
||||||
|
private final AddPrimaryKeyOperation.Builder primaryKey;
|
||||||
|
|
||||||
public Builder(String table, List<AddFieldOperation.Builder> fields) {
|
public Builder(String table, List<AddFieldOperation.Builder> fields, AddPrimaryKeyOperation.Builder primaryKey) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
|
this.primaryKey = primaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddTableOperation build() {
|
public AddTableOperation build() {
|
||||||
return new AddTableOperation(table, fields);
|
return new AddTableOperation(table, fields, primaryKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class M00010101000000_MigrationsLogTableMigration implements Migration {
|
|||||||
migrationBuilder.addTable(tableName, List.of(
|
migrationBuilder.addTable(tableName, List.of(
|
||||||
new AddFieldOperation.Builder(tableName, "migration").notNull(true).sqlType(typeMapper.map(String.class.getName()).orElseThrow()),
|
new AddFieldOperation.Builder(tableName, "migration").notNull(true).sqlType(typeMapper.map(String.class.getName()).orElseThrow()),
|
||||||
new AddFieldOperation.Builder(tableName, "version").notNull(true).sqlType(typeMapper.map(String.class.getName()).orElseThrow())
|
new AddFieldOperation.Builder(tableName, "version").notNull(true).sqlType(typeMapper.map(String.class.getName()).orElseThrow())
|
||||||
));
|
), null);
|
||||||
migrationBuilder.addUniqueKey("U_" + tableName + "_migration", tableName, List.of("migration"));
|
migrationBuilder.addUniqueKey("U_" + tableName + "_migration", tableName, List.of("migration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ class MigrationApplierTest {
|
|||||||
var operationBuilder = new MigrationOperation.Builder[]{null};
|
var operationBuilder = new MigrationOperation.Builder[]{null};
|
||||||
var operation = new MigrationOperation[]{null};
|
var operation = new MigrationOperation[]{null};
|
||||||
doAnswer(invok -> {
|
doAnswer(invok -> {
|
||||||
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of());
|
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of(), null);
|
||||||
operation[0] = operationBuilder[0].build();
|
operation[0] = operationBuilder[0].build();
|
||||||
return null;
|
return null;
|
||||||
}).when(migration).up(any(MigrationBuilder.class));
|
}).when(migration).up(any(MigrationBuilder.class));
|
||||||
@@ -207,7 +207,7 @@ class MigrationApplierTest {
|
|||||||
var operationBuilder = new MigrationOperation.Builder[]{null};
|
var operationBuilder = new MigrationOperation.Builder[]{null};
|
||||||
var operation = new MigrationOperation[]{null};
|
var operation = new MigrationOperation[]{null};
|
||||||
doAnswer(invok -> {
|
doAnswer(invok -> {
|
||||||
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of());
|
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of(), null);
|
||||||
operation[0] = operationBuilder[0].build();
|
operation[0] = operationBuilder[0].build();
|
||||||
return null;
|
return null;
|
||||||
}).when(migration).up(any(MigrationBuilder.class));
|
}).when(migration).up(any(MigrationBuilder.class));
|
||||||
@@ -238,7 +238,7 @@ class MigrationApplierTest {
|
|||||||
var operationBuilder = new MigrationOperation.Builder[]{null};
|
var operationBuilder = new MigrationOperation.Builder[]{null};
|
||||||
var operation = new MigrationOperation[]{null};
|
var operation = new MigrationOperation[]{null};
|
||||||
doAnswer(invok -> {
|
doAnswer(invok -> {
|
||||||
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of());
|
operationBuilder[0] = ((MigrationBuilder) invok.getArguments()[0]).addTable("test", List.of(), null);
|
||||||
operation[0] = operationBuilder[0].build();
|
operation[0] = operationBuilder[0].build();
|
||||||
return null;
|
return null;
|
||||||
}).when(migration).up(any(MigrationBuilder.class));
|
}).when(migration).up(any(MigrationBuilder.class));
|
||||||
|
|||||||
@@ -152,11 +152,18 @@ public class MigrationBuilderGenerator {
|
|||||||
private String addTableOp(AddTableOperation op) {
|
private String addTableOp(AddTableOperation op) {
|
||||||
imports.add(List.class);
|
imports.add(List.class);
|
||||||
imports.add(AddFieldOperation.class);
|
imports.add(AddFieldOperation.class);
|
||||||
imports.add(AddFieldOperation.Builder.class);
|
if (op.getPrimaryKey() != null) {
|
||||||
|
imports.add(AddPrimaryKeyOperation.class);
|
||||||
|
}
|
||||||
return "mb.addTable(\"" + op.getTable() + "\", List.of(\n"
|
return "mb.addTable(\"" + op.getTable() + "\", List.of(\n"
|
||||||
+ op.getFields().stream()
|
+ op.getFields().stream()
|
||||||
/**/.map(f -> " new AddFieldOperation.Builder(\"" + op.getTable() + "\", \"" + f.build().getField() + "\")" + addFieldOpOptional(f.build()).replace("\n", "\n "))
|
/**/.map(f -> " new AddFieldOperation.Builder(\"" + op.getTable() + "\", \"" + f.build().getField() + "\")" + addFieldOpOptional(f.build()).replace("\n", "\n "))
|
||||||
/**/.collect(Collectors.joining(",\n")) + "\n"
|
/**/.collect(Collectors.joining(",\n")) + "),\n"
|
||||||
|
+ (op.getPrimaryKey() != null
|
||||||
|
? " new AddPrimaryKeyOperation.Builder(\"" + op.getPrimaryKey().build().getName() + "\", \"" + op.getPrimaryKey().build().getTable() + "\", List.of("
|
||||||
|
+ op.getPrimaryKey().build().getFields().stream().map(e -> "\"" + e + "\"").collect(Collectors.joining(", "))
|
||||||
|
+ ")"
|
||||||
|
: " null")
|
||||||
+ "));";
|
+ "));";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,10 @@ public class MigrationCreator {
|
|||||||
.map(e -> new AddFieldOperation.Builder(toEntity.getName(), e.getName())
|
.map(e -> new AddFieldOperation.Builder(toEntity.getName(), e.getName())
|
||||||
.notNull(e.isNotNull())
|
.notNull(e.isNotNull())
|
||||||
.sqlType(getSqlType(e)))
|
.sqlType(getSqlType(e)))
|
||||||
.toList()
|
.toList(),
|
||||||
|
Optional.ofNullable(toEntity.getPrimaryKey())
|
||||||
|
.map(e -> new AddPrimaryKeyOperation.Builder(e.getName(), toEntity.getName(), e.getFields().stream().map(DbField::getName).toList()))
|
||||||
|
.orElse(null)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,7 +268,9 @@ public class MigrationCreator {
|
|||||||
var involvedFields = toEntity.getFields();
|
var involvedFields = toEntity.getFields();
|
||||||
var involvedForeignKeys = originalEntity.getPrimaryKey() != null
|
var involvedForeignKeys = originalEntity.getPrimaryKey() != null
|
||||||
&& originalEntity.getPrimaryKey().getFields().stream().anyMatch(involvedFields::contains);
|
&& originalEntity.getPrimaryKey().getFields().stream().anyMatch(involvedFields::contains);
|
||||||
if (involvedForeignKeys) {
|
var alreadyCreatedDuringTableCreation = steps.stream().anyMatch(e -> e instanceof AddTableOperation.Builder ato
|
||||||
|
&& ato.build().getTable().equals(originalEntity.getPrimaryKey().getEntity().getName()));
|
||||||
|
if (involvedForeignKeys && !alreadyCreatedDuringTableCreation) {
|
||||||
steps.add(new AddPrimaryKeyOperation.Builder(
|
steps.add(new AddPrimaryKeyOperation.Builder(
|
||||||
originalEntity.getPrimaryKey().getName(),
|
originalEntity.getPrimaryKey().getName(),
|
||||||
originalEntity.getPrimaryKey().getEntity().getName(),
|
originalEntity.getPrimaryKey().getEntity().getName(),
|
||||||
@@ -347,6 +352,12 @@ public class MigrationCreator {
|
|||||||
|
|
||||||
private void addPrimaryKeyDropGeneration(ModelBuilder fromReduced, ModelBuilder toReduced, ModelBuilder from, ModelBuilder to, List<MigrationOperation.Builder<?>> steps) {
|
private void addPrimaryKeyDropGeneration(ModelBuilder fromReduced, ModelBuilder toReduced, ModelBuilder from, ModelBuilder to, List<MigrationOperation.Builder<?>> steps) {
|
||||||
for (var fromEntity : fromReduced.getEntities()) {
|
for (var fromEntity : fromReduced.getEntities()) {
|
||||||
|
var toEntity = toReduced.getEntity(fromEntity.getTypeName());
|
||||||
|
if (toEntity == null) {
|
||||||
|
//table will be dropped -> no need to drop the primary key separately
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var originalEntity = from.getEntities().stream().filter(e -> e.getName().equals(fromEntity.getName())).findFirst().orElse(null);
|
var originalEntity = from.getEntities().stream().filter(e -> e.getName().equals(fromEntity.getName())).findFirst().orElse(null);
|
||||||
Check.notNull(originalEntity, "originalEntity"); //may never be null
|
Check.notNull(originalEntity, "originalEntity"); //may never be null
|
||||||
var involvedFields = fromEntity.getFields();
|
var involvedFields = fromEntity.getFields();
|
||||||
|
|||||||
@@ -46,19 +46,17 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateUp(MigrationCreator.Result res) {
|
private void validateUp(MigrationCreator.Result res) {
|
||||||
assertEquals(3, res.getStepsUp().size());
|
assertEquals(2, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddTableOperation o
|
.filter(e -> e instanceof AddTableOperation o
|
||||||
&& o.getTable().equals("AddedEntity")
|
&& o.getTable().equals("AddedEntity")
|
||||||
&& o.getFields().size() == 2
|
&& o.getFields().size() == 2
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("id")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("id")).count() == 1
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("addedField")).count() == 1)
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("addedField")).count() == 1
|
||||||
.count());
|
&& o.getPrimaryKey() != null
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
&& o.getPrimaryKey().build().getTable().equals("AddedEntity")
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
&& o.getPrimaryKey().build().getFields().size() == 1
|
||||||
&& o.getTable().equals("AddedEntity")
|
&& o.getPrimaryKey().build().getFields().get(0).equals("id"))
|
||||||
&& o.getFields().size() == 1
|
|
||||||
&& o.getFields().get(0).equals("id"))
|
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
@@ -72,17 +70,12 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateDown(MigrationCreator.Result res) {
|
private void validateDown(MigrationCreator.Result res) {
|
||||||
assertEquals(3, res.getStepsDown().size());
|
assertEquals(2, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("AddedEntity")
|
&& o.getTable().equals("AddedEntity")
|
||||||
&& o.getName().equals("FK_AddedEntity_AddedEntity_addedField"))
|
&& o.getName().equals("FK_AddedEntity_AddedEntity_addedField"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
|
||||||
&& o.getTable().equals("AddedEntity")
|
|
||||||
&& o.getName().equals("PRIMARY"))
|
|
||||||
.count());
|
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropTableOperation o
|
.filter(e -> e instanceof DropTableOperation o
|
||||||
&& o.getTable().equals("AddedEntity"))
|
&& o.getTable().equals("AddedEntity"))
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import jef.model.ModelBuilder;
|
|||||||
import jef.model.annotations.Clazz;
|
import jef.model.annotations.Clazz;
|
||||||
import jef.model.annotations.Id;
|
import jef.model.annotations.Id;
|
||||||
import jef.model.migration.operation.AddForeignKeyOperation;
|
import jef.model.migration.operation.AddForeignKeyOperation;
|
||||||
import jef.model.migration.operation.AddPrimaryKeyOperation;
|
|
||||||
import jef.model.migration.operation.AddTableOperation;
|
import jef.model.migration.operation.AddTableOperation;
|
||||||
import jef.model.migration.operation.DropConstraintOperation;
|
import jef.model.migration.operation.DropConstraintOperation;
|
||||||
import jef.model.migration.operation.DropTableOperation;
|
import jef.model.migration.operation.DropTableOperation;
|
||||||
@@ -39,12 +38,16 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateUp(MigrationCreator.Result res) {
|
private void validateUp(MigrationCreator.Result res) {
|
||||||
assertEquals(5, res.getStepsUp().size());
|
assertEquals(3, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddTableOperation o
|
.filter(e -> e instanceof AddTableOperation o
|
||||||
&& o.getTable().equals("objects1")
|
&& o.getTable().equals("objects1")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).build().getField().equals("i"))
|
&& o.getFields().get(0).build().getField().equals("i")
|
||||||
|
&& o.getPrimaryKey() != null
|
||||||
|
&& o.getPrimaryKey().build().getTable().equals("objects1")
|
||||||
|
&& o.getPrimaryKey().build().getFields().size() == 1
|
||||||
|
&& o.getPrimaryKey().build().getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddTableOperation o
|
.filter(e -> e instanceof AddTableOperation o
|
||||||
@@ -55,19 +58,11 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("i")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("i")).count() == 1
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("l")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("l")).count() == 1
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("o")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("o")).count() == 1
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("nestedI")).count() == 1)
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("nestedI")).count() == 1
|
||||||
.count());
|
&& o.getPrimaryKey() != null
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
&& o.getPrimaryKey().build().getTable().equals("TestClass")
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
&& o.getPrimaryKey().build().getFields().size() == 1
|
||||||
&& o.getTable().equals("objects1")
|
&& o.getPrimaryKey().build().getFields().get(0).equals("i"))
|
||||||
&& o.getFields().size() == 1
|
|
||||||
&& o.getFields().get(0).equals("i"))
|
|
||||||
.count());
|
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
|
||||||
&& o.getTable().equals("TestClass")
|
|
||||||
&& o.getFields().size() == 1
|
|
||||||
&& o.getFields().get(0).equals("i"))
|
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
@@ -81,22 +76,12 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateDown(MigrationCreator.Result res) {
|
private void validateDown(MigrationCreator.Result res) {
|
||||||
assertEquals(5, res.getStepsDown().size());
|
assertEquals(3, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("TestClass")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_TestClass_objects1_nestedI"))
|
&& o.getName().equals("FK_TestClass_objects1_nestedI"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
|
||||||
&& o.getTable().equals("TestClass")
|
|
||||||
&& o.getName().equals("PRIMARY"))
|
|
||||||
.count());
|
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
|
||||||
&& o.getTable().equals("objects1")
|
|
||||||
&& o.getName().equals("PRIMARY"))
|
|
||||||
.count());
|
|
||||||
|
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropTableOperation o
|
.filter(e -> e instanceof DropTableOperation o
|
||||||
|
|||||||
@@ -102,7 +102,10 @@ public class MysqlMigrationOperationTranslator implements MigrationOperationTran
|
|||||||
var f = e.build();
|
var f = e.build();
|
||||||
return "`" + f.getField() + "` " + f.getSqlType() + (f.isNotNull() ? " NOT NULL" : "");
|
return "`" + f.getField() + "` " + f.getSqlType() + (f.isNotNull() ? " NOT NULL" : "");
|
||||||
}).collect(Collectors.joining(", "))
|
}).collect(Collectors.joining(", "))
|
||||||
+ ")"); //TODO default collocation from database config or operation, field collation, primary key, constraints
|
+ (op.getPrimaryKey() != null
|
||||||
|
? ", PRIMARY KEY (" + op.getPrimaryKey().build().getFields().stream().map(e -> "`" + e + "`").collect(Collectors.joining(", ")) + ")"
|
||||||
|
: "")
|
||||||
|
+ ")"); //TODO default collocation from database config or operation, field collation, constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PreparedStatement translateAddUniqueKeyOperation(Connection connection, MigrationOperation operation) throws SQLException {
|
private static PreparedStatement translateAddUniqueKeyOperation(Connection connection, MigrationOperation operation) throws SQLException {
|
||||||
|
|||||||
Reference in New Issue
Block a user