This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit fe1a9f884f86956937948048b6904bc2b4f7d654
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat May 16 13:56:29 2026 -0400

    Tests cleanup
---
 .../apache/cayenne/unit/AllTestsSchemaManager.java | 266 ++++++++++++++-------
 .../org/apache/cayenne/unit/CayenneTestsEnv.java   |   7 +-
 cayenne/src/test/resources/cayenne-ALL.xml         |  68 ++++++
 3 files changed, 249 insertions(+), 92 deletions(-)

diff --git 
a/cayenne/src/test/java/org/apache/cayenne/unit/AllTestsSchemaManager.java 
b/cayenne/src/test/java/org/apache/cayenne/unit/AllTestsSchemaManager.java
index c229bacd7..a9dc68c2e 100644
--- a/cayenne/src/test/java/org/apache/cayenne/unit/AllTestsSchemaManager.java
+++ b/cayenne/src/test/java/org/apache/cayenne/unit/AllTestsSchemaManager.java
@@ -21,22 +21,13 @@ package org.apache.cayenne.unit;
 
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
-import org.apache.cayenne.access.DbGenerator;
-import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy;
-import org.apache.cayenne.access.jdbc.reader.DefaultRowReaderFactory;
-import 
org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
-import 
org.apache.cayenne.access.translator.select.DefaultSelectTranslatorFactory;
-import org.apache.cayenne.ashwood.AshwoodEntitySorter;
-import org.apache.cayenne.cache.MapQueryCache;
-import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.log.JdbcEventLogger;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.Procedure;
-import org.apache.cayenne.resource.URLResource;
+import org.apache.cayenne.runtime.CayenneRuntime;
 import org.apache.cayenne.unit.dba.TestDbAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,90 +43,49 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 import java.util.Set;
