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 2086d0bf1b2da115171dfcee51d0044de8a7f36d Author: Andrus Adamchik <[email protected]> AuthorDate: Fri May 15 19:14:07 2026 -0400 tests cleanup further unwinding weird tests injection --- .../apache/cayenne/CayennePersistentObjectIT.java | 283 +++++++++++---------- .../org/apache/cayenne/unit/CayenneTestsEnv.java | 60 ++--- .../cayenne/unit/dba/DerbyUnitDbAdapter.java | 5 - .../cayenne/unit/dba/MySQLUnitDbAdapter.java | 5 - .../cayenne/unit/dba/SQLServerUnitDbAdapter.java | 17 +- .../cayenne/unit/dba/SQLiteUnitDbAdapter.java | 10 - .../org/apache/cayenne/unit/dba/UnitDbAdapter.java | 114 +++++---- .../unit/runtime/AllTestsSchemaManager.java | 7 +- .../cayenne/unit/runtime/RuntimeCaseModule.java | 36 +-- .../RuntimeCaseSharedDataSourceFactory.java | 39 --- 10 files changed, 227 insertions(+), 349 deletions(-) diff --git a/cayenne/src/test/java/org/apache/cayenne/CayennePersistentObjectIT.java b/cayenne/src/test/java/org/apache/cayenne/CayennePersistentObjectIT.java index 8285a7293..4a1617b20 100644 --- a/cayenne/src/test/java/org/apache/cayenne/CayennePersistentObjectIT.java +++ b/cayenne/src/test/java/org/apache/cayenne/CayennePersistentObjectIT.java @@ -19,158 +19,159 @@ package org.apache.cayenne; -import static org.junit.jupiter.api.Assertions.*; - -import java.util.ArrayList; -import java.util.List; - import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.testdo.testmap.Artist; import org.apache.cayenne.testdo.testmap.ArtistExhibit; import org.apache.cayenne.testdo.testmap.Painting; -import org.apache.cayenne.unit.runtime.CayenneProjects; import org.apache.cayenne.unit.CayenneTestsEnv; -import org.junit.jupiter.api.extension.RegisterExtension; +import org.apache.cayenne.unit.runtime.CayenneProjects; import org.apache.cayenne.unit.util.TstBean; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + public class CayennePersistentObjectIT { - @RegisterExtension - static final CayenneTestsEnv env = CayenneTestsEnv.forProject(CayenneProjects.TESTMAP_PROJECT); + @RegisterExtension + static final CayenneTestsEnv env = CayenneTestsEnv.forProject(CayenneProjects.TESTMAP_PROJECT); - @Test - public void setObjectId() throws Exception { - GenericPersistentObject object = new GenericPersistentObject(); + @Test + public void setObjectId() throws Exception { + GenericPersistentObject object = new GenericPersistentObject(); ObjectId oid = ObjectId.of("T"); - assertNull(object.getObjectId()); - - object.setObjectId(oid); - assertSame(oid, object.getObjectId()); - } - - @Test - public void setPersistenceState() throws Exception { - GenericPersistentObject obj = new GenericPersistentObject(); - assertEquals(PersistenceState.TRANSIENT, obj.getPersistenceState()); - - obj.setPersistenceState(PersistenceState.COMMITTED); - assertEquals(PersistenceState.COMMITTED, obj.getPersistenceState()); - } - - @Test - public void readNestedProperty1() throws Exception { - Artist a = new Artist(); - assertNull(a.readNestedProperty("artistName")); - a.setArtistName("aaa"); - assertEquals("aaa", a.readNestedProperty("artistName")); - } - - @Test - public void readNestedPropertyNotPersistentString() throws Exception { - Artist a = new Artist(); - assertNull(a.readNestedProperty("someOtherProperty")); - a.setSomeOtherProperty("aaa"); - assertEquals("aaa", a.readNestedProperty("someOtherProperty")); - } - - @Test - public void readNestedPropertyNonPersistentNotString() throws Exception { - Artist a = new Artist(); - Object object = new Object(); - assertNull(a.readNestedProperty("someOtherObjectProperty")); - a.setSomeOtherObjectProperty(object); - assertSame(object, a.readNestedProperty("someOtherObjectProperty")); - } - - @Test - public void readNestedPropertyNonPersistentObjectPath() { - GenericPersistentObject o1 = new GenericPersistentObject(); - TstBean o2 = new TstBean(); - o2.setInteger(55); - o1.writePropertyDirectly("o2", o2); - - assertSame(o2, o1.readNestedProperty("o2")); - assertEquals(55, o1.readNestedProperty("o2.integer")); - assertEquals(TstBean.class, o1.readNestedProperty("o2.class")); - assertEquals(TstBean.class.getName(), o1.readNestedProperty("o2.class.name")); - } - - @SuppressWarnings("unchecked") - @Test - public void readNestedPropertyToManyInMiddle() throws Exception { - - Artist a = env.context().newObject(Artist.class); - ArtistExhibit ex = env.context().newObject(ArtistExhibit.class); - Painting p1 = env.context().newObject(Painting.class); - Painting p2 = env.context().newObject(Painting.class); - p1.setPaintingTitle("p1"); - p2.setPaintingTitle("p2"); - a.addToPaintingArray(p1); - a.addToPaintingArray(p2); - ex.setToArtist(a); - - List<String> names = (List<String>) a.readNestedProperty("paintingArray.paintingTitle"); - assertEquals(names.size(), 2); - assertEquals(names.get(0), "p1"); - assertEquals(names.get(1), "p2"); - - List<String> names2 = (List<String>) ex.readNestedProperty("toArtist.paintingArray.paintingTitle"); - assertEquals(names, names2); - } - - @SuppressWarnings("unchecked") - @Test - public void readNestedPropertyToManyInMiddle1() throws Exception { - - Artist a = env.context().newObject(Artist.class); - ArtistExhibit ex = env.context().newObject(ArtistExhibit.class); - Painting p1 = env.context().newObject(Painting.class); - Painting p2 = env.context().newObject(Painting.class); - p1.setPaintingTitle("p1"); - p2.setPaintingTitle("p2"); - a.addToPaintingArray(p1); - a.addToPaintingArray(p2); - ex.setToArtist(a); - - List<String> names = (List<String>) a.readNestedProperty("paintingArray+.paintingTitle"); - assertEquals(names.size(), 2); - assertEquals(names.get(0), "p1"); - assertEquals(names.get(1), "p2"); - - List<String> names2 = (List<String>) ex.readNestedProperty("toArtist.paintingArray+.paintingTitle"); - assertEquals(names, names2); - } - - @Test - public void filterObjects() { - - List<Painting> paintingList = new ArrayList<Painting>(); - Painting p1 = env.context().newObject(Painting.class); - Artist a1 = env.context().newObject(Artist.class); - a1.setArtistName("dddAd"); - p1.setToArtist(a1); - - paintingList.add(p1); - Expression exp = ExpressionFactory.likeExp("toArtist+.artistName", "d%"); - - List<Painting> rezult = exp.filterObjects(paintingList); - assertEquals(a1, rezult.get(0).getToArtist()); - } - - @Test - public void filterObjectsResultIsMutable() { - - List<Artist> artistList = new ArrayList<Artist>(); - Artist a = env.context().newObject(Artist.class); - a.setArtistName("Pablo"); - - Expression exp = ExpressionFactory.matchExp("artistName", "Mismatch"); - - List<Artist> result = exp.filterObjects(artistList); - assertTrue(result.isEmpty()); - result.add(a); // list should be mutable - assertTrue(!result.isEmpty()); - } + assertNull(object.getObjectId()); + + object.setObjectId(oid); + assertSame(oid, object.getObjectId()); + } + + @Test + public void setPersistenceState() throws Exception { + GenericPersistentObject obj = new GenericPersistentObject(); + assertEquals(PersistenceState.TRANSIENT, obj.getPersistenceState()); + + obj.setPersistenceState(PersistenceState.COMMITTED); + assertEquals(PersistenceState.COMMITTED, obj.getPersistenceState()); + } + + @Test + public void readNestedProperty1() throws Exception { + Artist a = new Artist(); + assertNull(a.readNestedProperty("artistName")); + a.setArtistName("aaa"); + assertEquals("aaa", a.readNestedProperty("artistName")); + } + + @Test + public void readNestedPropertyNotPersistentString() throws Exception { + Artist a = new Artist(); + assertNull(a.readNestedProperty("someOtherProperty")); + a.setSomeOtherProperty("aaa"); + assertEquals("aaa", a.readNestedProperty("someOtherProperty")); + } + + @Test + public void readNestedPropertyNonPersistentNotString() throws Exception { + Artist a = new Artist(); + Object object = new Object(); + assertNull(a.readNestedProperty("someOtherObjectProperty")); + a.setSomeOtherObjectProperty(object); + assertSame(object, a.readNestedProperty("someOtherObjectProperty")); + } + + @Test + public void readNestedPropertyNonPersistentObjectPath() { + GenericPersistentObject o1 = new GenericPersistentObject(); + TstBean o2 = new TstBean(); + o2.setInteger(55); + o1.writePropertyDirectly("o2", o2); + + assertSame(o2, o1.readNestedProperty("o2")); + assertEquals(55, o1.readNestedProperty("o2.integer")); + assertEquals(TstBean.class, o1.readNestedProperty("o2.class")); + assertEquals(TstBean.class.getName(), o1.readNestedProperty("o2.class.name")); + } + + @SuppressWarnings("unchecked") + @Test + public void readNestedPropertyToManyInMiddle() throws Exception { + + Artist a = env.context().newObject(Artist.class); + ArtistExhibit ex = env.context().newObject(ArtistExhibit.class); + Painting p1 = env.context().newObject(Painting.class); + Painting p2 = env.context().newObject(Painting.class); + p1.setPaintingTitle("p1"); + p2.setPaintingTitle("p2"); + a.addToPaintingArray(p1); + a.addToPaintingArray(p2); + ex.setToArtist(a); + + List<String> names = (List<String>) a.readNestedProperty("paintingArray.paintingTitle"); + assertEquals(names.size(), 2); + assertEquals(names.get(0), "p1"); + assertEquals(names.get(1), "p2"); + + List<String> names2 = (List<String>) ex.readNestedProperty("toArtist.paintingArray.paintingTitle"); + assertEquals(names, names2); + } + + @SuppressWarnings("unchecked") + @Test + public void readNestedPropertyToManyInMiddle1() throws Exception { + + Artist a = env.context().newObject(Artist.class); + ArtistExhibit ex = env.context().newObject(ArtistExhibit.class); + Painting p1 = env.context().newObject(Painting.class); + Painting p2 = env.context().newObject(Painting.class); + p1.setPaintingTitle("p1"); + p2.setPaintingTitle("p2"); + a.addToPaintingArray(p1); + a.addToPaintingArray(p2); + ex.setToArtist(a); + + List<String> names = (List<String>) a.readNestedProperty("paintingArray+.paintingTitle"); + assertEquals(names.size(), 2); + assertEquals(names.get(0), "p1"); + assertEquals(names.get(1), "p2"); + + List<String> names2 = (List<String>) ex.readNestedProperty("toArtist.paintingArray+.paintingTitle"); + assertEquals(names, names2); + } + + @Test + public void filterObjects() { + + List<Painting> paintingList = new ArrayList<Painting>(); + Painting p1 = env.context().newObject(Painting.class); + Artist a1 = env.context().newObject(Artist.class); + a1.setArtistName("dddAd"); + p1.setToArtist(a1); + + paintingList.add(p1); + Expression exp = ExpressionFactory.likeExp("toArtist+.artistName", "d%"); + + List<Painting> rezult = exp.filterObjects(paintingList); + assertEquals(a1, rezult.get(0).getToArtist()); + } + + @Test + public void filterObjectsResultIsMutable() { + + List<Artist> artistList = new ArrayList<Artist>(); + Artist a = env.context().newObject(Artist.class); + a.setArtistName("Pablo"); + + Expression exp = ExpressionFactory.matchExp("artistName", "Mismatch"); + + List<Artist> result = exp.filterObjects(artistList); + assertTrue(result.isEmpty()); + result.add(a); // list should be mutable + assertTrue(!result.isEmpty()); + } } 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 45210734c..8e5048f5e 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/CayenneTestsEnv.java @@ -34,7 +34,6 @@ import org.apache.cayenne.configuration.runtime.CoreModule; import org.apache.cayenne.configuration.runtime.DbAdapterFactory; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.di.AdhocObjectFactory; -import org.apache.cayenne.di.Binder; import org.apache.cayenne.di.DIBootstrap; import org.apache.cayenne.di.Injector; import org.apache.cayenne.di.Module; @@ -67,27 +66,34 @@ import java.util.stream.Collectors; public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { private static final Injector INJECTOR; + + // shared stack parts... use these directly from the tests public static final TestDataSources DATA_SOURCES; public static final AllTestsSchemaManager SCHEMAS; + public static final UnitDbAdapter UNIT_DB_ADAPTER; static { INJECTOR = DIBootstrap.createInjector(new RuntimeCaseModule()); + DATA_SOURCES = new TestDataSources( INJECTOR.getInstance(DataSourceDescriptor.class), INJECTOR.getInstance(AdhocObjectFactory.class)); + + UNIT_DB_ADAPTER = UnitDbAdapter.of(INJECTOR.getInstance(DbAdapter.class)); + SCHEMAS = new AllTestsSchemaManager( DATA_SOURCES, - INJECTOR.getInstance(UnitDbAdapter.class), - INJECTOR.getInstance(DbAdapter.class), + UNIT_DB_ADAPTER, INJECTOR.getInstance(JdbcEventLogger.class), INJECTOR.getInstance(DataMapLoader.class)); + SCHEMAS.rebuildSchema(); } private final String project; private final Module[] extraModules; private final boolean autoClean; - private final boolean weakReferences; + private final String retainStrategy; // single-test scoped vars private DataContext context; @@ -95,27 +101,28 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { private DbCleaner dbCleaner; private CayenneRuntime runtime; - private CayenneTestsEnv(String project, Module[] extraModules, boolean autoClean, boolean weakReferences) { + private CayenneTestsEnv(String project, Module[] extraModules, boolean autoClean, String retainStrategy) { this.project = project; this.extraModules = extraModules; this.autoClean = autoClean; - this.weakReferences = weakReferences; + this.retainStrategy = retainStrategy; } public static CayenneTestsEnv forProject(String project) { - return new CayenneTestsEnv(project, new Module[0], true, false); + // Soft refs by default instead of weak — avoids GC-sensitive test flakiness. + return new CayenneTestsEnv(project, new Module[0], true, "soft"); } public CayenneTestsEnv withExtraModules(Module... modules) { - return new CayenneTestsEnv(project, modules, autoClean, weakReferences); + return new CayenneTestsEnv(project, modules, autoClean, retainStrategy); } public CayenneTestsEnv withoutAutoClean() { - return new CayenneTestsEnv(project, extraModules, false, weakReferences); + return new CayenneTestsEnv(project, extraModules, false, retainStrategy); } public CayenneTestsEnv withWeakReferences() { - return new CayenneTestsEnv(project, extraModules, autoClean, true); + return new CayenneTestsEnv(project, extraModules, autoClean, "weak"); } @Override @@ -156,15 +163,11 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { } private CayenneRuntime buildRuntime() { - List<Module> modules = new ArrayList<>(); - modules.add(new TestRuntimeOverridesModule()); + List<Module> modules = new ArrayList<>(); + modules.add(b -> CoreModule.extend(b).setProperty(Constants.OBJECT_RETAIN_STRATEGY_PROPERTY, retainStrategy)); Collections.addAll(modules, extraModules); - if (weakReferences) { - modules.add(new WeakReferenceStrategyModule()); - } - CayenneRuntime runtime = CayenneRuntime.builder() .addConfig(project) .addModules(modules) @@ -187,7 +190,6 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { SelectTranslatorFactory selectTranslatorFactory = runtimeInjector.getInstance(SelectTranslatorFactory.class); SQLTemplateProcessor sqlTemplateProcessor = runtimeInjector.getInstance(SQLTemplateProcessor.class); - DataNode lastNode = null; for (DataMap dataMap : domain.getDataMaps()) { DataSource dataSource = DATA_SOURCES.dataSource(dataMap.getName()); @@ -215,11 +217,10 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { } domain.addNode(node); - lastNode = node; } if (domain.getDataMaps().size() == 1) { - domain.setDefaultNode(lastNode); + domain.setDefaultNode(domain.getDataNodes().iterator().next()); } } @@ -275,25 +276,4 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback { public SQLTemplateCustomizer sqlTemplateCustomizer() { return INJECTOR.getInstance(SQLTemplateCustomizer.class); } - - public static class WeakReferenceStrategyModule implements Module { - @Override - public void configure(Binder binder) { - CoreModule.extend(binder).setProperty(Constants.OBJECT_RETAIN_STRATEGY_PROPERTY, "weak"); - } - } - - private static class TestRuntimeOverridesModule implements Module { - - @Override - public void configure(Binder binder) { - - binder.bind(UnitDbAdapter.class).toInstance(INJECTOR.getInstance(UnitDbAdapter.class)); - binder.bind(TestDataSources.class).toInstance(DATA_SOURCES); - - CoreModule.extend(binder) - // Soft refs instead of weak — avoids GC-sensitive test flakiness. - .setProperty(Constants.OBJECT_RETAIN_STRATEGY_PROPERTY, "soft"); - } - } } diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/dba/DerbyUnitDbAdapter.java b/cayenne/src/test/java/org/apache/cayenne/unit/dba/DerbyUnitDbAdapter.java index cc97e0d57..9147d67b4 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/dba/DerbyUnitDbAdapter.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/dba/DerbyUnitDbAdapter.java @@ -68,11 +68,6 @@ public class DerbyUnitDbAdapter extends UnitDbAdapter { return true; } - @Override - public boolean supportsLongIn() { - return false; - } - @Override public boolean supportsNullComparison() { return false; diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/dba/MySQLUnitDbAdapter.java b/cayenne/src/test/java/org/apache/cayenne/unit/dba/MySQLUnitDbAdapter.java index a84f77231..a971cfab5 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/dba/MySQLUnitDbAdapter.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/dba/MySQLUnitDbAdapter.java @@ -73,11 +73,6 @@ public class MySQLUnitDbAdapter extends UnitDbAdapter { return true; } - @Override - public boolean supportsCaseSensitiveLike() { - return false; - } - @Override public boolean supportsStoredProcedures() { return true; diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLServerUnitDbAdapter.java b/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLServerUnitDbAdapter.java index 62866a9ff..25ff25132 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLServerUnitDbAdapter.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLServerUnitDbAdapter.java @@ -19,12 +19,12 @@ package org.apache.cayenne.unit.dba; -import java.sql.Connection; -import java.util.Collection; - import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.map.DataMap; +import java.sql.Connection; +import java.util.Collection; + public class SQLServerUnitDbAdapter extends SybaseUnitDbAdapter { public SQLServerUnitDbAdapter(DbAdapter adapter) { @@ -93,15 +93,4 @@ public class SQLServerUnitDbAdapter extends SybaseUnitDbAdapter { public boolean supportsCatalogs() { return true; } - - /** - * SqlServer actually supports case sensitivity, but it depends on server/session/table settings, - * so we just skip this for tests stability. - * - * @return false - */ - @Override - public boolean supportsCaseSensitiveLike() { - return false; - } } diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLiteUnitDbAdapter.java b/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLiteUnitDbAdapter.java index 72e464855..833d44fda 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLiteUnitDbAdapter.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/dba/SQLiteUnitDbAdapter.java @@ -31,16 +31,6 @@ public class SQLiteUnitDbAdapter extends UnitDbAdapter { return false; } - @Override - public boolean supportsColumnTypeReengineering() { - return false; - } - - @Override - public boolean supportsCaseSensitiveLike() { - return false; - } - @Override public boolean supportsAllAnySome() { return false; diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/dba/UnitDbAdapter.java b/cayenne/src/test/java/org/apache/cayenne/unit/dba/UnitDbAdapter.java index 2c8e2ac71..0a9c905a3 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/dba/UnitDbAdapter.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/dba/UnitDbAdapter.java @@ -20,11 +20,22 @@ package org.apache.cayenne.unit.dba; import org.apache.cayenne.CayenneRuntimeException; -import org.apache.cayenne.configuration.Constants; -import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.di.Inject; +import org.apache.cayenne.dba.db2.DB2Adapter; +import org.apache.cayenne.dba.derby.DerbyAdapter; +import org.apache.cayenne.dba.firebird.FirebirdAdapter; +import org.apache.cayenne.dba.frontbase.FrontBaseAdapter; +import org.apache.cayenne.dba.h2.H2Adapter; +import org.apache.cayenne.dba.hsqldb.HSQLDBAdapter; +import org.apache.cayenne.dba.ingres.IngresAdapter; +import org.apache.cayenne.dba.mysql.MySQLAdapter; +import org.apache.cayenne.dba.oracle.Oracle8Adapter; +import org.apache.cayenne.dba.oracle.OracleAdapter; +import org.apache.cayenne.dba.postgres.PostgresAdapter; +import org.apache.cayenne.dba.sqlite.SQLiteAdapter; +import org.apache.cayenne.dba.sqlserver.SQLServerAdapter; +import org.apache.cayenne.dba.sybase.SybaseAdapter; import org.apache.cayenne.exp.parser.ASTExtract; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbEntity; @@ -45,6 +56,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; /** * Defines API and a common superclass for testing various database features. @@ -52,20 +64,41 @@ import java.util.Map; * differently. Many things implemented in subclasses may become future * candidates for inclusion in the corresponding adapter code. */ -public class UnitDbAdapter { +public abstract class UnitDbAdapter { - private static final Logger logger = LoggerFactory.getLogger(UnitDbAdapter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(UnitDbAdapter.class); - @Inject - protected RuntimeProperties runtimeProperties; + public static UnitDbAdapter of(DbAdapter adapter) { - protected DbAdapter adapter; + // the order of cases is important due to random adapter subclasses + return switch (adapter) { + case FirebirdAdapter a -> new FirebirdUnitDbAdapter(a); + case Oracle8Adapter a -> new OracleUnitDbAdapter(a); + case OracleAdapter a -> new OracleUnitDbAdapter(a); + case DerbyAdapter a -> new DerbyUnitDbAdapter(a); + case SQLServerAdapter a -> new SQLServerUnitDbAdapter(a); + case SybaseAdapter a -> new SybaseUnitDbAdapter(a); + case MySQLAdapter a -> new MySQLUnitDbAdapter(a); + case PostgresAdapter a -> new PostgresUnitDbAdapter(a); + case DB2Adapter a -> new DB2UnitDbAdapter(a); + case HSQLDBAdapter a -> new HSQLDBUnitDbAdapter(a); + case H2Adapter a -> new H2UnitDbAdapter(a); + case FrontBaseAdapter a -> new FrontBaseUnitDbAdapter(a); + case IngresAdapter a -> new IngresUnitDbAdapter(a); + case SQLiteAdapter a -> new SQLiteUnitDbAdapter(a); - public UnitDbAdapter(DbAdapter adapter) { - if (adapter == null) { - throw new CayenneRuntimeException("Null adapter."); - } - this.adapter = adapter; + default -> throw new IllegalStateException("Unmapped adapter type: " + adapter.getClass().getName()); + }; + } + + protected final DbAdapter adapter; + + protected UnitDbAdapter(DbAdapter adapter) { + this.adapter = Objects.requireNonNull(adapter); + } + + public DbAdapter getAdapter() { + return adapter; } public boolean supportsPKGeneratorConcurrency() { @@ -75,11 +108,11 @@ public class UnitDbAdapter { public String getIdentifiersStartQuote() { return "\""; } - + public String getIdentifiersEndQuote() { return "\""; } - + /** * Returns whether the target DB treats REAL values as DOUBLEs. Default is * false, i.e. REALs are treated as FLOATs. @@ -114,22 +147,14 @@ public class UnitDbAdapter { QuotingStrategy strategy = adapter.getQuotingStrategy(); for (String constraint : constraints) { - StringBuilder drop = new StringBuilder(); - drop.append("ALTER TABLE ").append(strategy.quotedFullyQualifiedName(entity)) - .append(" DROP CONSTRAINT ").append(constraint); - executeDDL(conn, drop.toString()); + String drop = "ALTER TABLE " + strategy.quotedFullyQualifiedName(entity) + + " DROP CONSTRAINT " + constraint; + executeDDL(conn, drop); } } } - public void droppedTables(Connection con, DataMap map) throws Exception { - - } - - /** - * Callback method that allows Delegate to customize test procedure. - */ public void tweakProcedure(Procedure proc) { } @@ -137,7 +162,6 @@ public class UnitDbAdapter { } public void createdTables(Connection con, DataMap map) throws Exception { - } public boolean supportsStoredProcedures() { @@ -195,21 +219,13 @@ public class UnitDbAdapter { } public boolean supportsFKConstraints(DbEntity entity) { - if ("FK_OF_DIFFERENT_TYPE".equals(entity.getName())) { - return false; - } - - return true; + return !"FK_OF_DIFFERENT_TYPE".equals(entity.getName()); } public boolean supportsFKConstraints() { return true; } - public boolean supportsColumnTypeReengineering() { - return true; - } - /** * Returns true if the target database has support for large objects (BLOB, * CLOB). @@ -237,10 +253,6 @@ public class UnitDbAdapter { return true; } - public boolean supportsCaseSensitiveLike() { - return !runtimeProperties.getBoolean(Constants.CI_PROPERTY, false); - } - public boolean supportsCaseInsensitiveOrder() { return true; } @@ -258,13 +270,10 @@ public class UnitDbAdapter { } protected void executeDDL(Connection con, String ddl) throws Exception { - logger.info(ddl); - Statement st = con.createStatement(); + LOGGER.info(ddl); - try { + try (Statement st = con.createStatement()) { st.execute(ddl); - } finally { - st.close(); } } @@ -289,7 +298,7 @@ public class UnitDbAdapter { BufferedReader in = new BufferedReader(new InputStreamReader(resource)); StringBuffer buf = new StringBuffer(); try { - String line = null; + String line; while ((line = in.readLine()) != null) { buf.append(line).append('\n'); } @@ -315,7 +324,7 @@ public class UnitDbAdapter { * and Collections of constraint names as values. */ protected Map<String, Collection<String>> getConstraints(Connection conn, DataMap map, - Collection<String> includeTables) throws SQLException { + Collection<String> includeTables) throws SQLException { Map<String, Collection<String>> constraintMap = new HashMap<>(); @@ -330,8 +339,7 @@ public class UnitDbAdapter { QuotingStrategy strategy = adapter.getQuotingStrategy(); // Get all constraints for the table - ResultSet rs = metadata.getExportedKeys(entity.getCatalog(), entity.getSchema(), entity.getName()); - try { + try (ResultSet rs = metadata.getExportedKeys(entity.getCatalog(), entity.getSchema(), entity.getName())) { while (rs.next()) { String fk = rs.getString("FK_NAME"); String fkTable = rs.getString("FKTABLE_NAME"); @@ -347,8 +355,6 @@ public class UnitDbAdapter { constraints.add(strategy.quotedIdentifier(entity, fk)); } } - } finally { - rs.close(); } } @@ -415,10 +421,6 @@ public class UnitDbAdapter { return false; } - public boolean supportsLongIn() { - return true; - } - public boolean supportsNullComparison() { return true; } @@ -427,7 +429,7 @@ public class UnitDbAdapter { * Support for select like this: * SELECT t0.ARTIST_NAME FROM ARTIST t0 WHERE 'abc' */ - public boolean supportScalarAsExpression(){ + public boolean supportScalarAsExpression() { return false; } diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/AllTestsSchemaManager.java b/cayenne/src/test/java/org/apache/cayenne/unit/runtime/AllTestsSchemaManager.java index 367c222ce..b343ec5d8 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/AllTestsSchemaManager.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/runtime/AllTestsSchemaManager.java @@ -94,14 +94,15 @@ public class AllTestsSchemaManager { public AllTestsSchemaManager( TestDataSources dataSourceFactory, UnitDbAdapter unitDbAdapter, - DbAdapter dbAdapter, JdbcEventLogger jdbcEventLogger, DataMapLoader loader) { this.dataSourceFactory = dataSourceFactory; this.unitDbAdapter = unitDbAdapter; this.jdbcEventLogger = jdbcEventLogger; - this.domain = initDomain(loader, dbAdapter); + + // TODO: just create a normal CayenneRuntime with all the defaults + this.domain = initDomain(loader, unitDbAdapter.getAdapter()); } private DataDomain initDomain(DataMapLoader loader, DbAdapter dbAdapter) { @@ -349,8 +350,6 @@ public class AllTestsSchemaManager { } } } - - unitDbAdapter.droppedTables(conn, map); } } diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseModule.java b/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseModule.java index 5df296bf8..7889557f3 100644 --- a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseModule.java +++ b/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseModule.java @@ -32,7 +32,6 @@ import org.apache.cayenne.configuration.DefaultRuntimeProperties; import org.apache.cayenne.configuration.ObjectStoreFactory; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.configuration.runtime.CoreModuleExtender; -import org.apache.cayenne.configuration.runtime.DataSourceFactory; import org.apache.cayenne.configuration.runtime.PkGeneratorFactoryProvider; import org.apache.cayenne.configuration.xml.DataChannelMetaData; import org.apache.cayenne.configuration.xml.DefaultHandlerFactory; @@ -47,12 +46,10 @@ import org.apache.cayenne.dba.db2.DB2Adapter; import org.apache.cayenne.dba.db2.DB2PkGenerator; import org.apache.cayenne.dba.derby.DerbyAdapter; import org.apache.cayenne.dba.derby.DerbyPkGenerator; -import org.apache.cayenne.dba.firebird.FirebirdAdapter; import org.apache.cayenne.dba.frontbase.FrontBaseAdapter; import org.apache.cayenne.dba.frontbase.FrontBasePkGenerator; import org.apache.cayenne.dba.h2.H2Adapter; import org.apache.cayenne.dba.h2.H2PkGenerator; -import org.apache.cayenne.dba.hsqldb.HSQLDBAdapter; import org.apache.cayenne.dba.ingres.IngresAdapter; import org.apache.cayenne.dba.ingres.IngresPkGenerator; import org.apache.cayenne.dba.mysql.MySQLAdapter; @@ -62,7 +59,6 @@ import org.apache.cayenne.dba.oracle.OracleAdapter; import org.apache.cayenne.dba.oracle.OraclePkGenerator; import org.apache.cayenne.dba.postgres.PostgresAdapter; import org.apache.cayenne.dba.postgres.PostgresPkGenerator; -import org.apache.cayenne.dba.sqlite.SQLiteAdapter; import org.apache.cayenne.dba.sqlserver.SQLServerAdapter; import org.apache.cayenne.dba.sybase.SybaseAdapter; import org.apache.cayenne.dba.sybase.SybasePkGenerator; @@ -82,20 +78,6 @@ import org.apache.cayenne.reflect.generic.DefaultValueComparisonStrategyFactory; import org.apache.cayenne.reflect.generic.ValueComparisonStrategyFactory; import org.apache.cayenne.resource.ClassLoaderResourceLocator; import org.apache.cayenne.resource.ResourceLocator; -import org.apache.cayenne.unit.dba.DB2UnitDbAdapter; -import org.apache.cayenne.unit.dba.DerbyUnitDbAdapter; -import org.apache.cayenne.unit.dba.FirebirdUnitDbAdapter; -import org.apache.cayenne.unit.dba.FrontBaseUnitDbAdapter; -import org.apache.cayenne.unit.dba.H2UnitDbAdapter; -import org.apache.cayenne.unit.dba.HSQLDBUnitDbAdapter; -import org.apache.cayenne.unit.dba.IngresUnitDbAdapter; -import org.apache.cayenne.unit.dba.MySQLUnitDbAdapter; -import org.apache.cayenne.unit.dba.OracleUnitDbAdapter; -import org.apache.cayenne.unit.dba.PostgresUnitDbAdapter; -import org.apache.cayenne.unit.dba.SQLServerUnitDbAdapter; -import org.apache.cayenne.unit.dba.SQLiteUnitDbAdapter; -import org.apache.cayenne.unit.dba.SybaseUnitDbAdapter; -import org.apache.cayenne.unit.dba.UnitDbAdapter; import org.apache.cayenne.unit.testcontainers.Db2ContainerProvider; import org.apache.cayenne.unit.testcontainers.MariaDbContainerProvider; import org.apache.cayenne.unit.testcontainers.MysqlContainerProvider; @@ -115,21 +97,7 @@ public class RuntimeCaseModule implements Module { // these are the objects injectable in unit tests that subclass from RuntimeCase. - binder.bindMap(String.class, UnitDbAdapterProvider.TEST_ADAPTERS_MAP) - .put(FirebirdAdapter.class.getName(), FirebirdUnitDbAdapter.class.getName()) - .put(OracleAdapter.class.getName(), OracleUnitDbAdapter.class.getName()) - .put(DerbyAdapter.class.getName(), DerbyUnitDbAdapter.class.getName()) - .put(Oracle8Adapter.class.getName(), OracleUnitDbAdapter.class.getName()) - .put(SybaseAdapter.class.getName(), SybaseUnitDbAdapter.class.getName()) - .put(MySQLAdapter.class.getName(), MySQLUnitDbAdapter.class.getName()) - .put(PostgresAdapter.class.getName(), PostgresUnitDbAdapter.class.getName()) - .put(SQLServerAdapter.class.getName(), SQLServerUnitDbAdapter.class.getName()) - .put(DB2Adapter.class.getName(), DB2UnitDbAdapter.class.getName()) - .put(HSQLDBAdapter.class.getName(), HSQLDBUnitDbAdapter.class.getName()) - .put(H2Adapter.class.getName(), H2UnitDbAdapter.class.getName()) - .put(FrontBaseAdapter.class.getName(), FrontBaseUnitDbAdapter.class.getName()) - .put(IngresAdapter.class.getName(), IngresUnitDbAdapter.class.getName()) - .put(SQLiteAdapter.class.getName(), SQLiteUnitDbAdapter.class.getName()); + binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class); binder.bind(PkGenerator.class).to(JdbcPkGenerator.class); @@ -209,9 +177,7 @@ public class RuntimeCaseModule implements Module { return unitDataSourceDescriptor; } }); - binder.bind(DataSourceFactory.class).to(RuntimeCaseSharedDataSourceFactory.class); binder.bind(DbAdapter.class).toProvider(RuntimeCaseDbAdapterProvider.class); - binder.bind(UnitDbAdapter.class).toProvider(UnitDbAdapterProvider.class); // this factory is a hack that allows to inject to DbAdapters loaded outside of // server runtime... BatchQueryBuilderFactory is hardcoded and whatever is placed diff --git a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseSharedDataSourceFactory.java b/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseSharedDataSourceFactory.java deleted file mode 100644 index 17cfc66ea..000000000 --- a/cayenne/src/test/java/org/apache/cayenne/unit/runtime/RuntimeCaseSharedDataSourceFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************** - * 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.unit.runtime; - -import org.apache.cayenne.configuration.DataNodeDescriptor; -import org.apache.cayenne.configuration.runtime.DataSourceFactory; -import org.apache.cayenne.di.Inject; -import org.apache.cayenne.unit.TestDataSources; - -import javax.sql.DataSource; - -public class RuntimeCaseSharedDataSourceFactory implements DataSourceFactory { - - private TestDataSources factory; - - public RuntimeCaseSharedDataSourceFactory(@Inject TestDataSources factory) { - this.factory = factory; - } - - public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) { - return factory.sharedDataSource(); - } -}
