From 3e581a9e4af51f10cb439ebca3e9df0ec2de664d Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Sun, 27 Nov 2022 07:58:29 +0100 Subject: [PATCH] create primary keys on directly on table creation instead of a seperate operation --- .../jef/model/migration/MigrationBuilder.java | 4 +- .../operation/AddTableOperation.java | 7 +++- ...101000000_MigrationsLogTableMigration.java | 2 +- .../base/migration/MigrationApplierTest.java | 6 +-- .../creator/MigrationBuilderGenerator.java | 11 +++++- .../migration/creator/MigrationCreator.java | 15 ++++++- .../MigrationCreatorAddEntityTest.java | 21 ++++------ .../MigrationCreatorInitialMigrationTest.java | 39 ++++++------------- .../MysqlMigrationOperationTranslator.java | 5 ++- 9 files changed, 56 insertions(+), 54 deletions(-) diff --git a/core/src/main/java/jef/model/migration/MigrationBuilder.java b/core/src/main/java/jef/model/migration/MigrationBuilder.java index 4253621..73430fc 100644 --- a/core/src/main/java/jef/model/migration/MigrationBuilder.java +++ b/core/src/main/java/jef/model/migration/MigrationBuilder.java @@ -24,8 +24,8 @@ import java.util.List; public class MigrationBuilder { private final List> operations = new ArrayList<>(); - public AddTableOperation.Builder addTable(String table, List fields) { - var op = new AddTableOperation.Builder(table, fields); + public AddTableOperation.Builder addTable(String table, List fields, AddPrimaryKeyOperation.Builder primaryKey) { + var op = new AddTableOperation.Builder(table, fields, primaryKey); operations.add(op); return op; } diff --git a/core/src/main/java/jef/model/migration/operation/AddTableOperation.java b/core/src/main/java/jef/model/migration/operation/AddTableOperation.java index 8c84c00..d67f590 100644 --- a/core/src/main/java/jef/model/migration/operation/AddTableOperation.java +++ b/core/src/main/java/jef/model/migration/operation/AddTableOperation.java @@ -14,20 +14,23 @@ import java.util.List; public class AddTableOperation implements MigrationOperation { private final String table; private final List fields; + private final AddPrimaryKeyOperation.Builder primaryKey; @EqualsAndHashCode @ToString public static class Builder implements MigrationOperation.Builder { private final String table; private final List fields; + private final AddPrimaryKeyOperation.Builder primaryKey; - public Builder(String table, List fields) { + public Builder(String table, List fields, AddPrimaryKeyOperation.Builder primaryKey) { this.table = table; this.fields = fields; + this.primaryKey = primaryKey; } public AddTableOperation build() { - return new AddTableOperation(table, fields); + return new AddTableOperation(table, fields, primaryKey); } } } diff --git a/core/src/main/java/jef/platform/base/migration/M00010101000000_MigrationsLogTableMigration.java b/core/src/main/java/jef/platform/base/migration/M00010101000000_MigrationsLogTableMigration.java index 5efbca5..ba25860 100644 --- a/core/src/main/java/jef/platform/base/migration/M00010101000000_MigrationsLogTableMigration.java +++ b/core/src/main/java/jef/platform/base/migration/M00010101000000_MigrationsLogTableMigration.java @@ -20,7 +20,7 @@ public class M00010101000000_MigrationsLogTableMigration implements Migration { migrationBuilder.addTable(tableName, List.of( 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()) - )); + ), null); migrationBuilder.addUniqueKey("U_" + tableName + "_migration", tableName, List.of("migration")); } diff --git a/core/src/test/java/jef/platform/base/migration/MigrationApplierTest.java b/core/src/test/java/jef/platform/base/migration/MigrationApplierTest.java index 30c0ac8..d2d35a2 100644 --- a/core/src/test/java/jef/platform/base/migration/MigrationApplierTest.java +++ b/core/src/test/java/jef/platform/base/migration/MigrationApplierTest.java @@ -179,7 +179,7 @@ class MigrationApplierTest { var operationBuilder = new MigrationOperation.Builder[]{null}; var operation = new MigrationOperation[]{null}; 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(); return null; }).when(migration).up(any(MigrationBuilder.class)); @@ -207,7 +207,7 @@ class MigrationApplierTest { var operationBuilder = new MigrationOperation.Builder[]{null}; var operation = new MigrationOperation[]{null}; 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(); return null; }).when(migration).up(any(MigrationBuilder.class)); @@ -238,7 +238,7 @@ class MigrationApplierTest { var operationBuilder = new MigrationOperation.Builder[]{null}; var operation = new MigrationOperation[]{null}; 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(); return null; }).when(migration).up(any(MigrationBuilder.class)); diff --git a/migration-creator/src/main/java/jef/model/migration/creator/MigrationBuilderGenerator.java b/migration-creator/src/main/java/jef/model/migration/creator/MigrationBuilderGenerator.java index b28f463..94e8b4b 100644 --- a/migration-creator/src/main/java/jef/model/migration/creator/MigrationBuilderGenerator.java +++ b/migration-creator/src/main/java/jef/model/migration/creator/MigrationBuilderGenerator.java @@ -152,11 +152,18 @@ public class MigrationBuilderGenerator { private String addTableOp(AddTableOperation op) { imports.add(List.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" + op.getFields().stream() /**/.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") + "));"; } diff --git a/migration-creator/src/main/java/jef/model/migration/creator/MigrationCreator.java b/migration-creator/src/main/java/jef/model/migration/creator/MigrationCreator.java index 3e6664a..9692679 100644 --- a/migration-creator/src/main/java/jef/model/migration/creator/MigrationCreator.java +++ b/migration-creator/src/main/java/jef/model/migration/creator/MigrationCreator.java @@ -146,7 +146,10 @@ public class MigrationCreator { .map(e -> new AddFieldOperation.Builder(toEntity.getName(), e.getName()) .notNull(e.isNotNull()) .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 involvedForeignKeys = originalEntity.getPrimaryKey() != null && 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( originalEntity.getPrimaryKey().getName(), originalEntity.getPrimaryKey().getEntity().getName(), @@ -347,6 +352,12 @@ public class MigrationCreator { private void addPrimaryKeyDropGeneration(ModelBuilder fromReduced, ModelBuilder toReduced, ModelBuilder from, ModelBuilder to, List> steps) { 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); Check.notNull(originalEntity, "originalEntity"); //may never be null var involvedFields = fromEntity.getFields(); diff --git a/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java b/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java index 41adcb0..5128b24 100644 --- a/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java +++ b/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java @@ -46,19 +46,17 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase { } private void validateUp(MigrationCreator.Result res) { - assertEquals(3, res.getStepsUp().size()); + assertEquals(2, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddTableOperation o && o.getTable().equals("AddedEntity") && 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("addedField")).count() == 1) - .count()); - assertEquals(1, res.getStepsUp().stream() - .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("AddedEntity") - && o.getFields().size() == 1 - && o.getFields().get(0).equals("id")) + && o.getFields().stream().filter(f -> f.build().getField().equals("addedField")).count() == 1 + && o.getPrimaryKey() != null + && o.getPrimaryKey().build().getTable().equals("AddedEntity") + && o.getPrimaryKey().build().getFields().size() == 1 + && o.getPrimaryKey().build().getFields().get(0).equals("id")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddForeignKeyOperation o @@ -72,17 +70,12 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase { } private void validateDown(MigrationCreator.Result res) { - assertEquals(3, res.getStepsDown().size()); + assertEquals(2, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o && o.getTable().equals("AddedEntity") && o.getName().equals("FK_AddedEntity_AddedEntity_addedField")) .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() .filter(e -> e instanceof DropTableOperation o && o.getTable().equals("AddedEntity")) diff --git a/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java b/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java index 8ed4ea5..6c8415e 100644 --- a/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java +++ b/migration-creator/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java @@ -6,7 +6,6 @@ import jef.model.ModelBuilder; import jef.model.annotations.Clazz; import jef.model.annotations.Id; import jef.model.migration.operation.AddForeignKeyOperation; -import jef.model.migration.operation.AddPrimaryKeyOperation; import jef.model.migration.operation.AddTableOperation; import jef.model.migration.operation.DropConstraintOperation; import jef.model.migration.operation.DropTableOperation; @@ -39,12 +38,16 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa } private void validateUp(MigrationCreator.Result res) { - assertEquals(5, res.getStepsUp().size()); + assertEquals(3, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddTableOperation o && o.getTable().equals("objects1") && 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()); assertEquals(1, res.getStepsUp().stream() .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("l")).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) - .count()); - assertEquals(1, res.getStepsUp().stream() - .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("objects1") - && 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")) + && o.getFields().stream().filter(f -> f.build().getField().equals("nestedI")).count() == 1 + && o.getPrimaryKey() != null + && o.getPrimaryKey().build().getTable().equals("TestClass") + && o.getPrimaryKey().build().getFields().size() == 1 + && o.getPrimaryKey().build().getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddForeignKeyOperation o @@ -81,22 +76,12 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa } private void validateDown(MigrationCreator.Result res) { - assertEquals(5, res.getStepsDown().size()); + assertEquals(3, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o && o.getTable().equals("TestClass") && o.getName().equals("FK_TestClass_objects1_nestedI")) .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() .filter(e -> e instanceof DropTableOperation o diff --git a/mysql/src/main/java/jef/platform/mysql/migration/MysqlMigrationOperationTranslator.java b/mysql/src/main/java/jef/platform/mysql/migration/MysqlMigrationOperationTranslator.java index 3671cb3..efe28fd 100644 --- a/mysql/src/main/java/jef/platform/mysql/migration/MysqlMigrationOperationTranslator.java +++ b/mysql/src/main/java/jef/platform/mysql/migration/MysqlMigrationOperationTranslator.java @@ -102,7 +102,10 @@ public class MysqlMigrationOperationTranslator implements MigrationOperationTran var f = e.build(); return "`" + f.getField() + "` " + f.getSqlType() + (f.isNotNull() ? " NOT NULL" : ""); }).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 {