-import java.util.stream.Stream;
 
 public class AllTestsSchemaManager {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(AllTestsSchemaManager.class);
 
-    private static final String[] MAPS_FOR_SCHEMA_SETUP = {"testmap.map.xml", 
"compound.map.xml",
-            "misc-types.map.xml", "things.map.xml", "numeric-types.map.xml", 
"binary-pk.map.xml", "no-pk.map.xml",
-            "lob.map.xml", "date-time.map.xml", "enum.map.xml", 
"json.map.xml", "extended-type.map.xml",
-            "generated.map.xml", "mixed-persistence-strategy.map.xml", 
"people.map.xml", "primitive.map.xml",
-            "inheritance.map.xml", "locking.map.xml", "soft-delete.map.xml", 
"empty.map.xml", "relationships.map.xml",
-            "relationships-activity.map.xml", 
"relationships-delete-rules.map.xml",
-            "relationships-collection-to-many.map.xml", 
"relationships-child-master.map.xml",
-            "relationships-clob.map.xml", "relationships-flattened.map.xml", 
"relationships-many-to-many-join.map.xml",
-            "relationships-set-to-many.map.xml", 
"relationships-to-many-fk.map.xml", "relationships-to-one-fk.map.xml",
-            "return-types.map.xml", "uuid.map.xml", "multi-tier.map.xml", 
"reflexive.map.xml", "delete-rules.map.xml",
-            "lifecycle-callbacks-order.map.xml", "lifecycles.map.xml", 
"map-to-many.map.xml", "toone.map.xml",
-            "meaningful-pk.map.xml", "table-primitives.map.xml", 
"generic.map.xml", "map-db1.map.xml",
-            "map-db2.map.xml", "embeddable.map.xml", "qualified.map.xml", 
"quoted-identifiers.map.xml",
-            "inheritance-single-table1.map.xml", 
"inheritance-vertical.map.xml", "oneway-rels.map.xml",
-            "unsupported-distinct-types.map.xml", "array-type.map.xml", 
"cay-2032.map.xml",
-            "weighted-sort.map.xml", "hybrid-data-object.map.xml", 
"legacy-date-time.map.xml", "inheritance-with-enum.map.xml",
-            "lazy-attributes.map.xml", "cay2666/datamap.map.xml", 
"cay2641/datamapLazy.map.xml",
-            "annotation/datamapAnnotation.map.xml"};
-
     // hardcoded dependent entities that should be excluded if LOBs are not 
supported
     private static final Set<String> EXTRA_EXCLUDED_FOR_NO_LOB = 
Set.of("CLOB_DETAIL");
     private static final Set<String> EXTRA_EXCLUDED_FOR_NO_NATIVE_JSON = 
Set.of("JSON_OTHER");
 
     private final DataSource dataSource;
     private final TestDbAdapter testDbAdapter;
-    private final JdbcEventLogger jdbcEventLogger;
     private final DataDomain domain;
+    private final List<DataMap> dataMapsInSchemaSetupOrder;
 
-    public AllTestsSchemaManager(
-            DataSource dataSource,
-            DbAdapter dbAdapter,
-            JdbcEventLogger jdbcEventLogger,
-            DataMapLoader loader) {
+    public AllTestsSchemaManager(DataSource dataSource) {
 
         this.dataSource = dataSource;
-        this.testDbAdapter = TestDbAdapter.of(dbAdapter);
-        this.jdbcEventLogger = jdbcEventLogger;
-
-        // TODO: just create a normal CayenneRuntime with all the defaults
-        this.domain = initDomain(loader, dbAdapter);
-    }
-
-    private DataDomain initDomain(DataMapLoader loader, DbAdapter dbAdapter) {
-        DataDomain domain = new DataDomain("temp");
-        domain.setEventManager(new DefaultEventManager(2));
-        domain.setEntitySorter(new AshwoodEntitySorter());
-        domain.setQueryCache(new MapQueryCache(50));
-
-        Stream.of(MAPS_FOR_SCHEMA_SETUP).map(m -> 
getClass().getClassLoader().getResource(m))
-                .map(u -> loader.load(new URLResource(u)))
-                .forEach(m -> domain.addNode(initNode(m, dbAdapter)));
-
-        return domain;
-    }
-
-    private DataNode initNode(DataMap map, DbAdapter dbAdapter) {
+        this.domain = CayenneRuntime.builder()
+                .addConfig("cayenne-ALL.xml")
+                .dataSource(dataSource)
+                .build()
+                .getDataDomain();
+
+        this.testDbAdapter = 
TestDbAdapter.of(domain.getDefaultNode().getAdapter());
+
+        for (DataMap map : domain.getDataMaps()) {
+            // tweak mapping with a delegate
+            for (Procedure proc : map.getProcedures()) {
+                testDbAdapter.tweakProcedure(proc);
+            }
 
-        DataNode node = new DataNode(map.getName());
-        node.setJdbcEventLogger(jdbcEventLogger);
-        node.setAdapter(dbAdapter);
-        node.setDataSource(dataSource);
-        
-        // tweak mapping with a delegate
-        for (Procedure proc : map.getProcedures()) {
-            testDbAdapter.tweakProcedure(proc);
+            filterDataMap(map);
         }
-        filterDataMap(map);
 
-        node.addDataMap(map);
+        // TODO: suspect
+        domain.getEntitySorter().setEntityResolver(domain.getEntityResolver());
 
-        node.setSchemaUpdateStrategy(new SkipSchemaUpdateStrategy());
-        node.setRowReaderFactory(new DefaultRowReaderFactory());
-        node.setBatchTranslatorFactory(new DefaultBatchTranslatorFactory());
-        node.setSelectTranslatorFactory(new DefaultSelectTranslatorFactory());
-        return node;
+        this.dataMapsInSchemaSetupOrder = sortDataMapsInSchemaSetupOrder();
     }
 
     /**
@@ -185,8 +135,10 @@ public class AllTestsSchemaManager {
      * Drops all test tables.
      */
     private void dropSchema() throws Exception {
-        for (DataNode node : domain.getDataNodes()) {
-            dropSchema(node, node.getDataMaps().iterator().next());
+        ListIterator<DataMap> it = 
dataMapsInSchemaSetupOrder.listIterator(dataMapsInSchemaSetupOrder.size());
+        while (it.hasPrevious()) {
+            DataMap map = it.previous();
+            dropSchema(domain.lookupDataNode(map), map);
         }
     }
 
@@ -194,14 +146,14 @@ public class AllTestsSchemaManager {
      * Creates all test tables in the database.
      */
     private void createSchema() throws Exception {
-        for (DataNode node : domain.getDataNodes()) {
-            createSchema(node, node.getDataMaps().iterator().next());
+        for (DataMap map : dataMapsInSchemaSetupOrder) {
+            createSchema(domain.lookupDataNode(map), map);
         }
     }
 
     public void dropPKSupport() throws Exception {
-        for (DataNode node : domain.getDataNodes()) {
-            dropPKSupport(node, node.getDataMaps().iterator().next());
+        for (DataMap map : dataMapsInSchemaSetupOrder) {
+            dropPKSupport(domain.lookupDataNode(map), map);
         }
     }
 
@@ -211,9 +163,91 @@ public class AllTestsSchemaManager {
      * objects and data for primary key support.
      */
     public void createPKSupport() throws Exception {
-        for (DataNode node : domain.getDataNodes()) {
-            createPKSupport(node, node.getDataMaps().iterator().next());
+        for (DataMap map : dataMapsInSchemaSetupOrder) {
+            createPKSupport(domain.lookupDataNode(map), map);
+        }
+    }
+
+    private List<DataMap> sortDataMapsInSchemaSetupOrder() {
+        List<DataMap> maps = new ArrayList<>(domain.getDataMaps());
+        Map<DataMap, List<DataMap>> dependencies = new IdentityHashMap<>();
+
+        for (DataMap map : maps) {
+            dependencies.put(map, dataMapDependencies(map, maps));
+        }
+
+        List<DataMap> sorted = new ArrayList<>(maps.size());
+        Set<DataMap> visited = Collections.newSetFromMap(new 
IdentityHashMap<>());
+        Set<DataMap> visiting = Collections.newSetFromMap(new 
IdentityHashMap<>());
+
+        for (DataMap map : maps) {
+            sortDataMap(map, dependencies, visited, visiting, sorted);
+        }
+
+        return Collections.unmodifiableList(sorted);
+    }
+
+    private List<DataMap> dataMapDependencies(DataMap map, List<DataMap> maps) 
{
+        List<DataMap> dependencies = new ArrayList<>();
+
+        for (DbEntity entity : map.getDbEntities()) {
+            for (DbRelationship relationship : entity.getRelationships()) {
+                DataMap targetMap = dataMapDependency(map, relationship);
+                if (targetMap != null && maps.contains(targetMap) && 
!dependencies.contains(targetMap)) {
+                    dependencies.add(targetMap);
+                }
+            }
+        }
+
+        return dependencies;
+    }
+
+    private DataMap dataMapDependency(DataMap sourceMap, DbRelationship 
relationship) {
+        if (relationship.isRuntime() || relationship.isToMany() || 
!relationship.isToPK() || relationship.isToDependentPK()) {
+            return null;
+        }
+
+        boolean hasUnresolvedJoin = relationship.getJoins().stream()
+                .anyMatch(join -> join.getSource() == null || join.getTarget() 
== null);
+        if (hasUnresolvedJoin) {
+            return null;
+        }
+
+        DbEntity targetEntity = relationship.getTargetEntity();
+        DataMap targetMap = targetEntity != null ? targetEntity.getDataMap() : 
null;
+        if (targetMap == null || targetMap == sourceMap) {
+            return null;
+        }
+
+        if (domain.lookupDataNode(sourceMap) != 
domain.lookupDataNode(targetMap)) {
+            return null;
         }
+
+        return targetMap;
+    }
+
+    private void sortDataMap(
+            DataMap map,
+            Map<DataMap, List<DataMap>> dependencies,
+            Set<DataMap> visited,
+            Set<DataMap> visiting,
+            List<DataMap> sorted) {
+
+        if (visited.contains(map)) {
+            return;
+        }
+
+        if (!visiting.add(map)) {
+            throw new IllegalStateException("Cycle in DataMap dependencies 
involving " + map.getName());
+        }
+
+        for (DataMap dependency : dependencies.getOrDefault(map, 
Collections.emptyList())) {
+            sortDataMap(dependency, dependencies, visited, visiting, sorted);
+        }
+
+        visiting.remove(map);
+        visited.add(map);
+        sorted.add(map);
     }
 
     public List<DbEntity> dbEntitiesInInsertOrder(String mapName) {
@@ -229,7 +263,7 @@ public class AllTestsSchemaManager {
         // intentionally taking "mapName", not a "map", as we need to resolve 
the corresponding map in our private
         // namespace defined by "domain"
 
-        DataMap localMap = domain.getDataMap(mapName);
+        DataMap localMap = dataMap(mapName);
         List<DbEntity> entities = new ArrayList<>(localMap.getDbEntities());
         entities.removeAll(excludeEntities(entities));
 
@@ -376,8 +410,6 @@ public class AllTestsSchemaManager {
         DbAdapter adapter = node.getAdapter();
 
         List<DbEntity> orderedEntities = 
dbEntitiesInInsertOrder(map.getName());
-        List<DbEntity> excludedEntities = excludeEntities(map.getDbEntities());
-        DbGenerator gen = new DbGenerator(adapter, map, excludedEntities, 
domain, jdbcEventLogger);
         List<String> queries = new ArrayList<>();
 
         // table definitions
@@ -391,10 +423,72 @@ public class AllTestsSchemaManager {
                 continue;
             }
 
-            List<String> qs = gen.createConstraintsQueries(ent);
-            queries.addAll(qs);
+            queries.addAll(createConstraintsQueries(adapter, ent));
         }
 
         return queries;
     }
+
+    private List<String> createConstraintsQueries(DbAdapter adapter, DbEntity 
table) {
+        List<String> queries = new ArrayList<>();
+
+        for (DbRelationship rel : table.getRelationships()) {
+
+            if (rel.isRuntime()) {
+                continue;
+            }
+
+            if (rel.isToMany()) {
+                continue;
+            }
+
+            DataMap srcMap = rel.getSourceEntity().getDataMap();
+            DataMap targetMap = rel.getTargetEntity().getDataMap();
+
+            if (srcMap != null && targetMap != null && srcMap != targetMap) {
+                continue;
+            }
+
+            if (rel.isToPK() && !rel.isToDependentPK()) {
+                boolean hasUnresolvedJoin = rel.getJoins().stream()
+                        .anyMatch(join -> join.getSource() == null || 
join.getTarget() == null);
+
+                if (hasUnresolvedJoin) {
+                    continue;
+                }
+
+                if (adapter.supportsUniqueConstraints()) {
+                    DbRelationship reverse = rel.getReverseRelationship();
+                    if (reverse != null && !reverse.isToMany() && 
!reverse.isToPK()) {
+                        String unique = 
adapter.createUniqueConstraint(rel.getSourceEntity(), 
rel.getSourceAttributes());
+                        if (unique != null) {
+                            queries.add(unique);
+                        }
+                    }
+                }
+
+                String fk = adapter.createFkConstraint(rel);
+                if (fk != null) {
+                    queries.add(fk);
+                }
+            }
+        }
+
+        return queries;
+    }
+
+    private DataMap dataMap(String name) {
+        DataMap dataMap = domain.getDataMap(name);
+        if (dataMap != null) {
+            return dataMap;
+        }
+
+        for (DataMap candidate : domain.getDataMaps()) {
+            if (candidate.getName().endsWith('/' + name)) {
+                return candidate;
+            }
+        }
+
+        throw new IllegalArgumentException("Unknown DataMap: " + name);
+    }
 }
diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java 
b/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java
index e23013762..610ae6117 100644
--- a/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java
+++ b/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java
@@ -27,7 +27,6 @@ import org.apache.cayenne.access.jdbc.reader.RowReaderFactory;
 import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
 import org.apache.cayenne.access.translator.select.SelectTranslatorFactory;
 import org.apache.cayenne.configuration.Constants;
-import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.configuration.DataSourceDescriptor;
 import org.apache.cayenne.configuration.runtime.CoreModule;
@@ -78,11 +77,7 @@ public class CayenneTestsEnv implements BeforeEachCallback, 
AfterEachCallback {
                 INJECTOR.getInstance(DataSourceDescriptor.class),
                 INJECTOR.getInstance(AdhocObjectFactory.class));
 
-        SCHEMAS = new AllTestsSchemaManager(
-                DATA_SOURCES.sharedDataSource(),
-                INJECTOR.getInstance(DbAdapter.class),
-                INJECTOR.getInstance(JdbcEventLogger.class),
-                INJECTOR.getInstance(DataMapLoader.class));
+        SCHEMAS = new AllTestsSchemaManager(DATA_SOURCES.sharedDataSource());
 
         SCHEMAS.rebuildSchema();
     }
diff --git a/cayenne/src/test/resources/cayenne-ALL.xml 
b/cayenne/src/test/resources/cayenne-ALL.xml
new file mode 100644
index 000000000..b3035d0f0
--- /dev/null
+++ b/cayenne/src/test/resources/cayenne-ALL.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain xmlns="http://cayenne.apache.org/schema/12/domain";
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+        xsi:schemaLocation="http://cayenne.apache.org/schema/12/domain 
https://cayenne.apache.org/schema/12/domain.xsd";
+        project-version="12">
+       <map name="testmap"/>
+       <map name="compound"/>
+       <map name="misc-types"/>
+       <map name="things"/>
+       <map name="numeric-types"/>
+       <map name="binary-pk"/>
+       <map name="no-pk"/>
+       <map name="lob"/>
+       <map name="date-time"/>
+       <map name="enum"/>
+       <map name="json"/>
+       <map name="extended-type"/>
+       <map name="generated"/>
+       <map name="mixed-persistence-strategy"/>
+       <map name="people"/>
+       <map name="primitive"/>
+       <map name="inheritance"/>
+       <map name="locking"/>
+       <map name="soft-delete"/>
+       <map name="empty"/>
+       <map name="relationships"/>
+       <map name="relationships-activity"/>
+       <map name="relationships-delete-rules"/>
+       <map name="relationships-collection-to-many"/>
+       <map name="relationships-child-master"/>
+       <map name="relationships-clob"/>
+       <map name="relationships-flattened"/>
+       <map name="relationships-many-to-many-join"/>
+       <map name="relationships-set-to-many"/>
+       <map name="relationships-to-many-fk"/>
+       <map name="relationships-to-one-fk"/>
+       <map name="return-types"/>
+       <map name="uuid"/>
+       <map name="multi-tier"/>
+       <map name="reflexive"/>
+       <map name="delete-rules"/>
+       <map name="lifecycle-callbacks-order"/>
+       <map name="lifecycles"/>
+       <map name="map-to-many"/>
+       <map name="toone"/>
+       <map name="meaningful-pk"/>
+       <map name="table-primitives"/>
+       <map name="generic"/>
+       <map name="map-db1"/>
+       <map name="map-db2"/>
+       <map name="embeddable"/>
+       <map name="qualified"/>
+       <map name="quoted-identifiers"/>
+       <map name="inheritance-single-table1"/>
+       <map name="inheritance-vertical"/>
+       <map name="oneway-rels"/>
+       <map name="unsupported-distinct-types"/>
+       <map name="array-type"/>
+       <map name="cay-2032"/>
+       <map name="weighted-sort"/>
+       <map name="hybrid-data-object"/>
+       <map name="legacy-date-time"/>
+       <map name="inheritance-with-enum"/>
+       <map name="lazy-attributes"/>
+       <map name="cay2666/datamap"/>
+       <map name="cay2641/datamapLazy"/>
+       <map name="annotation/datamapAnnotation"/>
+</domain>

Reply via email to