diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java index 540e17850a535b8776daf4a6a7bf53a5499f1838..d69ea86e683faf960e7dd0b64ab01b10144c44c3 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SchemaServiceIntegrationTest.java @@ -194,6 +194,7 @@ public class SchemaServiceIntegrationTest extends AbstractUnitTest { assertEquals(1, uniques.size()); final UniqueDto unique0 = uniques.get(0); assertNotNull(unique0.getTable()); + assertEquals("some_constraint", unique0.getName()); assertNull(unique0.getTable().getId()); assertEquals(TABLE_1_INTERNALNAME, unique0.getTable().getName()); assertEquals(TABLE_1_INTERNALNAME, unique0.getTable().getInternalName()); diff --git a/dbrepo-data-service/rest-service/src/test/resources/init/weather.sql b/dbrepo-data-service/rest-service/src/test/resources/init/weather.sql index 7c3ca99ce39f61755752d2ecbb607ad6ed86e386..10cbf855655b57d02b4ed561d0c3cf50f0272dc4 100644 --- a/dbrepo-data-service/rest-service/src/test/resources/init/weather.sql +++ b/dbrepo-data-service/rest-service/src/test/resources/init/weather.sql @@ -17,7 +17,7 @@ CREATE TABLE weather_aus mintemp DOUBLE PRECISION NULL, rainfall DOUBLE PRECISION NULL, FOREIGN KEY (location) REFERENCES weather_location (location) ON DELETE SET NULL, - UNIQUE (`date`), + CONSTRAINT some_constraint UNIQUE (`date`), CHECK (`mintemp` > 0) ) WITH SYSTEM VERSIONING COMMENT 'Weather in Australia'; diff --git a/dbrepo-metadata-db/1_setup-schema.sql b/dbrepo-metadata-db/1_setup-schema.sql index 47ee3a95e2b88a62d4a2405f9c0f4d088167d748..9f0f2775cbd235973c1c44d773fa3efe79da5728 100644 --- a/dbrepo-metadata-db/1_setup-schema.sql +++ b/dbrepo-metadata-db/1_setup-schema.sql @@ -176,8 +176,9 @@ CREATE TABLE IF NOT EXISTS `mdb_columns` std_dev Numeric NULL, created timestamp NOT NULL DEFAULT NOW(), last_modified timestamp, + PRIMARY KEY (ID), FOREIGN KEY (tID) REFERENCES mdb_tables (ID) ON DELETE CASCADE, - PRIMARY KEY (ID) + UNIQUE (tID, internal_name) ) WITH SYSTEM VERSIONING; CREATE TABLE IF NOT EXISTS `mdb_columns_enums` diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java index c869e41637659675e317281fd55092e3b331fc6b..dd59e210033886535cbf6b708175b47dbc0f8341 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java @@ -24,7 +24,7 @@ import java.util.List; @EqualsAndHashCode(onlyExplicitlyIncluded = true) @EntityListeners(AuditingEntityListener.class) @jakarta.persistence.Table(name = "mdb_columns", uniqueConstraints = { - @UniqueConstraint(columnNames = {"tid", "internalName"}) + @UniqueConstraint(columnNames = {"tID", "internal_name"}) }) @NamedQueries({ @NamedQuery(name = "TableColumn.findAllByDatabaseId", query = "select c from TableColumn c where c.table.database.id = ?1"), @@ -56,7 +56,7 @@ public class TableColumn implements Comparable<TableColumn> { @Column(name = "auto_generated", columnDefinition = "BOOLEAN default false") private Boolean autoGenerated; - @Column(nullable = false, columnDefinition = "VARCHAR(64)") + @Column(name = "internal_name", nullable = false, columnDefinition = "VARCHAR(64)") private String internalName; @Column(columnDefinition = "VARCHAR(2048)") diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnConcept.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnConcept.java index 080abf87cd022f98f3414087d7b24fe94c0cebd7..e53e69f49808946cff5907f8057bde8923afd9b7 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnConcept.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnConcept.java @@ -50,7 +50,8 @@ public class TableColumnConcept { private Instant created; @ToString.Exclude - @OneToMany(fetch = FetchType.LAZY) + @org.springframework.data.annotation.Transient + @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinTable(name = "mdb_columns_concepts", inverseJoinColumns = { @JoinColumn(name = "cid", referencedColumnName = "id", insertable = false, updatable = false) diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnUnit.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnUnit.java index 21822c5da764886ef9c675d410cd6d74bbaaf4d2..df3950785e4d8a35ef4f8021bfe3a4c34540fbb2 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnUnit.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumnUnit.java @@ -49,7 +49,8 @@ public class TableColumnUnit { private Instant created; @ToString.Exclude - @OneToMany(fetch = FetchType.LAZY) + @org.springframework.data.annotation.Transient + @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinTable(name = "mdb_columns_units", inverseJoinColumns = { @JoinColumn(name = "cid", referencedColumnName = "id", insertable = false, updatable = false) diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/foreignKey/ForeignKeyReference.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/foreignKey/ForeignKeyReference.java index c63cdd22e6e4ade249ffc41c1305e1d8e7e0c44d..c5f3570099dd5bd12ec641f07e6d2a9f8963b1ce 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/foreignKey/ForeignKeyReference.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/foreignKey/ForeignKeyReference.java @@ -32,12 +32,14 @@ public class ForeignKeyReference { @JoinColumn(name = "fkid", referencedColumnName = "fkid", nullable = false) private ForeignKey foreignKey; + @org.springframework.data.annotation.Transient @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinColumns({ @JoinColumn(name = "cid", referencedColumnName = "id", nullable = false) }) private TableColumn column; + @org.springframework.data.annotation.Transient @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinColumns({ @JoinColumn(name = "rcid", referencedColumnName = "id", nullable = false) diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/primaryKey/PrimaryKey.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/primaryKey/PrimaryKey.java index c4ccc379c58d88df8bc2ccc0429bd969d0e5c031..aaa1e5fc8f9102c97294d1f9e53624c5fa3b8e45 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/primaryKey/PrimaryKey.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/primaryKey/PrimaryKey.java @@ -27,7 +27,7 @@ public class PrimaryKey { @ToString.Exclude @org.springframework.data.annotation.Transient - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinColumns({ @JoinColumn(name = "tid", referencedColumnName = "id", nullable = false) }) @@ -35,7 +35,7 @@ public class PrimaryKey { @ToString.Exclude @org.springframework.data.annotation.Transient - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinColumns({ @JoinColumn(name = "cid", referencedColumnName = "id", nullable = false) }) diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/unique/Unique.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/unique/Unique.java index 25ed2eae5d551896b6836cb6bd5c8bdd36724748..c49fc48eb67b6d5ed3689086a1fba4c75e7a1b6c 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/unique/Unique.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/constraints/unique/Unique.java @@ -33,13 +33,14 @@ public class Unique { @ToString.Exclude @org.springframework.data.annotation.Transient - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinColumns({ @JoinColumn(name = "tid", referencedColumnName = "id") }) private Table table; - @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @org.springframework.data.annotation.Transient + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}) @JoinTable( name = "mdb_constraints_unique_columns", joinColumns = { diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java index a9b04058e2373f6cb98f8f9cbedb11ba980fdcfc..f6c96f133d31e59bd72214133d5f707d8fdf0468 100644 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java @@ -555,7 +555,6 @@ public interface MetadataMapper { ref.getColumn().setDatabaseId(table.getTdbid()); ref.getReferencedColumn().setTableId(fk.getReferencedTable().getId()); ref.getReferencedColumn().setDatabaseId(table.getTdbid()); - log.trace("mapped foreign key part ({}) reference ({})", ref.getColumn().getInternalName(), ref.getReferencedColumn().getInternalName()); }); }); table.getConstraints() diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java index 1c91de7be10e544cfe9b9e5ce71c3af5c3f89e88..0a962f7d6edfe899365534a084a1faa265c6d864 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java @@ -11,9 +11,11 @@ import at.tuwien.entities.container.Container; import at.tuwien.entities.database.*; import at.tuwien.entities.database.table.Table; import at.tuwien.entities.database.table.columns.TableColumn; +import at.tuwien.entities.database.table.constraints.Constraints; import at.tuwien.entities.database.table.constraints.foreignKey.ForeignKey; import at.tuwien.entities.database.table.constraints.foreignKey.ForeignKeyReference; import at.tuwien.entities.database.table.constraints.primaryKey.PrimaryKey; +import at.tuwien.entities.database.table.constraints.unique.Unique; import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.gateway.DataServiceGateway; @@ -212,12 +214,14 @@ public class DatabaseServiceImpl implements DatabaseService { .forEach(column -> { column.setTable(tableEntity); }); + log.trace("mapped unique constraint: {} ({})", tableEntity.getName(), uk.getColumns().stream().map(TableColumn::getInternalName).toList()); }); /* map foreign key constraint(s) */ tableEntity.getConstraints() .getForeignKeys() .forEach(fk -> { fk.setTable(tableEntity); + log.trace("mapped foreign key constraint: {} ({}) -> {} ({})", fk.getTable().getInternalName(), fk.getReferences().stream().map(r -> r.getColumn().getInternalName()).toList(), fk.getReferencedTable().getInternalName(), fk.getReferences().stream().map(r -> r.getReferencedColumn().getInternalName()).toList()); }); /* map primary key constraint */ for (PrimaryKey key : tableEntity.getConstraints().getPrimaryKey()) { @@ -237,7 +241,6 @@ public class DatabaseServiceImpl implements DatabaseService { } /* update referenced tables after they are known to the service */ for (ForeignKey foreignKey : database.getTables().stream().map(t -> t.getConstraints().getForeignKeys()).flatMap(List::stream).toList()) { - log.trace("lookup table {} in tables: {}", foreignKey.getReferencedTable().getInternalName(), database.getTables().stream().map(Table::getInternalName).toList()); final Optional<Table> optional = database.getTables() .stream() .filter(t -> t.getInternalName().equals(foreignKey.getReferencedTable().getInternalName())) @@ -275,15 +278,25 @@ public class DatabaseServiceImpl implements DatabaseService { reference.setReferencedColumn(optional2.get()); } } - database.getTables() - .stream() - .filter(t -> t.getConstraints().getForeignKeys().size() > 0) - .map(t -> t.getConstraints().getForeignKeys()) - .flatMap(List::stream) - .filter(fk -> fk.getReferences().size() > 1) - .forEach(fk -> { - log.debug(""); - }); + /* correct the unique constraint columns */ + for (Table table : database.getTables()) { + for (Unique uniqueConstraint : table.getConstraints().getUniques()) { + uniqueConstraint.setColumns(uniqueConstraint.getColumns() + .stream() + .map(column -> { + final Optional<TableColumn> optional = table.getColumns() + .stream() + .filter(c -> c.getInternalName().equals(column.getInternalName())) + .findFirst(); + if (optional.isEmpty()) { + log.error("Failed to find unique constraint column: {}", column.getInternalName()); + throw new IllegalArgumentException("Failed to find unique constraint column: " + column.getInternalName()); + } + return optional.get(); + }) + .toList()); + } + } /* update in metadata database */ database = databaseRepository.save(database); /* save in search service */