You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/04/18 09:59:10 UTC
[06/19] cayenne git commit: Refactoring the PK definition
Refactoring the PK definition
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/284151ce
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/284151ce
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/284151ce
Branch: refs/heads/master
Commit: 284151ce85e8a91824c1528a245b64b9a2075ba7
Parents: 3512f80
Author: Aleksey Pleshkanev <pr...@hotmail.com>
Authored: Sun Mar 25 18:31:55 2018 +0300
Committer: Aleksey Pleshkanev <pr...@hotmail.com>
Committed: Sun Mar 25 18:31:55 2018 +0300
----------------------------------------------------------------------
.../reverse/configuration/ToolsModule.java | 24 +-
.../server/DefaultPkGeneratorFactory.java | 118 ----
.../server/PkGeneratorFactory.java | 25 -
.../server/PkGeneratorFactoryProvider.java | 17 +
.../configuration/server/ServerModule.java | 45 +-
.../java/org/apache/cayenne/dba/DbVersion.java | 108 ----
.../org/apache/cayenne/dba/JdbcPkGenerator.java | 641 ++++++++++---------
.../org/apache/cayenne/dba/PkGenerator.java | 25 +-
.../cayenne/dba/sqlserver/SQLServerSniffer.java | 23 +-
.../cayenne/dba/sybase/SybasePkGenerator.java | 4 +
.../server/DataDomainProviderTest.java | 13 +-
.../dba/sqlserver/SQLServerSnifferIT.java | 16 +-
.../unit/di/server/ServerCaseModule.java | 20 +-
13 files changed, 435 insertions(+), 644 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
index 3d3a1bd..2dd7f2e 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
@@ -19,8 +19,6 @@
package org.apache.cayenne.dbsync.reverse.configuration;
-import java.util.Objects;
-
import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry;
@@ -30,13 +28,19 @@ import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.configuration.server.*;
+import org.apache.cayenne.configuration.server.DataSourceFactory;
+import org.apache.cayenne.configuration.server.DbAdapterFactory;
+import org.apache.cayenne.configuration.server.DefaultDbAdapterFactory;
+import org.apache.cayenne.configuration.server.PkGeneratorFactoryProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.configuration.xml.DefaultDataChannelMetaData;
import org.apache.cayenne.configuration.xml.HandlerFactory;
import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
import org.apache.cayenne.configuration.xml.XMLReaderProvider;
+import org.apache.cayenne.dba.JdbcPkGenerator;
+import org.apache.cayenne.dba.PkGenerator;
import org.apache.cayenne.dba.db2.DB2Sniffer;
import org.apache.cayenne.dba.derby.DerbySniffer;
import org.apache.cayenne.dba.firebird.FirebirdSniffer;
@@ -49,7 +53,7 @@ import org.apache.cayenne.dba.openbase.OpenBaseSniffer;
import org.apache.cayenne.dba.oracle.OracleSniffer;
import org.apache.cayenne.dba.postgres.PostgresSniffer;
import org.apache.cayenne.dba.sqlite.SQLiteSniffer;
-import org.apache.cayenne.dba.sqlserver.SQLServerPkGenerator;
+import org.apache.cayenne.dba.sqlserver.SQLServerAdapter;
import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
import org.apache.cayenne.dba.sybase.SybasePkGenerator;
import org.apache.cayenne.dba.sybase.SybaseSniffer;
@@ -60,8 +64,8 @@ import org.apache.cayenne.di.Key;
import org.apache.cayenne.di.Module;
import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
-import org.apache.cayenne.log.Slf4jJdbcEventLogger;
import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.log.Slf4jJdbcEventLogger;
import org.apache.cayenne.project.ProjectModule;
import org.apache.cayenne.project.extension.ExtensionAwareHandlerFactory;
import org.apache.cayenne.resource.ClassLoaderResourceLocator;
@@ -69,8 +73,7 @@ import org.apache.cayenne.resource.ResourceLocator;
import org.slf4j.Logger;
import org.xml.sax.XMLReader;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2008;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2012;
+import java.util.Objects;
/**
* A DI module to bootstrap DI container for Cayenne Ant tasks and Maven
@@ -114,12 +117,11 @@ public class ToolsModule implements Module {
.add(SQLServerSniffer.class).add(OracleSniffer.class).add(PostgresSniffer.class)
.add(MySQLSniffer.class);
- ServerModule.contributePkGenerators(binder)
- .put(String.valueOf(MS_SQL_2008), SybasePkGenerator.class)
- .put(String.valueOf(MS_SQL_2012), SQLServerPkGenerator.class);
+ binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class);
+ binder.bind(PkGenerator.class).to(JdbcPkGenerator.class);
+ ServerModule.contributePkGenerators(binder).put(SQLServerAdapter.class.getName(), SybasePkGenerator.class);
binder.bind(DbAdapterFactory.class).to(DefaultDbAdapterFactory.class);
- binder.bind(PkGeneratorFactory.class).to(DefaultPkGeneratorFactory.class);
binder.bind(DataSourceFactory.class).to(DriverDataSourceFactory.class);
binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DefaultPkGeneratorFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DefaultPkGeneratorFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DefaultPkGeneratorFactory.java
deleted file mode 100644
index 9a64f99..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DefaultPkGeneratorFactory.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.apache.cayenne.configuration.server;
-
-import org.apache.cayenne.ConfigurationException;
-import org.apache.cayenne.configuration.Constants;
-import org.apache.cayenne.dba.DbVersion;
-import org.apache.cayenne.dba.JdbcAdapter;
-import org.apache.cayenne.dba.JdbcPkGenerator;
-import org.apache.cayenne.dba.PkGenerator;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.log.JdbcEventLogger;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-import java.util.Map;
-import java.util.Objects;
-
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2008;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2012;
-
-/**
- * A factory of PkGenerators that also loads user-provided pkGenerator or guesses
- * the pkGenerator from the database metadata.
- */
-public class DefaultPkGeneratorFactory implements PkGeneratorFactory {
-
- @Inject
- protected JdbcEventLogger jdbcEventLogger;
-
- protected Map<String, Class> pkGenerators;
-
- public DefaultPkGeneratorFactory(@Inject(Constants.SERVER_PK_GENERATORS_MAP) Map<String, Class> pkGenerators) {
- this.pkGenerators = Objects.requireNonNull(pkGenerators, () -> "Null pkGenerators list");
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public PkGenerator detectPkGenerator(DbVersion.DbType dbType, JdbcAdapter adapter, DatabaseMetaData md) throws SQLException {
-
- final int majorVersion = md.getDatabaseMajorVersion();
- final int minorVersion = md.getDatabaseMinorVersion();
-
- Class pkGeneratorClazz = null;
- DbVersion currentDbVersion = new DbVersion(dbType, majorVersion, minorVersion);
- switch (dbType) {
- case MS_SQL:
- pkGeneratorClazz = detectPkGenerator4MSSQL(currentDbVersion);
- break;
- default:
- jdbcEventLogger.log("Failed to detect PkGenerator, using generic generator");
- pkGeneratorClazz = defaultPkGenerator();
- }
-
- jdbcEventLogger.log("DB - '" + currentDbVersion + "'; PkGenerator - " + pkGeneratorClazz.getName());
-
- try {
- return newInstancePk(pkGeneratorClazz, adapter);
- } catch (Throwable throwable) {
- throw new ConfigurationException("Could not instantiate " + currentDbVersion, throwable);
- }
- }
-
- /**
- * @param pkGeneratorClazz {@link Class} for instantiation PkGenerator
- * @param adapter adapter for installation in PkGenerator
- */
- protected PkGenerator newInstancePk(Class pkGeneratorClazz, JdbcAdapter adapter) throws Throwable {
- Constructor pkGeneratorConstructor = pkGeneratorClazz.getDeclaredConstructor(JdbcAdapter.class);
- pkGeneratorConstructor.setAccessible(true);
-
- MethodHandle createPkGenerator = MethodHandles.lookup()
- .unreflectConstructor(pkGeneratorConstructor);
-
- return (PkGenerator) createPkGenerator.invoke(adapter);
- }
-
- protected Class defaultPkGenerator() {
- return JdbcPkGenerator.class;
- }
-
- /**
- * Choosing a specific generator, depending on the version of the database
- *
- * @param currentDbVersion version of the database for which you need to determine the PkGenerator
- */
- protected Class detectPkGenerator4MSSQL(DbVersion currentDbVersion) {
-
- if (!isCheckTypeGenerator(currentDbVersion, MS_SQL_2008, MS_SQL_2012)) {
- return defaultPkGenerator();
- }
-
- if (currentDbVersion.compareTo(MS_SQL_2012) >= 0) {
- String version = String.valueOf(MS_SQL_2012);
- if (pkGenerators.containsKey(version)) {
- return pkGenerators.get(version);
- }
- } else {
- String version = String.valueOf(MS_SQL_2008);
- if (pkGenerators.containsKey(version)) {
- return pkGenerators.get(version);
- }
- }
-
- jdbcEventLogger.log("Failed to detect PkGenerator, using generic generator");
- return defaultPkGenerator();
- }
-
- private boolean isCheckTypeGenerator(DbVersion currentDbVersion, DbVersion... dbVersions) {
- for (DbVersion item : dbVersions) {
- if (!item.isTypeCheck(currentDbVersion)) {
- return false;
- }
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactory.java
deleted file mode 100644
index 2e3882e..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.apache.cayenne.configuration.server;
-
-import org.apache.cayenne.dba.DbVersion;
-import org.apache.cayenne.dba.JdbcAdapter;
-import org.apache.cayenne.dba.PkGenerator;
-
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-
-/**
- * Interface for generator definition
- */
-public interface PkGeneratorFactory {
-
- /**
- * Discovering the primary key based on the database metadata
- *
- * @param dbType database type
- * @param adapter adapter for generator instantiation
- * @param md connection metadata
- * @return an instantiated instance of a specific generator for the current version of the database
- * @throws SQLException
- */
- PkGenerator detectPkGenerator(DbVersion.DbType dbType, JdbcAdapter adapter, DatabaseMetaData md) throws SQLException;
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactoryProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactoryProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactoryProvider.java
new file mode 100644
index 0000000..d003782
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/PkGeneratorFactoryProvider.java
@@ -0,0 +1,17 @@
+package org.apache.cayenne.configuration.server;
+
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.dba.PerAdapterProvider;
+import org.apache.cayenne.dba.PkGenerator;
+import org.apache.cayenne.di.Inject;
+
+import java.util.Map;
+
+public class PkGeneratorFactoryProvider extends PerAdapterProvider<PkGenerator> {
+
+ public PkGeneratorFactoryProvider(
+ @Inject(Constants.SERVER_PK_GENERATORS_MAP) Map<String, PkGenerator> perAdapterValues,
+ @Inject PkGenerator defaultValue) {
+ super(perAdapterValues, defaultValue);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
index a864245..ac7753f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
@@ -40,8 +40,8 @@ import org.apache.cayenne.access.types.BooleanType;
import org.apache.cayenne.access.types.ByteArrayType;
import org.apache.cayenne.access.types.ByteType;
import org.apache.cayenne.access.types.CalendarType;
-import org.apache.cayenne.access.types.CharacterValueType;
import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.CharacterValueType;
import org.apache.cayenne.access.types.DateType;
import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry;
import org.apache.cayenne.access.types.DoubleType;
@@ -58,6 +58,7 @@ import org.apache.cayenne.access.types.TimeType;
import org.apache.cayenne.access.types.TimestampType;
import org.apache.cayenne.access.types.UUIDValueType;
import org.apache.cayenne.access.types.UtilDateType;
+import org.apache.cayenne.access.types.ValueObjectType;
import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
import org.apache.cayenne.access.types.VoidType;
import org.apache.cayenne.ashwood.AshwoodEntitySorter;
@@ -82,6 +83,7 @@ import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
import org.apache.cayenne.configuration.xml.XMLReaderProvider;
+import org.apache.cayenne.dba.JdbcPkGenerator;
import org.apache.cayenne.dba.PkGenerator;
import org.apache.cayenne.dba.db2.DB2Sniffer;
import org.apache.cayenne.dba.derby.DerbySniffer;
@@ -95,7 +97,7 @@ import org.apache.cayenne.dba.openbase.OpenBaseSniffer;
import org.apache.cayenne.dba.oracle.OracleSniffer;
import org.apache.cayenne.dba.postgres.PostgresSniffer;
import org.apache.cayenne.dba.sqlite.SQLiteSniffer;
-import org.apache.cayenne.dba.sqlserver.SQLServerPkGenerator;
+import org.apache.cayenne.dba.sqlserver.SQLServerAdapter;
import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
import org.apache.cayenne.dba.sybase.SybasePkGenerator;
import org.apache.cayenne.dba.sybase.SybaseSniffer;
@@ -109,13 +111,12 @@ import org.apache.cayenne.di.Module;
import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.event.NoopEventBridgeProvider;
import org.apache.cayenne.event.EventBridge;
import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.log.Slf4jJdbcEventLogger;
+import org.apache.cayenne.event.NoopEventBridgeProvider;
import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.log.Slf4jJdbcEventLogger;
import org.apache.cayenne.map.EntitySorter;
-import org.apache.cayenne.access.types.ValueObjectType;
import org.apache.cayenne.resource.ClassLoaderResourceLocator;
import org.apache.cayenne.resource.ResourceLocator;
import org.apache.cayenne.template.CayenneSQLTemplateProcessor;
@@ -131,9 +132,6 @@ import org.xml.sax.XMLReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2008;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2012;
-
/**
* A DI module containing all Cayenne server runtime configuration.
*
@@ -219,8 +217,8 @@ public class ServerModule implements Module {
* @param binder DI binder passed to the module during injector startup.
* @return MapBuilder for properties.
*/
- public static MapBuilder<Class> contributePkGenerators(Binder binder) {
- return binder.bindMap(Class.class, Constants.SERVER_PK_GENERATORS_MAP);
+ public static MapBuilder<PkGenerator> contributePkGenerators(Binder binder) {
+ return binder.bindMap(PkGenerator.class, Constants.SERVER_PK_GENERATORS_MAP);
}
/**
@@ -309,10 +307,25 @@ public class ServerModule implements Module {
.add(SQLServerSniffer.class).add(OracleSniffer.class).add(PostgresSniffer.class)
.add(MySQLSniffer.class);
- contributePkGenerators(binder)
- .put(String.valueOf(MS_SQL_2008), SybasePkGenerator.class) //adding a generator for MS SQL version 2012 and higher
- .put(String.valueOf(MS_SQL_2012), SQLServerPkGenerator.class); //adding a generator since MS SQL version 2012
-
+ //installing Pk for adapters
+ binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class);
+ binder.bind(PkGenerator.class).to(JdbcPkGenerator.class);
+ contributePkGenerators(binder).put(SQLServerAdapter.class.getName(), SybasePkGenerator.class);
+
+ /*contributePkGenerators(binder)
+ .put(DB2Adapter.class.getName(), DB2PkGenerator.class)
+ .put(DerbyAdapter.class.getName(), DerbyPkGenerator.class)
+ .put(FrontBaseAdapter.class.getName(), FrontBaseAdapter.class)
+ .put(H2Adapter.class.getName(), H2PkGenerator.class)
+ .put(IngresAdapter.class.getName(), IngresPkGenerator.class)
+ .put(MySQLAdapter.class.getName(), MySQLPkGenerator.class)
+ .put(OpenBaseAdapter.class.getName(), OpenBasePkGenerator.class)
+ .put(OracleAdapter.class.getName(), OraclePkGenerator.class)
+ .put(Oracle8Adapter.class.getName(), OraclePkGenerator.class)
+ .put(PostgresAdapter.class.getName(), PostgresPkGenerator.class)
+ .put(SQLServerAdapter.class.getName(), SybasePkGenerator.class)
+ .put(SybaseAdapter.class.getName(), SybasePkGenerator.class);
+*/
// configure a filter chain with only one TransactionFilter as default
contributeDomainFilters(binder).add(TransactionFilter.class);
@@ -393,10 +406,6 @@ public class ServerModule implements Module {
// DbAdapters
binder.bind(DbAdapterFactory.class).to(DefaultDbAdapterFactory.class);
- //a default PkGeneratorFactory used to load custom and automatic
- //PkGenerators
- binder.bind(PkGeneratorFactory.class).to(DefaultPkGeneratorFactory.class);
-
// binding AshwoodEntitySorter without scope, as this is a stateful
// object and is
// configured by the owning domain
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/dba/DbVersion.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbVersion.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbVersion.java
deleted file mode 100644
index 3caca4a..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbVersion.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.apache.cayenne.dba;
-
-import java.util.Objects;
-
-/**
- * Description of the database version and its type
- */
-public class DbVersion implements Comparable<DbVersion> {
-
- /**
- * DbVersion: majorVersion = 11, minorVersion = 0
- */
- public static final DbVersion MS_SQL_2012;
-
- /**
- * DbVersion: majorVersion = 10, minorVersion = 0
- */
- public static final DbVersion MS_SQL_2008;
-
- static {
- MS_SQL_2012 = new DbVersion(DbType.MS_SQL, 11, 0);
- MS_SQL_2008 = new DbVersion(DbType.MS_SQL, 10, 0);
- }
-
- private final DbType dbType;
- private final int majorVersion;
- private final int minorVersion;
-
- public DbVersion(DbType dbType, int majorVersion, int minorVersion) {
- this.dbType = dbType;
- this.majorVersion = majorVersion;
- this.minorVersion = minorVersion;
- }
-
- public int getMajorVersion() {
- return majorVersion;
- }
-
- public int getMinorVersion() {
- return minorVersion;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof DbVersion)) {
- return false;
- }
-
- DbVersion dbVersion = (DbVersion) obj;
-
- return dbVersion.majorVersion == this.majorVersion &&
- dbVersion.minorVersion == this.minorVersion;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(this.majorVersion, this.minorVersion);
- }
-
- @Override
- public String toString() {
- return "DbVersion: [dbType: '" + this.dbType.getType() +
- "', majorVersion:'" + this.majorVersion +
- "', minorVersion:'" + this.minorVersion + "']";
- }
-
- /**
- * @return {@code true} if the types of equivalents,
- * {@code false} otherwise
- */
- public boolean isTypeCheck(DbVersion o) {
- return this.dbType == o.dbType;
- }
-
- /**
- * Compare by version, type is not taken into account.
- * Before calling this method, do a check:
- * {@link DbVersion#isTypeCheck(org.apache.cayenne.dba.DbVersion)}
- */
- @Override
- public int compareTo(DbVersion o) {
- if (o.equals(this)) {
- return 0;
- }
- if (this.majorVersion == o.minorVersion) {
- return this.minorVersion - o.minorVersion;
- }
- return this.majorVersion - o.majorVersion;
- }
-
- public enum DbType {
-
- MS_SQL("MICROSOFT SQL SERVER");
-
- private final String type;
-
- DbType(String type) {
- this.type = type;
- }
-
- public String getType() {
- return type;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
index 0d9e1fc..d427699 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
@@ -51,321 +51,328 @@ import java.util.concurrent.ConcurrentMap;
*/
public class JdbcPkGenerator implements PkGenerator {
- public static final int DEFAULT_PK_CACHE_SIZE = 20;
- static final long DEFAULT_PK_START_VALUE = 200;
-
- protected JdbcAdapter adapter;
- protected ConcurrentMap<String, Queue<Long>> pkCache = new ConcurrentHashMap<>();
- protected int pkCacheSize = DEFAULT_PK_CACHE_SIZE;
- protected long pkStartValue = DEFAULT_PK_START_VALUE;
-
- public JdbcPkGenerator(JdbcAdapter adapter) {
- this.adapter = adapter;
- }
-
- public JdbcAdapter getAdapter() {
- return adapter;
- }
-
- public void createAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
- // check if a table exists
-
- // create AUTO_PK_SUPPORT table
- if (!autoPkTableExists(node)) {
- runUpdate(node, pkTableCreateString());
- }
-
- // delete any existing pk entries
- if (!dbEntities.isEmpty()) {
- runUpdate(node, pkDeleteString(dbEntities));
- }
-
- // insert all needed entries
- for (DbEntity ent : dbEntities) {
- runUpdate(node, pkCreateString(ent.getName()));
- }
- }
-
- public List<String> createAutoPkStatements(List<DbEntity> dbEntities) {
- List<String> list = new ArrayList<>(dbEntities.size() + 2);
-
- list.add(pkTableCreateString());
- list.add(pkDeleteString(dbEntities));
-
- for (DbEntity ent : dbEntities) {
- list.add(pkCreateString(ent.getName()));
- }
-
- return list;
- }
-
- /**
- * Drops table named "AUTO_PK_SUPPORT" if it exists in the database.
- */
- public void dropAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
- if (autoPkTableExists(node)) {
- runUpdate(node, dropAutoPkString());
- }
- }
-
- public List<String> dropAutoPkStatements(List<DbEntity> dbEntities) {
- List<String> list = new ArrayList<>(1);
- list.add(dropAutoPkString());
- return list;
- }
-
- protected String pkTableCreateString() {
- return "CREATE TABLE AUTO_PK_SUPPORT " +
- "(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, PRIMARY KEY(TABLE_NAME))";
- }
-
- protected String pkDeleteString(List<DbEntity> dbEntities) {
- StringBuilder buf = new StringBuilder();
- buf.append("DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN (");
- int len = dbEntities.size();
- for (int i = 0; i < len; i++) {
- if (i > 0) {
- buf.append(", ");
- }
- DbEntity ent = dbEntities.get(i);
- buf.append('\'').append(ent.getName()).append('\'');
- }
- buf.append(')');
- return buf.toString();
- }
-
- protected String pkCreateString(String entName) {
- return "INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('" + entName + "', " + pkStartValue + ")";
- }
-
- protected String pkSelectString(String entName) {
- return "SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = '" + entName + '\'';
- }
-
- protected String pkUpdateString(String entName) {
- return "UPDATE AUTO_PK_SUPPORT SET NEXT_ID = NEXT_ID + " + pkCacheSize + " WHERE TABLE_NAME = '" + entName + '\'';
- }
-
- protected String dropAutoPkString() {
- return "DROP TABLE AUTO_PK_SUPPORT";
- }
-
- /**
- * Checks if AUTO_PK_TABLE already exists in the database.
- */
- protected boolean autoPkTableExists(DataNode node) throws SQLException {
-
- try (Connection con = node.getDataSource().getConnection()) {
- DatabaseMetaData md = con.getMetaData();
- try (ResultSet tables = md.getTables(null, null, "AUTO_PK_SUPPORT", null)) {
- return tables.next();
- }
- }
- }
-
- /**
- * Runs JDBC update over a Connection obtained from DataNode. Returns a
- * number of objects returned from update.
- *
- * @throws SQLException
- * in case of query failure.
- */
- public int runUpdate(DataNode node, String sql) throws SQLException {
- adapter.getJdbcEventLogger().log(sql);
-
- try (Connection con = node.getDataSource().getConnection()) {
- try (Statement upd = con.createStatement()) {
- return upd.executeUpdate(sql);
- }
- }
- }
-
- /**
- * Generates a unique and non-repeating primary key for specified dbEntity.
- * <p>
- * This implementation is naive since it does not lock the database rows
- * when executing select and subsequent update. Adapter-specific
- * implementations are more robust.
- * </p>
- *
- * @since 3.0
- */
- public Object generatePk(DataNode node, DbAttribute pk) throws Exception {
-
- DbEntity entity = pk.getEntity();
-
- switch (pk.getType()) {
- case Types.BINARY:
- case Types.VARBINARY:
- return IDUtil.pseudoUniqueSecureByteSequence(pk.getMaxLength());
- }
-
- DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
- long cacheSize;
- if (pkGenerator != null && pkGenerator.getKeyCacheSize() != null) {
- cacheSize = pkGenerator.getKeyCacheSize();
- } else {
- cacheSize = getPkCacheSize();
- }
-
- Long value;
-
- // if no caching, always generate fresh
- if (cacheSize <= 1) {
- value = longPkFromDatabase(node, entity);
- } else {
- Queue<Long> pks = pkCache.get(entity.getName());
-
- if (pks == null) {
- // created exhausted LongPkRange
- pks = new ConcurrentLinkedQueue<>();
- Queue<Long> previousPks = pkCache.putIfAbsent(entity.getName(), pks);
- if (previousPks != null) {
- pks = previousPks;
- }
- }
-
- value = pks.poll();
- if (value == null) {
- value = longPkFromDatabase(node, entity);
- for (long i = value + 1; i < value + cacheSize; i++) {
- pks.add(i);
- }
- }
- }
-
- if (pk.getType() == Types.BIGINT) {
- return value;
- } else {
- // leaving it up to the user to ensure that PK does not exceed max int...
- return value.intValue();
- }
- }
-
- /**
- * Performs primary key generation ignoring cache. Generates a range of
- * primary keys as specified by "pkCacheSize" bean property.
- * <p>
- * This method is called internally from "generatePkForDbEntity" and then
- * generated range of key values is saved in cache for performance.
- * Subclasses that implement different primary key generation solutions
- * should override this method, not "generatePkForDbEntity".
- * </p>
- *
- * @since 3.0
- */
- protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
- String select = "SELECT #result('NEXT_ID' 'long' 'NEXT_ID') FROM AUTO_PK_SUPPORT "
- + "WHERE TABLE_NAME = '" + entity.getName() + '\'';
-
- // run queries via DataNode to utilize its transactional behavior
- List<Query> queries = new ArrayList<>(2);
- queries.add(new SQLTemplate(entity, select));
- queries.add(new SQLTemplate(entity, pkUpdateString(entity.getName())));
-
- PkRetrieveProcessor observer = new PkRetrieveProcessor(entity.getName());
- node.performQueries(queries, observer);
- return observer.getId();
- }
-
- /**
- * Returns a size of the entity primary key cache. Default value is 20. If
- * cache size is set to a value less or equals than "one", no primary key
- * caching is done.
- */
- public int getPkCacheSize() {
- return pkCacheSize;
- }
-
- /**
- * Sets the size of the entity primary key cache. If
- * <code>pkCacheSize</code> parameter is less than 1, cache size is set to
- * "one".
- * <p>
- * <i>Note that our tests show that setting primary key cache value to
- * anything much bigger than 20 does not give any significant performance
- * increase. Therefore it does not make sense to use bigger values, since
- * this may potentially create big gaps in the database primary key
- * sequences in cases like application crashes or restarts. </i>
- * </p>
- */
- public void setPkCacheSize(int pkCacheSize) {
- this.pkCacheSize = (pkCacheSize < 1) ? 1 : pkCacheSize;
- }
-
- long getPkStartValue() {
- return pkStartValue;
- }
-
- void setPkStartValue(long startValue) {
- this.pkStartValue = startValue;
- }
-
- public void reset() {
- pkCache.clear();
- }
-
- /**
- * OperationObserver for primary key retrieval.
- */
- final class PkRetrieveProcessor implements OperationObserver {
-
- Number id;
- final String entityName;
-
- PkRetrieveProcessor(String entityName) {
- this.entityName = entityName;
- }
-
- public boolean isIteratedResult() {
- return false;
- }
-
- public long getId() {
- if (id == null) {
- throw new CayenneRuntimeException("No key was retrieved for entity %s", entityName);
- }
-
- return id.longValue();
- }
-
- public void nextRows(Query query, List<?> dataRows) {
- // process selected object, issue an update query
- if (dataRows == null || dataRows.size() == 0) {
- throw new CayenneRuntimeException("Error generating PK : entity not supported: %s", entityName);
- }
-
- if (dataRows.size() > 1) {
- throw new CayenneRuntimeException("Error generating PK : too many rows for entity: %s", entityName);
- }
-
- DataRow lastPk = (DataRow) dataRows.get(0);
- id = (Number) lastPk.get("NEXT_ID");
- }
-
- public void nextCount(Query query, int resultCount) {
- if (resultCount != 1) {
- throw new CayenneRuntimeException("Error generating PK for entity '%s': update count is wrong - %d"
- , entityName, resultCount);
- }
- }
-
- public void nextBatchCount(Query query, int[] resultCount) {
- }
-
- @Override
- public void nextGeneratedRows(Query query, ResultIterator keys, ObjectId idToUpdate) {
- }
-
- public void nextRows(Query q, ResultIterator it) {
- }
-
- public void nextQueryException(Query query, Exception ex) {
- throw new CayenneRuntimeException("Error generating PK for entity '" + entityName + "'.", ex);
- }
-
- public void nextGlobalException(Exception ex) {
- throw new CayenneRuntimeException("Error generating PK for entity: " + entityName, ex);
- }
- }
+ public static final int DEFAULT_PK_CACHE_SIZE = 20;
+ static final long DEFAULT_PK_START_VALUE = 200;
+
+ protected JdbcAdapter adapter;
+ protected ConcurrentMap<String, Queue<Long>> pkCache = new ConcurrentHashMap<>();
+ protected int pkCacheSize = DEFAULT_PK_CACHE_SIZE;
+ protected long pkStartValue = DEFAULT_PK_START_VALUE;
+
+ public JdbcPkGenerator() {
+ }
+
+ public JdbcPkGenerator(JdbcAdapter adapter) {
+ this.adapter = adapter;
+ }
+
+ public JdbcAdapter getAdapter() {
+ return this.adapter;
+ }
+
+ public void createAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
+ // check if a table exists
+
+ // create AUTO_PK_SUPPORT table
+ if (!autoPkTableExists(node)) {
+ runUpdate(node, pkTableCreateString());
+ }
+
+ // delete any existing pk entries
+ if (!dbEntities.isEmpty()) {
+ runUpdate(node, pkDeleteString(dbEntities));
+ }
+
+ // insert all needed entries
+ for (DbEntity ent : dbEntities) {
+ runUpdate(node, pkCreateString(ent.getName()));
+ }
+ }
+
+ public List<String> createAutoPkStatements(List<DbEntity> dbEntities) {
+ List<String> list = new ArrayList<>(dbEntities.size() + 2);
+
+ list.add(pkTableCreateString());
+ list.add(pkDeleteString(dbEntities));
+
+ for (DbEntity ent : dbEntities) {
+ list.add(pkCreateString(ent.getName()));
+ }
+
+ return list;
+ }
+
+ /**
+ * Drops table named "AUTO_PK_SUPPORT" if it exists in the database.
+ */
+ public void dropAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
+ if (autoPkTableExists(node)) {
+ runUpdate(node, dropAutoPkString());
+ }
+ }
+
+ public List<String> dropAutoPkStatements(List<DbEntity> dbEntities) {
+ List<String> list = new ArrayList<>(1);
+ list.add(dropAutoPkString());
+ return list;
+ }
+
+ protected String pkTableCreateString() {
+ return "CREATE TABLE AUTO_PK_SUPPORT " +
+ "(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, PRIMARY KEY(TABLE_NAME))";
+ }
+
+ protected String pkDeleteString(List<DbEntity> dbEntities) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN (");
+ int len = dbEntities.size();
+ for (int i = 0; i < len; i++) {
+ if (i > 0) {
+ buf.append(", ");
+ }
+ DbEntity ent = dbEntities.get(i);
+ buf.append('\'').append(ent.getName()).append('\'');
+ }
+ buf.append(')');
+ return buf.toString();
+ }
+
+ protected String pkCreateString(String entName) {
+ return "INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('" + entName + "', " + pkStartValue + ")";
+ }
+
+ protected String pkSelectString(String entName) {
+ return "SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = '" + entName + '\'';
+ }
+
+ protected String pkUpdateString(String entName) {
+ return "UPDATE AUTO_PK_SUPPORT SET NEXT_ID = NEXT_ID + " + pkCacheSize + " WHERE TABLE_NAME = '" + entName + '\'';
+ }
+
+ protected String dropAutoPkString() {
+ return "DROP TABLE AUTO_PK_SUPPORT";
+ }
+
+ /**
+ * Checks if AUTO_PK_TABLE already exists in the database.
+ */
+ protected boolean autoPkTableExists(DataNode node) throws SQLException {
+
+ try (Connection con = node.getDataSource().getConnection()) {
+ DatabaseMetaData md = con.getMetaData();
+ try (ResultSet tables = md.getTables(null, null, "AUTO_PK_SUPPORT", null)) {
+ return tables.next();
+ }
+ }
+ }
+
+ /**
+ * Runs JDBC update over a Connection obtained from DataNode. Returns a
+ * number of objects returned from update.
+ *
+ * @throws SQLException in case of query failure.
+ */
+ public int runUpdate(DataNode node, String sql) throws SQLException {
+ adapter.getJdbcEventLogger().log(sql);
+
+ try (Connection con = node.getDataSource().getConnection()) {
+ try (Statement upd = con.createStatement()) {
+ return upd.executeUpdate(sql);
+ }
+ }
+ }
+
+ /**
+ * Generates a unique and non-repeating primary key for specified dbEntity.
+ * <p>
+ * This implementation is naive since it does not lock the database rows
+ * when executing select and subsequent update. Adapter-specific
+ * implementations are more robust.
+ * </p>
+ *
+ * @since 3.0
+ */
+ public Object generatePk(DataNode node, DbAttribute pk) throws Exception {
+
+ DbEntity entity = pk.getEntity();
+
+ switch (pk.getType()) {
+ case Types.BINARY:
+ case Types.VARBINARY:
+ return IDUtil.pseudoUniqueSecureByteSequence(pk.getMaxLength());
+ }
+
+ DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
+ long cacheSize;
+ if (pkGenerator != null && pkGenerator.getKeyCacheSize() != null) {
+ cacheSize = pkGenerator.getKeyCacheSize();
+ } else {
+ cacheSize = getPkCacheSize();
+ }
+
+ Long value;
+
+ // if no caching, always generate fresh
+ if (cacheSize <= 1) {
+ value = longPkFromDatabase(node, entity);
+ } else {
+ Queue<Long> pks = pkCache.get(entity.getName());
+
+ if (pks == null) {
+ // created exhausted LongPkRange
+ pks = new ConcurrentLinkedQueue<>();
+ Queue<Long> previousPks = pkCache.putIfAbsent(entity.getName(), pks);
+ if (previousPks != null) {
+ pks = previousPks;
+ }
+ }
+
+ value = pks.poll();
+ if (value == null) {
+ value = longPkFromDatabase(node, entity);
+ for (long i = value + 1; i < value + cacheSize; i++) {
+ pks.add(i);
+ }
+ }
+ }
+
+ if (pk.getType() == Types.BIGINT) {
+ return value;
+ } else {
+ // leaving it up to the user to ensure that PK does not exceed max int...
+ return value.intValue();
+ }
+ }
+
+ @Override
+ public void setAdapter(DbAdapter adapter) {
+ this.adapter = (JdbcAdapter) adapter;
+ }
+
+ /**
+ * Performs primary key generation ignoring cache. Generates a range of
+ * primary keys as specified by "pkCacheSize" bean property.
+ * <p>
+ * This method is called internally from "generatePkForDbEntity" and then
+ * generated range of key values is saved in cache for performance.
+ * Subclasses that implement different primary key generation solutions
+ * should override this method, not "generatePkForDbEntity".
+ * </p>
+ *
+ * @since 3.0
+ */
+ protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
+ String select = "SELECT #result('NEXT_ID' 'long' 'NEXT_ID') FROM AUTO_PK_SUPPORT "
+ + "WHERE TABLE_NAME = '" + entity.getName() + '\'';
+
+ // run queries via DataNode to utilize its transactional behavior
+ List<Query> queries = new ArrayList<>(2);
+ queries.add(new SQLTemplate(entity, select));
+ queries.add(new SQLTemplate(entity, pkUpdateString(entity.getName())));
+
+ PkRetrieveProcessor observer = new PkRetrieveProcessor(entity.getName());
+ node.performQueries(queries, observer);
+ return observer.getId();
+ }
+
+ /**
+ * Returns a size of the entity primary key cache. Default value is 20. If
+ * cache size is set to a value less or equals than "one", no primary key
+ * caching is done.
+ */
+ public int getPkCacheSize() {
+ return pkCacheSize;
+ }
+
+ /**
+ * Sets the size of the entity primary key cache. If
+ * <code>pkCacheSize</code> parameter is less than 1, cache size is set to
+ * "one".
+ * <p>
+ * <i>Note that our tests show that setting primary key cache value to
+ * anything much bigger than 20 does not give any significant performance
+ * increase. Therefore it does not make sense to use bigger values, since
+ * this may potentially create big gaps in the database primary key
+ * sequences in cases like application crashes or restarts. </i>
+ * </p>
+ */
+ public void setPkCacheSize(int pkCacheSize) {
+ this.pkCacheSize = (pkCacheSize < 1) ? 1 : pkCacheSize;
+ }
+
+ long getPkStartValue() {
+ return pkStartValue;
+ }
+
+ void setPkStartValue(long startValue) {
+ this.pkStartValue = startValue;
+ }
+
+ public void reset() {
+ pkCache.clear();
+ }
+
+ /**
+ * OperationObserver for primary key retrieval.
+ */
+ final class PkRetrieveProcessor implements OperationObserver {
+
+ Number id;
+ final String entityName;
+
+ PkRetrieveProcessor(String entityName) {
+ this.entityName = entityName;
+ }
+
+ public boolean isIteratedResult() {
+ return false;
+ }
+
+ public long getId() {
+ if (id == null) {
+ throw new CayenneRuntimeException("No key was retrieved for entity %s", entityName);
+ }
+
+ return id.longValue();
+ }
+
+ public void nextRows(Query query, List<?> dataRows) {
+ // process selected object, issue an update query
+ if (dataRows == null || dataRows.size() == 0) {
+ throw new CayenneRuntimeException("Error generating PK : entity not supported: %s", entityName);
+ }
+
+ if (dataRows.size() > 1) {
+ throw new CayenneRuntimeException("Error generating PK : too many rows for entity: %s", entityName);
+ }
+
+ DataRow lastPk = (DataRow) dataRows.get(0);
+ id = (Number) lastPk.get("NEXT_ID");
+ }
+
+ public void nextCount(Query query, int resultCount) {
+ if (resultCount != 1) {
+ throw new CayenneRuntimeException("Error generating PK for entity '%s': update count is wrong - %d"
+ , entityName, resultCount);
+ }
+ }
+
+ public void nextBatchCount(Query query, int[] resultCount) {
+ }
+
+ @Override
+ public void nextGeneratedRows(Query query, ResultIterator keys, ObjectId idToUpdate) {
+ }
+
+ public void nextRows(Query q, ResultIterator it) {
+ }
+
+ public void nextQueryException(Query query, Exception ex) {
+ throw new CayenneRuntimeException("Error generating PK for entity '" + entityName + "'.", ex);
+ }
+
+ public void nextGlobalException(Exception ex) {
+ throw new CayenneRuntimeException("Error generating PK for entity: " + entityName, ex);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/dba/PkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/PkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/PkGenerator.java
index d223e72..97d8f01 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/PkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/PkGenerator.java
@@ -30,12 +30,13 @@ import org.apache.cayenne.map.DbEntity;
*/
public interface PkGenerator {
+
/**
* Generates necessary database objects to provide automatic primary key support.
- *
- * @param node node that provides access to a DataSource.
+ *
+ * @param node node that provides access to a DataSource.
* @param dbEntities a list of entities that require primary key auto-generation
- * support
+ * support
*/
void createAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception;
@@ -49,10 +50,10 @@ public interface PkGenerator {
/**
* Drops any common database objects associated with automatic primary key generation
* process. This may be lookup tables, special stored procedures or sequences.
- *
- * @param node node that provides access to a DataSource.
+ *
+ * @param node node that provides access to a DataSource.
* @param dbEntities a list of entities whose primary key auto-generation support
- * should be dropped.
+ * should be dropped.
*/
void dropAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception;
@@ -64,12 +65,22 @@ public interface PkGenerator {
/**
* Generates a unique and non-repeating primary key for specified PK attribute.
- *
+ *
* @since 3.0
*/
Object generatePk(DataNode dataNode, DbAttribute pk) throws Exception;
/**
+ * Install the adapter associated with current PkGenerator
+ */
+ void setAdapter(DbAdapter q);
+
+ /**
+ * Get an adapter associated with current PkGenerator
+ */
+ DbAdapter getAdapter();
+
+ /**
* Resets any cached primary keys forcing generator to go to the database next time id
* generation is requested. May not be applicable for all generator implementations.
*/
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
index aef4e9c..301ef98 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
@@ -20,17 +20,15 @@
package org.apache.cayenne.dba.sqlserver;
import org.apache.cayenne.configuration.server.DbAdapterDetector;
-import org.apache.cayenne.configuration.server.PkGeneratorFactory;
+import org.apache.cayenne.configuration.server.PkGeneratorFactoryProvider;
import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.DbVersion;
import org.apache.cayenne.dba.PkGenerator;
import org.apache.cayenne.di.AdhocObjectFactory;
import org.apache.cayenne.di.Inject;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
-
-import static org.apache.cayenne.dba.DbVersion.DbType.MS_SQL;
+import java.util.Objects;
/**
* Detects SQLServer database from JDBC metadata.
@@ -41,22 +39,16 @@ public class SQLServerSniffer implements DbAdapterDetector {
protected AdhocObjectFactory objectFactory;
- protected PkGeneratorFactory pkGeneratorFactory;
-
- private final DbVersion.DbType dbType;
+ protected PkGeneratorFactoryProvider pkGeneratorProvider;
- public SQLServerSniffer(@Inject AdhocObjectFactory objectFactory, @Inject PkGeneratorFactory pkGeneratorFactory) {
+ public SQLServerSniffer(@Inject AdhocObjectFactory objectFactory,
+ @Inject PkGeneratorFactoryProvider pkGeneratorProvider) {
this.objectFactory = objectFactory;
- this.pkGeneratorFactory = pkGeneratorFactory;
- this.dbType = MS_SQL;
+ this.pkGeneratorProvider = Objects.requireNonNull(pkGeneratorProvider, () -> "Null pkGeneratorProvider");
}
@Override
public DbAdapter createAdapter(DatabaseMetaData md) throws SQLException {
- String dbName = md.getDatabaseProductName();
- if (dbName == null || !dbName.toUpperCase().contains(dbType.getType())) {
- return null;
- }
SQLServerAdapter adapter = objectFactory.newInstance(
SQLServerAdapter.class,
@@ -70,7 +62,8 @@ public class SQLServerSniffer implements DbAdapterDetector {
try {
generatedKeys = md.supportsGetGeneratedKeys();
if (generatedKeys) {
- pkGenerator = pkGeneratorFactory.detectPkGenerator(dbType, adapter, md);
+ pkGenerator = pkGeneratorProvider.get(adapter);
+
}
} catch (Throwable th) {
// catch exceptions resulting from incomplete JDBC3 implementation
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
index c815473..a309f23 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
@@ -40,6 +40,10 @@ import java.util.List;
*/
public class SybasePkGenerator extends JdbcPkGenerator {
+ public SybasePkGenerator(){
+ super();
+ }
+
protected SybasePkGenerator(JdbcAdapter adapter) {
super(adapter);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
index beba838..44ab64a 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
@@ -53,6 +53,8 @@ import org.apache.cayenne.configuration.DefaultDataChannelDescriptorMerger;
import org.apache.cayenne.configuration.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.RuntimeProperties;
import org.apache.cayenne.configuration.mock.MockDataSourceFactory;
+import org.apache.cayenne.dba.JdbcPkGenerator;
+import org.apache.cayenne.dba.PkGenerator;
import org.apache.cayenne.dba.db2.DB2Sniffer;
import org.apache.cayenne.dba.derby.DerbySniffer;
import org.apache.cayenne.dba.firebird.FirebirdSniffer;
@@ -66,7 +68,7 @@ import org.apache.cayenne.dba.oracle.OracleAdapter;
import org.apache.cayenne.dba.oracle.OracleSniffer;
import org.apache.cayenne.dba.postgres.PostgresSniffer;
import org.apache.cayenne.dba.sqlite.SQLiteSniffer;
-import org.apache.cayenne.dba.sqlserver.SQLServerPkGenerator;
+import org.apache.cayenne.dba.sqlserver.SQLServerAdapter;
import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
import org.apache.cayenne.dba.sybase.SybasePkGenerator;
import org.apache.cayenne.dba.sybase.SybaseSniffer;
@@ -97,8 +99,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2008;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2012;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -161,9 +161,9 @@ public class DataDomainProviderTest {
ServerModule.contributeDomainListeners(binder).add(mockListener);
ServerModule.contributeProjectLocations(binder).add(testConfigName);
- ServerModule.contributePkGenerators(binder)
- .put(String.valueOf(MS_SQL_2008), SybasePkGenerator.class)
- .put(String.valueOf(MS_SQL_2012), SQLServerPkGenerator.class);
+ binder.bind(PkGenerator.class).to(JdbcPkGenerator.class);
+ binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class);
+ ServerModule.contributePkGenerators(binder).put(SQLServerAdapter.class.getName(), SybasePkGenerator.class);
// configure extended types
ServerModule.contributeDefaultTypes(binder);
@@ -194,7 +194,6 @@ public class DataDomainProviderTest {
binder.bind(DataChannelDescriptorMerger.class).to(DefaultDataChannelDescriptorMerger.class);
binder.bind(DataChannelDescriptorLoader.class).toInstance(testLoader);
binder.bind(DbAdapterFactory.class).to(DefaultDbAdapterFactory.class);
- binder.bind(PkGeneratorFactory.class).to(DefaultPkGeneratorFactory.class);
binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class);
binder.bind(BatchTranslatorFactory.class).to(DefaultBatchTranslatorFactory.class);
binder.bind(SelectTranslatorFactory.class).to(DefaultSelectTranslatorFactory.class);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/test/java/org/apache/cayenne/dba/sqlserver/SQLServerSnifferIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/dba/sqlserver/SQLServerSnifferIT.java b/cayenne-server/src/test/java/org/apache/cayenne/dba/sqlserver/SQLServerSnifferIT.java
index ab19411..23946ab 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/dba/sqlserver/SQLServerSnifferIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/dba/sqlserver/SQLServerSnifferIT.java
@@ -19,12 +19,7 @@
package org.apache.cayenne.dba.sqlserver;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.sql.Connection;
-
-import org.apache.cayenne.configuration.server.PkGeneratorFactory;
+import org.apache.cayenne.configuration.server.PkGeneratorFactoryProvider;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.di.AdhocObjectFactory;
import org.apache.cayenne.di.Inject;
@@ -36,6 +31,11 @@ import org.apache.cayenne.unit.di.server.ServerCaseDataSourceFactory;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
import org.junit.Test;
+import java.sql.Connection;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
public class SQLServerSnifferIT extends ServerCase {
@@ -49,12 +49,12 @@ public class SQLServerSnifferIT extends ServerCase {
private AdhocObjectFactory objectFactory;
@Inject
- private PkGeneratorFactory pkGeneratorFactory;
+ private PkGeneratorFactoryProvider pkGeneratorProvider;
@Test
public void testCreateAdapter() throws Exception {
- SQLServerSniffer sniffer = new SQLServerSniffer(objectFactory, pkGeneratorFactory);
+ SQLServerSniffer sniffer = new SQLServerSniffer(objectFactory, pkGeneratorProvider);
DbAdapter adapter = null;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/284151ce/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
index 75f4905..4b7701c 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
@@ -56,7 +56,10 @@ import org.apache.cayenne.configuration.DefaultObjectStoreFactory;
import org.apache.cayenne.configuration.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.ObjectStoreFactory;
import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.configuration.server.*;
+import org.apache.cayenne.configuration.server.DataSourceFactory;
+import org.apache.cayenne.configuration.server.PkGeneratorFactoryProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.configuration.server.ServerRuntime;
import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.configuration.xml.DefaultHandlerFactory;
import org.apache.cayenne.configuration.xml.HandlerFactory;
@@ -66,6 +69,8 @@ import org.apache.cayenne.configuration.xml.XMLReaderProvider;
import org.apache.cayenne.conn.DataSourceInfo;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.dba.JdbcAdapter;
+import org.apache.cayenne.dba.JdbcPkGenerator;
+import org.apache.cayenne.dba.PkGenerator;
import org.apache.cayenne.dba.db2.DB2Adapter;
import org.apache.cayenne.dba.derby.DerbyAdapter;
import org.apache.cayenne.dba.firebird.FirebirdAdapter;
@@ -80,7 +85,6 @@ 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.sqlserver.SQLServerPkGenerator;
import org.apache.cayenne.dba.sybase.SybaseAdapter;
import org.apache.cayenne.dba.sybase.SybasePkGenerator;
import org.apache.cayenne.di.AdhocObjectFactory;
@@ -91,8 +95,8 @@ import org.apache.cayenne.di.Module;
import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
import org.apache.cayenne.di.spi.DefaultScope;
-import org.apache.cayenne.log.Slf4jJdbcEventLogger;
import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.log.Slf4jJdbcEventLogger;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.resource.ClassLoaderResourceLocator;
import org.apache.cayenne.resource.ResourceLocator;
@@ -120,9 +124,6 @@ import org.xml.sax.XMLReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2008;
-import static org.apache.cayenne.dba.DbVersion.MS_SQL_2012;
-
public class ServerCaseModule implements Module {
protected DefaultScope testScope;
@@ -160,9 +161,9 @@ public class ServerCaseModule implements Module {
// Should remove problems with random-failing tests (those that are GC-sensitive).
.put(Constants.SERVER_OBJECT_RETAIN_STRATEGY_PROPERTY, "soft");
- ServerModule.contributePkGenerators(binder)
- .put(String.valueOf(MS_SQL_2008), SybasePkGenerator.class)
- .put(String.valueOf(MS_SQL_2012), SQLServerPkGenerator.class);
+ binder.bind(PkGeneratorFactoryProvider.class).to(PkGeneratorFactoryProvider.class);
+ binder.bind(PkGenerator.class).to(JdbcPkGenerator.class);
+ ServerModule.contributePkGenerators(binder).put(SQLServerAdapter.class.getName(), SybasePkGenerator.class);
// configure extended types
ServerModule.contributeDefaultTypes(binder)
@@ -207,7 +208,6 @@ public class ServerCaseModule implements Module {
binder.bind(DbAdapter.class).toProvider(ServerCaseDbAdapterProvider.class);
binder.bind(JdbcAdapter.class).toProvider(ServerCaseDbAdapterProvider.class);
binder.bind(UnitDbAdapter.class).toProvider(UnitDbAdapterProvider.class);
- binder.bind(PkGeneratorFactory.class).to(DefaultPkGeneratorFactory.class);
// this factory is a hack that allows to inject to DbAdapters loaded outside of
// server runtime... BatchQueryBuilderFactory is hardcoded and whatever is placed