From c13735ee610514a2a44a8baf8dcea9c644f5c7b6 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 15:51:07 +0100
Subject: [PATCH 01/14] update test dataMaps
---
.../src/test/resources/lifecycle-map.map.xml | 8 ++--
.../src/test/resources/compound.map.xml | 8 ++--
.../src/test/resources/embeddable.map.xml | 4 +-
.../src/test/resources/generated.map.xml | 8 ++--
.../inheritance-single-table1.map.xml | 8 ++--
.../resources/inheritance-vertical.map.xml | 40 +++++++++----------
.../src/test/resources/meaningful-pk.map.xml | 4 +-
.../src/test/resources/multi-tier.map.xml | 4 +-
.../configuration/xml/testConfigMap4.map.xml | 12 +++---
.../relationships-delete-rules.map.xml | 8 ++--
.../resources/relationships-flattened.map.xml | 8 ++--
.../relationships-many-to-many-join.map.xml | 8 ++--
.../relationships-to-many-fk.map.xml | 4 +-
.../src/test/resources/testmap.map.xml | 24 +++++------
.../src/test/resources/toone.map.xml | 4 +-
.../unsupported-distinct-types.map.xml | 16 ++++----
16 files changed, 84 insertions(+), 84 deletions(-)
diff --git a/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml b/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
index cbcba1c2f7..fbd8f002b9 100644
--- a/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
+++ b/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
@@ -116,16 +116,16 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/compound.map.xml b/cayenne-server/src/test/resources/compound.map.xml
index 2570294293..3ad42f04e6 100644
--- a/cayenne-server/src/test/resources/compound.map.xml
+++ b/cayenne-server/src/test/resources/compound.map.xml
@@ -86,17 +86,17 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/embeddable.map.xml b/cayenne-server/src/test/resources/embeddable.map.xml
index e65c5eb889..7b39c29658 100644
--- a/cayenne-server/src/test/resources/embeddable.map.xml
+++ b/cayenne-server/src/test/resources/embeddable.map.xml
@@ -56,7 +56,7 @@
-
+
@@ -65,7 +65,7 @@
-
+
diff --git a/cayenne-server/src/test/resources/generated.map.xml b/cayenne-server/src/test/resources/generated.map.xml
index 38a9c79500..2c5c530183 100644
--- a/cayenne-server/src/test/resources/generated.map.xml
+++ b/cayenne-server/src/test/resources/generated.map.xml
@@ -63,16 +63,16 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/inheritance-single-table1.map.xml b/cayenne-server/src/test/resources/inheritance-single-table1.map.xml
index 11f798b80f..ffa9a282a1 100644
--- a/cayenne-server/src/test/resources/inheritance-single-table1.map.xml
+++ b/cayenne-server/src/test/resources/inheritance-single-table1.map.xml
@@ -53,22 +53,22 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/inheritance-vertical.map.xml b/cayenne-server/src/test/resources/inheritance-vertical.map.xml
index 4cf9f46e97..664f0ace46 100644
--- a/cayenne-server/src/test/resources/inheritance-vertical.map.xml
+++ b/cayenne-server/src/test/resources/inheritance-vertical.map.xml
@@ -170,16 +170,16 @@
-
+
-
+
-
+
-
+
@@ -191,28 +191,28 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -221,7 +221,7 @@
-
+
@@ -236,28 +236,28 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/meaningful-pk.map.xml b/cayenne-server/src/test/resources/meaningful-pk.map.xml
index c72e416567..d8105e1171 100644
--- a/cayenne-server/src/test/resources/meaningful-pk.map.xml
+++ b/cayenne-server/src/test/resources/meaningful-pk.map.xml
@@ -49,13 +49,13 @@
-
+
-
+
diff --git a/cayenne-server/src/test/resources/multi-tier.map.xml b/cayenne-server/src/test/resources/multi-tier.map.xml
index 7c45cfe266..566366fdad 100644
--- a/cayenne-server/src/test/resources/multi-tier.map.xml
+++ b/cayenne-server/src/test/resources/multi-tier.map.xml
@@ -54,7 +54,7 @@
-
+
@@ -72,7 +72,7 @@
-
+
diff --git a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/testConfigMap4.map.xml b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/testConfigMap4.map.xml
index 9513b1cb00..81a7a44fd7 100644
--- a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/testConfigMap4.map.xml
+++ b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/testConfigMap4.map.xml
@@ -177,7 +177,7 @@
-
+
@@ -186,10 +186,10 @@
-
+
-
+
@@ -198,7 +198,7 @@
-
+
@@ -216,13 +216,13 @@
-
+
-
+
diff --git a/cayenne-server/src/test/resources/relationships-delete-rules.map.xml b/cayenne-server/src/test/resources/relationships-delete-rules.map.xml
index c2553352aa..cf337af20d 100644
--- a/cayenne-server/src/test/resources/relationships-delete-rules.map.xml
+++ b/cayenne-server/src/test/resources/relationships-delete-rules.map.xml
@@ -30,16 +30,16 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/relationships-flattened.map.xml b/cayenne-server/src/test/resources/relationships-flattened.map.xml
index e1f3938cfd..0d54de020a 100644
--- a/cayenne-server/src/test/resources/relationships-flattened.map.xml
+++ b/cayenne-server/src/test/resources/relationships-flattened.map.xml
@@ -99,16 +99,16 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/relationships-many-to-many-join.map.xml b/cayenne-server/src/test/resources/relationships-many-to-many-join.map.xml
index 4da95b3346..9f73c7ec29 100644
--- a/cayenne-server/src/test/resources/relationships-many-to-many-join.map.xml
+++ b/cayenne-server/src/test/resources/relationships-many-to-many-join.map.xml
@@ -22,16 +22,16 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/relationships-to-many-fk.map.xml b/cayenne-server/src/test/resources/relationships-to-many-fk.map.xml
index 149b044f4b..4e3d8e468e 100644
--- a/cayenne-server/src/test/resources/relationships-to-many-fk.map.xml
+++ b/cayenne-server/src/test/resources/relationships-to-many-fk.map.xml
@@ -32,13 +32,13 @@
-
+
-
+
diff --git a/cayenne-server/src/test/resources/testmap.map.xml b/cayenne-server/src/test/resources/testmap.map.xml
index 0b2ee630c0..06520b3893 100644
--- a/cayenne-server/src/test/resources/testmap.map.xml
+++ b/cayenne-server/src/test/resources/testmap.map.xml
@@ -164,7 +164,7 @@
-
+
@@ -176,31 +176,31 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -212,19 +212,19 @@
-
+
-
+
-
+
-
+
diff --git a/cayenne-server/src/test/resources/toone.map.xml b/cayenne-server/src/test/resources/toone.map.xml
index ef9ddbfaa4..d2d78c9b8b 100644
--- a/cayenne-server/src/test/resources/toone.map.xml
+++ b/cayenne-server/src/test/resources/toone.map.xml
@@ -12,10 +12,10 @@
-
+
-
+
diff --git a/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml b/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
index 3c6d7ea12b..578df54629 100644
--- a/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
+++ b/cayenne-server/src/test/resources/unsupported-distinct-types.map.xml
@@ -26,28 +26,28 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
From 04532a65842886eef1845868cc334ddaad4e6373 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 15:55:47 +0100
Subject: [PATCH 02/14] update tests
---
.../dbsync/merge/DataMapMergerTest.java | 20 +++++++++----------
.../cayenne/dbsync/merge/MergerFactoryIT.java | 2 ++
.../dbsync/merge/builders/DataMapBuilder.java | 8 ++++----
.../merge/builders/DbRelationshipBuilder.java | 16 +++++++++++++--
.../token/model/DropColumnToModelIT.java | 1 +
.../model/DropRelationshipToModelIT.java | 1 +
.../reverse/dbload/RelationshipsLoaderIT.java | 2 +-
.../flush/ArcValuesCreationHandlerTest.java | 12 +++++------
.../xml/DbRelationshipHandlerTest.java | 2 +-
9 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
index 4f14d81433..33c2301520 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
@@ -252,7 +252,7 @@ public void testAddRelationship() throws Exception {
dbEntity("table2").attributes(
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt())
- ).join("rel", "table1.attr01", "table2.attr01")
+ ).join("rel", "table1.attr01", "table2.attr01", true)
.build();
DataMap db = dataMap().with(
@@ -287,8 +287,8 @@ public void testAddRelationship1() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr01")
- .join("rel1", "table1.attr01", "table2.attr03")
+ ).join("rel", "table1.attr01", "table2.attr01",true)
+ .join("rel1", "table1.attr01", "table2.attr03",false)
.build();
DataMap db = dataMap().with(
@@ -300,8 +300,8 @@ public void testAddRelationship1() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr02")
- .join("rel1", "table1.attr01", "table2.attr03")
+ ).join("rel", "table1.attr01", "table2.attr02",true)
+ .join("rel1", "table1.attr01", "table2.attr03",false)
.build();
@@ -329,7 +329,7 @@ public void testTableNameUppercaseRelationship() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "TABLE1.attr01", "table2.attr01").build();
+ ).join("rel", "TABLE1.attr01", "table2.attr01",true).build();
DataMap db = dataMap().with(
dbEntity("table1").attributes(
@@ -340,7 +340,7 @@ public void testTableNameUppercaseRelationship() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr01").build();
+ ).join("rel", "table1.attr01", "table2.attr01",false).build();
List tokens = dbMerger().createMergeTokens(existing, db);
@@ -358,7 +358,7 @@ public void testAttributeNameUppercaseRelationship() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.ATTR01", "table2.attr01").build();
+ ).join("rel", "table1.ATTR01", "table2.attr01",true).build();
DataMap db = dataMap().with(
dbEntity("table1").attributes(
@@ -369,7 +369,7 @@ public void testAttributeNameUppercaseRelationship() throws Exception {
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt().primaryKey(),
dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr01").build();
+ ).join("rel", "table1.attr01", "table2.attr01",false).build();
List tokens = dbMerger().createMergeTokens(existing, db);
@@ -397,7 +397,7 @@ public void testRemoveRelationship() throws Exception {
dbEntity("table2").attributes(
dbAttr("attr01").typeInt().primaryKey(),
dbAttr("attr02").typeInt())
- ).join("rel", "table1.attr01", "table2.attr01")
+ ).join("rel", "table1.attr01", "table2.attr01",true)
.build();
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergerFactoryIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergerFactoryIT.java
index 4d420d41a2..900bd996ca 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergerFactoryIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergerFactoryIT.java
@@ -201,6 +201,7 @@ public void testAddForeignKeyWithTable() throws Exception {
r1.setSourceEntity(dbEntity);
r1.setTargetEntityName(artistDbEntity);
r1.setToMany(false);
+ r1.setFK(true);
r1.addJoin(new DbJoin(r1, "ARTIST_ID", "ARTIST_ID"));
dbEntity.addRelationship(r1);
@@ -262,6 +263,7 @@ public void testAddForeignKeyAfterTable() throws Exception {
r1.setSourceEntity(dbEntity);
r1.setTargetEntityName(artistDbEntity);
r1.setToMany(false);
+ r1.setFK(true);
r1.addJoin(new DbJoin(r1, "ARTIST_ID", "ARTIST_ID"));
dbEntity.addRelationship(r1);
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
index 5a7d518aaf..e89cc46558 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
@@ -87,11 +87,11 @@ public DataMapBuilder withObjEntities(int count) {
return this;
}
- public DataMapBuilder join(String from, String to) {
- return join(null, from, to);
+ public DataMapBuilder join(String from, String to,boolean isFK) {
+ return join(null, from, to,isFK);
}
- public DataMapBuilder join(String name, String from, String to) {
+ public DataMapBuilder join(String name, String from, String to, boolean isFK) {
String[] fromSplit = from.split("\\.");
DbEntity fromEntity = obj.getDbEntity(fromSplit[0]);
if (fromEntity == null) {
@@ -103,7 +103,7 @@ public DataMapBuilder join(String name, String from, String to) {
fromEntity.addRelationship(new DbRelationshipBuilder(name)
.from(fromEntity, fromSplit[1])
.to(toSplit[0], toSplit[1])
-
+ .fK(isFK)
.build());
return this;
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbRelationshipBuilder.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbRelationshipBuilder.java
index d9d8553e2e..5543280497 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbRelationshipBuilder.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DbRelationshipBuilder.java
@@ -52,14 +52,19 @@ public DbRelationshipBuilder name(String name) {
return this;
}
- public DbRelationshipBuilder from(DbEntity entity, String ... columns) {
+ public DbRelationshipBuilder from(DbEntity entity, String... columns) {
obj.setSourceEntity(entity);
this.from = columns;
return this;
}
- public DbRelationshipBuilder to(String entityName, String ... columns) {
+ public DbRelationshipBuilder fK(boolean fk) {
+ obj.setFK(fk);
+ return this;
+ }
+
+ public DbRelationshipBuilder to(String entityName, String... columns) {
obj.setTargetEntityName(entityName);
this.to = columns;
@@ -80,6 +85,13 @@ public DbRelationship build() {
obj.addJoin(new DbJoin(obj, from[i], to[i]));
}
+ DbJoin join = new DbJoin(obj);
+ if (!obj.isFK() && join.getTarget() != null && join.getSource() != null) {
+ if (join.getTarget().isPrimaryKey() && !join.getSource().isPrimaryKey()) {
+ obj.setFK(true);
+ }
+ }
+
return obj;
}
}
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropColumnToModelIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropColumnToModelIT.java
index 69e5cc3163..360ef4e8a2 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropColumnToModelIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropColumnToModelIT.java
@@ -151,6 +151,7 @@ public void testRemoveFKColumnWithoutRelationshipInDb() throws Exception {
rel2To1.setSourceEntity(dbEntity2);
rel2To1.setTargetEntityName(dbEntity1);
rel2To1.setToMany(false);
+ rel2To1.setFK(true);
rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
dbEntity2.addRelationship(rel2To1);
assertSame(rel1To2, rel2To1.getReverseRelationship());
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropRelationshipToModelIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropRelationshipToModelIT.java
index 7dc4d5a965..73558ff9e4 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropRelationshipToModelIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/model/DropRelationshipToModelIT.java
@@ -86,6 +86,7 @@ public void testForeignKey() throws Exception {
rel2To1.setSourceEntity(dbEntity2);
rel2To1.setTargetEntityName(dbEntity1);
rel2To1.setToMany(false);
+ rel2To1.setFK(true);
rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
dbEntity2.addRelationship(rel2To1);
assertSame(rel1To2, rel2To1.getReverseRelationship());
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
index 40b64cf4c2..2c0189a0eb 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
@@ -76,7 +76,7 @@ public void testRelationshipLoad() throws Exception {
assertNotNull("No relationship to PAINTING_INFO", oneToOne);
assertFalse("Relationship to PAINTING_INFO must be to-one", oneToOne.isToMany());
- assertTrue("Relationship to PAINTING_INFO must be to-one", oneToOne.isToDependentPK());
+ assertTrue("Relationship to PAINTING_INFO must be to-one", oneToOne.isFK());
}
// private void assertUniqueConstraintsInRelationships(DataMap map) {
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/flush/ArcValuesCreationHandlerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/flush/ArcValuesCreationHandlerTest.java
index b6ad2f7384..3acf82e859 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/flush/ArcValuesCreationHandlerTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/flush/ArcValuesCreationHandlerTest.java
@@ -87,7 +87,7 @@ public void processRelationshipPkPkMaster() {
ObjectId targetId = ObjectId.of("test2", "id2", 2);
DbRelationship relationship = DbRelBuilder.of("id1", "id2")
- .withToDepPk().withDstPk().withSrcPk().build();
+ .withDstPk().withSrcPk().build();
handler.processRelationship(relationship, srcId, targetId, true);
@@ -105,7 +105,7 @@ public void processRelationshipPkPkDependent() {
ObjectId targetId = ObjectId.of("test2", "id2", 2);
DbRelationship relationship = DbRelBuilder.of("id1", "id2")
- .withDstPk().withSrcPk().build();
+ .withFk().withDstPk().withSrcPk().build();
handler.processRelationship(relationship, srcId, targetId, true);
@@ -164,7 +164,7 @@ final static class DbRelBuilder {
private String dstName;
private boolean srcPk;
private boolean dstPk;
- private boolean toDepPk;
+ private boolean fK;
static DbRelBuilder of(String srcName, String dstName) {
DbRelBuilder builder = new DbRelBuilder();
@@ -183,14 +183,14 @@ DbRelBuilder withDstPk() {
return this;
}
- DbRelBuilder withToDepPk() {
- toDepPk = true;
+ DbRelBuilder withFk() {
+ fK = true;
return this;
}
DbRelationship build() {
DbRelationship relationship = mock(DbRelationship.class);
- when(relationship.isToDependentPK()).thenReturn(toDepPk);
+ when(relationship.isFK()).thenReturn(fK);
DbJoin join = mock(DbJoin.class);
DbAttribute src = new DbAttribute(srcName);
src.setPrimaryKey(srcPk);
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/DbRelationshipHandlerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/DbRelationshipHandlerTest.java
index 98e41c5f97..209a716dc3 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/DbRelationshipHandlerTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/DbRelationshipHandlerTest.java
@@ -50,7 +50,7 @@ public NamespaceAwareNestedTagHandler createHandler(NamespaceAwareNestedTagHandl
assertNotNull(relationship);
assertEquals("PAINTING", relationship.getTargetEntityName());
- assertTrue(relationship.isToDependentPK());
+ assertTrue(!relationship.isFK());
assertTrue(relationship.isToMany());
assertEquals("ID", relationship.getJoins().get(0).getSourceName());
assertEquals("ARTIST_ID", relationship.getJoins().get(0).getTargetName());
From c459290ecac3cc293ed405558ddf9382bb9f7bb4 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 15:56:27 +0100
Subject: [PATCH 03/14] update xsd schema
---
.../main/resources/org/apache/cayenne/schema/11/modelMap.xsd | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cayenne-server/src/main/resources/org/apache/cayenne/schema/11/modelMap.xsd b/cayenne-server/src/main/resources/org/apache/cayenne/schema/11/modelMap.xsd
index 014f419f22..a388cad334 100644
--- a/cayenne-server/src/main/resources/org/apache/cayenne/schema/11/modelMap.xsd
+++ b/cayenne-server/src/main/resources/org/apache/cayenne/schema/11/modelMap.xsd
@@ -149,7 +149,7 @@
-
+
From 4500d89887f3b398ffc1202ff6c4c2dacdf6f861 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 16:01:52 +0100
Subject: [PATCH 04/14] reading/writing in xml
---
.../cayenne/configuration/xml/DbRelationshipHandler.java | 7 ++++++-
.../main/java/org/apache/cayenne/map/DbRelationship.java | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DbRelationshipHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DbRelationshipHandler.java
index da390e1ddc..71cc0342b2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DbRelationshipHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DbRelationshipHandler.java
@@ -79,7 +79,7 @@ private void createRelationship(Attributes attributes) throws SAXException {
dbRelationship.setSourceEntity(source);
dbRelationship.setTargetEntityName(attributes.getValue("target"));
dbRelationship.setToMany(DataMapHandler.TRUE.equalsIgnoreCase(attributes.getValue("toMany")));
- dbRelationship.setToDependentPK(DataMapHandler.TRUE.equalsIgnoreCase(attributes.getValue("toDependentPK")));
+ dbRelationship.setFK(DataMapHandler.TRUE.equalsIgnoreCase(attributes.getValue("fk")));
source.addRelationship(dbRelationship);
}
@@ -89,6 +89,11 @@ private void createDbAttributePair(Attributes attributes) {
join.setSourceName(attributes.getValue("source"));
join.setTargetName(attributes.getValue("target"));
dbRelationship.addJoin(join);
+ if (!dbRelationship.isFK() && join.getTarget() != null) {
+ if (join.getTarget().isPrimaryKey() && !join.getSource().isPrimaryKey()) {
+ dbRelationship.setFK(true);
+ }
+ }
}
public DbRelationship getDbRelationship() {
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index 15145ca729..4fc2792e92 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -77,7 +77,7 @@ public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
encoder.attribute("target", getTargetEntityName());
}
- encoder.attribute("toDependentPK", isToDependentPK() && isValidForDepPk());
+ encoder.attribute("fk", isFK() && isValidForDepPk());
encoder.attribute("toMany", isToMany());
encoder.nested(getJoins(), delegate);
From 19490039ce32bd8e1b0bac18f9fbf7a11df69e1e Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 17:08:58 +0100
Subject: [PATCH 05/14] logic in cayenne-server
---
.../apache/cayenne/access/DbGenerator.java | 4 +-
.../flush/ArcValuesCreationHandler.java | 2 +-
.../operation/GraphBasedDbRowOpSorter.java | 2 +-
.../cayenne/ashwood/AshwoodEntitySorter.java | 2 +-
.../java/org/apache/cayenne/map/DbEntity.java | 4 +-
.../apache/cayenne/map/DbRelationship.java | 47 +++++--------------
.../apache/cayenne/map/ObjRelationship.java | 4 +-
7 files changed, 21 insertions(+), 44 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
index 022cc367b0..4a71a84de7 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
@@ -361,11 +361,11 @@ public List createConstraintsQueries(DbEntity table) {
}
// create an FK CONSTRAINT only if the relationship is to PK
- // and if this is not a dependent PK
+ // and if this is FK
// create UNIQUE CONSTRAINT on FK if reverse relationship is to-one
- if (rel.isToPK() && !rel.isToDependentPK()) {
+ if (rel.isToPK() && rel.isFK()) {
if (getAdapter().supportsUniqueConstraints()) {
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
index 91f86bd5d6..6abd47744c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
@@ -191,7 +191,7 @@ protected void processRelationship(DbRelationship dbRelationship, ObjectId srcId
} else {
// case 2 and 3
processDelete = false;
- if(dbRelationship.isToDependentPK()) {
+ if(!dbRelationship.isFK()) {
valueToUse = ObjectIdValueSupplier.getFor(srcId, join.getSourceName());
rowOp = factory.getOrCreate(dbRelationship.getTargetEntity(), targetId, DbRowOpType.UPDATE);
attribute = join.getTarget();
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/operation/GraphBasedDbRowOpSorter.java b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/operation/GraphBasedDbRowOpSorter.java
index 8ed9617736..e16afa5ecf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/operation/GraphBasedDbRowOpSorter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/operation/GraphBasedDbRowOpSorter.java
@@ -82,7 +82,7 @@ private void initDataNoSync() {
resolver.getDbEntities().forEach(entity ->
entity.getRelationships().forEach(dbRelationship -> {
- if(dbRelationship.isToMany() || !dbRelationship.isToPK() || dbRelationship.isToDependentPK()) {
+ if(dbRelationship.isToMany() || !dbRelationship.isToPK() || !dbRelationship.isFK()) {
// TODO: can we ignore all of these relationships?
return;
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
index 169ad91f27..6b3f118fd4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ashwood/AshwoodEntitySorter.java
@@ -113,7 +113,7 @@ protected void doIndexSorter() {
for (DbEntity destination : entityResolver.getDbEntities()) {
for (DbRelationship candidate : destination.getRelationships()) {
- if ((!candidate.isToMany() && !candidate.isToDependentPK()) || candidate.isToMasterPK()) {
+ if ( candidate.isToMasterPK()) {
DbEntity origin = candidate.getTargetEntity();
boolean newReflexive = destination.equals(origin);
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
index ef4305f150..67b984dd6c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
@@ -426,8 +426,8 @@ private void handleAttributeUpdate(AttributeEvent e) {
// check toDep PK for reverse relationships
for (DbRelationship rel : getRelationships()) {
DbRelationship reverse = rel.getReverseRelationship();
- if(reverse != null && reverse.isToDependentPK() && !reverse.isValidForDepPk()) {
- reverse.setToDependentPK(false);
+ if(reverse != null && reverse.isFK() && !reverse.isValidForFk()) {
+ reverse.setFK(false);
}
}
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index 4fc2792e92..fbacbb481f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -42,11 +42,7 @@ public class DbRelationship extends Relationship joins = new ArrayList<>(2);
- // Is relationship from source to target points to dependent primary
- // key (primary key column of destination table that is also a FK to the
- // source
- // column)
- protected boolean toDependentPK;
+ protected boolean isFK;
public DbRelationship() {
super();
@@ -77,7 +73,7 @@ public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
encoder.attribute("target", getTargetEntityName());
}
- encoder.attribute("fk", isFK() && isValidForDepPk());
+ encoder.attribute("fk", isFK() && isValidForFk());
encoder.attribute("toMany", isToMany());
encoder.nested(getJoins(), delegate);
@@ -146,14 +142,7 @@ public DbRelationship createReverseRelationship() {
DbRelationship reverse = new DbRelationship();
reverse.setSourceEntity(targetEntity);
reverse.setTargetEntityName(getSourceEntity().getName());
-
- // TODO: andrus 12/24/2007 - one more case to handle - set reverse
- // toDepPK = true
- // if this relationship toDepPK is false, but the entities are joined on
- // a PK...
- // on the other hand, these can still be two independent entities...
-
- if (isToDependentPK() && !toMany && joins.size() == targetEntity.getPrimaryKeys().size()) {
+ if (!isFK() && !toMany && joins.size() == targetEntity.getPrimaryKeys().size()) {
reverse.setToMany(false);
} else {
reverse.setToMany(!toMany);
@@ -258,16 +247,11 @@ public boolean isFromPK() {
}
/**
- * Returns true
if a method isToDependentPK
of
- * reverse relationship of this relationship returns true
.
+ * Returns true
if a method isFK
of
+ * reverse relationship of this relationship returns false
.
*/
public boolean isToMasterPK() {
- if (isToMany() || isToDependentPK()) {
- return false;
- }
-
- DbRelationship revRel = getReverseRelationship();
- return revRel != null && revRel.isToDependentPK();
+ return !isToMany() && isFK();
}
/**
@@ -278,28 +262,21 @@ public boolean isToMasterPK() {
* @since 4.0
*/
public boolean isSourceIndependentFromTargetChange() {
- // note - call "isToPK" at the end of the chain, since
- // if it is to a dependent PK, we still should return true...
- return isToMany() || isToDependentPK() || !isToPK();
+ return !isFK();
}
- /**
- * Returns true
if relationship from source to target points to
- * dependent primary key. Dependent PK is a primary key column of the
- * destination table that is also a FK to the source column.
- */
- public boolean isToDependentPK() {
- return toDependentPK;
+ public boolean isFK() {
+ return isFK;
}
- public void setToDependentPK(boolean toDependentPK) {
- this.toDependentPK = toDependentPK;
+ public void setFK(boolean FK) {
+ this.isFK = FK;
}
/**
* @since 1.1
*/
- public boolean isValidForDepPk() {
+ public boolean isValidForFk() {
// handle case with no joins
if (getJoins().size() == 0) {
return false;
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjRelationship.java
index ee36fbf68f..ba59bba256 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjRelationship.java
@@ -321,7 +321,7 @@ public boolean isOptional() {
return false;
}
DbRelationship reverseRelationship = dbRelationship.getReverseRelationship();
- return !reverseRelationship.isToDependentPK();
+ return reverseRelationship.isFK();
}
return true;
@@ -378,7 +378,7 @@ public boolean isSourceIndependentFromTargetChange() {
* Returns true if underlying DbRelationships point to dependent entity.
*/
public boolean isToDependentEntity() {
- return (getDbRelationships().get(0)).isToDependentPK();
+ return !(getDbRelationships().get(0)).isFK();
}
/**
From f76f28f8a6350d5294f4fc0668c5eb57a619cfcc Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 17 Mar 2023 17:12:09 +0100
Subject: [PATCH 06/14] logic in cayenne-dbsync
---
.../merge/factory/IngresMergerTokenFactory.java | 2 +-
.../reverse/dbimport/ManyToManyCandidateEntity.java | 4 ++--
.../dbsync/reverse/dbload/RelationshipLoader.java | 12 ++++++------
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/IngresMergerTokenFactory.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/IngresMergerTokenFactory.java
index 74c929dabf..4f24435183 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/IngresMergerTokenFactory.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/IngresMergerTokenFactory.java
@@ -80,7 +80,7 @@ public MergerToken createAddRelationshipToDb(DbEntity entity, final DbRelationsh
return new AddRelationshipToDb(entity, rel) {
@Override
public List createSql(DbAdapter adapter) {
- if (!rel.isToMany() && rel.isToPK() && !rel.isToDependentPK()) {
+ if (rel.isToMasterPK()) {
DbEntity source = (DbEntity) rel.getSourceEntity();
QuotingStrategy context = adapter.getQuotingStrategy();
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java
index 3eb9836074..eed688d80f 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java
@@ -87,8 +87,8 @@ private boolean isManyToMany() {
boolean isNotHaveAttributes = joinEntity.getAttributes().size() == 0;
return isNotHaveAttributes
- && reverseRelationship1 != null && reverseRelationship1.isToDependentPK()
- && reverseRelationship2 != null && reverseRelationship2.isToDependentPK()
+ && reverseRelationship1 != null && !reverseRelationship1.isFK()
+ && reverseRelationship2 != null && !reverseRelationship2.isFK()
&& entity1 != null && entity2 != null;
}
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
index fdd2899b11..aa348c1c34 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
@@ -87,10 +87,10 @@ public void load(DatabaseMetaData metaData, DbLoadDataStore map) throws SQLExcep
createAndAppendJoins(exportedKeys, pkEntity, fkEntity, forwardRelationship, reverseRelationship);
- boolean toDependentPK = isToDependentPK(forwardRelationship);
- boolean toMany = isToMany(toDependentPK, fkEntity, forwardRelationship);
+ boolean fk = isFK(forwardRelationship);
+ boolean toMany = isToMany(fk, fkEntity, forwardRelationship);
- forwardRelationship.setToDependentPK(toDependentPK);
+ forwardRelationship.setFK(fk);
forwardRelationship.setToMany(toMany);
// set relationship names only after their joins are ready ...
@@ -146,11 +146,11 @@ private void checkAndAddRelationship(DbEntity entity, DbRelationship relationshi
}
}
- private boolean isToMany(boolean toDependentPK, DbEntity fkEntity, DbRelationship forwardRelationship) {
- return !toDependentPK || fkEntity.getPrimaryKeys().size() != forwardRelationship.getJoins().size();
+ private boolean isToMany(boolean isFK, DbEntity fkEntity, DbRelationship forwardRelationship) {
+ return !isFK || fkEntity.getPrimaryKeys().size() != forwardRelationship.getJoins().size();
}
- private boolean isToDependentPK(DbRelationship forwardRelationship) {
+ private boolean isFK(DbRelationship forwardRelationship) {
for (DbJoin dbJoin : forwardRelationship.getJoins()) {
if (!dbJoin.getTarget().isPrimaryKey()) {
return false;
From a8bc6fba0b832a23c5ef0a488f6cb28b00489069 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Fri, 24 Mar 2023 10:04:32 +0100
Subject: [PATCH 07/14] modeler update
---
.../apache/cayenne/map/DbRelationship.java | 15 +-
.../modeler/DbRelationshipDialogView.java | 12 +-
.../modeler/dialog/DbRelationshipDialog.java | 141 ++++++++++--------
.../dbentity/DbAttributeTableModel.java | 49 ++++--
.../dbentity/DbEntityRelationshipPanel.java | 2 +-
.../dbentity/DbRelationshipTableModel.java | 63 ++++----
.../undo/RelationshipUndoableEdit.java | 2 +-
.../cayenne/wocompat/EOModelProcessor.java | 4 +-
8 files changed, 156 insertions(+), 132 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index fbacbb481f..afbff7d7ff 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -278,20 +278,7 @@ public void setFK(boolean FK) {
*/
public boolean isValidForFk() {
// handle case with no joins
- if (getJoins().size() == 0) {
- return false;
- }
-
- for (DbJoin join : getJoins()) {
- DbAttribute target = join.getTarget();
- DbAttribute source = join.getSource();
-
- if (target != null && !target.isPrimaryKey() || source != null && !source.isPrimaryKey()) {
- return false;
- }
- }
-
- return true;
+ return getJoins().size() != 0;
}
/**
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/DbRelationshipDialogView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/DbRelationshipDialogView.java
index d17eb1a9be..aa22983837 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/DbRelationshipDialogView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/DbRelationshipDialogView.java
@@ -46,7 +46,7 @@ public class DbRelationshipDialogView extends CayenneDialog {
private JTextField name;
private JComboBox targetEntities;
- private JCheckBox toDepPk;
+ private JCheckBox fK;
private JCheckBox toMany;
private JTextField comment;
private JLabel sourceName;
@@ -71,7 +71,7 @@ public DbRelationshipDialogView() {
private void initView() {
name = new JTextField(25);
targetEntities = new JComboBox<>();
- toDepPk = new JCheckBox();
+ fK = new JCheckBox();
toMany = new JCheckBox();
comment = new JTextField(25);
@@ -114,8 +114,8 @@ private void initView() {
builder.addLabel("Target Entity:", cc.xy(1, 7));
builder.add(targetEntities, cc.xywh(3, 7, 1, 1));
- builder.addLabel("To Dep PK:", cc.xy(1, 9));
- builder.add(toDepPk, cc.xywh(3, 9, 1, 1));
+ builder.addLabel("Foreign key:", cc.xy(1, 9));
+ builder.add(fK, cc.xywh(3, 9, 1, 1));
builder.addLabel("To Many:", cc.xy(1, 11));
builder.add(toMany, cc.xywh(3, 11, 1, 1));
@@ -165,8 +165,8 @@ public JComboBox getTargetEntities() {
return targetEntities;
}
- public JCheckBox getToDepPk() {
- return toDepPk;
+ public JCheckBox getFK() {
+ return fK;
}
public JCheckBox getToMany() {
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbRelationshipDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbRelationshipDialog.java
index c8d57ea76f..efe4e2161d 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbRelationshipDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbRelationshipDialog.java
@@ -19,25 +19,10 @@
package org.apache.cayenne.modeler.dialog;
-import javax.swing.AbstractListModel;
-import javax.swing.ComboBoxModel;
-import javax.swing.JComboBox;
-import javax.swing.JOptionPane;
-import javax.swing.table.TableColumn;
-import java.awt.Component;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.dbsync.naming.NameBuilder;
+import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
@@ -55,6 +40,23 @@
import org.apache.cayenne.project.extension.info.ObjectInfo;
import org.apache.cayenne.util.Util;
+import javax.swing.AbstractListModel;
+import javax.swing.ComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.TableColumn;
+import java.awt.Component;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
/**
* @since 4.2
*/
@@ -125,15 +127,15 @@ private void initFromModel() {
view.getTargetEntities().setModel(targetComboBoxModel);
view.getSourceName().setText(relationship.getSourceEntityName());
- view.getToDepPk().setSelected(relationship.isToDependentPK());
+ view.getFK().setSelected(relationship.isFK());
view.getToMany().setSelected(relationship.isToMany());
view.getNameField().setText(relationship.getName());
- if(reverseRelationship != null) {
+ if (reverseRelationship != null) {
view.getReverseName().setText(reverseRelationship.getName());
}
- if(relationship.getTargetEntity() == null) {
+ if (relationship.getTargetEntity() == null) {
enableOptions(false);
} else {
enableInfo();
@@ -147,10 +149,10 @@ private void initFromModel() {
private void initController() {
view.getTargetEntities().addActionListener(action -> {
- DbEntity selectedItem = ((TargetComboBoxModel)view.getTargetEntities().getModel()).selected;
- if(relationship.getTargetEntityName() == null) {
+ DbEntity selectedItem = ((TargetComboBoxModel) view.getTargetEntities().getModel()).selected;
+ if (relationship.getTargetEntityName() == null) {
relationship.setTargetEntityName(selectedItem.getName());
- } else if(!relationship.getTargetEntityName().equals(selectedItem.getName())){
+ } else if (!relationship.getTargetEntityName().equals(selectedItem.getName())) {
if (WarningDialogByDbTargetChange.showWarningDialog(projectController, relationship)) {
// clear joins...
relationship.removeAllJoins();
@@ -158,8 +160,8 @@ private void initController() {
} else {
view.getTargetEntities().setSelectedItem(relationship.getTargetEntityName());
}
- relationship.setToDependentPK(false);
- view.getToDepPk().setSelected(relationship.isValidForDepPk());
+ relationship.setFK(false);
+ view.getFK().setSelected(relationship.isValidForFk());
projectController.fireDbRelationshipEvent(new RelationshipEvent(this, relationship, relationship.getSourceEntity()));
}
enableInfo();
@@ -183,12 +185,12 @@ private void initController() {
DbJoin join = model.getJoin(row);
relationship.removeJoin(join);
- if(relationship.isValidForDepPk()) {
- view.getToDepPk().setEnabled(true);
+ if (relationship.isValidForFk()) {
+ view.getFK().setEnabled(true);
} else {
- view.getToDepPk().setEnabled(false);
- view.getToDepPk().setSelected(false);
- relationship.setToDependentPK(false);
+ view.getFK().setEnabled(false);
+ view.getFK().setSelected(false);
+ relationship.setFK(false);
}
model.removeRow(join);
@@ -206,27 +208,35 @@ private void initController() {
view.setVisible(false);
});
- view.addWindowListener(new WindowAdapter()
- {
+ view.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
view.setCancelPressed(true);
}
});
- view.getToDepPk().setEnabled(relationship.isValidForDepPk());
- view.getToDepPk().addActionListener(selected -> {
- boolean isSelected = view.getToDepPk().isSelected();
+ view.getFK().setEnabled(relationship.isValidForFk());
+ view.getFK().addActionListener(selected -> {
+ boolean isSelected = view.getFK().isSelected();
DbRelationship reverseRelationship = relationship.getReverseRelationship();
- if(reverseRelationship != null && reverseRelationship.isToDependentPK() && isSelected) {
- boolean setToDepPk = JOptionPane.showConfirmDialog(Application.getFrame(), "Unset reverse relationship's \"To Dep PK\" setting?",
- "Warning", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION;
- relationship.setToDependentPK(setToDepPk);
- reverseRelationship.setToDependentPK(!setToDepPk);
+ if (reverseRelationship != null) {
+ boolean isOKAnswer = JOptionPane.showConfirmDialog(Application.getFrame()
+ , isSelected ? "Foreign key will be unset in reverse relationship" : "Foreign key will be set in reverse relationship"
+ , "Warning"
+ , JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION;
+ if (isOKAnswer) {
+ relationship.setFK(isSelected);
+ reverseRelationship.setFK(!isSelected);
+ } else {
+ relationship.setFK(!isSelected);
+ reverseRelationship.setFK(isSelected);
+ view.getFK().setSelected(!isSelected);
+ }
} else {
- relationship.setToDependentPK(view.getToDepPk().isSelected());
+ relationship.setFK(isSelected);
}
});
+
}
private void enableInfo() {
@@ -236,12 +246,21 @@ private void enableInfo() {
projectController, this, true));
view.getTable().getModel().addTableModelListener(change -> {
- if(change.getLastRow() != Integer.MAX_VALUE) {
- if(relationship.isValidForDepPk()) {
- view.getToDepPk().setEnabled(true);
- } else {
- view.getToDepPk().setEnabled(false);
+ if (!isEventRowDeletion(change)) {
+ if (relationship.getReverseRelationship() == null) {
+ for (DbJoin join : relationship.getJoins()) {
+ if (!relationship.isFK()) {
+ DbAttribute target = join.getTarget();
+ DbAttribute source = join.getSource();
+
+ if (target != null && source != null && target.isPrimaryKey() && !source.isPrimaryKey()) {
+ relationship.setFK(true);
+ view.getFK().setSelected(true);
+ }
+ }
+ }
}
+ view.getFK().setEnabled(relationship.isValidForFk());
}
});
@@ -262,6 +281,10 @@ private void enableInfo() {
view.getTablePreferences().bind(view.getTable(), null, null, null, DbJoinTableModel.SOURCE, true);
}
+ private boolean isEventRowDeletion(TableModelEvent change) {
+ return change.getLastRow() == Integer.MAX_VALUE;
+ }
+
private void enableOptions(boolean enable) {
view.enableOptions(enable);
}
@@ -313,11 +336,11 @@ private void save() {
if (relationship.getSourceEntity() == relationship.getTargetEntity()) {
projectController
.fireDbRelationshipEvent(
- new RelationshipEvent(
- this,
- reverseRelationship,
- reverseRelationship.getSourceEntity(),
- MapEvent.ADD));
+ new RelationshipEvent(
+ this,
+ reverseRelationship,
+ reverseRelationship.getSourceEntity(),
+ MapEvent.ADD));
}
} else {
handleNameUpdate(reverseRelationship, view.getReverseName().getText().trim());
@@ -327,8 +350,8 @@ private void save() {
reverseRelationship.setJoins(reverseJoins);
// check if joins map to a primary key of this entity
- if (!relationship.isToDependentPK() && reverseRelationship.isValidForDepPk()) {
- reverseRelationship.setToDependentPK(true);
+ if (!relationship.isFK() && reverseRelationship.isValidForFk()) {
+ reverseRelationship.setFK(true);
}
}
@@ -336,7 +359,7 @@ private void save() {
}
private void handleNameUpdate(DbRelationship relationship, String userInputName) {
- if(Util.nullSafeEquals(relationship.getName(), userInputName)) {
+ if (Util.nullSafeEquals(relationship.getName(), userInputName)) {
return;
}
@@ -353,7 +376,7 @@ private void handleNameUpdate(DbRelationship relationship, String userInputName)
projectController
.fireDbRelationshipEvent(
- new RelationshipEvent(this, relationship, relationship.getSourceEntity(), oldName));
+ new RelationshipEvent(this, relationship, relationship.getSourceEntity(), oldName));
}
private Collection getReverseJoins() {
@@ -380,7 +403,7 @@ private Collection getReverseJoins() {
}
private void fireDbRelationshipEvent(boolean isCreate) {
- if(!isCreate) {
+ if (!isCreate) {
projectController
.fireDbRelationshipEvent(
new RelationshipEvent(this, relationship, relationship.getSourceEntity(), MapEvent.CHANGE));
@@ -388,7 +411,7 @@ private void fireDbRelationshipEvent(boolean isCreate) {
Application.getInstance().getUndoManager().addEdit(undo);
} else {
DbEntity dbEntity = relationship.getSourceEntity();
- if(dbEntity.getRelationship(relationship.getName()) == null) {
+ if (dbEntity.getRelationship(relationship.getName()) == null) {
dbEntity.addRelationship(relationship);
}
@@ -421,7 +444,7 @@ final class TargetComboBoxModel extends AbstractListModel implements Com
}
private String getTitle(DbEntity entity) {
- if(entity == null) {
+ if (entity == null) {
return "";
}
return relationship.getSourceEntity().getDataMap() == entity.getDataMap()
@@ -441,8 +464,8 @@ public String getElementAt(int index) {
@Override
public void setSelectedItem(Object anItem) {
- String title = (String)anItem;
- if(title != null) {
+ String title = (String) anItem;
+ if (title != null) {
int spacer = title.indexOf(' ');
if (spacer != -1) {
title = title.substring(0, spacer);
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
index 4998183fef..37697b99b5 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
@@ -53,12 +53,12 @@ public class DbAttributeTableModel extends CayenneTableModel {
protected DbEntity entity;
public DbAttributeTableModel(DbEntity entity, ProjectController mediator,
- Object eventSource) {
+ Object eventSource) {
this(entity, mediator, eventSource, new ArrayList<>(entity.getAttributes()));
}
public DbAttributeTableModel(DbEntity entity, ProjectController mediator,
- Object eventSource, List objectList) {
+ Object eventSource, List objectList) {
super(mediator, eventSource, objectList);
this.entity = entity;
}
@@ -71,11 +71,11 @@ public int typeColumnInd() {
return DB_ATTRIBUTE_TYPE;
}
- public int lengthColumnId(){
+ public int lengthColumnId() {
return DB_ATTRIBUTE_MAX;
}
- public int scaleColumnId(){
+ public int scaleColumnId() {
return DB_ATTRIBUTE_SCALE;
}
@@ -176,7 +176,7 @@ public void setUpdatedValueAt(Object newVal, int row, int col) {
e.setOldName(attr.getName());
attr.setName((String) newVal);
attr.getEntity().dbAttributeChanged(e);
-
+
fireTableCellUpdated(row, col);
break;
case DB_ATTRIBUTE_TYPE:
@@ -274,7 +274,7 @@ public boolean setPrimaryKey(Boolean newVal, DbAttribute attr, int row) {
// when PK is unset, we need to fix some derived flags
if (!flag) {
-
+//TODO OOOOOO
attr.setGenerated(false);
Collection relationships = ProjectUtil
@@ -283,27 +283,44 @@ public boolean setPrimaryKey(Boolean newVal, DbAttribute attr, int row) {
.addAll(ProjectUtil.getRelationshipsUsingAttributeAsSource(attr));
if (relationships.size() > 0) {
- relationships.removeIf(relationship -> !relationship.isToDependentPK());
+ relationships.removeIf(relationship -> !relationship.isFK());
// filtered only those that are to dep PK
if (relationships.size() > 0) {
- String message = (relationships.size() == 1)
- ? "Fix \"To Dep PK\" relationship using this attribute?"
+ /* String message = (relationships.size() == 1)
+ ? "Fix \"Foreign key\" relationship using this attribute?"
: "Fix " + relationships.size()
- + " \"To Dep PK\" relationships using this attribute?";
+ + " \"Foreign key\" relationships using this attribute?";
+ */
+
+
+ StringBuilder message = new StringBuilder("Removing an attribute can affect the following relationships:\n");
+ for (DbRelationship relationship : relationships) {
+ message.append(relationship.getName()).append("\n");
+ }
+ message.append("It would be a good idea to check them after making the change. Continue?");
+
+ /* JOptionPane.showMessageDialog(Application.getFrame()
+ , message
+ , "Warning"
+ , JOptionPane.PLAIN_MESSAGE);
+*/
int answer = JOptionPane.showConfirmDialog(
Application.getFrame(),
- message);
- if (answer != JOptionPane.YES_OPTION) {
+ message.toString(),
+ "Warning",
+ JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.WARNING_MESSAGE);
+ if (answer != JOptionPane.OK_OPTION) {
// no action needed
return false;
}
- // fix target relationships
+ /* // fix target relationships
for (DbRelationship relationship : relationships) {
- relationship.setToDependentPK(false);
- }
+ relationship.setFK(false);
+ }*/
}
}
}
@@ -345,7 +362,7 @@ public boolean isColumnSortable(int sortCol) {
@Override
public void sortByColumn(int sortCol, boolean isAscent) {
- switch(sortCol){
+ switch (sortCol) {
case DB_ATTRIBUTE_NAME:
sortByElementProperty("name", isAscent);
break;
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipPanel.java
index 93080652b9..94cb094aec 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipPanel.java
@@ -233,7 +233,7 @@ protected void rebuildTable(DbEntity entity) {
targetCombo = Application.getWidgetFactory().createComboBox();
AutoCompletion.enable(targetCombo);
- table.getColumnModel().getColumn(DbRelationshipTableModel.TO_DEPENDENT_KEY)
+ table.getColumnModel().getColumn(DbRelationshipTableModel.FK)
.setCellRenderer(new CheckBoxCellRenderer());
targetCombo.setRenderer(CellRenderers.entityListRendererWithIcons(entity.getDataMap()));
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
index cb27cad215..daf2f2834a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
@@ -35,21 +35,20 @@
/**
* Table model for DbRelationship table.
- *
*/
public class DbRelationshipTableModel extends CayenneTableModel {
// Columns
static final int NAME = 0;
static final int TARGET = 1;
- static final int TO_DEPENDENT_KEY = 2;
+ static final int FK = 2;
static final int CARDINALITY = 3;
static final int COMMENTS = 4;
protected DbEntity entity;
public DbRelationshipTableModel(DbEntity entity, ProjectController mediator,
- Object eventSource) {
+ Object eventSource) {
super(mediator, eventSource, new ArrayList<>(entity.getRelationships()));
this.entity = entity;
@@ -72,8 +71,8 @@ public String getColumnName(int col) {
return "Name";
case TARGET:
return "Target";
- case TO_DEPENDENT_KEY:
- return "To Dep PK";
+ case FK:
+ return "FK";
case CARDINALITY:
return "To Many";
case COMMENTS:
@@ -87,7 +86,7 @@ public Class getColumnClass(int col) {
switch (col) {
case TARGET:
return DbEntity.class;
- case TO_DEPENDENT_KEY:
+ case FK:
case CARDINALITY:
return Boolean.class;
default:
@@ -110,8 +109,8 @@ public Object getValueAt(int row, int col) {
return rel.getName();
case TARGET:
return rel.getTargetEntity();
- case TO_DEPENDENT_KEY:
- return rel.isToDependentPK() ? Boolean.TRUE : Boolean.FALSE;
+ case FK:
+ return rel.isFK() ? Boolean.TRUE : Boolean.FALSE;
case CARDINALITY:
return rel.isToMany() ? Boolean.TRUE : Boolean.FALSE;
case COMMENTS:
@@ -138,35 +137,33 @@ public void setUpdatedValueAt(Object aValue, int row, int column) {
rel.setName((String) aValue);
mediator.fireDbRelationshipEvent(e);
fireTableCellUpdated(row, column);
- } else if (column == TO_DEPENDENT_KEY) {
+ } else if (column == FK) {
boolean flag = (Boolean) aValue;
- // make sure reverse relationship "to-dep-pk" is unset.
- if (flag) {
- DbRelationship reverse = rel.getReverseRelationship();
- if (reverse != null && reverse.isToDependentPK()) {
- String message = "Unset reverse relationship's \"To Dep PK\" setting?";
- int answer = JOptionPane.showConfirmDialog(
- Application.getFrame(),
- message);
- if (answer != JOptionPane.YES_OPTION) {
- // no action needed
- return;
- }
-
- // unset reverse
- reverse.setToDependentPK(false);
+ // set/unset FK at both ends of relationship.
+ DbRelationship reverse = rel.getReverseRelationship();
+ if (reverse != null) {
+ boolean isOKAnswer = JOptionPane.showConfirmDialog(Application.getFrame()
+ , flag ? "Foreign key will be unset in reverse relationship" : "Foreign key will be set in reverse relationship"
+ , "Warning"
+ , JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION;
+ if (isOKAnswer) {
+ rel.setFK(flag);
+ reverse.setFK(!flag);
+ } else {
+ rel.setFK(!flag);
+ reverse.setFK(flag);
}
+ } else {
+ rel.setFK(flag);
}
-
- rel.setToDependentPK(flag);
mediator.fireDbRelationshipEvent(new RelationshipEvent(eventSource, rel, entity));
} else if (column == CARDINALITY) {
rel.setToMany((Boolean) aValue);
mediator.fireDbRelationshipEvent(new RelationshipEvent(eventSource, rel, entity));
updateDependentObjRelationships(rel);
- } else if(column == COMMENTS) {
+ } else if (column == COMMENTS) {
setComment((String) aValue, rel);
mediator.fireDbRelationshipEvent(new RelationshipEvent(eventSource, rel, entity));
}
@@ -186,7 +183,7 @@ void updateDependentObjRelationships(DbRelationship relationship) {
Collection objRelationshipsForDbRelationship = ProjectUtil
.findObjRelationshipsForDbRelationship(mediator, relationship);
- for(ObjRelationship objRelationship : objRelationshipsForDbRelationship) {
+ for (ObjRelationship objRelationship : objRelationshipsForDbRelationship) {
objRelationship.recalculateToManyValue();
}
}
@@ -195,10 +192,10 @@ public boolean isCellEditable(int row, int col) {
DbRelationship rel = getRelationship(row);
if (rel == null) {
return false;
- } else if(col == TARGET) {
+ } else if (col == TARGET) {
return false;
- } else if (col == TO_DEPENDENT_KEY) {
- return rel.isValidForDepPk();
+ } else if (col == FK) {
+ return rel.isValidForFk();
}
return true;
}
@@ -217,8 +214,8 @@ public void sortByColumn(int sortCol, boolean isAscent) {
case TARGET:
sortByElementProperty("targetEntityName", isAscent);
break;
- case TO_DEPENDENT_KEY:
- sortByElementProperty("toDependentPK", isAscent);
+ case FK:
+ sortByElementProperty("FK", isAscent);
break;
case CARDINALITY:
sortByElementProperty("toMany", isAscent);
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/undo/RelationshipUndoableEdit.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/undo/RelationshipUndoableEdit.java
index 789a932735..ebd227ab9c 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/undo/RelationshipUndoableEdit.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/undo/RelationshipUndoableEdit.java
@@ -102,7 +102,7 @@ private Relationship,?,?> copyRelationship(Relationship,?,?> relationship) {
private DbRelationship getDbRelationship(DbRelationship dbRelationship) {
DbRelationship rel = new DbRelationship();
rel.setName(dbRelationship.getName());
- rel.setToDependentPK(dbRelationship.isToDependentPK());
+ rel.setFK(dbRelationship.isFK());
rel.setToMany(dbRelationship.isToMany());
rel.setTargetEntityName(dbRelationship.getTargetEntityName());
rel.setSourceEntity(dbRelationship.getSourceEntity());
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index 3947f57148..0c518ca06d 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -597,7 +597,7 @@ protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) {
String relName = (String) relMap.get("name");
boolean toMany = "Y".equals(relMap.get("isToMany"));
- boolean toDependentPK = "Y".equals(relMap.get("propagatesPrimaryKey"));
+ boolean isFK = "Y".equals(relMap.get("propagatesPrimaryKey"));
ObjEntity target = helper.getDataMap().getObjEntity(targetName);
// target maybe null for cross-EOModel relationships
@@ -629,7 +629,7 @@ protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) {
dbRel.setTargetEntityName(dbTarget);
dbRel.setToMany(toMany);
dbRel.setName(relName);
- dbRel.setToDependentPK(toDependentPK);
+ dbRel.setFK(isFK);
dbSrc.addRelationship(dbRel);
List joins = (List) relMap.get("joins");
From 0f839053211cdb2e031d5367fef90b9c75ce7069 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Mon, 27 Mar 2023 14:51:01 +0200
Subject: [PATCH 08/14] RelationshipLoader update
---
.../reverse/dbload/RelationshipLoader.java | 24 +++++++------------
.../reverse/dbload/RelationshipsLoaderIT.java | 2 +-
2 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
index aa348c1c34..42360ddceb 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java
@@ -76,6 +76,7 @@ public void load(DatabaseMetaData metaData, DbLoadDataStore map) throws SQLExcep
DbRelationship forwardRelationship = new DbRelationship();
forwardRelationship.setSourceEntity(pkEntity);
forwardRelationship.setTargetEntityName(fkEntity);
+ forwardRelationship.setFK(false);
// TODO: dirty and non-transparent... using DbRelationshipDetected for the benefit of the merge package.
// This info is available from joins....
@@ -84,14 +85,10 @@ public void load(DatabaseMetaData metaData, DbLoadDataStore map) throws SQLExcep
reverseRelationship.setSourceEntity(fkEntity);
reverseRelationship.setTargetEntityName(pkEntity);
reverseRelationship.setToMany(false);
-
+ reverseRelationship.setFK(true);
createAndAppendJoins(exportedKeys, pkEntity, fkEntity, forwardRelationship, reverseRelationship);
- boolean fk = isFK(forwardRelationship);
- boolean toMany = isToMany(fk, fkEntity, forwardRelationship);
-
- forwardRelationship.setFK(fk);
- forwardRelationship.setToMany(toMany);
+ forwardRelationship.setToMany(isToMany(fkEntity,forwardRelationship));
// set relationship names only after their joins are ready ...
// generator logic is based on relationship state...
@@ -146,18 +143,13 @@ private void checkAndAddRelationship(DbEntity entity, DbRelationship relationshi
}
}
- private boolean isToMany(boolean isFK, DbEntity fkEntity, DbRelationship forwardRelationship) {
- return !isFK || fkEntity.getPrimaryKeys().size() != forwardRelationship.getJoins().size();
- }
-
- private boolean isFK(DbRelationship forwardRelationship) {
- for (DbJoin dbJoin : forwardRelationship.getJoins()) {
- if (!dbJoin.getTarget().isPrimaryKey()) {
- return false;
+ private boolean isToMany(DbEntity fkEntity, DbRelationship forwardRelationship) {
+ for (DbJoin join : forwardRelationship.getJoins()) {
+ if (!join.getSource().isPrimaryKey() || !join.getTarget().isPrimaryKey()) {
+ return true;
}
}
-
- return true;
+ return fkEntity.getPrimaryKeys().size() != forwardRelationship.getJoins().size();
}
private void createAndAppendJoins(Set exportedKeys, DbEntity pkEntity, DbEntity fkEntity,
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
index 2c0189a0eb..7b78c61082 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipsLoaderIT.java
@@ -76,7 +76,7 @@ public void testRelationshipLoad() throws Exception {
assertNotNull("No relationship to PAINTING_INFO", oneToOne);
assertFalse("Relationship to PAINTING_INFO must be to-one", oneToOne.isToMany());
- assertTrue("Relationship to PAINTING_INFO must be to-one", oneToOne.isFK());
+ assertTrue("Relationship to PAINTING_INFO must be to-one", !oneToOne.isFK());
}
// private void assertUniqueConstraintsInRelationships(DataMap map) {
From 1c55d29ebc903d7fa2be2d44f11b66dfeca401f9 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Mon, 27 Mar 2023 14:51:39 +0200
Subject: [PATCH 09/14] rename in DbRelationshipValidator
---
.../project/validation/DbRelationshipValidator.java | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/validation/DbRelationshipValidator.java b/cayenne-project/src/main/java/org/apache/cayenne/project/validation/DbRelationshipValidator.java
index 9fffbbc0f3..4543e74524 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/validation/DbRelationshipValidator.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/validation/DbRelationshipValidator.java
@@ -137,14 +137,13 @@ private void checkTypesOfAttributesInRelationship(DbRelationship relationship, V
}
private void checkOnGeneratedStrategyConflict(DbRelationship relationship, ValidationResult validationResult) {
- if (relationship.isToDependentPK()) {
- Collection attributes = relationship.getTargetEntity().getGeneratedAttributes();
- for (DbAttribute attribute : attributes) {
- if (attribute.isGenerated()) {
+ if (relationship.isFK()) {
+ for (DbJoin join : relationship.getJoins()) {
+ if (join.getSource().isGenerated()) {
addFailure(
validationResult,
relationship,
- "'To Dep Pk' incompatible with Database-Generated on '%s' relationship",
+ "'FK' incompatible with Database-Generated on '%s' relationship",
toString(relationship));
}
}
From e0956b1d69b0b82ae124517aa0166728b26b1e51 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka
Date: Tue, 4 Apr 2023 16:37:20 +0300
Subject: [PATCH 10/14] ToDepPkToFkUpdater added
---
.../upgrade/DefaultUpgradeService.java | 2 +-
.../upgrade/handlers/UpgradeHandler.java | 6 +
.../upgrade/handlers/UpgradeHandler_V11.java | 8 +
.../upgrade/utils/ToDepPkToFkUpdater.java | 251 ++++++++++++++++++
.../upgrade/DefaultUpgradeServiceTest.java | 2 +-
.../handlers/BaseUpgradeHandlerTest.java | 15 ++
.../handlers/UpgradeHandler_V11Test.java | 78 ++++++
.../upgrade/handlers/fkTestmap-1.map.xml | 135 ++++++++++
.../upgrade/handlers/fkTestmap-2.map.xml | 16 ++
9 files changed, 511 insertions(+), 2 deletions(-)
create mode 100644 cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java
create mode 100644 cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-1.map.xml
create mode 100644 cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-2.map.xml
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
index ceafe92a23..ee9a16936f 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/DefaultUpgradeService.java
@@ -187,8 +187,8 @@ protected List upgradeDOM(Resource resource, List h
for(UpgradeUnit dataMapUnit : dataMapUnits) {
handler.processDataMapDom(dataMapUnit);
}
+ handler.processAllDataMapDomes(dataMapUnits);
}
-
return allUnits;
}
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler.java
index e0818a261b..27219711ca 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler.java
@@ -29,6 +29,8 @@
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
+import java.util.List;
+
/**
* Interface that upgrade handlers should implement.
* Implementation also should be injected into DI stack in right order.
@@ -108,4 +110,8 @@ default void updateExtensionSchema(UpgradeUnit upgradeUnit, String extension) {
element.setAttribute("xmlns", "http://cayenne.apache.org/schema/"+getVersion()+"/"+extension);
}
}
+
+ default void processAllDataMapDomes(List dataMapUnits) {
+ //noop
+ }
}
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
index efa19727f2..6d92453d88 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
@@ -20,6 +20,7 @@
package org.apache.cayenne.project.upgrade.handlers;
import org.apache.cayenne.project.upgrade.UpgradeUnit;
+import org.apache.cayenne.project.upgrade.utils.ToDepPkToFkUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
@@ -36,6 +37,7 @@
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -87,6 +89,12 @@ public void processDataMapDom(UpgradeUnit upgradeUnit) {
updateDbImportConfig(upgradeUnit);
}
+ @Override
+ public void processAllDataMapDomes(List dataMapUnits) {
+ ToDepPkToFkUpdater fkUpdater = new ToDepPkToFkUpdater();
+ fkUpdater.update(dataMapUnits);
+ }
+
private void upgradeComments(UpgradeUnit upgradeUnit) {
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList infoNodes;
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java
new file mode 100644
index 0000000000..b24aa621f2
--- /dev/null
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java
@@ -0,0 +1,251 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.project.upgrade.utils;
+
+import org.apache.cayenne.project.upgrade.UpgradeUnit;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ToDepPkToFkUpdater {
+
+ private static final String TO_DEP_PK_TAG = "toDependentPK";
+ private static final String FK_TAG = "fk";
+ private static final String DB_RELATIONSHIP_TAG = "db-relationship";
+ private static final String DB_ENTITY_TAG = "db-entity";
+ private static final String DB_ATTRIBUTE_PAIR_TAG = "db-attribute-pair";
+
+ public void update(List units) {
+
+ List dataMaps = new ArrayList<>(units.size());
+ List combinedDbEntityList = new ArrayList<>();
+
+ for (UpgradeUnit upgradeUnit : units) {
+ Element dataMap = upgradeUnit.getDocument().getDocumentElement();
+ dataMaps.add(dataMap);
+ combinedDbEntityList.add(dataMap.getElementsByTagName(DB_ENTITY_TAG));
+ }
+
+ for (Element dataMap : dataMaps) {
+ NodeList relationships = dataMap.getElementsByTagName(DB_RELATIONSHIP_TAG);
+
+ for (int i = 0; i < relationships.getLength(); i++) {
+ Node relationship = relationships.item(i);
+
+ Element reverseRelationship = findReverseRelationship(relationships, relationship);
+
+ if (reverseRelationship == null) {
+ reverseRelationship = findReverseInAllDatamaps(dataMaps, relationship);
+ }
+
+ if (!isToDepPK(relationship)
+ && !isToDepPK(reverseRelationship)
+ && !isFK(relationship)
+ && !isFK(reverseRelationship)) {
+ setFk((Element) relationship, reverseRelationship, combinedDbEntityList);
+ }
+
+ if (isToDepPK(relationship)) {
+ handleToDepPK(relationship, reverseRelationship, combinedDbEntityList);
+ }
+ }
+ }
+ }
+
+ private Element findReverseInAllDatamaps(List dataMaps, Node relationship) {
+ for (Element dataMap : dataMaps) {
+ NodeList relationships = dataMap.getElementsByTagName(DB_RELATIONSHIP_TAG);
+ Element reverseRelationship = findReverseRelationship(relationships, relationship);
+ if (reverseRelationship != null) {
+ return reverseRelationship;
+ }
+ }
+ return null;
+ }
+
+ private void setFk(Element relationship, Element reverseRelationship, List combinedDbEntityList) {
+ NodeList pairNodes = relationship.getElementsByTagName(DB_ATTRIBUTE_PAIR_TAG);
+ for (int i = 0; i < pairNodes.getLength(); i++) {
+ String joinSource = pairNodes.item(i).getAttributes().getNamedItem("source").getNodeValue();
+ String joinTarget = pairNodes.item(i).getAttributes().getNamedItem("target").getNodeValue();
+
+ NamedNodeMap relationshipAttrs = relationship.getAttributes();
+
+ String sourceEntityName = relationshipAttrs.getNamedItem("source").getNodeValue();
+ String targetEntityName = relationshipAttrs.getNamedItem("target").getNodeValue();
+
+ Node sourceEntity = getDbEntityByName(combinedDbEntityList, sourceEntityName);
+ Node targetEntity = getDbEntityByName(combinedDbEntityList, targetEntityName);
+
+ if (sourceEntity != null && targetEntity != null) {
+
+ boolean sourceIsPrimaryKey = isPrimaryKey(joinSource, sourceEntity.getChildNodes());
+ boolean targetIsPrimaryKey = isPrimaryKey(joinTarget, targetEntity.getChildNodes());
+
+ if (sourceIsPrimaryKey != targetIsPrimaryKey) {
+ if (reverseRelationship != null && sourceIsPrimaryKey) {
+ reverseRelationship.setAttribute(FK_TAG, "true");
+ }
+ if (reverseRelationship != null && !sourceIsPrimaryKey) {
+ relationship.setAttribute(FK_TAG, "true");
+ }
+
+ if (reverseRelationship == null && !sourceIsPrimaryKey) {
+ relationship.setAttribute(FK_TAG, "true");
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ private boolean isPrimaryKey(String joinName, NodeList childNodes) {
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node item = childNodes.item(i);
+ if (item.getAttributes() != null) {
+ String name = item.getAttributes().getNamedItem("name").getNodeValue();
+ if (name.equals(joinName)) {
+ Node isPrimaryKey = item.getAttributes().getNamedItem("isPrimaryKey");
+ if (isPrimaryKey != null) {
+ return isPrimaryKey.getNodeValue().equals("true");
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private Node getDbEntityByName(List combinedDbEntityList, String searchedEntityName) {
+ for (NodeList list : combinedDbEntityList) {
+ for (int i = 0; i < list.getLength(); i++) {
+ String entityName = list.item(i).getAttributes().getNamedItem("name").getNodeValue();
+ if (searchedEntityName.equals(entityName)) {
+ return list.item(i);
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean isToDepPK(Node relationship) {
+ if (relationship == null) {
+ return false;
+ }
+ NamedNodeMap relationshipAttrs = relationship.getAttributes();
+ Node toDependentPK = relationshipAttrs.getNamedItem(TO_DEP_PK_TAG);
+ return toDependentPK != null && toDependentPK.getNodeValue().equalsIgnoreCase("true");
+ }
+
+ private boolean isFK(Node relationship) {
+ if (relationship == null) {
+ return false;
+ }
+ NamedNodeMap relationshipAttrs = relationship.getAttributes();
+ Node fkNode = relationshipAttrs.getNamedItem(FK_TAG);
+ return fkNode != null && fkNode.getNodeValue().equalsIgnoreCase("true");
+ }
+
+ private void handleToDepPK(Node relationship, Element reverseRelationship, List combinedDbEntityList) {
+ relationship.getAttributes().removeNamedItem(TO_DEP_PK_TAG);
+ if (reverseRelationship != null) {
+ if (!isToDepPK(reverseRelationship)) {
+ reverseRelationship.setAttribute(FK_TAG, "true");
+ } else {
+ reverseRelationship.getAttributes().removeNamedItem(TO_DEP_PK_TAG);
+ setFk((Element) relationship, reverseRelationship, combinedDbEntityList);
+ }
+ }
+ }
+
+ private Element findReverseRelationship(NodeList dbRelationshipList, Node dbRelationshipNode) {
+ Element dbRelationship = (Element) dbRelationshipNode;
+
+ String sourceAttr = dbRelationship.getAttribute("source");
+ String targetAttr = dbRelationship.getAttribute("target");
+
+ List pairs = getDbAttrPairs(dbRelationship);
+
+ for (int j = 0; j < dbRelationshipList.getLength(); j++) {
+ Node candidateDbRelationshipNode = dbRelationshipList.item(j);
+ if (candidateDbRelationshipNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element candidateDbRelationship = (Element) candidateDbRelationshipNode;
+ if (isCandidateSuitable(sourceAttr, targetAttr, pairs, candidateDbRelationship)) {
+ return candidateDbRelationship;
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean isCandidateSuitable(String sourceAttr, String targetAttr, List pairs, Element candidateDbRelationship) {
+ String candidateSourceAttr = candidateDbRelationship.getAttribute("source");
+ String candidateTargetAttr = candidateDbRelationship.getAttribute("target");
+
+ List candidatePairs = getDbAttrPairs(candidateDbRelationship);
+
+ return sourceAttr.equals(candidateTargetAttr)
+ && targetAttr.equals(candidateSourceAttr)
+ && pairs.size() == candidatePairs.size()
+ && containAllReversed(pairs, candidatePairs);
+ }
+
+ private boolean containAllReversed(List pairs, List candidatePairs) {
+ return pairs.stream()
+ .allMatch(pair -> candidatePairs.stream().anyMatch(pair::isReverseFor));
+ }
+
+ private List getDbAttrPairs(Element dbRelationship) {
+ List pairs = new ArrayList<>();
+ NodeList attributes = dbRelationship.getElementsByTagName(DB_ATTRIBUTE_PAIR_TAG);
+ for (int j = 0; j < attributes.getLength(); j++) {
+ Node attributeNode = attributes.item(j);
+ if (attributeNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = (Element) attributeNode;
+ String pairSource = element.getAttribute("source");
+ String pairTarget = element.getAttribute("target");
+ pairs.add(new DbAttrPair(pairSource, pairTarget));
+ }
+ }
+ return pairs;
+ }
+
+ private static class DbAttrPair {
+ private final String source;
+ private final String target;
+
+ public DbAttrPair(String source, String target) {
+ this.source = source;
+ this.target = target;
+ }
+
+ private boolean isReverseFor(DbAttrPair pair) {
+ return this.source.equals(pair.target) && this.target.equals(pair.source);
+ }
+
+ }
+}
+
+
+
+
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
index a2ba5ca124..3d594ccfec 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
@@ -131,7 +131,7 @@ public void upgradeDOM() throws Exception {
verify(handler).processProjectDom(any(UpgradeUnit.class));
// two data maps
verify(handler, times(2)).processDataMapDom(any(UpgradeUnit.class));
- verifyNoMoreInteractions(handler);
+ // verifyNoMoreInteractions(handler);
}
}
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/BaseUpgradeHandlerTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/BaseUpgradeHandlerTest.java
index e021b15900..9cf1266cca 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/BaseUpgradeHandlerTest.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/BaseUpgradeHandlerTest.java
@@ -21,6 +21,8 @@
import java.io.InputStreamReader;
import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -58,6 +60,19 @@ Document processDataMapDom(String xmlResourceName) throws Exception {
return unit.getDocument();
}
+ List processAllDataMapDomes(List xmlResourceNames) throws Exception {
+ List upgradeUnits = new ArrayList<>(xmlResourceNames.size());
+ List documents = new ArrayList<>();
+ for (String xmlResourceName : xmlResourceNames) {
+ UpgradeUnit unit = new UpgradeUnit(new URLResource(getClass().getResource(xmlResourceName)),
+ documentFromResource(xmlResourceName));
+ upgradeUnits.add(unit);
+ documents.add(unit.getDocument());
+ }
+ handler.processAllDataMapDomes(upgradeUnits);
+ return documents;
+ }
+
Document documentFromString(String xml) throws Exception {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
return db.parse(new InputSource(new StringReader(xml)));
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
index b5419295de..c52b5a54b0 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
@@ -27,7 +27,12 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import java.util.Arrays;
+import java.util.List;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@@ -181,6 +186,79 @@ public void testDbImportDomUpgrade() throws Exception {
assertEquals(1, elements);
}
+ @Test
+ public void testToDepPkToFkUpgrade() throws Exception {
+ List resources = Arrays.asList( "fkTestmap-1.map.xml","fkTestmap-2.map.xml");
+ List documents = processAllDataMapDomes(resources);
+ Document fkTestmap_1 = documents.get(0);
+ Document fkTestmap_2 = documents.get(1);
+
+ Element rootMap_1 = fkTestmap_1.getDocumentElement();
+ NodeList dbRelationshipsMap_1 = rootMap_1.getElementsByTagName("db-relationship");
+
+ Element rootMap_2 = fkTestmap_2.getDocumentElement();
+ NodeList dbRelationshipsMap_2 = rootMap_2.getElementsByTagName("db-relationship");
+
+ for (int i = 0; i < dbRelationshipsMap_1.getLength(); i++) {
+ NamedNodeMap attributes = dbRelationshipsMap_1.item(i).getAttributes();
+ String name = attributes.getNamedItem("name").getNodeValue();
+ Node fk = attributes.getNamedItem("fk");
+ switch (name) {
+ case "reverse_several_matching_joins":
+ case "noReverse_fk":
+ case "joinsAnotherOrder":
+ case "toDepPk":
+ case "nPk_Pk":
+ case "toDepPK_toDepPK":
+ assertNotNull(fk);
+ assertEquals(fk.getNodeValue(), "true");
+ break;
+
+ case "nPk_nPk":
+ case "reverse_nPk_nPk":
+ case "noReverse_notFk":
+ case "reverse_nPk_Pk":
+ case "reverse_PK_PK":
+ case "PK_PK":
+ case "several_matching_joins":
+ case "reverse_toDepPK_toDepPK":
+ assertNull(fk);
+ break;
+ }
+ }
+
+ for (int i = 0; i < dbRelationshipsMap_2.getLength(); i++) {
+ NamedNodeMap attributes = dbRelationshipsMap_2.item(i).getAttributes();
+ String name = attributes.getNamedItem("name").getNodeValue();
+ Node fk = attributes.getNamedItem("fk");
+ switch (name) {
+ case "reverse_reverseInAnotherDatamap":
+ case "reverse_reverseInAnotherDatamapToDepPK":
+ assertNotNull(fk);
+ assertEquals(fk.getNodeValue(), "true");
+ break;
+ }
+ }
+
+ for (int i = 0; i < dbRelationshipsMap_1.getLength(); i++) {
+ NamedNodeMap attributes = dbRelationshipsMap_1.item(i).getAttributes();
+ String name = attributes.getNamedItem("name").getNodeValue();
+ Node toDepPK = attributes.getNamedItem("toDependentPK");
+ switch (name) {
+ case "reverse_toDepPk":
+ case "reverseInAnotherDatamapToDepPK":
+ case "toDepPK_toDepPK":
+ case "reverse_toDepPK_toDepPK":
+ assertNull(toDepPK);
+ break;
+ }
+ }
+
+ assertEquals(18, dbRelationshipsMap_1.getLength());
+ assertEquals(2, dbRelationshipsMap_2.getLength());
+
+ }
+
@Test
public void testModelUpgrade() {
DataChannelDescriptor descriptor = mock(DataChannelDescriptor.class);
diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-1.map.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-1.map.xml
new file mode 100644
index 0000000000..81e93ab510
--- /dev/null
+++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-1.map.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-2.map.xml b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-2.map.xml
new file mode 100644
index 0000000000..e0383b5b11
--- /dev/null
+++ b/cayenne-project/src/test/resources/org/apache/cayenne/project/upgrade/handlers/fkTestmap-2.map.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 9835613e905737adfc6fa78c1de38c3660339e57 Mon Sep 17 00:00:00 2001
From: Ivan Nikitka
Date: Fri, 7 Apr 2023 17:00:48 +0300
Subject: [PATCH 11/14] comments update
---
.../flush/ArcValuesCreationHandler.java | 4 ++--
.../java/org/apache/cayenne/map/DbEntity.java | 2 +-
.../dbentity/DbAttributeTableModel.java | 21 +------------------
3 files changed, 4 insertions(+), 23 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
index 6abd47744c..1b3cecc4e9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
@@ -172,8 +172,8 @@ protected void processRelationship(DbRelationship dbRelationship, ObjectId srcId
// We manage 3 cases here:
// 1. PK -> FK: just propagate value from PK and to FK
- // 2. PK -> PK: check isToDep flag and set dependent one
- // 3. NON-PK -> FK (not supported fully for now, see CAY-2488): also check isToDep flag,
+ // 2. PK -> PK: check isFk flag and set dependent one
+ // 3. NON-PK -> FK (not supported fully for now, see CAY-2488): also check isFk flag,
// but get value from DbRow, not ObjID
if(srcPK != targetPK) {
// case 1
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
index 67b984dd6c..a67d22a7a1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java
@@ -423,7 +423,7 @@ private void handleAttributeUpdate(AttributeEvent e) {
}
}
- // check toDep PK for reverse relationships
+ // check isFk for reverse relationships
for (DbRelationship rel : getRelationships()) {
DbRelationship reverse = rel.getReverseRelationship();
if(reverse != null && reverse.isFK() && !reverse.isValidForFk()) {
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
index 37697b99b5..0a41d196e9 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
@@ -274,7 +274,6 @@ public boolean setPrimaryKey(Boolean newVal, DbAttribute attr, int row) {
// when PK is unset, we need to fix some derived flags
if (!flag) {
-//TODO OOOOOO
attr.setGenerated(false);
Collection relationships = ProjectUtil
@@ -285,27 +284,14 @@ public boolean setPrimaryKey(Boolean newVal, DbAttribute attr, int row) {
if (relationships.size() > 0) {
relationships.removeIf(relationship -> !relationship.isFK());
- // filtered only those that are to dep PK
+ // filtered only those that are isFk
if (relationships.size() > 0) {
- /* String message = (relationships.size() == 1)
- ? "Fix \"Foreign key\" relationship using this attribute?"
- : "Fix " + relationships.size()
- + " \"Foreign key\" relationships using this attribute?";
- */
-
-
StringBuilder message = new StringBuilder("Removing an attribute can affect the following relationships:\n");
for (DbRelationship relationship : relationships) {
message.append(relationship.getName()).append("\n");
}
message.append("It would be a good idea to check them after making the change. Continue?");
-
- /* JOptionPane.showMessageDialog(Application.getFrame()
- , message
- , "Warning"
- , JOptionPane.PLAIN_MESSAGE);
-*/
int answer = JOptionPane.showConfirmDialog(
Application.getFrame(),
message.toString(),
@@ -316,11 +302,6 @@ public boolean setPrimaryKey(Boolean newVal, DbAttribute attr, int row) {
// no action needed
return false;
}
-
- /* // fix target relationships
- for (DbRelationship relationship : relationships) {
- relationship.setFK(false);
- }*/
}
}
}
From 3866ac43948d1f9eed2820ead7d247a7d06fd75f Mon Sep 17 00:00:00 2001
From: Ivan Nikitka
Date: Fri, 7 Apr 2023 17:02:12 +0300
Subject: [PATCH 12/14] move to handlers package
---
.../cayenne/project/upgrade/handlers/UpgradeHandler_V11.java | 3 +--
.../upgrade/{utils => handlers/v11}/ToDepPkToFkUpdater.java | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
rename cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/{utils => handlers/v11}/ToDepPkToFkUpdater.java (99%)
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
index 6d92453d88..972235b8f0 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11.java
@@ -20,7 +20,7 @@
package org.apache.cayenne.project.upgrade.handlers;
import org.apache.cayenne.project.upgrade.UpgradeUnit;
-import org.apache.cayenne.project.upgrade.utils.ToDepPkToFkUpdater;
+import org.apache.cayenne.project.upgrade.handlers.v11.ToDepPkToFkUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
@@ -37,7 +37,6 @@
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Paths;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
similarity index 99%
rename from cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java
rename to cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
index b24aa621f2..d306ab97c5 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/utils/ToDepPkToFkUpdater.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
@@ -17,7 +17,7 @@
* under the License.
****************************************************************/
-package org.apache.cayenne.project.upgrade.utils;
+package org.apache.cayenne.project.upgrade.handlers.v11;
import org.apache.cayenne.project.upgrade.UpgradeUnit;
import org.w3c.dom.Element;
From 64dd442fed2a182efe2b1bbc75dc422f0545bb6d Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Tue, 11 Apr 2023 11:51:26 +0200
Subject: [PATCH 13/14] ToDepPkToFkUpdater refactoring
---
.../handlers/v11/ToDepPkToFkUpdater.java | 72 ++++++++++++-------
1 file changed, 46 insertions(+), 26 deletions(-)
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
index d306ab97c5..b1fa0eb72b 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/handlers/v11/ToDepPkToFkUpdater.java
@@ -20,6 +20,8 @@
package org.apache.cayenne.project.upgrade.handlers.v11;
import org.apache.cayenne.project.upgrade.UpgradeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@@ -36,6 +38,8 @@ public class ToDepPkToFkUpdater {
private static final String DB_ENTITY_TAG = "db-entity";
private static final String DB_ATTRIBUTE_PAIR_TAG = "db-attribute-pair";
+ private static final Logger logger = LoggerFactory.getLogger(ToDepPkToFkUpdater.class);
+
public void update(List units) {
List dataMaps = new ArrayList<>(units.size());
@@ -85,42 +89,56 @@ private Element findReverseInAllDatamaps(List dataMaps, Node relationsh
}
private void setFk(Element relationship, Element reverseRelationship, List combinedDbEntityList) {
- NodeList pairNodes = relationship.getElementsByTagName(DB_ATTRIBUTE_PAIR_TAG);
- for (int i = 0; i < pairNodes.getLength(); i++) {
- String joinSource = pairNodes.item(i).getAttributes().getNamedItem("source").getNodeValue();
- String joinTarget = pairNodes.item(i).getAttributes().getNamedItem("target").getNodeValue();
- NamedNodeMap relationshipAttrs = relationship.getAttributes();
-
- String sourceEntityName = relationshipAttrs.getNamedItem("source").getNodeValue();
- String targetEntityName = relationshipAttrs.getNamedItem("target").getNodeValue();
-
- Node sourceEntity = getDbEntityByName(combinedDbEntityList, sourceEntityName);
- Node targetEntity = getDbEntityByName(combinedDbEntityList, targetEntityName);
+ Node sourceEntity = getDbEntityByJoinDirection(combinedDbEntityList, relationship, "source");
+ Node targetEntity = getDbEntityByJoinDirection(combinedDbEntityList, relationship, "target");
+ NodeList pairNodes = relationship.getElementsByTagName(DB_ATTRIBUTE_PAIR_TAG);
+ for (int i = 0; i < pairNodes.getLength(); i++) {
if (sourceEntity != null && targetEntity != null) {
+ Node currentNode = pairNodes.item(i);
- boolean sourceIsPrimaryKey = isPrimaryKey(joinSource, sourceEntity.getChildNodes());
- boolean targetIsPrimaryKey = isPrimaryKey(joinTarget, targetEntity.getChildNodes());
+ boolean sourceIsPK = isPrimaryKey(sourceEntity, currentNode, "source");
+ boolean targetIsPK = isPrimaryKey(targetEntity, currentNode, "target");
- if (sourceIsPrimaryKey != targetIsPrimaryKey) {
- if (reverseRelationship != null && sourceIsPrimaryKey) {
- reverseRelationship.setAttribute(FK_TAG, "true");
- }
- if (reverseRelationship != null && !sourceIsPrimaryKey) {
- relationship.setAttribute(FK_TAG, "true");
- }
-
- if (reverseRelationship == null && !sourceIsPrimaryKey) {
- relationship.setAttribute(FK_TAG, "true");
- }
+ if (sourceIsPK != targetIsPK) {
+ handleDefinedFkCase(relationship, reverseRelationship, sourceIsPK);
return;
+ } else {
+ handleUndefinedFkCase(relationship, reverseRelationship, pairNodes, i);
}
}
}
}
- private boolean isPrimaryKey(String joinName, NodeList childNodes) {
+ private void handleUndefinedFkCase(Element relationship, Element reverseRelationship, NodeList pairNodes, int i) {
+ //Check is this last join, which means there are no joins where fk direction is defined and this
+ // relationship has both side.
+ if (isLastJoinPair(pairNodes, i) && reverseRelationship != null) {
+ relationship.setAttribute(FK_TAG, "true");
+ logger.warn(String.format("Foreign key in relationships pair %s and %s was undefined. FK = true was set in the %s by default"
+ , relationship.getAttribute("name")
+ , reverseRelationship.getAttribute("name")
+ , relationship.getAttribute("name")));
+ }
+ }
+
+ private void handleDefinedFkCase(Element relationship, Element reverseRelationship, boolean sourceIsPK) {
+ if (sourceIsPK && reverseRelationship != null) {
+ reverseRelationship.setAttribute(FK_TAG, "true");
+ }
+ if (!sourceIsPK) {
+ relationship.setAttribute(FK_TAG, "true");
+ }
+ }
+
+ private boolean isLastJoinPair(NodeList pairNodes, int i) {
+ return i == pairNodes.getLength() - 1;
+ }
+
+ private boolean isPrimaryKey(Node entity, Node node, String joinDirection) {
+ String joinName = node.getAttributes().getNamedItem(joinDirection).getNodeValue();
+ NodeList childNodes = entity.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (item.getAttributes() != null) {
@@ -136,7 +154,9 @@ private boolean isPrimaryKey(String joinName, NodeList childNodes) {
return false;
}
- private Node getDbEntityByName(List combinedDbEntityList, String searchedEntityName) {
+ private Node getDbEntityByJoinDirection(List combinedDbEntityList, Element relationship, String joinDirection) {
+ NamedNodeMap relationshipAttrs = relationship.getAttributes();
+ String searchedEntityName = relationshipAttrs.getNamedItem(joinDirection).getNodeValue();
for (NodeList list : combinedDbEntityList) {
for (int i = 0; i < list.getLength(); i++) {
String entityName = list.item(i).getAttributes().getNamedItem("name").getNodeValue();
From 135ab2469e02679fa1489edee3ce4110574f67bf Mon Sep 17 00:00:00 2001
From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com>
Date: Tue, 11 Apr 2023 11:52:16 +0200
Subject: [PATCH 14/14] tests updating
---
.../cayenne/project/upgrade/DefaultUpgradeServiceTest.java | 3 ++-
.../project/upgrade/handlers/UpgradeHandler_V11Test.java | 7 +++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
index 3d594ccfec..c0f4822736 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/DefaultUpgradeServiceTest.java
@@ -131,7 +131,8 @@ public void upgradeDOM() throws Exception {
verify(handler).processProjectDom(any(UpgradeUnit.class));
// two data maps
verify(handler, times(2)).processDataMapDom(any(UpgradeUnit.class));
- // verifyNoMoreInteractions(handler);
+ verify(handler).processAllDataMapDomes(anyList());
+ verifyNoMoreInteractions(handler);
}
}
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
index c52b5a54b0..fc6b826402 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/upgrade/handlers/UpgradeHandler_V11Test.java
@@ -209,17 +209,16 @@ public void testToDepPkToFkUpgrade() throws Exception {
case "joinsAnotherOrder":
case "toDepPk":
case "nPk_Pk":
+ case "nPk_nPk":
+ case "PK_PK":
case "toDepPK_toDepPK":
assertNotNull(fk);
assertEquals(fk.getNodeValue(), "true");
break;
-
- case "nPk_nPk":
- case "reverse_nPk_nPk":
case "noReverse_notFk":
case "reverse_nPk_Pk":
+ case "reverse_nPk_nPk":
case "reverse_PK_PK":
- case "PK_PK":
case "several_matching_joins":
case "reverse_toDepPK_toDepPK":
assertNull(fk);