|
|
|
@ -15,15 +15,8 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package org.springframework.data.jdbc.core.mapping.schema; |
|
|
|
package org.springframework.data.jdbc.core.mapping.schema; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Collection; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.*; |
|
|
|
import static org.assertj.core.api.Assertions.*; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import liquibase.change.Change; |
|
|
|
import liquibase.change.Change; |
|
|
|
import liquibase.change.ColumnConfig; |
|
|
|
import liquibase.change.ColumnConfig; |
|
|
|
import liquibase.change.core.AddForeignKeyConstraintChange; |
|
|
|
import liquibase.change.core.AddForeignKeyConstraintChange; |
|
|
|
@ -31,6 +24,12 @@ import liquibase.change.core.CreateTableChange; |
|
|
|
import liquibase.changelog.ChangeSet; |
|
|
|
import liquibase.changelog.ChangeSet; |
|
|
|
import liquibase.changelog.DatabaseChangeLog; |
|
|
|
import liquibase.changelog.DatabaseChangeLog; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Collection; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import org.assertj.core.groups.Tuple; |
|
|
|
import org.assertj.core.groups.Tuple; |
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
import org.springframework.data.annotation.Id; |
|
|
|
import org.springframework.data.annotation.Id; |
|
|
|
@ -39,12 +38,12 @@ import org.springframework.data.relational.core.mapping.Column; |
|
|
|
import org.springframework.data.relational.core.mapping.MappedCollection; |
|
|
|
import org.springframework.data.relational.core.mapping.MappedCollection; |
|
|
|
import org.springframework.data.relational.core.mapping.RelationalMappingContext; |
|
|
|
import org.springframework.data.relational.core.mapping.RelationalMappingContext; |
|
|
|
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; |
|
|
|
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; |
|
|
|
import org.springframework.data.util.Optionals; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Unit tests for {@link LiquibaseChangeSetWriter}. |
|
|
|
* Unit tests for {@link LiquibaseChangeSetWriter}. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Mark Paluch |
|
|
|
* @author Mark Paluch |
|
|
|
|
|
|
|
* @author Evgenii Koba |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class LiquibaseChangeSetWriterUnitTests { |
|
|
|
class LiquibaseChangeSetWriterUnitTests { |
|
|
|
|
|
|
|
|
|
|
|
@ -117,8 +116,8 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
|
|
|
|
|
|
|
|
Optional<Change> tableWithFk = changeSet.getChanges().stream().filter(change -> { |
|
|
|
Optional<Change> tableWithFk = changeSet.getChanges().stream().filter(change -> { |
|
|
|
return change instanceof CreateTableChange && ((CreateTableChange) change).getTableName() |
|
|
|
return change instanceof CreateTableChange |
|
|
|
.equals("table_with_fk_field"); |
|
|
|
&& ((CreateTableChange) change).getTableName().equals("table_with_fk_field"); |
|
|
|
}).findFirst(); |
|
|
|
}).findFirst(); |
|
|
|
assertThat(tableWithFk.isPresent()).isEqualTo(true); |
|
|
|
assertThat(tableWithFk.isPresent()).isEqualTo(true); |
|
|
|
|
|
|
|
|
|
|
|
@ -136,23 +135,19 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
|
|
|
|
|
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "no_id_table", |
|
|
|
assertCreateTable(changeSet, "no_id_table", Tuple.tuple("field", "VARCHAR(255 BYTE)", null), |
|
|
|
Tuple.tuple("field", "VARCHAR(255 BYTE)", null), |
|
|
|
Tuple.tuple("list_id", "INT", true), Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true), |
|
|
|
Tuple.tuple("list_id", "INT", true), |
|
|
|
|
|
|
|
Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true), |
|
|
|
|
|
|
|
Tuple.tuple("map_of_no_id_tables_key", "VARCHAR(255 BYTE)", true)); |
|
|
|
Tuple.tuple("map_of_no_id_tables_key", "VARCHAR(255 BYTE)", true)); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "map_of_no_id_tables", |
|
|
|
assertCreateTable(changeSet, "map_of_no_id_tables", Tuple.tuple("list_id", "INT", true), |
|
|
|
Tuple.tuple("list_id", "INT", true), |
|
|
|
|
|
|
|
Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true)); |
|
|
|
Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true)); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "list_of_map_of_no_id_tables", Tuple.tuple("id", "INT", true)); |
|
|
|
assertCreateTable(changeSet, "list_of_map_of_no_id_tables", Tuple.tuple("id", "INT", true)); |
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "list_id,list_of_map_of_no_id_tables_key", |
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "list_id,list_of_map_of_no_id_tables_key", "map_of_no_id_tables", |
|
|
|
"map_of_no_id_tables", "list_id,list_of_map_of_no_id_tables_key"); |
|
|
|
"list_id,list_of_map_of_no_id_tables_key"); |
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "map_of_no_id_tables", "list_id", |
|
|
|
assertAddForeignKey(changeSet, "map_of_no_id_tables", "list_id", "list_of_map_of_no_id_tables", "id"); |
|
|
|
"list_of_map_of_no_id_tables", "id"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test // GH-1599
|
|
|
|
@Test // GH-1599
|
|
|
|
@ -165,76 +160,25 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
|
|
|
|
|
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "other_table", |
|
|
|
assertCreateTable(changeSet, "other_table", Tuple.tuple("id", "BIGINT", true), |
|
|
|
Tuple.tuple("id", "BIGINT", true), Tuple.tuple("one_to_one_level1", "INT", null)); |
|
|
|
Tuple.tuple("one_to_one_level1", "INT", null)); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "one_to_one_level2", Tuple.tuple("one_to_one_level1", "INT", true)); |
|
|
|
assertCreateTable(changeSet, "one_to_one_level2", Tuple.tuple("one_to_one_level1", "INT", true)); |
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "no_id_table", Tuple.tuple("field", "VARCHAR(255 BYTE)", null), |
|
|
|
assertCreateTable(changeSet, "no_id_table", Tuple.tuple("field", "VARCHAR(255 BYTE)", null), |
|
|
|
Tuple.tuple("one_to_one_level2", "INT", true), Tuple.tuple("additional_one_to_one_level2", "INT", null)); |
|
|
|
Tuple.tuple("one_to_one_level2", "INT", true), Tuple.tuple("additional_one_to_one_level2", "INT", null)); |
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "other_table", "one_to_one_level1", |
|
|
|
assertAddForeignKey(changeSet, "other_table", "one_to_one_level1", "one_to_one_level1", "id"); |
|
|
|
"one_to_one_level1", "id"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "one_to_one_level2", "one_to_one_level1", |
|
|
|
assertAddForeignKey(changeSet, "one_to_one_level2", "one_to_one_level1", "one_to_one_level1", "id"); |
|
|
|
"one_to_one_level1", "id"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "one_to_one_level2", |
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "one_to_one_level2", "one_to_one_level2", "one_to_one_level1"); |
|
|
|
"one_to_one_level2", "one_to_one_level1"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "additional_one_to_one_level2", |
|
|
|
assertAddForeignKey(changeSet, "no_id_table", "additional_one_to_one_level2", "one_to_one_level2", |
|
|
|
"one_to_one_level2", "one_to_one_level1"); |
|
|
|
"one_to_one_level1"); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test // GH-1599
|
|
|
|
|
|
|
|
void createForeignKeyForCircularWithId() { |
|
|
|
|
|
|
|
RelationalMappingContext context = new RelationalMappingContext() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Collection<RelationalPersistentEntity<?>> getPersistentEntities() { |
|
|
|
|
|
|
|
return List.of(getPersistentEntity(CircularWithId.class), getPersistentEntity(ParentOfCircularWithId.class)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LiquibaseChangeSetWriter writer = new LiquibaseChangeSetWriter(context); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "circular_with_id", |
|
|
|
|
|
|
|
Tuple.tuple("id", "INT", true), |
|
|
|
|
|
|
|
Tuple.tuple("circular_with_id", "INT", null), |
|
|
|
|
|
|
|
Tuple.tuple("parent_of_circular_with_id", "INT", null)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "circular_with_id", "parent_of_circular_with_id", |
|
|
|
|
|
|
|
"parent_of_circular_with_id", "id"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "circular_with_id", "circular_with_id", |
|
|
|
|
|
|
|
"circular_with_id", "id"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test // GH-1599
|
|
|
|
|
|
|
|
void createForeignKeyForCircularNoId() { |
|
|
|
|
|
|
|
RelationalMappingContext context = new RelationalMappingContext() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Collection<RelationalPersistentEntity<?>> getPersistentEntities() { |
|
|
|
|
|
|
|
return List.of(getPersistentEntity(CircularNoId.class), getPersistentEntity(ParentOfCircularNoId.class)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LiquibaseChangeSetWriter writer = new LiquibaseChangeSetWriter(context); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertCreateTable(changeSet, "circular_no_id", |
|
|
|
|
|
|
|
Tuple.tuple("circular_no_id", "INT", true), |
|
|
|
|
|
|
|
Tuple.tuple("parent_of_circular_no_id", "INT", null)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "circular_no_id", "parent_of_circular_no_id", |
|
|
|
|
|
|
|
"parent_of_circular_no_id", "id"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertAddForeignKey(changeSet, "circular_no_id", "circular_no_id", |
|
|
|
|
|
|
|
"circular_no_id", "parent_of_circular_no_id"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void assertCreateTable(ChangeSet changeSet, String tableName, Tuple... columnTuples) { |
|
|
|
void assertCreateTable(ChangeSet changeSet, String tableName, Tuple... columnTuples) { |
|
|
|
Optional<Change> createTableOptional = changeSet.getChanges().stream().filter(change -> { |
|
|
|
Optional<Change> createTableOptional = changeSet.getChanges().stream().filter(change -> { |
|
|
|
@ -247,8 +191,8 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
.containsExactly(columnTuples); |
|
|
|
.containsExactly(columnTuples); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void assertAddForeignKey(ChangeSet changeSet, String baseTableName, String baseColumnNames, String referencedTableName, |
|
|
|
void assertAddForeignKey(ChangeSet changeSet, String baseTableName, String baseColumnNames, |
|
|
|
String referencedColumnNames) { |
|
|
|
String referencedTableName, String referencedColumnNames) { |
|
|
|
Optional<Change> addFkOptional = changeSet.getChanges().stream().filter(change -> { |
|
|
|
Optional<Change> addFkOptional = changeSet.getChanges().stream().filter(change -> { |
|
|
|
return change instanceof AddForeignKeyConstraintChange |
|
|
|
return change instanceof AddForeignKeyConstraintChange |
|
|
|
&& ((AddForeignKeyConstraintChange) change).getBaseTableName().equals(baseTableName) |
|
|
|
&& ((AddForeignKeyConstraintChange) change).getBaseTableName().equals(baseTableName) |
|
|
|
@ -280,22 +224,19 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class Tables { |
|
|
|
static class Tables { |
|
|
|
@Id int id; |
|
|
|
@Id int id; |
|
|
|
@MappedCollection |
|
|
|
@MappedCollection Set<OtherTable> tables; |
|
|
|
Set<OtherTable> tables; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class SetOfTables { |
|
|
|
static class SetOfTables { |
|
|
|
@Id int id; |
|
|
|
@Id int id; |
|
|
|
@MappedCollection(idColumn = "set_id") |
|
|
|
@MappedCollection(idColumn = "set_id") Set<Tables> setOfTables; |
|
|
|
Set<Tables> setOfTables; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class DifferentTables { |
|
|
|
static class DifferentTables { |
|
|
|
@Id int id; |
|
|
|
@Id int id; |
|
|
|
@MappedCollection(idColumn = "tables_id") |
|
|
|
@MappedCollection(idColumn = "tables_id") Set<TableWithFkField> tables; |
|
|
|
Set<TableWithFkField> tables; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@ -311,15 +252,13 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class MapOfNoIdTables { |
|
|
|
static class MapOfNoIdTables { |
|
|
|
@MappedCollection |
|
|
|
@MappedCollection Map<String, NoIdTable> tables; |
|
|
|
Map<String, NoIdTable> tables; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class ListOfMapOfNoIdTables { |
|
|
|
static class ListOfMapOfNoIdTables { |
|
|
|
@Id int id; |
|
|
|
@Id int id; |
|
|
|
@MappedCollection(idColumn = "list_id") |
|
|
|
@MappedCollection(idColumn = "list_id") List<MapOfNoIdTables> listOfTables; |
|
|
|
List<MapOfNoIdTables> listOfTables; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@ -332,33 +271,7 @@ class LiquibaseChangeSetWriterUnitTests { |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
static class OneToOneLevel2 { |
|
|
|
static class OneToOneLevel2 { |
|
|
|
NoIdTable table1; |
|
|
|
NoIdTable table1; |
|
|
|
@Column("additional_one_to_one_level2") |
|
|
|
@Column("additional_one_to_one_level2") NoIdTable table2; |
|
|
|
NoIdTable table2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
|
|
|
|
static class ParentOfCircularWithId { |
|
|
|
|
|
|
|
@Id int id; |
|
|
|
|
|
|
|
CircularWithId circularWithId; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
|
|
|
|
static class CircularWithId { |
|
|
|
|
|
|
|
@Id int id; |
|
|
|
|
|
|
|
CircularWithId circularWithId; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
|
|
|
|
static class ParentOfCircularNoId { |
|
|
|
|
|
|
|
@Id int id; |
|
|
|
|
|
|
|
CircularNoId CircularNoId; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.data.relational.core.mapping.Table |
|
|
|
|
|
|
|
static class CircularNoId { |
|
|
|
|
|
|
|
CircularNoId CircularNoId; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|