Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--features/org.eclipse.emf.cdo.server.product-feature/rootfiles/configuration/cdo-server.xml38
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/plugin.xml20
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/schema/delegateProviders.exsd109
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java231
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java18
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreChunkReader.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java181
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegateProvider.java35
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMetaDataManager.java96
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IPreparedStatementCache.java47
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IAttributeMapping.java35
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java128
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java71
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IFeatureMapping.java24
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java99
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java45
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java170
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IReferenceMapping.java78
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java120
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java47
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java145
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java566
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java27
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java375
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java69
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java275
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java552
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java334
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java1661
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java49
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java648
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegateProvider.java37
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java454
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AttributeMapping.java327
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ClassMapping.java708
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/FeatureMapping.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalClassMapping.java112
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalMappingStrategy.java225
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/MappingStrategy.java390
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/NoClassMapping.java124
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ReferenceMapping.java198
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/RootClassMapping.java45
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ToOneReferenceMapping.java35
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java409
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalClassMapping.java96
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalMappingStrategy.java72
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java370
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java189
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java522
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java62
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java401
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java49
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java563
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java50
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java514
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java (renamed from plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java)146
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/CDO AllTests (Hsqldb).launch4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java18
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbNonAudit.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java31
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmtNonAudit.java51
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java130
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java31
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_248052_Test.java43
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_251752_Test.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_272861_Test.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java421
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Scenario.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AbstractDBStoreVerifier.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java40
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java52
84 files changed, 6126 insertions, 7370 deletions
diff --git a/features/org.eclipse.emf.cdo.server.product-feature/rootfiles/configuration/cdo-server.xml b/features/org.eclipse.emf.cdo.server.product-feature/rootfiles/configuration/cdo-server.xml
index 3511572e8f..7cde0d1348 100644
--- a/features/org.eclipse.emf.cdo.server.product-feature/rootfiles/configuration/cdo-server.xml
+++ b/features/org.eclipse.emf.cdo.server.product-feature/rootfiles/configuration/cdo-server.xml
@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<cdoServer>
- <!--acceptor type="http"/ -->
+ <!--
+ <acceptor type="http"/>
+ -->
<acceptor type="tcp" listenAddr="0.0.0.0" port="2036">
- <!-- negotiator type="challenge" description="/temp/users.db"/ -->
+ <!--
+ <negotiator type="challenge" description="/temp/users.db"/>
+ -->
</acceptor>
<repository name="repo1">
@@ -21,39 +25,33 @@
<property name="toOneReferences" value="LIKE_ATTRIBUTES"/>
</mappingStrategy>
- <!-- Old setting <jdbcDelegate type="statement" />
- is now replaced by preparedStatement: -->
- <jdbcDelegate type="preparedStatement" >
- <!-- to explicitly force prepared statement caching (e.g., if statement pooling is not supported
- by the JDBC driver, use
- <property name="cacheStatements" value="enabled" />
- Else, the implicit default is:
- <property name="cacheStatements" value="guess" />
- Which guesses the correct setting based on the JDBC driver's metadata.
- Also supported is the third setting "disabled".
- -->
- </jdbcDelegate>
<dbAdapter name="derby-embedded"/>
<dataSource class="org.apache.derby.jdbc.EmbeddedDataSource"
databaseName="/temp/cdodb1"
createDatabase="create"/>
- <!--<dbAdapter name="hsqldb"/>
+ <!--
+ <dbAdapter name="hsqldb"/>
<dataSource class="org.eclipse.net4j.db.hsqldb.HSQLDBDataSource"
database="jdbc:hsqldb:mem:cdodb1"
- user="sa"/>-->
+ user="sa"/>
+ -->
- <!--<dbAdapter name="mysql"/>
+ <!--
+ <dbAdapter name="mysql"/>
<dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
url="jdbc:mysql://localhost/cdodb1"
- user="sa"/>-->
+ user="sa"/>
+ -->
- <!--<dbAdapter name="postgresql"/>
+ <!--
+ <dbAdapter name="postgresql"/>
<dataSource class="org.postgresql.ds.PGSimpleDataSource"
url="jdbc:postgresql://localhost:5432/cdo"
databaseName="cdo"
user="cdo"
- password="cdo"/>-->
+ password="cdo"/>
+ -->
</store>
</repository>
diff --git a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF
index 51ca5023cf..2cf0fda3bd 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF
@@ -17,4 +17,5 @@ Export-Package: org.eclipse.emf.cdo.server.db;version="2.0.0",
org.eclipse.emf.cdo.server.internal.db;version="2.0.0";x-friends:="org.eclipse.emf.cdo.tests",
org.eclipse.emf.cdo.server.internal.db.bundle;version="2.0.0";x-internal:=true,
org.eclipse.emf.cdo.server.internal.db.jdbc;version="2.0.0";x-friends:="org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.server.internal.db.mapping;version="2.0.0";x-friends:="org.eclipse.emf.cdo.tests"
+ org.eclipse.emf.cdo.server.internal.db.mapping;version="2.0.0";x-friends:="org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="2.0.0";x-friends:="org.eclipse.emf.cdo.tests"
diff --git a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
index acd168a01a..4a30c67ec8 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
+++ b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
@@ -14,7 +14,6 @@
<plugin>
<extension-point id="mappingStrategies" name="CDO Mapping Strategies" schema="schema/mappingStrategies.exsd"/>
- <extension-point id="jdbcDelegateProviders" name="CDO JDBC Delegate Providers" schema="schema/delegateProviders.exsd"/>
<extension
point="org.eclipse.emf.cdo.server.storeFactories">
@@ -27,25 +26,12 @@
<extension
point="org.eclipse.emf.cdo.server.db.mappingStrategies">
<mappingStrategy
- class="org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy"
+ class="org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy"
type="horizontal">
</mappingStrategy>
<mappingStrategy
- class="org.eclipse.emf.cdo.server.internal.db.mapping.VerticalMappingStrategy"
- type="vertical">
+ class="org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy"
+ type="horizontalNonAudit">
</mappingStrategy>
</extension>
-
- <extension
- point="org.eclipse.emf.cdo.server.db.jdbcDelegateProviders">
- <jdbcDelegateProvider
- class="org.eclipse.emf.cdo.server.internal.db.jdbc.StatementJDBCDelegateProvider"
- type="statement">
- </jdbcDelegateProvider>
- <jdbcDelegateProvider
- class="org.eclipse.emf.cdo.server.internal.db.jdbc.PreparedStatementJDBCDelegateProvider"
- type="preparedStatement">
- </jdbcDelegateProvider>
- </extension>
-
</plugin>
diff --git a/plugins/org.eclipse.emf.cdo.server.db/schema/delegateProviders.exsd b/plugins/org.eclipse.emf.cdo.server.db/schema/delegateProviders.exsd
deleted file mode 100644
index 048126191d..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/schema/delegateProviders.exsd
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Schema file written by PDE -->
-<schema targetNamespace="org.eclipse.emf.cdo.server.db" xmlns="http://www.w3.org/2001/XMLSchema">
-<annotation>
- <appinfo>
- <meta.schema plugin="org.eclipse.emf.cdo.server.db" id="jdbcDelegateProviders" name="CDO JDBC Delegate Providers"/>
- </appinfo>
- <documentation>
- [Enter description of this extension point.]
- </documentation>
- </annotation>
-
- <element name="extension">
- <annotation>
- <appinfo>
- <meta.element />
- </appinfo>
- </annotation>
- <complexType>
- <sequence>
- <element ref="jdbcDelegateProvider" minOccurs="1" maxOccurs="unbounded"/>
- </sequence>
- <attribute name="point" type="string" use="required">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- <attribute name="id" type="string">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- <attribute name="name" type="string">
- <annotation>
- <documentation>
-
- </documentation>
- <appinfo>
- <meta.attribute translatable="true"/>
- </appinfo>
- </annotation>
- </attribute>
- </complexType>
- </element>
-
- <element name="jdbcDelegateProvider">
- <complexType>
- <attribute name="type" type="string" use="required">
- <annotation>
- <documentation>
-
- </documentation>
- </annotation>
- </attribute>
- <attribute name="class" type="string" use="required">
- <annotation>
- <documentation>
-
- </documentation>
- <appinfo>
- <meta.attribute kind="java" basedOn=":org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider"/>
- </appinfo>
- </annotation>
- </attribute>
- </complexType>
- </element>
-
- <annotation>
- <appinfo>
- <meta.section type="since"/>
- </appinfo>
- <documentation>
- [Enter the first release in which this extension point appears.]
- </documentation>
- </annotation>
-
- <annotation>
- <appinfo>
- <meta.section type="examples"/>
- </appinfo>
- <documentation>
- [Enter extension point usage example here.]
- </documentation>
- </annotation>
-
- <annotation>
- <appinfo>
- <meta.section type="apiInfo"/>
- </appinfo>
- <documentation>
- [Enter API information here.]
- </documentation>
- </annotation>
-
- <annotation>
- <appinfo>
- <meta.section type="implementation"/>
- </appinfo>
- <documentation>
- [Enter information about supplied implementation of this extension point.]
- </documentation>
- </annotation>
-
-
-</schema>
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
index 06a2caebec..9d43f88d09 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
@@ -7,6 +7,9 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ *
*/
package org.eclipse.emf.cdo.server.db;
@@ -14,21 +17,29 @@ import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.DBStore;
+import org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.jdbc.PreparedStatementJDBCDelegateProvider;
-import org.eclipse.emf.cdo.server.internal.db.jdbc.StatementJDBCDelegateProvider;
-import org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy;
+import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
/**
* @author Eike Stepper
*/
@@ -37,12 +48,12 @@ public final class CDODBUtil
/**
* @since 2.0
*/
- public static final String EXT_POINT_MAPPING_STRATEGIES = "mappingStrategies";
+ public static final int DEFAULT_STATEMENT_CACHE_CAPACITY = 200;
/**
* @since 2.0
*/
- public static final String EXT_POINT_JDBC_DELEGATE_PROVIDERS = "jdbcDelegateProviders";
+ public static final String EXT_POINT_MAPPING_STRATEGIES = "mappingStrategies";
private CDODBUtil()
{
@@ -52,13 +63,12 @@ public final class CDODBUtil
* @since 2.0
*/
public static IDBStore createStore(IMappingStrategy mappingStrategy, IDBAdapter dbAdapter,
- IDBConnectionProvider dbConnectionProvider, IJDBCDelegateProvider delegateProvider)
+ IDBConnectionProvider dbConnectionProvider)
{
DBStore store = new DBStore();
store.setMappingStrategy(mappingStrategy);
store.setDBAdapter(dbAdapter);
store.setDbConnectionProvider(dbConnectionProvider);
- store.setJDBCDelegateProvider(delegateProvider);
mappingStrategy.setStore(store);
return store;
}
@@ -68,23 +78,15 @@ public final class CDODBUtil
*/
public static IMappingStrategy createHorizontalMappingStrategy()
{
- return new HorizontalMappingStrategy();
- }
-
- /**
- * @since 2.0
- */
- public static IJDBCDelegateProvider createStatementJDBCDelegateProvider()
- {
- return new StatementJDBCDelegateProvider();
+ return new HorizontalAuditMappingStrategy();
}
/**
* @since 2.0
*/
- public static IJDBCDelegateProvider createPreparedStatementJDBCDelegateProvider()
+ public static IMappingStrategy createHorizontalNonAuditMappingStrategy()
{
- return new PreparedStatementJDBCDelegateProvider();
+ return new HorizontalNonAuditMappingStrategy();
}
/**
@@ -121,71 +123,172 @@ public final class CDODBUtil
}
/**
+ * Get the long value of a CDOID (by delegating to {@link CDOIDUtil#getLong(org.eclipse.emf.cdo.common.id.CDOID)}) In
+ * addition, provide a check for external IDs which are not supported by the DBStore
+ *
+ * @param id
+ * the ID to convert to long
+ * @return the long value of the ID
+ * @throws IllegalArgumentException
+ * if the ID is not convertibla
* @since 2.0
*/
- public static IJDBCDelegateProvider createDelegateProvider(String type)
+ public static long getLong(CDOID id)
{
- IExtensionRegistry registry = Platform.getExtensionRegistry();
- IConfigurationElement[] elements = registry.getConfigurationElementsFor(OM.BUNDLE_ID,
- EXT_POINT_JDBC_DELEGATE_PROVIDERS);
- for (final IConfigurationElement element : elements)
+ if (id != null && id.getType() == CDOID.Type.EXTERNAL_OBJECT)
+ {
+ throw new IllegalArgumentException("DBStore does not support external references: " + id);
+ }
+
+ return CDOIDUtil.getLong(id);
+ }
+
+ /**
+ * Execute update on the given prepared statement and handle common cases of return values.
+ *
+ * @param stmt
+ * the prepared statement
+ * @param exactlyOne
+ * if <code>true</code>, the update count is checked to be <code>1</code>. Else the update result is only
+ * checked so that the update was successful (i.e. result code != Statement.EXECUTE_FAILED).
+ * @return the update count / execution result as returned by {@link PreparedStatement#executeUpdate()}. Can be used
+ * by the caller to perform more advanced checks.
+ * @throws SQLException
+ * if {@link PreparedStatement#executeUpdate()} throws it.
+ * @throws IllegalStateException
+ * if the check indicated by <code>excatlyOne</code> indicates an error.
+ * @since 2.0
+ */
+ public static int sqlUpdate(PreparedStatement stmt, boolean exactlyOne) throws SQLException
+ {
+ DBUtil.trace(stmt.toString());
+ int result = stmt.executeUpdate();
+
+ // basic check of update result
+ if (exactlyOne && result != 1)
{
- if ("jdbcDelegateProvider".equals(element.getName()))
+ throw new IllegalStateException(stmt.toString() + " returned Update count " + result + " (expected: 1)");
+ }
+
+ if (result == Statement.EXECUTE_FAILED)
+ {
+ throw new IllegalStateException(stmt.toString() + " returned EXECUTE_FAILED.");
+ }
+
+ return result;
+ }
+
+ /**
+ * For debugging purposes ONLY!
+ *
+ * @deprecated Should only be used when debugging.
+ * @since 2.0
+ */
+ @Deprecated
+ public static void sqlDump(Connection conn, String sql)
+ {
+ ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDODBUtil.class);
+ ResultSet rs = null;
+ try
+ {
+ TRACER.format("Dumping output of {0}", sql);
+ rs = conn.createStatement().executeQuery(sql);
+ int numCol = rs.getMetaData().getColumnCount();
+
+ StringBuilder row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
{
- String typeAttr = element.getAttribute("type");
- if (ObjectUtil.equals(typeAttr, type))
+ row.append(String.format("%10s | ", rs.getMetaData().getColumnLabel(c)));
+ }
+
+ TRACER.trace(row.toString());
+
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append("-----------+--");
+ }
+
+ TRACER.trace(row.toString());
+
+ while (rs.next())
+ {
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
{
- try
- {
- return (IJDBCDelegateProvider)element.createExecutableExtension("class");
- }
- catch (CoreException ex)
- {
- throw WrappedException.wrap(ex);
- }
+ row.append(String.format("%10s | ", rs.getString(c)));
}
+
+ TRACER.trace(row.toString());
}
- }
- return null;
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append("-----------+-");
+ }
+
+ TRACER.trace(row.toString());
+ }
+ catch (SQLException ex)
+ {
+ // NOP
+ }
+ finally
+ {
+ if (rs != null)
+ {
+ try
+ {
+ rs.close();
+ }
+ catch (SQLException ex)
+ {
+ // NOP
+ }
+ }
+ }
}
/**
- * Get the long value of a CDOID (by delegating to {@link CDOIDUtil#getLong(org.eclipse.emf.cdo.common.id.CDOID)}) In
- * addition, provide a check for external IDs which are not supported by the DBStore
+ * For debugging purposes ONLY!
*
- * @param id
- * the ID to convert to long
- * @return the long value of the ID
- * @throws IllegalArgumentException
- * if the ID is not convertibla
+ * @deprecated Should only be used when debugging.
* @since 2.0
*/
- public static long getLong(CDOID id)
+ @Deprecated
+ public static void sqlDump(IDBConnectionProvider connectionProvider, String sql)
{
- if (id != null && id.getType() == CDOID.Type.EXTERNAL_OBJECT)
+ Connection connection = connectionProvider.getConnection();
+
+ try
{
- throw new IllegalArgumentException("DBStore does not support external references: " + id);
+ sqlDump(connection, sql);
+ }
+ finally
+ {
+ DBUtil.close(connection);
}
+ }
- return CDOIDUtil.getLong(id);
+ /**
+ * Creates a prepared statement cache with the {@link CDODBUtil#DEFAULT_STATEMENT_CACHE_CAPACITY default capacity}.
+ *
+ * @since 2.0
+ * @see CDODBUtil#createStatementCache(int)
+ */
+ public static IPreparedStatementCache createStatementCache()
+ {
+ return createStatementCache(DEFAULT_STATEMENT_CACHE_CAPACITY);
}
- // public static CDODBStoreManager getStoreManager(IDBAdapter dbAdapter,
- // DataSource dataSource)
- // {
- // CDODBStoreManager storeManager = new CDODBStoreManager(dbAdapter,
- // dataSource);
- // storeManager.initDatabase();
- // return storeManager;
- // }
- //
- // public static CDODBStoreManager getStoreManager()
- // {
- // Properties properties = OM.BUNDLE.getConfigProperties();
- // String adapterName = properties.getProperty("store.adapterName", "derby-embedded");
- // IDBAdapter dbAdapter = DBUtil.getDBAdapter(adapterName);
- // DataSource dataSource = DBUtil.createDataSource(properties, "datasource");
- // return getStoreManager(dbAdapter, dataSource);
- // }
+ /**
+ * Creates a prepared statement cache with the given capacity.
+ *
+ * @since 2.0
+ */
+ public static IPreparedStatementCache createStatementCache(int capacity)
+ {
+ return new SmartPreparedStatementCache(capacity);
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
index 3a51ec57b7..0613a904f4 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
@@ -7,6 +7,8 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.db;
@@ -19,11 +21,8 @@ import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.db.ddl.IDBSchema;
-import org.eclipse.emf.ecore.EModelElement;
-
/**
* @author Eike Stepper
- * @noimplement This interface is not intended to be implemented by clients.
*/
public interface IDBStore extends IStore
{
@@ -44,20 +43,17 @@ public interface IDBStore extends IStore
/**
* @since 2.0
*/
- public long getMetaID(EModelElement modelElement);
-
- /**
- * @since 2.0
- */
- public EModelElement getMetaInstance(long id);
+ public IDBStoreAccessor getReader(ISession session);
/**
* @since 2.0
*/
- public IDBStoreAccessor getReader(ISession session);
+ public IDBStoreAccessor getWriter(ITransaction transaction);
/**
+ * Get the meta data manager associated with this DBStore.
+ *
* @since 2.0
*/
- public IDBStoreAccessor getWriter(ITransaction transaction);
+ public IMetaDataManager getMetaDataManager();
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
index 53eeb07cfd..4837553cf7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
*/
@@ -12,16 +12,19 @@ package org.eclipse.emf.cdo.server.db;
import org.eclipse.emf.cdo.server.IStoreAccessor;
+import java.sql.Connection;
+
/**
* @author Eike Stepper
- * @noimplement This interface is not intended to be implemented by clients.
*/
public interface IDBStoreAccessor extends IStoreAccessor
{
public IDBStore getStore();
+ public Connection getConnection();
+
/**
* @since 2.0
*/
- public IJDBCDelegate getJDBCDelegate();
+ public IPreparedStatementCache getStatementCache();
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreChunkReader.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreChunkReader.java
index a987beccc8..ff4fd4e613 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreChunkReader.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreChunkReader.java
@@ -14,7 +14,6 @@ import org.eclipse.emf.cdo.server.IStoreChunkReader;
/**
* @author Eike Stepper
- * @noimplement This interface is not intended to be implemented by clients.
*/
public interface IDBStoreChunkReader extends IStoreChunkReader
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java
deleted file mode 100644
index e456e1fc40..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Winkler - initial API and implementation
- * Eike Stepper - maintenance
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.db;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.server.internal.db.jdbc.AbstractJDBCDelegate;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.IDBConnectionProvider;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import java.sql.PreparedStatement;
-import java.sql.Statement;
-import java.util.List;
-
-/**
- * Interface for all JDBC related activities regarding revisions.
- *
- * @author Stefan Winkler
- * @since 2.0
- * @noimplement This interface is not intended to be implemented by clients. Please extend the abstract class
- * {@link AbstractJDBCDelegate} instead.
- */
-public interface IJDBCDelegate extends IDBConnectionProvider
-{
- // --------------------------------------------------------------
- // General methods
- // --------------------------------------------------------------
-
- /**
- * Get the one omnipresent statement object of this JDBC delegate
- */
- public Statement getStatement();
-
- /**
- * Get a prepared statement. The caller is responsible of closing it.
- */
- public PreparedStatement getPreparedStatement(String sql);
-
- public void setStoreAccessor(IDBStoreAccessor storeAccessor);
-
- /**
- * Do any outstanding writes (e.g. execute batches). Called any number of times - but at least once immediately before
- * commit().
- *
- * @see IStoreAccessor#write(org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext, OMMonitor)
- */
- public void flush(OMMonitor monitor);
-
- /**
- * Do a commit on the JDBC connection.
- */
- public void commit(OMMonitor monitor);
-
- /**
- * Do a rollback on the JDBC connection.
- */
- public void rollback();
-
- // --------------------------------------------------------------
- // Writing Revisions / Attributes
- // --------------------------------------------------------------
-
- /**
- * Insert an attribute row.
- */
- public void insertAttributes(InternalCDORevision revision, IClassMapping classMapping);
-
- /**
- * Update an attribute row.
- */
- public void updateAttributes(InternalCDORevision revision, IClassMapping classMapping);
-
- /**
- * Update an attribute row.
- */
- public void updateAttributes(CDOID id, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, IClassMapping classMapping);
-
- /**
- * Update an attribute row (including containment and resource attributes).
- */
- public void updateAttributes(CDOID id, int newVersion, long created, CDOID newContainerId,
- int newContainingFeatureId, CDOID newResourceId, List<Pair<IAttributeMapping, Object>> attributeChanges,
- IClassMapping classMapping);
-
- /**
- * Set the revised date of a specific revision's previous version.
- */
- public void updateRevisedForReplace(InternalCDORevision revision, IClassMapping classMapping);
-
- /**
- * Set the revised date of all unrevised rows of cdoid
- */
- public void updateRevisedForDetach(CDOID id, long revised, IClassMapping classMapping);
-
- /**
- * Remove an attribute row.
- */
- public void deleteAttributes(CDOID id, IClassMapping classMapping);
-
- // --------------------------------------------------------------
- // Writing References
- // --------------------------------------------------------------
-
- /**
- * Insert a reference row.
- */
- public void insertReference(CDOID id, int version, int index, CDOID targetId, IReferenceMapping referenceMapping);
-
- /**
- * Insert a reference row shifting all subsequent indices one position up.
- */
- public void insertReferenceRow(CDOID id, int newVersion, int index, CDOID value, IReferenceMapping referenceMapping);
-
- /**
- * Move one reference row shifting all subsequent indices in between accordingly.
- */
- public void moveReferenceRow(CDOID id, int newVersion, int oldPosition, int newPosition,
- IReferenceMapping referenceMapping);
-
- /**
- * Remove a reference row shifting all subsequent indices one position down.
- */
- public void removeReferenceRow(CDOID id, int index, int newVersion, IReferenceMapping referenceMapping);
-
- /**
- * Update the value of a reference row.
- */
- public void updateReference(CDOID id, int newVersion, int index, CDOID value, IReferenceMapping referenceMapping);
-
- /**
- * Delete all reference rows of a cdoid.
- */
- public void deleteReferences(CDOID id, IReferenceMapping referenceMapping);
-
- /**
- * Update the version number of all references of a CDOID to newVersion.
- */
- public void updateReferenceVersion(CDOID id, int newVersion, IReferenceMapping referenceMapping);
-
- // --------------------------------------------------------------
- // Reading
- // --------------------------------------------------------------
-
- /**
- * Select a revision's attributes
- *
- * @return <code>true</code> if the revision attributes have been successfully loaded.<br>
- * <code>false</code> if the revision does not exist in the database.
- */
- public boolean selectRevisionAttributes(InternalCDORevision revision, IClassMapping classMapping, String where);
-
- /**
- * Select a revision's references (or a part thereof)
- */
- public void selectRevisionReferences(InternalCDORevision revision, IReferenceMapping referenceMapping,
- int referenceChunk);
-
- /**
- * Select a revision's reference's chunks
- */
- public void selectRevisionReferenceChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks,
- IReferenceMapping referenceMapping, String where);
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegateProvider.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegateProvider.java
deleted file mode 100644
index 4aec6409eb..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegateProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Winkler - initial API and implementation
- * Eike Stepper - maintenance
- */
-package org.eclipse.emf.cdo.server.db;
-
-import java.util.Map;
-
-/**
- * Wraps the creation of JDBCDelegates.
- *
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IJDBCDelegateProvider
-{
- /**
- * Creates and returns a JDBC delegate.
- * <p>
- * This is part of the org.eclipse.emf.cdo.server.db.jdbcDelegateProviders extension point.
- */
- public IJDBCDelegate getJDBCDelegate();
-
- /**
- * Set configuration properties
- */
- public void setProperties(Map<String, String> properties);
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMetaDataManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMetaDataManager.java
new file mode 100644
index 0000000000..247b0916af
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMetaDataManager.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.db;
+
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EPackage;
+
+import java.sql.Connection;
+import java.util.Collection;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public interface IMetaDataManager
+{
+ /**
+ * Returns the meta ID of the given {@link EModelElement}. <code> getMetaID(getMetaInstance(x))</code> yields
+ * <code>x</code>
+ *
+ * @param modelElement
+ * the element
+ * @return the corresponding ID
+ * @since 2.0
+ */
+ public long getMetaID(EModelElement modelElement);
+
+ /**
+ * Returns the {@link EModelElement} referred to by the given ID. <code> getMetaInstance(getMetaID(m))</code> yields
+ * <code>m</code>
+ *
+ * @since 2.0
+ */
+ public EModelElement getMetaInstance(long id);
+
+ /**
+ * Loads a package unit from the database.
+ *
+ * @param connection
+ * the DB connection to read from.
+ * @param packageUnit
+ * the package unit to load.
+ * @return the loaded package unit.
+ * @since 2.0
+ */
+ public EPackage[] loadPackageUnit(Connection connection, InternalCDOPackageUnit packageUnit);
+
+/**
+ * Reads information about package units present in the database.
+ * @param connection the DB connection to read from.
+ * @return a collection of package unit information records which can be
+ * passed to {@link IMetaDataManager#loadPackageUnit(Connection, InternalCDOPackageUnit))
+ * in order to read the EPackage.
+ *
+ * @since 2.0
+ */
+ public Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection);
+
+ /**
+ * Write package units to the database.
+ *
+ * @param connection
+ * the DB connection to write to.
+ * @param packageUnits
+ * the package units to write.
+ * @param monitor
+ * the monitor to indicate progress.
+ * @since 2.0
+ */
+ public void writePackageUnits(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor);
+
+ /**
+ * Get the DB type associated with the given {@link EClassifier}.
+ *
+ * @param eType
+ * the type to look up.
+ * @return the {@link DBType} of the given {@link EClassifier}.
+ * @since 2.0
+ */
+ public DBType getDBType(EClassifier eType);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java
index 152eb82ca8..b7f86154c5 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.db;
@@ -15,6 +16,8 @@ import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.ecore.EClass;
+import java.sql.Connection;
+
/**
* @author Eike Stepper
*/
@@ -34,4 +37,14 @@ public interface IObjectTypeCache
* @since 2.0
*/
public void removeObjectType(IDBStoreAccessor accessor, CDOID id);
+
+ /**
+ * Return the maximum object id managed by this cache.
+ *
+ * @param connection
+ * the DB connection to use.
+ * @return the maximum object id.
+ * @since 2.0
+ */
+ public long getMaxId(Connection connection);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IPreparedStatementCache.java
new file mode 100644
index 0000000000..256d50fa28
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IPreparedStatementCache.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.db;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+/**
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface IPreparedStatementCache
+{
+ public void setConnection(Connection connection);
+
+ public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability);
+
+ public void releasePreparedStatement(PreparedStatement ps);
+
+ /**
+ * An enum for the degree of probability to which a prepared statement is reused later on. This is used for managing
+ * the cache of prepared statements so that statements which are more likely reused are kept in the cache longer. Rule
+ * of thumb:
+ * <ul>
+ * <li>For global statements which are used regularly (such as lookup object in cdo_objects) use {@value #MAX}.
+ * <li>For constant object-specific statements which are used regularly use {@value #HIGH}.
+ * <li>For object-specific statements which are assembled from constants which are used regularly use {@value #MEDIUM}.
+ * <li>For all other dynamic statements, like queries, use {@value #LOW}
+ * </ul>
+ *
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+ public static enum ReuseProbability
+ {
+ MAX, HIGH, MEDIUM, LOW;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IAttributeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IAttributeMapping.java
deleted file mode 100644
index aee4967bbf..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IAttributeMapping.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.ddl.IDBField;
-
-import java.sql.ResultSet;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public interface IAttributeMapping extends IFeatureMapping
-{
- public IDBField getField();
-
- public void appendValue(StringBuilder builder, InternalCDORevision revision);
-
- public void appendValue(StringBuilder builder, Object value);
-
- public void extractValue(ResultSet resultSet, int column, InternalCDORevision revision);
-
- public Object getRevisionValue(InternalCDORevision revision);
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
index 7877c715ed..2367cf8add 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
@@ -4,77 +4,125 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.db.mapping;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
-import java.util.List;
-import java.util.Set;
+import java.sql.PreparedStatement;
+import java.util.Collection;
/**
+ * Basic interface for class mappings.
+ *
* @author Eike Stepper
+ * @author Stefan Winkler
* @since 2.0
*/
public interface IClassMapping
{
- public IMappingStrategy getMappingStrategy();
-
- public EClass getEClass();
-
- public IDBTable getTable();
-
- public Set<IDBTable> getAffectedTables();
-
- public boolean hasFullRevisionInfo();
-
- public IFeatureMapping getFeatureMapping(EStructuralFeature feature);
-
- public List<IAttributeMapping> getAttributeMappings();
-
- public List<IReferenceMapping> getReferenceMappings();
-
- public IAttributeMapping getAttributeMapping(EStructuralFeature feature);
-
- public IReferenceMapping getReferenceMapping(EStructuralFeature feature);
+ /**
+ * Returns all DB tables which are used by this class and all its contained features.
+ *
+ * @return a collection of all tables of this class and all its contained features.
+ */
+ public Collection<IDBTable> getDBTables();
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor);
+ /**
+ * Get the mapping of the many-valued feature.
+ *
+ * @param feature
+ * the feature for which the mapping should be returned. <code>feature.isMany()</code> has to be
+ * <code>true</code>.
+ * @return the list mapping corresponding to the feature.
+ */
+ public IListMapping getListMapping(EStructuralFeature feature);
- public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
- OMMonitor monitor);
+ /**
+ * Read the current version of a revision.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param revision
+ * the revision object into which the data should be read. The revision has to be have its ID set to the
+ * requested object's ID. The version is ignored, as the version parameter is used to determine the version
+ * to be read.
+ * @param listChunk
+ * the chunk size to read attribute lists.
+ * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision
+ * could not be found. In this case, the content of <code>revision</code> is undefined.
+ */
+ public boolean readRevision(IDBStoreAccessor dbStoreAccessor, InternalCDORevision revision, int listChunk);
- public void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor);
+ /**
+ * Write the revision data to the database.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param revision
+ * the revision to write.
+ * @param monitor
+ * the monitor to indicate progress.
+ */
+ public void writeRevision(IDBStoreAccessor dbStoreAccessor, InternalCDORevision revision, OMMonitor monitor);
/**
- * @return <code>true</code> if the revision has been loaded sucessfully.<br>
- * <code>false</code> if the revision does not exist in the DB.
+ * Removes an object from the database. In the case of auditing support the object is just marked as revised, else it
+ * it permanently deleted.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param id
+ * the ID of the object to remove.
+ * @param revised
+ * the timeStamp when this object became detached.
+ * @param monitor
+ * the monitor to indicate progress.
*/
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk);
+ public void detachObject(IDBStoreAccessor dbStoreAccessor, CDOID id, long revised, OMMonitor monitor);
/**
- * @return <code>true</code> if the revision has been loaded sucessfully.<br>
- * <code>false</code> if the revision does not exist in the DB.
+ * Create a prepared statement which returns all IDs of instances of the corresponding class.
+ *
+ * @param accessor
+ * the accessor to use to create the statement
+ * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>.
*/
- public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
- int referenceChunk);
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor);
/**
- * @return <code>true</code> if the revision has been loaded sucessfully.<br>
- * <code>false</code> if the revision does not exist in the DB.
+ * Create a prepared statement which returns all IDs of instances of the corresponding class.
+ *
+ * @param accessor
+ * the accessor to use to create the statement
+ * @param folderId
+ * the ID of the containing folder. <code>0</code> means none.
+ * @param name
+ * the name of the resource node to look up
+ * @param exactMatch
+ * if <code>true</code>, <code>name</code> must match exactly, otherwise all resource nodes starting with
+ * <code>name</code> are returned.
+ * @param timeStamp
+ * a timestamp in the past if past versions should be looked up. In case of no audit support, this must be
+ * {@link CDORevision#UNSPECIFIED_DATE}.
+ * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>.
+ * @throws ImplementationError
+ * if called on a mapping which does not map an <code>EClass instanceof CDOResourceNode</code>.
*/
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
- int referenceChunk);
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, long timeStamp);
+
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java
new file mode 100644
index 0000000000..e7120b459f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+/**
+ * Interface which complements {@link IClassMapping} with methods to facilitate
+ * audit support.
+ *
+ * @see {@link IMappingStrategy#hasAuditSupport()
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ *
+ * @since 2.0
+ */
+public interface IClassMappingAuditSupport
+{
+
+ /**
+ * Read a specific version of a revision. If this method returns <code>true</code> it is guaranteed that
+ * <code>revision.getVersion() == version</code>
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param revision
+ * the revision object into which the data should be read. The revision has to be have its ID set to the
+ * requested object's ID. The version is ignored, as the version parameter is used to determine the version
+ * to be read.
+ * @param version
+ * the version which should be read.
+ * @param listChunk
+ * the chunk size to read attribute lists.
+ * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision
+ * could not be found. In this case, the content of <code>revision</code> is undefined.
+ */
+ public boolean readRevisionByVersion(IDBStoreAccessor dbStoreAccessor, InternalCDORevision revision, int version,
+ int listChunk);
+
+ /**
+ * Read a specific past version of a revision. If this method returns <code>true</code> it is guaranteed that
+ * <code>revision.getCreated() <= timeStamp && (getRevised() == 0 || getRevised() >= timeStamp))</code>
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param revision
+ * the revision object into which the data should be read. The revision has to be have its ID set to the
+ * requested object's ID. The version is ignored, as the version parameter is used to determine the version
+ * to be read.
+ * @param timeStamp
+ * the timeStamp which should be used to determine the revision's version.
+ * @param listChunk
+ * the chunk size to read attribute lists.
+ * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision
+ * could not be found. In this case, the content of <code>revision</code> is undefined.
+ */
+ public boolean readRevisionByTime(IDBStoreAccessor dbStoreAccessor, InternalCDORevision revision, long timeStamp,
+ int listChunk);
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java
new file mode 100644
index 0000000000..c602528342
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+/**
+ * Interface which complements {@link IClassMapping} with methods to facilitate
+ * revision delta support.
+ *
+ * @see {@link IMappingStrategy#hasDeltaSupport()
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface IClassMappingDeltaSupport
+{
+
+ /**
+ * Write a revision delta.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param delta
+ * the delta to write.
+ * @param created
+ * the creation timestamp of the new version
+ * @param monitor
+ * the monitor to report progress.
+ */
+ public void writeRevisionDelta(IDBStoreAccessor dbStoreAccessor, InternalCDORevisionDelta delta, long created,
+ OMMonitor monitor);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IFeatureMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IFeatureMapping.java
deleted file mode 100644
index 8315a82e89..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IFeatureMapping.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public interface IFeatureMapping
-{
- public IClassMapping getClassMapping();
-
- public EStructuralFeature getFeature();
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java
new file mode 100644
index 0000000000..c26ce2b807
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.ddl.IDBTable;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Interface for mapping features with <code>isMany() == true</code>.
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface IListMapping
+{
+ /**
+ * Return the mapped feature.
+ *
+ * @return the mapped feature.
+ */
+ public EStructuralFeature getFeature();
+
+ /**
+ * Returns all DB tables which are used by this feature.
+ *
+ * @return a collection of all tables of this feature.
+ */
+ public Collection<IDBTable> getDBTables();
+
+ /**
+ * Write a complete list of values to the database.
+ *
+ * @param accessor
+ * the accessor to use.
+ * @param revision
+ * the revision containing the list to be written.
+ */
+ public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision);
+
+ /**
+ * Read the list size and the complete list or the first part of it.
+ *
+ * @param accessor
+ * the accessor to use.
+ * @param revision
+ * the revision into which the list values should be read.
+ * @param listChunk
+ * indicating the lazy loading behavior: {@link CDORevision#UNCHUNKED} means that the whole list should be
+ * read. Else, if <code>listChunk >= 0</code>, the list is filled with
+ * {@link InternalCDORevision#UNINITIALIZED} and only the first <code>listChunk</code> values are read.
+ */
+ public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk);
+
+ /**
+ * Used to load-on-demand chunks of a list.
+ *
+ * @param dbStoreChunkReader
+ * the chunkReader to use
+ * @param chunks
+ * the chunks to read
+ * @param where
+ * the where-clause to use in order to read the chunks.
+ */
+ public void readChunks(IDBStoreChunkReader dbStoreChunkReader, List<Chunk> chunks, String where);
+
+ /**
+ * Hook with which a list mapping is notified that a containing object has been revised. Can be implemented in order
+ * to clean up lists of revised objects.
+ *
+ * @param accessor
+ * the accessor to use.
+ * @param id
+ * the ID of the object which has been revised.
+ * @param revised
+ * the timestamp at which the object was revised.
+ */
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java
new file mode 100644
index 0000000000..0bf019fa6f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+
+/**
+ * Interface to complement {@link IListMapping} in order to provide list delta processing support.
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface IListMappingDeltaSupport
+{
+ /**
+ * Process a set of CDOFeatureDeltas for a many-valued feature.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the ID of the revision affected
+ * @param oldVersion
+ * the original version of the revision
+ * @param newVersion
+ * the new revision of the revision (after the change)
+ * @param created
+ * the creation date for the new revision
+ * @param delta
+ * the {@link CDOListFeatureDelta} which contains the list deltas.
+ */
+ public void processDelta(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, long created,
+ CDOListFeatureDelta delta);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
index dabd735285..b89e07a92b 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,25 +7,38 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.db.mapping;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.internal.db.DBStore;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.util.collection.CloseableIterator;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.ENamedElement;
+import org.eclipse.emf.ecore.EStructuralFeature;
import java.sql.Connection;
import java.util.Map;
/**
+ * The mapping strategy acts as a connection between the DBStore and the database management (and OR-mapping) classes.
+ * The {@link DBStore} uses methods of this interface to create and lookup mappings (or mappers, as they could also be
+ * named as such) and to get properties and informations about the mappings used. The mapping classes (e.g., instances
+ * of IClassMapping and IListMapping) also use this class as a central point of information and as a resource of common
+ * functionalities.
+ *
* @author Eike Stepper
+ * @author Stefan Winkler
* @since 2.0
*/
public interface IMappingStrategy
@@ -59,30 +72,161 @@ public interface IMappingStrategy
*/
public static final String PROP_FORCE_NAMES_WITH_ID = "forceNamesWithID";
- public static final String PROP_TO_MANY_REFERENCE_MAPPING = "toManyReferenceMapping";
+ /**
+ * @return the store, this MappingStrategy instance belongs to.
+ */
+ public IDBStore getStore();
- public static final String PROP_TO_ONE_REFERENCE_MAPPING = "toOneReferenceMapping";
+ /**
+ * Set the store to which this MappingStrategy instance belongs. Should only be called by the {@link DBStore}, and
+ * only once to initialize the connection between {@link DBStore} and mapping strategy.
+ *
+ * @param dbStore
+ * the DBStore instance to which this MappingStrategy instance belongs.
+ */
+ public void setStore(IDBStore dbStore);
- public String getType();
+ /**
+ * Factory for value mappings of single-valued attributes.
+ *
+ * @param feature
+ * the feature for which a mapping should be created. It must hold <code>feature.isMany() == false</code>.
+ * @return the mapping created.
+ */
+ public ITypeMapping createValueMapping(EStructuralFeature feature);
- public IDBStore getStore();
+ /**
+ * Factory for value mappings of multi-valued-attributes.
+ *
+ * @param containingClass
+ * the class containing the feature.
+ * @param feature
+ * the feature for which a mapping should be created. It must hold <code>feature.isMany() == true</code>.
+ * @return
+ */
+ public IListMapping createListMapping(EClass containingClass, EStructuralFeature feature);
- public void setStore(IDBStore store);
+ /**
+ * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes.
+ *
+ * @param element
+ * the element for which the name should be created. It must hold:
+ * <code>element instanceof EClass || element instanceof EPackage</code>.
+ * @return the created table name. It is guaranteed that the table name is compatible with the chosen database.
+ */
+ public String getTableName(ENamedElement element);
- public Map<String, String> getProperties();
+ /**
+ * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes.
+ * Should only be called by mapping classes.
+ *
+ * @param containingClass
+ * the class containeng the feature.
+ * @param feature
+ * the feature for which the table name should be created.
+ * @return the created table name. It is guaranteed that the table name is compatible with the chosen database.
+ */
+ public String getTableName(EClass containingClass, EStructuralFeature feature);
- public void setProperties(Map<String, String> properties);
+ /**
+ * Create a suitable column name which can be used to map the given element. Should only be called by mapping classes.
+ *
+ * @param feature
+ * the feature for which the column name should be created.
+ * @return the created column name. It is guaranteed that the name is compatible with the chosen database.
+ */
+ public String getFieldName(EStructuralFeature feature);
+ /**
+ * Create and initialize the mapping infrastructure for the given packages. Should be called from the DBStore or the
+ * DBStoreAccessor.
+ *
+ * @param connection
+ * the connection to use.
+ * @param packageUnits
+ * the packages whose elements should be mapped.
+ * @param monitor
+ * the monitor to report progress.
+ */
+ public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor);
+
+ /**
+ * Look up an existing class mapping for the given class. Before this method is called, the class mapping must have
+ * been initialized by calling {@link #createMapping(Connection, InternalCDOPackageUnit[], OMMonitor)} on its
+ * containing package.
+ *
+ * @param eClass
+ * the class to look up.
+ * @return the class mapping.
+ */
public IClassMapping getClassMapping(EClass eClass);
- public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor);
+ /**
+ * Query if this mapping supports revision deltas. <br>
+ * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by
+ * {@link #getClassMapping(EClass)} implement {@link IClassMappingDeltaSupport}.
+ *
+ * @return <code>true</code> if revision deltas are supported, <code>false</code> else.
+ */
+ public boolean hasDeltaSupport();
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id);
+ /**
+ * Query if this mapping supports audits. <br>
+ * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by
+ * {@link #getClassMapping(EClass)} implement {@link IClassMappingAuditSupport}.
+ *
+ * @return <code>true</code> if audits are supported, <code>false</code> else.
+ */
+ public boolean hasAuditSupport();
- public void queryResources(IDBStoreAccessor accessor, IStoreAccessor.QueryResourcesContext context);
+ /**
+ * Execute a resource query.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param context
+ * the context from which the query parameters are read and to which the result is written.
+ */
+ public void queryResources(IDBStoreAccessor dbStoreAccessor, QueryResourcesContext context);
/**
- * Returns the maximum CDOID value.
+ * Read the type (i.e. class) of the object referred to by a given ID.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use to look up the type.
+ * @param id
+ * the ID of the object for which the type is to be determined.
+ * @return the type of the object.
+ */
+ public CDOClassifierRef readObjectType(IDBStoreAccessor dbStoreAccessor, CDOID id);
+
+ /**
+ * Get an iterator over all instances of objects in the store.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @return the iterator.
+ */
+ public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor dbStoreAccessor);
+
+ /**
+ * Return the maximum object id used in the store. This is used by the DBStore if a previous crash is discovered
+ * during the startup process. Should only be called by the DBStore and only during startup.
+ *
+ * @param dbAdapter
+ * the dbAdapter to use to access the database
+ * @param connection
+ * the connection to use to access the database
+ * @return the maximum object id used in the store.
*/
public long repairAfterCrash(IDBAdapter dbAdapter, Connection connection);
+
+ /**
+ * Set configuration properties for this mapping strategy. Should only be called by the factory creating the mapping
+ * strategy instance.
+ *
+ * @param properties
+ * the configuration properties to set.
+ */
+ public void setProperties(Map<String, String> properties);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IReferenceMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IReferenceMapping.java
deleted file mode 100644
index deb57c43bc..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IReferenceMapping.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.ddl.IDBTable;
-
-import java.util.List;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public interface IReferenceMapping extends IFeatureMapping
-{
- public IDBTable getTable();
-
- public boolean isWithFeature();
-
- /**
- * Write a list of references completely
- */
- public void writeReference(IDBStoreAccessor accessor, InternalCDORevision revision);
-
- /**
- * Write one element of the list of references
- */
- public void writeReferenceEntry(IDBStoreAccessor accessor, CDOID id, int version, int idx, CDOID targetId);
-
- /**
- * Insert a single reference (entry) and move all subsequent entries of the list upwards
- */
- public void insertReferenceEntry(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, CDOID value);
-
- /**
- * Moves a single reference (entry) from <code>oldPosition</code> to <code>newPosition</code> and update the list
- * indexes of the entries in between.
- */
- public void moveReferenceEntry(IDBStoreAccessor accessor, CDOID id, int newVersion, int oldPosition, int newPosition);
-
- /**
- * Remove a single reference (entry) and move all subsequent entries of the list downwards to fill the gap.
- */
- public void removeReferenceEntry(IDBStoreAccessor accessor, CDOID id, int index, int newVersion);
-
- /**
- * Updates the value and version of a single reference (entry).
- */
- public void updateReference(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, CDOID value);
-
- /**
- * Updates the version of all entries of a reference (list) to <code>newVersion</code>.
- */
- public void updateReferenceVersion(IDBStoreAccessor accessor, CDOID id, int newVersion);
-
- /**
- * Clears the list of references for the revision with ID <code>id</code>.
- */
- public void deleteReference(IDBStoreAccessor accessor, CDOID id);
-
- public void readReference(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk);
-
- public void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String string);
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java
new file mode 100644
index 0000000000..c16756cc06
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Mapping of single values to and from the database.
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface ITypeMapping
+{
+ /**
+ * @return The feature which is associated with this mapping.
+ */
+ public EStructuralFeature getFeature();
+
+ /**
+ * @return The db field which is associated with this mapping.
+ */
+ public IDBField getField();
+
+ /**
+ * Creates the DBField and adds it to the given table. The name of the DBField is derived from the feature.
+ *
+ * @param table
+ * the table to add this field to.
+ */
+ public void createDBField(IDBTable table);
+
+ /**
+ * Creates the DBField and adds it to the given table. The name of the DBField is explicitly determined by the
+ * corresponding parameter.
+ *
+ * @param table
+ * the table to add this field to.
+ * @param fieldName
+ * the name for the DBField.
+ */
+ public void createDBField(IDBTable table, String fieldName);
+
+ /**
+ * Set the given value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> method.
+ *
+ * @param stmt
+ * the prepared statement to set the value
+ * @param index
+ * the index to use for the <code>setXxx</code> method.
+ * @param value
+ * the value to set.
+ * @throws SQLException
+ * if the <code>setXxx</code> throws it.
+ */
+ public void setValue(PreparedStatement stmt, int index, Object value) throws SQLException;
+
+ /**
+ * Set a value of the given revision to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code>
+ * method. The feature from which the value is taken is determined by {@link #getFeature()}.
+ *
+ * @param stmt
+ * the prepared statement to set the value
+ * @param index
+ * the index to use for the <code>setXxx</code> method.
+ * @param revision
+ * the revision to get the value to set from.
+ * @throws SQLException
+ * if the <code>setXxx</code> throws it.
+ */
+ public void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision value) throws SQLException;
+
+ /**
+ * Read a value from a {@link ResultSet} and convert it from the DB to the CDO representation.
+ *
+ * @param resultSet
+ * the result set to read from
+ * @param i
+ * the column index in the result set to read from
+ * @return the read value
+ * @throws SQLException
+ * if reading the value throws an SQLException
+ */
+ public Object readValue(ResultSet resultSet, int i) throws SQLException;
+
+ /**
+ * Read a value from a {@link ResultSet}, convert it from the DB to the CDO representation and set it to the feature
+ * of the revision. The feature is determined by getFeature()
+ *
+ * @param resultSet
+ * the result set to read from
+ * @param i
+ * the column index in the result set to read from
+ * @param revision
+ * the revision to which the value should be set.
+ * @throws SQLException
+ * if reading the value throws an SQLException
+ */
+ public void readValueToRevision(ResultSet resultSet, int i, InternalCDORevision revision) throws SQLException;
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java
new file mode 100644
index 0000000000..003cb58797
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Winkler - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.internal.db;
+
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
+
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import java.sql.Connection;
+
+/**
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public abstract class AbstractPreparedStatementCache extends Lifecycle implements IPreparedStatementCache
+{
+ private Connection connection;
+
+ public AbstractPreparedStatementCache()
+ {
+ }
+
+ public final Connection getConnection()
+ {
+ return connection;
+ }
+
+ public final void setConnection(Connection connection)
+ {
+ checkInactive();
+ this.connection = connection;
+ }
+
+ @Override
+ protected void doBeforeActivate()
+ {
+ checkState(connection, "Must have valid connection to start.");
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
index 5d72877b26..a772fe809c 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,8 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ *
*/
package org.eclipse.emf.cdo.server.internal.db;
@@ -120,17 +122,17 @@ public class CDODBSchema extends DBSchema
public static final String ATTRIBUTES_FEATURE = "cdo_feature";
/**
- * Field names of reference tables
+ * Field names of list tables
*/
- public static final String REFERENCES_FEATURE = "cdo_feature";
+ public static final String LIST_FEATURE = "cdo_feature";
- public static final String REFERENCES_SOURCE = "cdo_source";
+ public static final String LIST_REVISION_ID = "cdo_source";
- public static final String REFERENCES_VERSION = "cdo_version";
+ public static final String LIST_REVISION_VERSION = "cdo_version";
- public static final String REFERENCES_IDX = "cdo_idx";
+ public static final String LIST_IDX = "cdo_idx";
- public static final String REFERENCES_TARGET = "cdo_target";
+ public static final String LIST_VALUE = "cdo_value";
private CDODBSchema()
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
index 599f0316d6..5078fb3277 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
@@ -4,29 +4,25 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
* Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.internal.db;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDMeta;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.server.ISession;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
import org.eclipse.emf.cdo.spi.server.LongIDStore;
import org.eclipse.emf.cdo.spi.server.StoreAccessorPool;
import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.IDBConnectionProvider;
@@ -37,19 +33,11 @@ import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.ProgressDistributor;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EModelElement;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.ecore.InternalEObject;
-
import javax.sql.DataSource;
import java.sql.Connection;
+import java.sql.SQLException;
import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
/**
@@ -71,8 +59,6 @@ public class DBStore extends LongIDStore implements IDBStore
private IDBConnectionProvider dbConnectionProvider;
- private IJDBCDelegateProvider jdbcDelegateProvider;
-
@ExcludeFromDump
private transient ProgressDistributor accessorWriteDistributor = new ProgressDistributor.Geometric()
{
@@ -95,50 +81,13 @@ public class DBStore extends LongIDStore implements IDBStore
@ExcludeFromDump
private transient StoreAccessorPool writerPool = new StoreAccessorPool(this, null);
- private static Map<EClassifier, DBType> typeMap = new HashMap<EClassifier, DBType>();
-
- static
- {
- typeMap.put(EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP);
- typeMap.put(EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR);
-
- typeMap.put(EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN);
- typeMap.put(EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT);
- typeMap.put(EcorePackage.eINSTANCE.getEChar(), DBType.CHAR);
- typeMap.put(EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE);
- typeMap.put(EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT);
- typeMap.put(EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER);
- typeMap.put(EcorePackage.eINSTANCE.getELong(), DBType.BIGINT);
- typeMap.put(EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT);
-
- typeMap.put(EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN);
- typeMap.put(EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT);
- typeMap.put(EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR);
- typeMap.put(EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE);
- typeMap.put(EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT);
- typeMap.put(EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER);
- typeMap.put(EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT);
- typeMap.put(EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT);
- }
+ private transient IMetaDataManager metaDataManager;
public DBStore()
{
- super(TYPE, set(ChangeFormat.REVISION, ChangeFormat.DELTA), set(RevisionTemporality.AUDITING,
- RevisionTemporality.NONE), set(RevisionParallelism.NONE));
- setRevisionTemporality(RevisionTemporality.AUDITING);
- }
-
- @Override
- public Set<ChangeFormat> getSupportedChangeFormats()
- {
- if (getRevisionTemporality() == RevisionTemporality.AUDITING)
- {
- return set(ChangeFormat.REVISION);
- }
- else
- {
- return set(ChangeFormat.REVISION, ChangeFormat.DELTA);
- }
+ super(TYPE, set(ChangeFormat.REVISION, ChangeFormat.DELTA), //
+ set(RevisionTemporality.AUDITING, RevisionTemporality.NONE), //
+ set(RevisionParallelism.NONE));
}
public IMappingStrategy getMappingStrategy()
@@ -150,6 +99,8 @@ public class DBStore extends LongIDStore implements IDBStore
{
this.mappingStrategy = mappingStrategy;
mappingStrategy.setStore(this);
+
+ setRevisionTemporality(mappingStrategy.hasAuditSupport() ? RevisionTemporality.AUDITING : RevisionTemporality.NONE);
}
public IDBAdapter getDBAdapter()
@@ -169,7 +120,6 @@ public class DBStore extends LongIDStore implements IDBStore
public void setDbConnectionProvider(IDBConnectionProvider dbConnectionProvider)
{
- // TODO Need to update provider in JDBCWrapper, too?
this.dbConnectionProvider = dbConnectionProvider;
}
@@ -178,16 +128,6 @@ public class DBStore extends LongIDStore implements IDBStore
dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
}
- public IJDBCDelegateProvider getJDBCDelegateProvider()
- {
- return jdbcDelegateProvider;
- }
-
- public void setJDBCDelegateProvider(IJDBCDelegateProvider provider)
- {
- jdbcDelegateProvider = provider;
- }
-
public ProgressDistributor getAccessorWriteDistributor()
{
return accessorWriteDistributor;
@@ -234,33 +174,19 @@ public class DBStore extends LongIDStore implements IDBStore
return new DBStoreAccessor(this, transaction);
}
- public long getMetaID(EModelElement modelElement)
+ protected Connection getConnection()
{
- InternalCDOPackageRegistry packageRegistry = (InternalCDOPackageRegistry)getRepository().getPackageRegistry();
+ Connection connection = dbConnectionProvider.getConnection();
try
{
- CDOID cdoid = packageRegistry.getMetaInstanceMapper().lookupMetaInstanceID((InternalEObject)modelElement);
- return ((CDOIDMeta)cdoid).getLongValue();
+ connection.setAutoCommit(false);
}
- catch (RuntimeException ex)
+ catch (SQLException ex)
{
- packageRegistry.getMetaInstanceMapper().lookupMetaInstanceID((InternalEObject)modelElement);
- throw ex;
+ throw new DBException(ex);
}
- }
-
- public EModelElement getMetaInstance(long id)
- {
- CDOIDMeta cdoid = CDOIDUtil.createMeta(id);
- InternalCDOPackageRegistry packageRegistry = (InternalCDOPackageRegistry)getRepository().getPackageRegistry();
- InternalEObject metaInstance = packageRegistry.getMetaInstanceMapper().lookupMetaInstance(cdoid);
- return (EModelElement)metaInstance;
- }
- public Connection getConnection()
- {
- Connection connection = dbConnectionProvider.getConnection();
if (connection == null)
{
throw new DBException("No connection from connection provider: " + dbConnectionProvider);
@@ -286,13 +212,22 @@ public class DBStore extends LongIDStore implements IDBStore
checkNull(mappingStrategy, "mappingStrategy is null");
checkNull(dbAdapter, "dbAdapter is null");
checkNull(dbConnectionProvider, "dbConnectionProvider is null");
+
+ checkState(getRevisionTemporality() == RevisionTemporality.AUDITING == mappingStrategy.hasAuditSupport(),
+ "AuditSupport of MappingStrategy and Store does not match. Please check configuration.");
}
@Override
protected void doActivate() throws Exception
{
super.doActivate();
+
+ dbSchema = createSchema();
+ metaDataManager = new MetaDataManager(this);
+ LifecycleUtil.activate(metaDataManager);
+
Connection connection = getConnection();
+ LifecycleUtil.activate(mappingStrategy);
try
{
@@ -306,8 +241,7 @@ public class DBStore extends LongIDStore implements IDBStore
reStart(connection);
}
- LifecycleUtil.activate(mappingStrategy);
- dbSchema = createSchema();
+ connection.commit();
}
finally
{
@@ -370,6 +304,7 @@ public class DBStore extends LongIDStore implements IDBStore
{
throw new DBException("No row updated in table " + CDODBSchema.REPOSITORY);
}
+
}
@Override
@@ -377,6 +312,9 @@ public class DBStore extends LongIDStore implements IDBStore
{
Connection connection = null;
+ LifecycleUtil.deactivate(metaDataManager);
+ metaDataManager = null;
+
try
{
connection = getConnection();
@@ -405,6 +343,8 @@ public class DBStore extends LongIDStore implements IDBStore
{
throw new DBException("No row updated in table " + CDODBSchema.REPOSITORY);
}
+
+ connection.commit();
}
finally
{
@@ -432,24 +372,21 @@ public class DBStore extends LongIDStore implements IDBStore
return System.currentTimeMillis();
}
- public static DBType getDBType(EClassifier type)
+ public IMetaDataManager getMetaDataManager()
{
- if (type instanceof EClass)
- {
- return DBType.BIGINT;
- }
+ return metaDataManager;
+ }
- if (type instanceof EEnum)
+ @Override
+ public Set<ChangeFormat> getSupportedChangeFormats()
+ {
+ if (mappingStrategy.hasDeltaSupport())
{
- return DBType.INTEGER;
+ return set(ChangeFormat.DELTA);
}
-
- DBType dbType = typeMap.get(type);
- if (dbType != null)
+ else
{
- return dbType;
+ return set(ChangeFormat.REVISION);
}
-
- return DBType.VARCHAR;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index c8ac86f85e..31f09eb153 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -8,31 +8,28 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.internal.db;
import org.eclipse.emf.cdo.common.CDOQueryInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDMeta;
-import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.server.IQueryContext;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.ISession;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.server.IStore.RevisionTemporality;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
@@ -40,8 +37,6 @@ import org.eclipse.emf.cdo.spi.server.LongIDStoreAccessor;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBRowHandler;
-import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
@@ -55,16 +50,12 @@ import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
-import java.sql.PreparedStatement;
+import java.sql.Connection;
import java.sql.SQLException;
-import java.util.ArrayList;
+import java.sql.Statement;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* @author Eike Stepper
@@ -73,9 +64,11 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, DBStoreAccessor.class);
- private static final boolean ZIP_PACKAGE_BYTES = true;
+ private Connection connection = null;
- private IJDBCDelegate jdbcDelegate;
+ private IPreparedStatementCache statementCache = null;
+
+ private Timer connectionKeepAliveTimer = null;
@ExcludeFromDump
@SuppressWarnings("unchecked")
@@ -91,31 +84,19 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
{
public void runLoop(int index, CommitContext commitContext, OMMonitor monitor) throws Exception
{
- jdbcDelegate.flush(monitor.fork());
+ // TODO - reenable when reimplementing stmt caching
+ // flush(monitor.fork());
}
});
public DBStoreAccessor(DBStore store, ISession session) throws DBException
{
super(store, session);
- initJDBCDelegate();
}
public DBStoreAccessor(DBStore store, ITransaction transaction) throws DBException
{
super(store, transaction);
- initJDBCDelegate();
- }
-
- private void initJDBCDelegate()
- {
- jdbcDelegate = getStore().getJDBCDelegateProvider().getJDBCDelegate();
- jdbcDelegate.setStoreAccessor(this);
- }
-
- public IJDBCDelegate getJDBCDelegate()
- {
- return jdbcDelegate;
}
@Override
@@ -124,81 +105,14 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
return (DBStore)super.getStore();
}
- public DBStoreChunkReader createChunkReader(InternalCDORevision revision, EStructuralFeature feature)
+ public IPreparedStatementCache getStatementCache()
{
- return new DBStoreChunkReader(this, revision, feature);
- }
-
- public final Collection<InternalCDOPackageUnit> readPackageUnits()
- {
- final Map<String, InternalCDOPackageUnit> packageUnits = new HashMap<String, InternalCDOPackageUnit>();
- IDBRowHandler unitRowHandler = new IDBRowHandler()
- {
- public boolean handle(int row, final Object... values)
- {
- InternalCDOPackageUnit packageUnit = createPackageUnit();
- packageUnit.setOriginalType(CDOPackageUnit.Type.values()[(Integer)values[1]]);
- packageUnit.setTimeStamp((Long)values[2]);
- packageUnits.put((String)values[0], packageUnit);
- return true;
- }
- };
-
- DBUtil.select(jdbcDelegate.getConnection(), unitRowHandler, CDODBSchema.PACKAGE_UNITS_ID,
- CDODBSchema.PACKAGE_UNITS_ORIGINAL_TYPE, CDODBSchema.PACKAGE_UNITS_TIME_STAMP);
-
- final Map<String, List<InternalCDOPackageInfo>> packageInfos = new HashMap<String, List<InternalCDOPackageInfo>>();
- IDBRowHandler infoRowHandler = new IDBRowHandler()
- {
- public boolean handle(int row, final Object... values)
- {
- long metaLB = (Long)values[3];
- long metaUB = (Long)values[4];
- CDOIDMetaRange metaIDRange = metaLB == 0 ? null : CDOIDUtil.createMetaRange(CDOIDUtil.createMeta(metaLB),
- (int)(metaUB - metaLB) + 1);
-
- InternalCDOPackageInfo packageInfo = createPackageInfo();
- packageInfo.setPackageURI((String)values[1]);
- packageInfo.setParentURI((String)values[2]);
- packageInfo.setMetaIDRange(metaIDRange);
-
- String unit = (String)values[0];
- List<InternalCDOPackageInfo> list = packageInfos.get(unit);
- if (list == null)
- {
- list = new ArrayList<InternalCDOPackageInfo>();
- packageInfos.put(unit, list);
- }
-
- list.add(packageInfo);
- return true;
- }
- };
-
- DBUtil.select(jdbcDelegate.getConnection(), infoRowHandler, CDODBSchema.PACKAGE_INFOS_UNIT,
- CDODBSchema.PACKAGE_INFOS_URI, CDODBSchema.PACKAGE_INFOS_PARENT, CDODBSchema.PACKAGE_INFOS_META_LB,
- CDODBSchema.PACKAGE_INFOS_META_UB);
-
- for (Entry<String, InternalCDOPackageUnit> entry : packageUnits.entrySet())
- {
- String id = entry.getKey();
- InternalCDOPackageUnit packageUnit = entry.getValue();
-
- List<InternalCDOPackageInfo> list = packageInfos.get(id);
- InternalCDOPackageInfo[] array = list.toArray(new InternalCDOPackageInfo[list.size()]);
- packageUnit.setPackageInfos(array);
- }
-
- return packageUnits.values();
+ return statementCache;
}
- public final EPackage[] loadPackageUnit(InternalCDOPackageUnit packageUnit)
+ public DBStoreChunkReader createChunkReader(InternalCDORevision revision, EStructuralFeature feature)
{
- String where = CDODBSchema.PACKAGE_UNITS_ID.getName() + "='" + packageUnit.getID() + "'";
- Object[] values = DBUtil.select(jdbcDelegate.getConnection(), where, CDODBSchema.PACKAGE_UNITS_PACKAGE_DATA);
- byte[] bytes = (byte[])values[0];
- EPackage ePackage = createEPackage(packageUnit, bytes);
- return EMFUtil.getAllPackages(ePackage);
+ return new DBStoreChunkReader(this, revision, feature);
}
public CloseableIterator<CDOID> readObjectIDs()
@@ -221,7 +135,25 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
return getStore().getMappingStrategy().readObjectType(this, id);
}
- public InternalCDORevision readRevision(CDOID id, int referenceChunk, AdditionalRevisionCache cache)
+ protected EClass getObjectType(CDOID id)
+ {
+ EClass result = getStore().getRepository().getRevisionManager().getObjectType(id);
+ if (result == null)
+ {
+ CDOClassifierRef type = readObjectType(id);
+ if (type == null)
+ {
+ return null;
+ }
+
+ IRepository repository = getStore().getRepository();
+ CDOPackageRegistry packageRegistry = repository.getPackageRegistry();
+ result = (EClass)type.resolve(packageRegistry);
+ }
+ return result;
+ }
+
+ public InternalCDORevision readRevision(CDOID id, int listChunk, AdditionalRevisionCache cache)
{
if (TRACER.isEnabled())
{
@@ -238,7 +170,7 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
- if (mapping.readRevision(this, revision, referenceChunk))
+ if (mapping.readRevision(this, revision, listChunk))
{
return revision;
}
@@ -247,9 +179,15 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
return null;
}
- public InternalCDORevision readRevisionByTime(CDOID id, int referenceChunk, AdditionalRevisionCache cache,
- long timeStamp)
+ public InternalCDORevision readRevisionByTime(CDOID id, int listChunk, AdditionalRevisionCache cache, long timeStamp)
{
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+
+ if (!mappingStrategy.hasAuditSupport())
+ {
+ throw new UnsupportedOperationException("Mapping strategy does not support audits.");
+ }
+
if (TRACER.isEnabled())
{
TRACER.format("Selecting revision: {0}, timestamp={1,date} {1,time}", id, timeStamp);
@@ -258,9 +196,8 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
EClass eClass = getObjectType(id);
InternalCDORevision revision = (InternalCDORevision)CDORevisionUtil.create(eClass, id);
- IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
- IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
- if (mapping.readRevisionByTime(this, revision, timeStamp, referenceChunk))
+ IClassMappingAuditSupport mapping = (IClassMappingAuditSupport)mappingStrategy.getClassMapping(eClass);
+ if (mapping.readRevisionByTime(this, revision, timeStamp, listChunk))
{
return revision;
}
@@ -269,29 +206,54 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
return null;
}
- public InternalCDORevision readRevisionByVersion(CDOID id, int referenceChunk, AdditionalRevisionCache cache,
- int version)
+ public InternalCDORevision readRevisionByVersion(CDOID id, int listChunk, AdditionalRevisionCache cache, int version)
{
- if (TRACER.isEnabled())
- {
- TRACER.format("Selecting revision: {0}, version={1}", id, version);
- }
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
EClass eClass = getObjectType(id);
InternalCDORevision revision = (InternalCDORevision)CDORevisionUtil.create(eClass, id);
-
- IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
- if (mapping.readRevisionByVersion(this, revision, version, referenceChunk))
+
+ boolean success = false;
+
+ if (mappingStrategy.hasAuditSupport())
{
- return revision;
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Selecting revision: {0}, version={1}", id, version);
+ }
+
+ // if audit support is present, just use the audit method
+ success = ((IClassMappingAuditSupport)mapping).readRevisionByVersion(this, revision, version, listChunk);
}
+ else
+ {
+ // if audit support is not present, we still have to provide a method
+ // to readRevisionByVersion because TransactionCommitContext.computeDirtyObject
+ // needs to lookup the base revision for a change. Hence we emulate this
+ // behavior by getting the current revision and asserting that the version
+ // has not changed. This is valid because if the version has changed,
+ // we are in trouble because of a conflict anyways.
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Selecting current base revision: {0}", id);
+ }
- // Reading failed - revision does not exist.
- return null;
+ success = mapping.readRevision(this, revision, listChunk);
+
+ if (success && revision.getVersion() != version)
+ {
+ throw new IllegalStateException("Can only retrieve current version " + revision.getVersion() + " for " + id
+ + " - version requested was " + version + ".");
+ }
+ }
+
+ return success ? revision : null;
}
/**
+ * TODO: implement as query when query implementation is done?
+ *
* @since 2.0
*/
public void queryResources(QueryResourcesContext context)
@@ -309,20 +271,6 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
throw new UnsupportedOperationException();
}
- protected EClass getObjectType(CDOID id)
- {
- // TODO Replace calls to getObjectType by optimized calls to RevisionManager.getObjectType (cache!)
- CDOClassifierRef type = readObjectType(id);
- if (type == null)
- {
- return null;
- }
-
- IRepository repository = getStore().getRepository();
- CDOPackageRegistry packageRegistry = repository.getPackageRegistry();
- return (EClass)type.resolve(packageRegistry);
- }
-
public CloseableIterator<Object> createQueryIterator(CDOQueryInfo queryInfo)
{
throw new UnsupportedOperationException();
@@ -330,6 +278,7 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
public void refreshRevisions()
{
+ // TODO is this empty on purpose or should it be implemented (how?)
}
@Override
@@ -339,177 +288,14 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
distributor.run(ops, context, monitor);
}
- public final void writePackageUnits(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- try
- {
- monitor.begin(2);
- fillSystemTables(packageUnits, monitor.fork());
- createModelTables(packageUnits, monitor.fork());
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void fillSystemTables(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- try
- {
- monitor.begin(packageUnits.length);
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- fillSystemTables(packageUnit, monitor.fork());
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void fillSystemTables(InternalCDOPackageUnit packageUnit, OMMonitor monitor)
- {
- try
- {
- InternalCDOPackageInfo[] packageInfos = packageUnit.getPackageInfos();
- monitor.begin(1 + packageInfos.length);
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Writing package unit: {0}", packageUnit);
- }
-
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " VALUES (?, ?, ?, ?)";
- DBUtil.trace(sql);
- PreparedStatement pstmt = null;
- Async async = monitor.forkAsync();
-
- try
- {
- pstmt = jdbcDelegate.getPreparedStatement(sql);
- pstmt.setString(1, packageUnit.getID());
- pstmt.setInt(2, packageUnit.getOriginalType().ordinal());
- pstmt.setLong(3, packageUnit.getTimeStamp());
- pstmt.setBytes(4, getEPackageBytes(packageUnit));
-
- if (pstmt.execute())
- {
- throw new DBException("No result set expected");
- }
-
- if (pstmt.getUpdateCount() == 0)
- {
- throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_UNITS);
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(pstmt);
- async.stop();
- }
-
- for (InternalCDOPackageInfo packageInfo : packageInfos)
- {
- fillSystemTables(packageInfo, monitor); // Don't fork monitor
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private byte[] getEPackageBytes(InternalCDOPackageUnit packageUnit)
- {
- EPackage ePackage = packageUnit.getTopLevelPackageInfo().getEPackage();
- CDOPackageRegistry packageRegistry = getStore().getRepository().getPackageRegistry();
- return EMFUtil.getEPackageBytes(ePackage, ZIP_PACKAGE_BYTES, packageRegistry);
- }
-
- private EPackage createEPackage(InternalCDOPackageUnit packageUnit, byte[] bytes)
- {
- CDOPackageRegistry packageRegistry = getStore().getRepository().getPackageRegistry();
- return EMFUtil.createEPackage(packageUnit.getID(), bytes, ZIP_PACKAGE_BYTES, packageRegistry);
- }
-
- private void fillSystemTables(InternalCDOPackageInfo packageInfo, OMMonitor monitor)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Writing package info: {0}", packageInfo);
- }
-
- String packageURI = packageInfo.getPackageURI();
- String parentURI = packageInfo.getParentURI();
- String unitID = packageInfo.getPackageUnit().getID();
- CDOIDMetaRange metaIDRange = packageInfo.getMetaIDRange();
- long metaLB = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getLowerBound()).getLongValue();
- long metaUB = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getUpperBound()).getLongValue();
-
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " VALUES (?, ?, ?, ?, ?)";
- DBUtil.trace(sql);
- PreparedStatement pstmt = null;
- Async async = monitor.forkAsync();
-
- try
- {
- pstmt = jdbcDelegate.getPreparedStatement(sql);
- pstmt.setString(1, packageURI);
- pstmt.setString(2, parentURI);
- pstmt.setString(3, unitID);
- pstmt.setLong(4, metaLB);
- pstmt.setLong(5, metaUB);
-
- if (pstmt.execute())
- {
- throw new DBException("No result set expected");
- }
-
- if (pstmt.getUpdateCount() == 0)
- {
- throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_INFOS);
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(pstmt);
- async.stop();
- }
- }
-
- private void createModelTables(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- monitor.begin();
- Async async = monitor.forkAsync();
-
- try
- {
- Set<IDBTable> affectedTables = mapPackageUnits(packageUnits);
- getStore().getDBAdapter().createTables(affectedTables, jdbcDelegate.getConnection());
- }
- finally
- {
- async.stop();
- monitor.done();
- }
- }
-
@Override
protected void writeRevisionDeltas(InternalCDORevisionDelta[] revisionDeltas, long created, OMMonitor monitor)
{
- if (!(getStore().getRevisionTemporality() == RevisionTemporality.NONE))
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+
+ if (!mappingStrategy.hasDeltaSupport())
{
- throw new UnsupportedOperationException("Revision Deltas are only supported in non-auditing mode!");
+ throw new UnsupportedOperationException("Mapping strategy does not support revision deltas.");
}
monitor.begin(revisionDeltas.length);
@@ -529,7 +315,8 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
protected void writeRevisionDelta(InternalCDORevisionDelta delta, long created, OMMonitor monitor)
{
EClass eClass = getObjectType(delta.getID());
- IClassMapping mapping = getStore().getMappingStrategy().getClassMapping(eClass);
+ IClassMappingDeltaSupport mapping = (IClassMappingDeltaSupport)getStore().getMappingStrategy().getClassMapping(
+ eClass);
mapping.writeRevisionDelta(this, delta, created, monitor);
}
@@ -594,118 +381,143 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
mapping.detachObject(this, id, revised, monitor);
}
- /**
- * TODO Move this somehow to DBAdapter
- */
- protected Boolean getBoolean(Object value)
+ public Connection getConnection()
{
- if (value == null)
+ return connection;
+ }
+
+ public final void commit(OMMonitor monitor)
+ {
+ monitor.begin();
+ Async async = monitor.forkAsync();
+
+ if (TRACER.isEnabled())
{
- return null;
+ TRACER.format("--- DB COMMIT ---");
}
- if (value instanceof Boolean)
+ try
{
- return (Boolean)value;
+ getConnection().commit();
}
-
- if (value instanceof Number)
+ catch (SQLException ex)
{
- return ((Number)value).intValue() != 0;
+ throw new DBException(ex);
}
-
- throw new IllegalArgumentException("Not a boolean value: " + value);
- }
-
- protected Set<IDBTable> mapPackageUnits(InternalCDOPackageUnit[] packageUnits)
- {
- Set<IDBTable> affectedTables = new HashSet<IDBTable>();
- if (packageUnits != null && packageUnits.length != 0)
+ finally
{
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- mapPackageInfos(packageUnit.getPackageInfos(), affectedTables);
- }
+ async.stop();
+ monitor.done();
}
-
- return affectedTables;
}
- protected void mapPackageInfos(InternalCDOPackageInfo[] packageInfos, Set<IDBTable> affectedTables)
+ @Override
+ protected final void rollback(IStoreAccessor.CommitContext commitContext)
{
- for (InternalCDOPackageInfo packageInfo : packageInfos)
+ if (TRACER.isEnabled())
{
- EPackage ePackage = packageInfo.getEPackage();
- if (!CDOModelUtil.isCorePackage(ePackage))
- {
- EClass[] persistentClasses = EMFUtil.getPersistentClasses(ePackage);
- Set<IDBTable> tables = mapClasses(persistentClasses);
- affectedTables.addAll(tables);
- }
+ TRACER.format("--- DB ROLLBACK ---");
}
- }
- protected Set<IDBTable> mapClasses(EClass... eClasses)
- {
- Set<IDBTable> affectedTables = new HashSet<IDBTable>();
- if (eClasses != null && eClasses.length != 0)
+ try
{
- IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
- for (EClass eClass : eClasses)
- {
- IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
- if (mapping != null)
- {
- affectedTables.addAll(mapping.getAffectedTables());
- }
- }
+ getConnection().rollback();
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
}
-
- return affectedTables;
}
- protected InternalCDOPackageUnit createPackageUnit()
+ @Override
+ protected void doActivate() throws Exception
{
- return (InternalCDOPackageUnit)CDOModelUtil.createPackageUnit();
+ connection = getStore().getConnection();
+
+ connectionKeepAliveTimer = new Timer("Connection-Keep-Alive-" + toString());
+ connectionKeepAliveTimer.schedule(new ConnectionKeepAliveTask(), ConnectionKeepAliveTask.EXECUTION_PERIOD,
+ ConnectionKeepAliveTask.EXECUTION_PERIOD);
+
+ // TODO - make this configurable?
+ statementCache = CDODBUtil.createStatementCache();
+ statementCache.setConnection(connection);
+
+ LifecycleUtil.activate(statementCache);
}
- protected InternalCDOPackageInfo createPackageInfo()
+ @Override
+ protected void doDeactivate() throws Exception
{
- return (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo();
+ LifecycleUtil.deactivate(statementCache);
+
+ connectionKeepAliveTimer.cancel();
+ connectionKeepAliveTimer = null;
+
+ DBUtil.close(connection);
+ connection = null;
}
- public final void commit(OMMonitor monitor)
+ @Override
+ protected void doPassivate() throws Exception
{
- jdbcDelegate.commit(monitor);
+ // Do nothing
}
@Override
- protected final void rollback(CommitContext context)
+ protected void doUnpassivate() throws Exception
{
- jdbcDelegate.rollback();
+ // do nothing
}
- @Override
- protected void doActivate() throws Exception
+ public EPackage[] loadPackageUnit(InternalCDOPackageUnit packageUnit)
{
- LifecycleUtil.activate(jdbcDelegate);
+ return getStore().getMetaDataManager().loadPackageUnit(getConnection(), packageUnit);
}
- @Override
- protected void doDeactivate() throws Exception
+ public Collection<InternalCDOPackageUnit> readPackageUnits()
{
- LifecycleUtil.deactivate(jdbcDelegate);
+ return getStore().getMetaDataManager().readPackageUnits(getConnection());
}
- @Override
- protected void doPassivate() throws Exception
+ public void writePackageUnits(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
{
- // Do nothing
+ monitor.begin(2);
+ try
+ {
+ getStore().getMetaDataManager().writePackageUnits(getConnection(), packageUnits, monitor.fork());
+ getStore().getMappingStrategy().createMapping(getConnection(), packageUnits, monitor.fork());
+ }
+ finally
+ {
+ monitor.done();
+ }
}
- @Override
- protected void doUnpassivate() throws Exception
+ private class ConnectionKeepAliveTask extends TimerTask
{
- // Do nothing
+ public static final long EXECUTION_PERIOD = 1000 * 60 * 60 * 4; // 4 hours
+
+ @Override
+ public void run()
+ {
+ Statement stmt = null;
+ try
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("DB connection keep-alive task activated.");
+ }
+ stmt = connection.createStatement();
+ stmt.executeQuery("SELECT 1 FROM " + CDODBSchema.REPOSITORY);
+ }
+ catch (SQLException e)
+ {
+ OM.LOG.error("DB connection keep-alive failed.", e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
index 3fde4ce6ba..1de3985e2d 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
@@ -13,8 +13,8 @@ package org.eclipse.emf.cdo.server.internal.db;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
import org.eclipse.emf.cdo.spi.server.StoreChunkReader;
import org.eclipse.emf.ecore.EStructuralFeature;
@@ -26,7 +26,7 @@ import java.util.List;
*/
public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChunkReader
{
- private IReferenceMapping referenceMapping;
+ private IListMapping referenceMapping;
private StringBuilder builder = new StringBuilder();
@@ -35,7 +35,7 @@ public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChun
super(accessor, revision, feature);
IMappingStrategy mappingStrategy = accessor.getStore().getMappingStrategy();
IClassMapping mapping = mappingStrategy.getClassMapping(revision.getEClass());
- referenceMapping = mapping.getReferenceMapping(feature);
+ referenceMapping = mapping.getListMapping(feature);
}
@Override
@@ -49,7 +49,7 @@ public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChun
{
super.addSimpleChunk(index);
builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
+ builder.append(CDODBSchema.LIST_IDX);
builder.append("=");
builder.append(index);
}
@@ -59,7 +59,7 @@ public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChun
{
super.addRangedChunk(fromIndex, toIndex);
builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
+ builder.append(CDODBSchema.LIST_IDX);
builder.append(" BETWEEN ");
builder.append(fromIndex);
builder.append(" AND ");
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java
index 1f238772a8..7112195c4a 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
*/
package org.eclipse.emf.cdo.server.internal.db;
@@ -14,7 +15,6 @@ import org.eclipse.emf.cdo.internal.server.RepositoryConfigurator;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IStoreFactory;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.net4j.db.DBUtil;
@@ -48,33 +48,10 @@ public class DBStoreFactory implements IStoreFactory
public IStore createStore(Element storeConfig)
{
IMappingStrategy mappingStrategy = getMappingStrategy(storeConfig);
- IJDBCDelegateProvider delegateProvider = getDelegateProvider(storeConfig);
IDBAdapter dbAdapter = getDBAdapter(storeConfig);
DataSource dataSource = getDataSource(storeConfig);
IDBConnectionProvider connectionProvider = DBUtil.createConnectionProvider(dataSource);
- return CDODBUtil.createStore(mappingStrategy, dbAdapter, connectionProvider, delegateProvider);
- }
-
- private IJDBCDelegateProvider getDelegateProvider(Element storeConfig)
- {
- NodeList delegateProviderConfigs = storeConfig.getElementsByTagName("jdbcDelegate");
- if (delegateProviderConfigs.getLength() != 1)
- {
- throw new IllegalStateException("Exactly one delegate provider must be configured for DB store");
- }
-
- Element delegateProviderConfig = (Element)delegateProviderConfigs.item(0);
- String delegateProviderType = delegateProviderConfig.getAttribute("type");
- IJDBCDelegateProvider delegateProvider = CDODBUtil.createDelegateProvider(delegateProviderType);
- if (delegateProvider == null)
- {
- throw new IllegalArgumentException("Unknown JDBC delegate type: " + delegateProviderType);
- }
-
- Map<String, String> properties = RepositoryConfigurator.getProperties(delegateProviderConfig, 1);
- delegateProvider.setProperties(properties);
-
- return delegateProvider;
+ return CDODBUtil.createStore(mappingStrategy, dbAdapter, connectionProvider);
}
private IMappingStrategy getMappingStrategy(Element storeConfig)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java
new file mode 100644
index 0000000000..d7bee71d0a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java
@@ -0,0 +1,375 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDMeta;
+import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.server.db.IDBStore;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBRowHandler;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * @author Eike Stepper
+ */
+public class MetaDataManager extends Lifecycle implements IMetaDataManager
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, MetaDataManager.class);
+
+ private static Map<EClassifier, DBType> typeMap = new HashMap<EClassifier, DBType>();
+
+ private static final boolean ZIP_PACKAGE_BYTES = true;
+
+ private IDBStore store;
+
+ static
+ {
+ typeMap.put(EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP);
+ typeMap.put(EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR);
+ typeMap.put(EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB);
+
+ typeMap.put(EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN);
+ typeMap.put(EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT);
+ typeMap.put(EcorePackage.eINSTANCE.getEChar(), DBType.CHAR);
+ typeMap.put(EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE);
+ typeMap.put(EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT);
+ typeMap.put(EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER);
+ typeMap.put(EcorePackage.eINSTANCE.getELong(), DBType.BIGINT);
+ typeMap.put(EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT);
+
+ typeMap.put(EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN);
+ typeMap.put(EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT);
+ typeMap.put(EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR);
+ typeMap.put(EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE);
+ typeMap.put(EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT);
+ typeMap.put(EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER);
+ typeMap.put(EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT);
+ typeMap.put(EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT);
+ }
+
+ public MetaDataManager(IDBStore store)
+ {
+ this.store = store;
+ }
+
+ public long getMetaID(EModelElement modelElement)
+ {
+ CDOID cdoid = getPackageRegistry().getMetaInstanceMapper().lookupMetaInstanceID((InternalEObject)modelElement);
+ return CDOIDUtil.getLong(cdoid);
+ }
+
+ public EModelElement getMetaInstance(long id)
+ {
+ CDOIDMeta cdoid = CDOIDUtil.createMeta(id);
+ InternalEObject metaInstance = getPackageRegistry().getMetaInstanceMapper().lookupMetaInstance(cdoid);
+ return (EModelElement)metaInstance;
+ }
+
+ public final EPackage[] loadPackageUnit(Connection connection, InternalCDOPackageUnit packageUnit)
+ {
+ String where = CDODBSchema.PACKAGE_UNITS_ID.getName() + "='" + packageUnit.getID() + "'";
+ Object[] values = DBUtil.select(connection, where, CDODBSchema.PACKAGE_UNITS_PACKAGE_DATA);
+ byte[] bytes = (byte[])values[0];
+ EPackage ePackage = createEPackage(packageUnit, bytes);
+ return EMFUtil.getAllPackages(ePackage);
+ }
+
+ public Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection)
+ {
+ final Map<String, InternalCDOPackageUnit> packageUnits = new HashMap<String, InternalCDOPackageUnit>();
+ IDBRowHandler unitRowHandler = new IDBRowHandler()
+ {
+ public boolean handle(int row, final Object... values)
+ {
+ InternalCDOPackageUnit packageUnit = createPackageUnit();
+ packageUnit.setOriginalType(CDOPackageUnit.Type.values()[(Integer)values[1]]);
+ packageUnit.setTimeStamp((Long)values[2]);
+ packageUnits.put((String)values[0], packageUnit);
+ return true;
+ }
+ };
+
+ DBUtil.select(connection, unitRowHandler, CDODBSchema.PACKAGE_UNITS_ID, CDODBSchema.PACKAGE_UNITS_ORIGINAL_TYPE,
+ CDODBSchema.PACKAGE_UNITS_TIME_STAMP);
+
+ final Map<String, List<InternalCDOPackageInfo>> packageInfos = new HashMap<String, List<InternalCDOPackageInfo>>();
+ IDBRowHandler infoRowHandler = new IDBRowHandler()
+ {
+ public boolean handle(int row, final Object... values)
+ {
+ long metaLB = (Long)values[3];
+ long metaUB = (Long)values[4];
+ CDOIDMetaRange metaIDRange = metaLB == 0 ? null : CDOIDUtil.createMetaRange(CDOIDUtil.createMeta(metaLB),
+ (int)(metaUB - metaLB) + 1);
+
+ InternalCDOPackageInfo packageInfo = createPackageInfo();
+ packageInfo.setPackageURI((String)values[1]);
+ packageInfo.setParentURI((String)values[2]);
+ packageInfo.setMetaIDRange(metaIDRange);
+
+ String unit = (String)values[0];
+ List<InternalCDOPackageInfo> list = packageInfos.get(unit);
+ if (list == null)
+ {
+ list = new ArrayList<InternalCDOPackageInfo>();
+ packageInfos.put(unit, list);
+ }
+
+ list.add(packageInfo);
+ return true;
+ }
+ };
+
+ DBUtil.select(connection, infoRowHandler, CDODBSchema.PACKAGE_INFOS_UNIT, CDODBSchema.PACKAGE_INFOS_URI,
+ CDODBSchema.PACKAGE_INFOS_PARENT, CDODBSchema.PACKAGE_INFOS_META_LB, CDODBSchema.PACKAGE_INFOS_META_UB);
+
+ for (Entry<String, InternalCDOPackageUnit> entry : packageUnits.entrySet())
+ {
+ String id = entry.getKey();
+ InternalCDOPackageUnit packageUnit = entry.getValue();
+
+ List<InternalCDOPackageInfo> list = packageInfos.get(id);
+ InternalCDOPackageInfo[] array = list.toArray(new InternalCDOPackageInfo[list.size()]);
+ packageUnit.setPackageInfos(array);
+ }
+
+ return packageUnits.values();
+ }
+
+ public final void writePackageUnits(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
+ {
+ try
+ {
+ monitor.begin(2);
+ fillSystemTables(connection, packageUnits, monitor.fork());
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ public DBType getDBType(EClassifier type)
+ {
+ if (type instanceof EClass)
+ {
+ return DBType.BIGINT;
+ }
+
+ if (type instanceof EEnum)
+ {
+ return DBType.INTEGER;
+ }
+
+ DBType dbType = typeMap.get(type);
+ if (dbType != null)
+ {
+ return dbType;
+ }
+
+ return DBType.VARCHAR;
+ }
+
+ protected IDBStore getStore()
+ {
+ return store;
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ checkState(store != null, "Store is not set");
+ }
+
+ protected InternalCDOPackageInfo createPackageInfo()
+ {
+ return (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo();
+ }
+
+ protected InternalCDOPackageUnit createPackageUnit()
+ {
+ return (InternalCDOPackageUnit)CDOModelUtil.createPackageUnit();
+ }
+
+ private InternalCDOPackageRegistry getPackageRegistry()
+ {
+ return (InternalCDOPackageRegistry)store.getRepository().getPackageRegistry();
+ }
+
+ private EPackage createEPackage(InternalCDOPackageUnit packageUnit, byte[] bytes)
+ {
+ return EMFUtil.createEPackage(packageUnit.getID(), bytes, ZIP_PACKAGE_BYTES, getPackageRegistry());
+ }
+
+ private byte[] getEPackageBytes(InternalCDOPackageUnit packageUnit)
+ {
+ EPackage ePackage = packageUnit.getTopLevelPackageInfo().getEPackage();
+ CDOPackageRegistry packageRegistry = getStore().getRepository().getPackageRegistry();
+ return EMFUtil.getEPackageBytes(ePackage, ZIP_PACKAGE_BYTES, packageRegistry);
+ }
+
+ private void fillSystemTables(Connection connection, InternalCDOPackageUnit packageUnit, OMMonitor monitor)
+ {
+ try
+ {
+ InternalCDOPackageInfo[] packageInfos = packageUnit.getPackageInfos();
+ monitor.begin(1 + packageInfos.length);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing package unit: {0}", packageUnit);
+ }
+
+ String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " VALUES (?, ?, ?, ?)";
+ DBUtil.trace(sql);
+ PreparedStatement pstmt = null;
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ pstmt = connection.prepareStatement(sql);
+ pstmt.setString(1, packageUnit.getID());
+ pstmt.setInt(2, packageUnit.getOriginalType().ordinal());
+ pstmt.setLong(3, packageUnit.getTimeStamp());
+ pstmt.setBytes(4, getEPackageBytes(packageUnit));
+
+ if (pstmt.execute())
+ {
+ throw new DBException("No result set expected");
+ }
+
+ if (pstmt.getUpdateCount() == 0)
+ {
+ throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_UNITS);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(pstmt);
+ async.stop();
+ }
+
+ for (InternalCDOPackageInfo packageInfo : packageInfos)
+ {
+ fillSystemTables(connection, packageInfo, monitor); // Don't fork monitor
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private void fillSystemTables(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
+ {
+ try
+ {
+ monitor.begin(packageUnits.length);
+ for (InternalCDOPackageUnit packageUnit : packageUnits)
+ {
+ fillSystemTables(connection, packageUnit, monitor.fork());
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private void fillSystemTables(Connection connection, InternalCDOPackageInfo packageInfo, OMMonitor monitor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing package info: {0}", packageInfo);
+ }
+
+ String packageURI = packageInfo.getPackageURI();
+ String parentURI = packageInfo.getParentURI();
+ String unitID = packageInfo.getPackageUnit().getID();
+ CDOIDMetaRange metaIDRange = packageInfo.getMetaIDRange();
+ long metaLB = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getLowerBound()).getLongValue();
+ long metaUB = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getUpperBound()).getLongValue();
+
+ String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " VALUES (?, ?, ?, ?, ?)";
+ DBUtil.trace(sql);
+ PreparedStatement pstmt = null;
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ pstmt = connection.prepareStatement(sql);
+ pstmt.setString(1, packageURI);
+ pstmt.setString(2, parentURI);
+ pstmt.setString(3, unitID);
+ pstmt.setLong(4, metaLB);
+ pstmt.setLong(5, metaUB);
+
+ if (pstmt.execute())
+ {
+ throw new DBException("No result set expected");
+ }
+
+ if (pstmt.getUpdateCount() == 0)
+ {
+ throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_INFOS);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(pstmt);
+ async.stop();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java
new file mode 100644
index 0000000000..6387550a0b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db;
+
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBUtil;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.HashSet;
+
+/**
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class NullPreparedStatementCache extends AbstractPreparedStatementCache implements IPreparedStatementCache
+{
+ private HashSet<PreparedStatement> allocatedStatements = new HashSet<PreparedStatement>();
+
+ public NullPreparedStatementCache()
+ {
+ }
+
+ public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability)
+ {
+ try
+ {
+ PreparedStatement result = getConnection().prepareStatement(sql);
+ allocatedStatements.add(result);
+ return result;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ }
+
+ public void releasePreparedStatement(PreparedStatement ps)
+ {
+ allocatedStatements.remove(ps);
+ DBUtil.close(ps);
+ }
+
+ @Override
+ protected void doBeforeDeactivate() throws Exception
+ {
+ if (!allocatedStatements.isEmpty())
+ {
+ OM.LOG.warn("Possible Leak Detected:");
+ for (PreparedStatement ps : allocatedStatements)
+ {
+ OM.LOG.warn("- " + ps.toString());
+ }
+ assert false;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java
index 70611f9453..d085ef52f9 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java
@@ -51,7 +51,7 @@ public abstract class ObjectIDIterator implements CloseableIterator<CDOID>
public void close()
{
- DBUtil.close(currentResultSet);
+ closeCurrentResultSet();
nextID = null;
closed = true;
}
@@ -99,7 +99,8 @@ public abstract class ObjectIDIterator implements CloseableIterator<CDOID>
return true;
}
- DBUtil.close(currentResultSet);
+ closeCurrentResultSet();
+
currentResultSet = null;
return false;
}
@@ -110,6 +111,11 @@ public abstract class ObjectIDIterator implements CloseableIterator<CDOID>
}
}
+ protected void closeCurrentResultSet()
+ {
+ DBUtil.close(currentResultSet);
+ }
+
public CDOID next()
{
if (nextID == null)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java
new file mode 100644
index 0000000000..96d4d22766
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java
@@ -0,0 +1,275 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Winkler - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.internal.db;
+
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.util.ImplementationError;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.HashMap;
+
+/**
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class SmartPreparedStatementCache extends AbstractPreparedStatementCache
+{
+ private Cache cache;
+
+ private HashMap<PreparedStatement, CachedPreparedStatement> checkedOut = new HashMap<PreparedStatement, CachedPreparedStatement>();
+
+ public SmartPreparedStatementCache(int capacity)
+ {
+ cache = new Cache(capacity);
+ }
+
+ public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability)
+ {
+ CachedPreparedStatement cachedStatement = cache.remove(sql);
+
+ if (cachedStatement == null)
+ {
+ cachedStatement = createCachedPreparedStatement(sql, reuseProbability);
+ }
+
+ PreparedStatement result = cachedStatement.getPreparedStatement();
+ checkedOut.put(result, cachedStatement);
+
+ return result;
+ }
+
+ public void releasePreparedStatement(PreparedStatement ps)
+ {
+ CachedPreparedStatement cachedStatement = checkedOut.remove(ps);
+ cache.put(cachedStatement);
+ }
+
+ @Override
+ protected void doBeforeDeactivate() throws Exception
+ {
+ if (!checkedOut.isEmpty())
+ {
+ OM.LOG.warn("Statement leak detected.");
+ }
+ }
+
+ private CachedPreparedStatement createCachedPreparedStatement(String sql, ReuseProbability reuseProbability)
+ {
+ PreparedStatement stmt;
+ try
+ {
+ stmt = getConnection().prepareStatement(sql);
+ CachedPreparedStatement result = new CachedPreparedStatement(sql, reuseProbability, stmt);
+ return result;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ }
+
+ private static final class Cache
+ {
+ private CacheList lists[];
+
+ private HashMap<String, CachedPreparedStatement> lookup;
+
+ private int capacity;
+
+ public Cache(int capacity)
+ {
+ this.capacity = capacity;
+
+ lookup = new HashMap<String, CachedPreparedStatement>(capacity);
+
+ lists = new CacheList[ReuseProbability.values().length];
+ for (ReuseProbability prob : ReuseProbability.values())
+ {
+ lists[prob.ordinal()] = new CacheList();
+ }
+ }
+
+ public void put(CachedPreparedStatement cachedStatement)
+ {
+ // refresh age
+ cachedStatement.touch();
+
+ // put into appripriate list
+ lists[cachedStatement.getProbability().ordinal()].add(cachedStatement);
+
+ // put into lookup table
+ if (lookup.put(cachedStatement.getSql(), cachedStatement) != null)
+ {
+ throw new ImplementationError(cachedStatement.getSql() + " already in cache.");
+ }
+
+ // handle capacity overflow
+ if (lookup.size() > capacity)
+ {
+ evictOne();
+ }
+ }
+
+ private void evictOne()
+ {
+ long maxAge = -1;
+ int ordinal = -1;
+
+ for (ReuseProbability prob : ReuseProbability.values())
+ {
+ if (!lists[prob.ordinal()].isEmpty())
+ {
+ long age = lists[prob.ordinal()].tail().getAge();
+ if (maxAge < age)
+ {
+ maxAge = age;
+ ordinal = prob.ordinal();
+ }
+ }
+ }
+
+ remove(lists[ordinal].tail().getSql());
+ }
+
+ public CachedPreparedStatement remove(String sql)
+ {
+ CachedPreparedStatement result = lookup.remove(sql);
+ if (result == null)
+ {
+ return null;
+ }
+ else
+ {
+ lists[result.getProbability().ordinal()].remove(result);
+ return result;
+ }
+ }
+
+ private class CacheList
+ {
+ private CachedPreparedStatement first = null;
+
+ private CachedPreparedStatement last = null;
+
+ public CacheList()
+ {
+ };
+
+ public void add(CachedPreparedStatement s)
+ {
+ if (first == null)
+ {
+ first = s;
+ last = s;
+ s.previous = null;
+ s.next = null;
+ }
+ else
+ {
+ first.previous = s;
+ s.next = first;
+ first = s;
+ }
+ }
+
+ public void remove(CachedPreparedStatement s)
+ {
+ if (s == first)
+ {
+ first = s.next;
+ }
+ if (s.next != null)
+ {
+ s.next.previous = s.previous;
+ }
+ if (s == last)
+ {
+ last = s.previous;
+ }
+ if (s.previous != null)
+ {
+ s.previous.next = s.next;
+ }
+
+ s.previous = null;
+ s.next = null;
+ }
+
+ public CachedPreparedStatement tail()
+ {
+ return last;
+ }
+
+ public boolean isEmpty()
+ {
+ return first == null;
+ }
+ }
+ };
+
+ private static final class CachedPreparedStatement
+ {
+ private long timeStamp;
+
+ private String sql;
+
+ private ReuseProbability probability;
+
+ private PreparedStatement statement;
+
+ /**
+ * DL field
+ */
+ private CachedPreparedStatement previous;
+
+ /**
+ * DL field
+ */
+ private CachedPreparedStatement next;
+
+ public CachedPreparedStatement(String sql, ReuseProbability prob, PreparedStatement stmt)
+ {
+ this.sql = sql;
+ probability = prob;
+ statement = stmt;
+ timeStamp = System.currentTimeMillis();
+ }
+
+ public PreparedStatement getPreparedStatement()
+ {
+ return statement;
+ }
+
+ public long getAge()
+ {
+ long currentTime = System.currentTimeMillis();
+ return (currentTime - timeStamp) * probability.ordinal();
+ }
+
+ public void touch()
+ {
+ timeStamp = System.currentTimeMillis();
+ }
+
+ public String getSql()
+ {
+ return sql;
+ }
+
+ public ReuseProbability getProbability()
+ {
+ return probability;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java
deleted file mode 100644
index 33acb78d42..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Winkler - initial API and implementation
- * Eike Stepper - maintenance
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBConnectionProvider;
-import org.eclipse.net4j.util.collection.MoveableList;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This abstract implementation of the {@link IJDBCDelegate} interface is used to translate CDO-related objects to base
- * types (e.g. CDOIDs to long) and then to delegate the database execution part to the doXYZ methods which should be
- * implemented by extenders. The purpose of this is to provide several JDBC strategies (e.g. simple or prepared
- * statement database access) depending on the requirements, but a single point of interpreting and transforming
- * CDO-internal structures. The JDBCDelegate also keeps open one database connection and one statement which can be used
- * to perform operations on the database. Extenders may, but don't have to, use the statement to perform operations.
- *
- * @author Stefan Winkler
- * @since 2.0
- */
-public abstract class AbstractJDBCDelegate extends Lifecycle implements IJDBCDelegate
-{
- private IDBStoreAccessor storeAccessor;
-
- private Connection connection;
-
- private Statement statement;
-
- public AbstractJDBCDelegate()
- {
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- connection = getConnectionProvider().getConnection();
- connection.setAutoCommit(isReadOnly());
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- DBUtil.close(statement);
- statement = null;
-
- DBUtil.close(connection);
- connection = null;
-
- super.doDeactivate();
- }
-
- public IDBStoreAccessor getStoreAccessor()
- {
- return storeAccessor;
- }
-
- public void setStoreAccessor(IDBStoreAccessor storeAccessor)
- {
- checkInactive();
- this.storeAccessor = storeAccessor;
- }
-
- public IDBConnectionProvider getConnectionProvider()
- {
- return storeAccessor.getStore().getDBConnectionProvider();
- }
-
- public boolean isReadOnly()
- {
- return storeAccessor.isReader();
- }
-
- public final Connection getConnection()
- {
- return connection;
- }
-
- public final Statement getStatement()
- {
- if (statement == null)
- {
- try
- {
- statement = getConnection().createStatement();
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- return statement;
- }
-
- public PreparedStatement getPreparedStatement(String sql)
- {
- try
- {
- return getConnection().prepareStatement(sql);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- public final void commit(OMMonitor monitor)
- {
- monitor.begin();
- Async async = monitor.forkAsync();
-
- try
- {
- getConnection().commit();
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- async.stop();
- monitor.done();
- }
- }
-
- public final void rollback()
- {
- try
- {
- getConnection().rollback();
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- public final void insertAttributes(InternalCDORevision revision, IClassMapping classMapping)
- {
- doInsertAttributes(classMapping.getTable().getName(), revision, classMapping.getAttributeMappings(), classMapping
- .hasFullRevisionInfo());
- }
-
- public final void updateAttributes(InternalCDORevision cdoRevision, IClassMapping classMapping)
- {
- InternalCDORevision revision = cdoRevision;
-
- List<IAttributeMapping> attributeMappings = classMapping.getAttributeMappings();
- if (attributeMappings == null)
- {
- attributeMappings = Collections.emptyList();
- }
-
- List<Pair<IAttributeMapping, Object>> attributeChanges = new ArrayList<Pair<IAttributeMapping, Object>>(
- attributeMappings.size());
-
- for (IAttributeMapping am : classMapping.getAttributeMappings())
- {
- attributeChanges.add(new Pair<IAttributeMapping, Object>(am, am.getRevisionValue(revision)));
- }
-
- updateAttributes(revision.getID(), revision.getVersion(), revision.getCreated(), (CDOID)revision.getContainerID(),
- revision.getContainingFeatureID(), revision.getResourceID(), attributeChanges, classMapping);
- }
-
- public void updateAttributes(CDOID id, int newVersion, long created, CDOID newContainerId,
- int newContainingFeatureId, CDOID newResourceId, List<Pair<IAttributeMapping, Object>> attributeChanges,
- IClassMapping classMapping)
- {
- doUpdateAttributes(classMapping.getTable().getName(), CDOIDUtil.getLong(id), newVersion, created, CDOIDUtil
- .getLong(newContainerId), newContainingFeatureId, CDOIDUtil.getLong(newResourceId), attributeChanges,
- classMapping.hasFullRevisionInfo());
- }
-
- public final void updateAttributes(CDOID id, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, IClassMapping classMapping)
- {
- doUpdateAttributes(classMapping.getTable().getName(), CDOIDUtil.getLong(id), newVersion, created, attributeChanges,
- classMapping.hasFullRevisionInfo());
- }
-
- public final void updateRevisedForReplace(InternalCDORevision revision, IClassMapping classMapping)
- {
- doUpdateRevisedForReplace(classMapping.getTable().getName(), revision.getCreated() - 1, CDOIDUtil.getLong(revision
- .getID()), revision.getVersion() - 1);
- }
-
- public final void updateRevisedForDetach(CDOID id, long revised, IClassMapping classMapping)
- {
- doUpdateRevisedForDetach(classMapping.getTable().getName(), revised, CDOIDUtil.getLong(id));
- }
-
- public final void deleteAttributes(CDOID id, IClassMapping classMapping)
- {
- doDeleteAttributes(classMapping.getTable().getName(), CDOIDUtil.getLong(id));
- }
-
- public final void insertReference(CDOID id, int version, int index, CDOID targetId, IReferenceMapping referenceMapping)
- {
- doInsertReference(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id), version,
- index, CDODBUtil.getLong(targetId));
- }
-
- public void insertReferenceRow(CDOID id, int newVersion, int index, CDOID value, IReferenceMapping referenceMapping)
- {
- doInsertReferenceRow(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id),
- newVersion, CDODBUtil.getLong(value), index);
- }
-
- public void moveReferenceRow(CDOID id, int newVersion, int oldPosition, int newPosition,
- IReferenceMapping referenceMapping)
- {
- doMoveReferenceRow(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id),
- newVersion, oldPosition, newPosition);
- }
-
- public void removeReferenceRow(CDOID id, int index, int newVersion, IReferenceMapping referenceMapping)
- {
- doRemoveReferenceRow(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id),
- index, newVersion);
- }
-
- public final void deleteReferences(CDOID id, IReferenceMapping referenceMapping)
- {
- doDeleteReferences(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id));
- }
-
- public void updateReference(CDOID id, int version, int index, CDOID targetId, IReferenceMapping referenceMapping)
- {
- doUpdateReference(referenceMapping.getTable().getName(), getDBID(referenceMapping), CDOIDUtil.getLong(id), version,
- index, CDODBUtil.getLong(targetId));
- }
-
- public final void updateReferenceVersion(CDOID id, int newVersion, IReferenceMapping referenceMapping)
- {
- doUpdateReferenceVersion(referenceMapping.getTable().getName(), CDOIDUtil.getLong(id), newVersion);
- }
-
- public final boolean selectRevisionAttributes(InternalCDORevision revision, IClassMapping classMapping, String where)
- {
- List<IAttributeMapping> attributeMappings = classMapping.getAttributeMappings();
- if (attributeMappings == null)
- {
- attributeMappings = Collections.emptyList();
- }
-
- boolean withFullRevisionInfo = classMapping.hasFullRevisionInfo();
- ResultSet resultSet = null;
- try
- {
- resultSet = doSelectRevisionAttributes(classMapping.getTable().getName(), CDOIDUtil.getLong(revision.getID()),
- attributeMappings, withFullRevisionInfo, where);
-
- if (!resultSet.next())
- {
- return false;
- }
-
- int i = 0;
- if (withFullRevisionInfo)
- {
- InternalCDORevision rev = revision;
- rev.setVersion(resultSet.getInt(++i));
- rev.setCreated(resultSet.getLong(++i));
- rev.setRevised(resultSet.getLong(++i));
- rev.setResourceID(CDOIDUtil.createLong(resultSet.getLong(++i)));
- rev.setContainerID(CDOIDUtil.createLong(resultSet.getLong(++i)));
- rev.setContainingFeatureID(resultSet.getInt(++i));
- }
-
- if (attributeMappings != null)
- {
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- attributeMapping.extractValue(resultSet, ++i, revision);
- }
- }
-
- return true;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- close(resultSet);
- }
- }
-
- public void selectRevisionReferences(InternalCDORevision revision, IReferenceMapping referenceMapping,
- int referenceChunk)
- {
- MoveableList<Object> list = revision.getList(referenceMapping.getFeature());
-
- CDOID source = revision.getID();
- long sourceId = CDOIDUtil.getLong(source);
- int version = revision.getVersion();
-
- ResultSet resultSet = null;
- try
- {
- resultSet = doSelectRevisionReferences(referenceMapping.getTable().getName(), sourceId, version,
- getDBID(referenceMapping), "");
-
- while (resultSet.next() && (referenceChunk == CDORevision.UNCHUNKED || --referenceChunk >= 0))
- {
- long target = resultSet.getLong(1);
- list.add(CDOIDUtil.createLong(target));
- }
-
- // TODO Optimize this?
- while (resultSet.next())
- {
- list.add(InternalCDORevision.UNINITIALIZED);
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- close(resultSet);
- }
- }
-
- public void selectRevisionReferenceChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks,
- IReferenceMapping referenceMapping, String where)
- {
- CDOID source = chunkReader.getRevision().getID();
- long sourceId = CDOIDUtil.getLong(source);
- int version = chunkReader.getRevision().getVersion();
-
- ResultSet resultSet = null;
-
- try
- {
- resultSet = doSelectRevisionReferences(referenceMapping.getTable().getName(), sourceId, version,
- getDBID(referenceMapping), where);
-
- Chunk chunk = null;
- int chunkSize = 0;
- int chunkIndex = 0;
- int indexInChunk = 0;
-
- while (resultSet.next())
- {
- long target = resultSet.getLong(1);
- if (chunk == null)
- {
- chunk = chunks.get(chunkIndex++);
- chunkSize = chunk.size();
- }
-
- chunk.add(indexInChunk++, CDOIDUtil.createLong(target));
- if (indexInChunk == chunkSize)
- {
- chunk = null;
- indexInChunk = 0;
- }
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- close(resultSet);
- }
- }
-
- private long getDBID(IReferenceMapping referenceMapping)
- {
- if (referenceMapping.isWithFeature())
- {
- return storeAccessor.getStore().getMetaID(referenceMapping.getFeature());
- }
-
- return 0;
- }
-
- /**
- * Close the given result set and the statement, if this is needed (which is the case, iff the resultSet's statement
- * is not the one which is kept open by this instance).
- */
- private void close(ResultSet resultSet)
- {
- Statement stmt = null;
-
- try
- {
- stmt = resultSet.getStatement();
- }
- catch (Exception ex)
- {
- // Ignore
- }
- finally
- {
- DBUtil.close(resultSet);
- }
-
- // if the statement is one that has been created for the operation only
- // release it.
- if (stmt != statement)
- {
- releaseStatement(stmt);
- }
- }
-
- /**
- * Release a statement which has been used by the doSelectXxx implementations to create the respective ResultSet. This
- * must only be called with statements created by subclasses. Subclasses should override to handle special cases like
- * cached statements which are kept open.
- *
- * @param stmt
- * the statement to close
- */
- protected void releaseStatement(Statement stmt)
- {
- DBUtil.close(stmt);
- }
-
- /**
- * Insert an attribute row.
- */
- protected abstract void doInsertAttributes(String tableName, CDORevision revision,
- List<IAttributeMapping> attributeMappings, boolean withFullRevisionInfo);
-
- /**
- * Update an attribute row.
- */
- protected abstract void doUpdateAttributes(String name, long long1, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, boolean hasFullRevisionInfo);
-
- /**
- * Update an attribute row including containment and resource attributes.
- */
- protected abstract void doUpdateAttributes(String name, long long1, int newVersion, long created,
- long newContainerId, int newContainingFeatureId, long newResourceId,
- List<Pair<IAttributeMapping, Object>> attributeChanges, boolean hasFullRevisionInfo);
-
- /**
- * Set the revised date of a cdoid (the cdoid is to be detached)
- */
- protected abstract void doUpdateRevisedForDetach(String tableName, long revised, long cdoid);
-
- /**
- * Set the revised date of a specific revision's previous version (the previous version is to be replaced).
- */
- protected abstract void doUpdateRevisedForReplace(String tableName, long revisedStamp, long cdoid, int version);
-
- /**
- * Delete an attribute row.
- */
- protected abstract void doDeleteAttributes(String name, long cdoid1);
-
- /**
- * Insert one reference of a particular CDOID and adjusts indexes.
- */
- protected abstract void doInsertReferenceRow(String tableName, long metaID, long cdoid, int newVersion, long l,
- int index);
-
- /**
- * Insert a reference row. Note: this is likely to be replaced by an implementation that supports storing multiple
- * references in one batch.
- */
- protected abstract void doInsertReference(String tableName, long metaID, long source, int version, int i, long target);
-
- /**
- * Update the target ID of one reference of a particular CDOID.
- */
- protected abstract void doUpdateReference(String name, long metaID, long sourceId, int newVersion, int index,
- long targetId);
-
- /**
- * Moves one reference of a particular CDOID and adjusts indexes.
- */
- protected abstract void doMoveReferenceRow(String tableName, long metaID, long cdoid, int newVersion,
- int oldPosition, int newPosition);
-
- /**
- * Delete all references of a particular CDOID.
- */
- protected abstract void doDeleteReferences(String tableName, long metaID, long cdoid);
-
- /**
- * Deletes one reference of a particular CDOID and adjusts indexes.
- *
- * @param newVersion
- */
- protected abstract void doRemoveReferenceRow(String tableName, long metaID, long cdoid, int index, int newVersion);
-
- /**
- * Update all references of cdoid to newVersion
- */
- protected abstract void doUpdateReferenceVersion(String tableName, long cdoid, int newVersion);
-
- /**
- * Select a revision's attributes. The caller is resposible for closing resultSet and associated statement, if
- * appropriate.
- */
- protected abstract ResultSet doSelectRevisionAttributes(String tableName, long revisionId,
- List<IAttributeMapping> attributeMappings, boolean hasFullRevisionInfo, String where) throws SQLException;
-
- /**
- * Select a revision's references (or a part thereof) The caller is resposible for closing resultSet and associated
- * statement, if appropriate.
- */
- protected abstract ResultSet doSelectRevisionReferences(String tableName, long sourceId, int version, long metaID,
- String where) throws SQLException;
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java
deleted file mode 100644
index f45a982705..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.Statement;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class is only to be used in tests (there is a static data aggregation member!).
- *
- * @author Stefan Winkler
- * @since 2.0
- */
-public class JDBCPerformanceReporter extends Lifecycle implements IJDBCDelegate
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, JDBCPerformanceReporter.class);
-
- private static Map<String, TimeData> timeData = Collections.synchronizedMap(new HashMap<String, TimeData>());
-
- private IJDBCDelegate delegate;
-
- public JDBCPerformanceReporter()
- {
- }
-
- public IJDBCDelegate getDelegate()
- {
- return delegate;
- }
-
- public void setDelegate(IJDBCDelegate delegate)
- {
- checkInactive();
- this.delegate = delegate;
- }
-
- public Connection getConnection()
- {
- return delegate.getConnection();
- }
-
- public PreparedStatement getPreparedStatement(String sql)
- {
- return delegate.getPreparedStatement(sql);
- }
-
- public Statement getStatement()
- {
- return delegate.getStatement();
- }
-
- public void insertAttributes(InternalCDORevision revision, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.insertAttributes(revision, classMapping);
- time = System.currentTimeMillis() - time;
-
- registerCall("insertAttributes", time);
- }
-
- public void insertReference(CDOID id, int version, int index, CDOID targetId, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.insertReference(id, version, index, targetId, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("insertReferenceDbId", time);
- }
-
- public void flush(OMMonitor monitor)
- {
- long time = System.currentTimeMillis();
- delegate.flush(monitor);
- time = System.currentTimeMillis() - time;
- registerCall("write", time);
- }
-
- public void commit(OMMonitor monitor)
- {
- delegate.commit(monitor);
- }
-
- public void rollback()
- {
- delegate.rollback();
- }
-
- public boolean selectRevisionAttributes(InternalCDORevision revision, IClassMapping classMapping, String where)
- {
- long time = System.currentTimeMillis();
- boolean result = delegate.selectRevisionAttributes(revision, null, where);
- time = System.currentTimeMillis() - time;
- registerCall("selectAttributes", time);
- return result;
- }
-
- public void selectRevisionReferenceChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks,
- IReferenceMapping referenceMapping, String where)
- {
- long time = System.currentTimeMillis();
- delegate.selectRevisionReferenceChunks(chunkReader, chunks, referenceMapping, where);
- time = System.currentTimeMillis() - time;
- registerCall("selectReferencesChunks", time);
- }
-
- public void selectRevisionReferences(InternalCDORevision revision, IReferenceMapping referenceMapping,
- int referenceChunk)
- {
- long time = System.currentTimeMillis();
- delegate.selectRevisionReferences(revision, referenceMapping, referenceChunk);
- time = System.currentTimeMillis() - time;
- registerCall("selectReferences", time);
- }
-
- public final void updateRevisedForReplace(InternalCDORevision revision, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateRevisedForReplace(revision, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateRevisedForReplace", time);
- }
-
- public final void updateRevisedForDetach(CDOID cdoid, long revised, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateRevisedForDetach(cdoid, revised, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateRevisedForDetach", time);
- }
-
- public void deleteAttributes(CDOID id, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.deleteAttributes(id, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("deleteAttributes", time);
- }
-
- public void deleteReferences(CDOID id, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.deleteReferences(id, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("deleteReferences", time);
- }
-
- public void updateAttributes(InternalCDORevision revision, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateAttributes(revision, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateAllAttributes", time);
- }
-
- public void updateAttributes(CDOID id, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateAttributes(id, newVersion, created, attributeChanges, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateAttributes", time);
- }
-
- public void updateReferenceVersion(CDOID id, int newVersion, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateReferenceVersion(id, newVersion, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateReferenceVersion", time);
- }
-
- public void insertReferenceRow(CDOID id, int newVersion, int index, CDOID value, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.insertReferenceRow(id, newVersion, index, value, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("insertReferenceRow", time);
- }
-
- public void updateReference(CDOID id, int newVersion, int index, CDOID value, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateReference(id, newVersion, index, value, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateReference", time);
- }
-
- public void moveReferenceRow(CDOID id, int newVersion, int oldPosition, int newPosition,
- IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.moveReferenceRow(id, newVersion, oldPosition, newPosition, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("moveReferenceRow", time);
- }
-
- public void removeReferenceRow(CDOID id, int index, int newVersion, IReferenceMapping referenceMapping)
- {
- long time = System.currentTimeMillis();
- delegate.removeReferenceRow(id, index, newVersion, referenceMapping);
- time = System.currentTimeMillis() - time;
- registerCall("removeReferenceRow", time);
- }
-
- public void updateAttributes(CDOID id, int newVersion, long created, CDOID newContainerId,
- int newContainingFeatureId, CDOID newResourceId, List<Pair<IAttributeMapping, Object>> attributeChanges,
- IClassMapping classMapping)
- {
- long time = System.currentTimeMillis();
- delegate.updateAttributes(id, newVersion, created, newContainerId, newContainingFeatureId, newResourceId,
- attributeChanges, classMapping);
- time = System.currentTimeMillis() - time;
- registerCall("updateAttributes_with_containment", time);
- }
-
- public void setStoreAccessor(IDBStoreAccessor storeAccessor)
- {
- delegate.setStoreAccessor(storeAccessor);
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkState(delegate, "delegate");
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- LifecycleUtil.activate(delegate);
- super.doActivate();
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- report();
- super.doDeactivate();
- LifecycleUtil.deactivate(delegate);
- }
-
- public static void report()
- {
- for (TimeData td : timeData.values())
- {
- td.report(TRACER);
- }
- }
-
- private static void registerCall(String method, long time)
- {
- TimeData data = timeData.get(method);
- if (data == null)
- {
- data = new TimeData(method);
- timeData.put(method, data);
- }
-
- data.registerCall(time);
- }
-
- /**
- * @author Stefan Winkler
- * @since 2.0
- */
- private static final class TimeData
- {
- private String method;
-
- private long numberOfCalls = 0;
-
- private long timeMax = Integer.MIN_VALUE;
-
- private long timeMin = Integer.MAX_VALUE;
-
- private long timeTotal = 0;
-
- public TimeData(String method)
- {
- this.method = method;
- }
-
- public synchronized void registerCall(long time)
- {
- if (timeMin > time)
- {
- timeMin = time;
- }
- if (timeMax < time)
- {
- timeMax = time;
- }
-
- numberOfCalls++;
- timeTotal += time;
- }
-
- public void report(ContextTracer tracer)
- {
- tracer.format("{0}: {1} calls, {2} avg, {3} min, {4} max", method, numberOfCalls, timeTotal / numberOfCalls,
- timeMin, timeMax);
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java
deleted file mode 100644
index 7634e77155..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java
+++ /dev/null
@@ -1,1661 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-import org.eclipse.net4j.util.ref.ReferenceValueMap;
-
-import org.eclipse.emf.ecore.EEnumLiteral;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * @author Stefan Winkler
- * @since 2.0
- */
-public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate
-{
- /**
- * Value for {@link #cachingFlag}: Guess if caching is needed
- */
- public static final String CACHE_STMTS_GUESS = "guess";
-
- /**
- * Value for {@link #cachingFlag}: Turn caching on
- */
- public static final String CACHE_STMTS_TRUE = "true";
-
- /**
- * Value for {@link #cachingFlag}: Turn caching off
- */
- public static final String CACHE_STMTS_FALSE = "false";
-
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, PreparedStatementJDBCDelegate.class);
-
- private static final String SQL_UPDATE_REVISE_VERSION = " SET " + CDODBSchema.ATTRIBUTES_REVISED + " = ? WHERE "
- + CDODBSchema.ATTRIBUTES_ID + " = ? AND " + CDODBSchema.ATTRIBUTES_VERSION + " = ?";
-
- private static final String SQL_UPDATE_REVISE_UNREVISED = " SET " + CDODBSchema.ATTRIBUTES_REVISED + " = ? WHERE "
- + CDODBSchema.ATTRIBUTES_ID + " = ? AND " + CDODBSchema.ATTRIBUTES_REVISED + " = 0";
-
- private static final String SQL_INSERT_REFERENCE_WITH_DBID = " VALUES (?, ?, ?, ?, ?)";
-
- private static final String SQL_INSERT_REFERENCE = " VALUES (?, ?, ?, ?)";
-
- /**
- * Cache for preparedStatements used in diverse methods
- */
- private Map<CacheKey, WrappedPreparedStatement> statementCache = null;
-
- /**
- * Container for dirty statements. A statement is considered 'dirty', if addBatch was called, but not executeBatch.
- */
- private Map<CacheKey, PreparedStatement> dirtyStatements = null;
-
- /**
- * This flag determines, if prepared statements should be cached within this delegate. Its value is guessed in
- * {@link #postInitConnection()} based on the fact if the JDBC driver supports pooled statements. If it does, caching
- * in the delegate is unnecessary.
- */
- private boolean cacheStatements;
-
- private CachingEnablement cachingEnablement;
-
- /**
- * This statement is used for unprepared batched statements like in
- * {@link #doUpdateAttributes(String, long, int, long, List, boolean)}
- */
- private Statement miscStatement = null;
-
- public PreparedStatementJDBCDelegate()
- {
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- dirtyStatements = new ReferenceValueMap.Strong<CacheKey, PreparedStatement>();
-
- switch (cachingEnablement)
- {
- case ENABLED:
- cacheStatements = true;
- break;
-
- case DISABLED:
- cacheStatements = false;
- break;
-
- case GUESS:
- try
- {
- cacheStatements = !getConnection().getMetaData().supportsStatementPooling();
- }
- catch (SQLException ex)
- {
- OM.LOG.warn("Failed to guess JDBC statement pooling. Activating cache, just to be sure ...", ex);
- cacheStatements = true;
- }
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("JDBC PreparedStatement caching is " + (cacheStatements ? "enabled." : "NOT enabled."));
- }
-
- if (cacheStatements)
- {
- // initialize cache ...
- statementCache = new ReferenceValueMap.Soft<CacheKey, WrappedPreparedStatement>();
- }
- }
-
- @Override
- protected void doBeforeDeactivate() throws Exception
- {
- for (PreparedStatement ps : dirtyStatements.values())
- {
- DBUtil.close(ps);
- }
-
- dirtyStatements.clear();
- if (cacheStatements)
- {
- for (WrappedPreparedStatement ps : statementCache.values())
- {
- DBUtil.close(ps.getWrappedStatement());
- }
-
- statementCache.clear();
- }
-
- super.doBeforeDeactivate();
- }
-
- public CachingEnablement getCachingEnablement()
- {
- return cachingEnablement;
- }
-
- public void setCachingEnablement(CachingEnablement cachingEnablement)
- {
- checkInactive();
- this.cachingEnablement = cachingEnablement;
- }
-
- public void flush(OMMonitor monitor)
- {
- try
- {
- monitor.begin(dirtyStatements.size() + 1);
-
- if (miscStatement != null)
- {
- Async async = monitor.forkAsync();
- try
- {
- int[] results = miscStatement.executeBatch();
- for (int result : results)
- {
- checkState(result == 1, "Batch of misc statements did not return '1'");
- }
- }
- catch (SQLException ex)
- {
- throw new DBException("Batch execution failed for misc statement.", ex);
- }
- finally
- {
- try
- {
- miscStatement.close();
- }
- catch (SQLException ex)
- {
- // eat up ...
- }
- miscStatement = null;
- async.stop();
- }
- }
-
- for (Entry<CacheKey, PreparedStatement> entry : dirtyStatements.entrySet())
- {
- try
- {
- int[] results;
- Async async = monitor.forkAsync();
-
- try
- {
- results = entry.getValue().executeBatch();
- }
- finally
- {
- async.stop();
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Executing batch for {0} [{1}]", entry.getKey().toString(), entry.getValue());
- }
-
- for (int result : results)
- {
- checkState(result != Statement.EXECUTE_FAILED, "Batch execution returned EXECUTE_FAILED!");
- }
- }
- catch (SQLException ex)
- {
- throw new DBException("Batch execution failed for " + entry.getKey().toString() + " [" + entry.getValue()
- + "]", ex);
- }
- }
- }
- finally
- {
- if (!cacheStatements)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Closing prepared statements.");
- }
-
- for (PreparedStatement ps : dirtyStatements.values())
- {
- DBUtil.close(ps);
- }
- }
- else
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Re-caching prepared statements.");
- }
-
- for (Entry<CacheKey, PreparedStatement> entry : dirtyStatements.entrySet())
- {
- cacheStatement(entry.getKey(), entry.getValue());
- }
- }
-
- dirtyStatements.clear();
-
- monitor.done();
- }
- }
-
- @Override
- protected void doInsertAttributes(String tableName, CDORevision rev, List<IAttributeMapping> attributeMappings,
- boolean withFullRevisionInfo)
- {
- boolean firstBatch = false;
- InternalCDORevision revision = (InternalCDORevision)rev;
-
- if (attributeMappings == null)
- {
- attributeMappings = Collections.emptyList();
- }
-
- PreparedStatement stmt = getDirtyStatement(StmtType.INSERT_ATTRIBUTES, tableName);
- if (stmt == null && cacheStatements)
- {
- firstBatch = true;
- stmt = getAndRemoveCachedStatement(StmtType.INSERT_ATTRIBUTES, tableName);
- }
-
- try
- {
- firstBatch = true;
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder();
-
- sql.append("INSERT INTO ");
- sql.append(tableName);
- sql.append(" VALUES (?, ?, ");
- if (withFullRevisionInfo)
- {
- sql.append("?, ?, ?, ?, ?, ?");
- }
-
- for (int i = 0; i < attributeMappings.size(); i++)
- {
- sql.append(", ?");
- }
-
- sql.append(")");
- stmt = getConnection().prepareStatement(sql.toString());
- }
-
- int col = 1;
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
- stmt.setInt(col++, revision.getVersion());
- if (withFullRevisionInfo)
- {
- stmt.setLong(col++, getStoreAccessor().getStore().getMetaID(revision.getEClass()));
- stmt.setLong(col++, revision.getCreated());
- stmt.setLong(col++, revision.getRevised());
- stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
- stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
- stmt.setInt(col++, revision.getContainingFeatureID());
- }
-
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- Object value = attributeMapping.getRevisionValue(revision);
-
- if (value == null)
- {
- stmt.setNull(col++, attributeMapping.getField().getType().getCode());
- }
- else if (value instanceof java.util.Date)
- {
- // BUG 217255
- stmt.setTimestamp(col++, new Timestamp(((Date)value).getTime()));
- }
- else if (value instanceof EEnumLiteral)
- {
- stmt.setInt(col++, ((EEnumLiteral)value).getValue());
- }
- else
- {
- stmt.setObject(col++, value);
- }
- }
-
- if (firstBatch)
- {
- addDirtyStatement(StmtType.INSERT_ATTRIBUTES, tableName, stmt);
- }
-
- stmt.addBatch();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- }
-
- @Override
- protected void doUpdateAttributes(String tableName, long cdoid, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, boolean hasFullRevisionInfo)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(" = ");
- builder.append(created);
-
- for (Pair<IAttributeMapping, Object> attributeChange : attributeChanges)
- {
- IAttributeMapping attributeMapping = attributeChange.getElement1();
- builder.append(", ");
- builder.append(attributeMapping.getField());
- builder.append(" = ");
- attributeMapping.appendValue(builder, attributeChange.getElement2());
- }
-
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" = ");
- builder.append(cdoid);
-
- String sql = builder.toString();
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("Batching misc statement:" + sql);
- }
-
- try
- {
- if (miscStatement == null)
- {
- miscStatement = getConnection().createStatement();
- }
- miscStatement.addBatch(sql);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- @Override
- protected void doUpdateAttributes(String tableName, long cdoid, int newVersion, long created, long newContainerId,
- int newContainingFeatureId, long newResourceId, List<Pair<IAttributeMapping, Object>> attributeChanges,
- boolean hasFullRevisionInfo)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(" = ");
- builder.append(created);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(" = ");
- builder.append(newContainerId);
-
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
- builder.append(" = ");
- builder.append(newContainingFeatureId);
-
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(" = ");
- builder.append(newResourceId);
-
- for (Pair<IAttributeMapping, Object> attributeChange : attributeChanges)
- {
- IAttributeMapping attributeMapping = attributeChange.getElement1();
- builder.append(", ");
- builder.append(attributeMapping.getField());
- builder.append(" = ");
- attributeMapping.appendValue(builder, attributeChange.getElement2());
- }
-
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" = ");
- builder.append(cdoid);
-
- String sql = builder.toString();
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- try
- {
- if (miscStatement == null)
- {
- miscStatement = getConnection().createStatement();
- }
- miscStatement.addBatch(sql);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- @Override
- protected void doUpdateRevisedForReplace(String tableName, long revisedStamp, long cdoid, int version)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.REVISE_VERSION, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("UPDATE ");
- sql.append(tableName);
- sql.append(SQL_UPDATE_REVISE_VERSION);
- stmt = getConnection().prepareStatement(sql.toString());
-
- if (cacheStatements)
- {
- cacheStatement(StmtType.REVISE_VERSION, tableName, stmt);
- }
- }
-
- stmt.setLong(1, revisedStamp);
- stmt.setLong(2, cdoid);
- stmt.setInt(3, version);
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- @Override
- protected void doUpdateRevisedForDetach(String tableName, long revisedStamp, long cdoid)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.REVISE_UNREVISED, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("UPDATE ");
- sql.append(tableName);
- sql.append(SQL_UPDATE_REVISE_UNREVISED);
- stmt = getConnection().prepareStatement(sql.toString());
-
- if (cacheStatements)
- {
- cacheStatement(StmtType.REVISE_UNREVISED, tableName, stmt);
- }
- }
-
- stmt.setLong(1, revisedStamp);
- stmt.setLong(2, cdoid);
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- /*
- * This has been the preparedStatement version of updateAttributes. Does not make sense now, as amount of attributes
- * is variable. Preparing for any number of attributes is not very intelligent ...
- * @Override protected void doUpdateAllAttributes(String tableName, long cdoid, int version, long created,
- * List<Pair<IAttributeMapping, Object>> attributeChanges, boolean withFullRevisionInfo) { boolean firstBatch = false;
- * PreparedStatement stmt = getDirtyStatement(StmtType.UPDATE_ATTRIBUTES, tableName); if (stmt == null &&
- * cacheStatements) { firstBatch = true; stmt = getAndRemoveCachedStatement(StmtType.UPDATE_ATTRIBUTES, tableName); }
- * try { firstBatch = true; if (stmt == null) { StringBuilder sql = new StringBuilder(); sql.append("UPDATE ");
- * sql.append(tableName); sql.append(" SET "); sql.append(CDODBSchema.ATTRIBUTES_VERSION); sql.append(" = ? "); if
- * (withFullRevisionInfo) { sql.append(", "); sql.append(CDODBSchema.ATTRIBUTES_RESOURCE); sql.append(" = ?,");
- * sql.append(CDODBSchema.ATTRIBUTES_CONTAINER); sql.append(" = ?,"); sql.append(CDODBSchema.ATTRIBUTES_FEATURE);
- * sql.append(" = ?"); } for (IAttributeMapping attributeMapping : attributeMappings) { sql.append(", ");
- * sql.append(attributeMapping.getField()); sql.append(" = ?"); } sql.append(" WHERE ");
- * sql.append(CDODBSchema.ATTRIBUTES_ID); sql.append(" = ? "); stmt =
- * getConnection().prepareStatement(sql.toString()); } int col = 1; if (TRACER.isEnabled()) {
- * TRACER.trace(stmt.toString()); } stmt.setInt(col++, revision.getVersion()); if (withFullRevisionInfo) {
- * stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID())); stmt.setLong(col++,
- * CDOIDUtil.getLong((CDOID)revision.getContainerID())); stmt.setInt(col++, revision.getContainingFeatureID()); } for
- * (IAttributeMapping attributeMapping : attributeMappings) { Object value =
- * attributeMapping.getRevisionValue(revision); if (value == null) { stmt.setNull(col++,
- * attributeMapping.getField().getType().getCode()); } else { stmt.setObject(col++, value); } } stmt.setLong(col++,
- * CDOIDUtil.getLong(revision.getID())); if (firstBatch) { addDirtyStatement(StmtType.UPDATE_ATTRIBUTES, tableName,
- * stmt); } stmt.addBatch(); } catch (SQLException e) { throw new DBException(e); } }
- */
-
- @Override
- protected void doDeleteAttributes(String tableName, long cdoid)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.DELETE_ATTRIBUTES, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("DELETE FROM ");
- sql.append(tableName);
- sql.append(" WHERE ");
- sql.append(CDODBSchema.ATTRIBUTES_ID);
- sql.append(" = ? ");
-
- stmt = getConnection().prepareStatement(sql.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.DELETE_ATTRIBUTES, tableName, stmt);
- }
- }
-
- stmt.setLong(1, cdoid);
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- @Override
- protected void doInsertReference(String tableName, long dbID, long source, int version, int index, long target)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.INSERT_REFERENCES, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("INSERT INTO ");
- sql.append(tableName);
- sql.append(dbID != 0 ? SQL_INSERT_REFERENCE_WITH_DBID : SQL_INSERT_REFERENCE);
- stmt = getConnection().prepareStatement(sql.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.INSERT_REFERENCES, tableName, stmt);
- }
- }
-
- int idx = 1;
- if (dbID != 0)
- {
- stmt.setLong(idx++, dbID);
- }
-
- stmt.setLong(idx++, source);
- stmt.setInt(idx++, version);
- stmt.setInt(idx++, index);
- stmt.setLong(idx++, target);
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- @Override
- protected void doInsertReferenceRow(String tableName, long metaID, long cdoid, int newVersion, long target, int index)
- {
- move1up(tableName, metaID, cdoid, newVersion, index);
- doInsertReference(tableName, metaID, cdoid, newVersion, index, target);
- }
-
- @Override
- protected void doMoveReferenceRow(String tableName, long metaID, long cdoid, int newVersion, int oldPosition,
- int newPosition)
- {
- if (oldPosition == newPosition)
- {
- return;
- }
-
- // move element away temporarily
- updateOneIndex(tableName, metaID, cdoid, newVersion, oldPosition, -1);
-
- // move elements in between
- if (oldPosition < newPosition)
- {
- move1down(tableName, metaID, cdoid, newVersion, oldPosition, newPosition);
- }
- else
- {
- // oldPosition > newPosition -- equal case is handled above
- move1up(tableName, metaID, cdoid, newVersion, newPosition, oldPosition);
- }
-
- // move temporary element to new position
- updateOneIndex(tableName, metaID, cdoid, newVersion, -1, newPosition);
-
- }
-
- @Override
- protected void doRemoveReferenceRow(String tableName, long metaID, long cdoid, int index, int newVersion)
- {
- deleteReferenceRow(tableName, metaID, cdoid, index);
- move1down(tableName, metaID, cdoid, newVersion, index);
- }
-
- @Override
- protected void doUpdateReference(String tableName, long metaID, long sourceId, int newVersion, int index,
- long targetId)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.UPDATE_REFERENCE, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_TARGET);
- builder.append(" = ?, ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.UPDATE_REFERENCE, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setLong(idx++, targetId);
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, sourceId);
- stmt.setLong(idx++, index);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- @Override
- protected void doUpdateReferenceVersion(String tableName, long cdoid, int newVersion)
- {
- boolean firstBatch = false;
-
- PreparedStatement stmt = getDirtyStatement(StmtType.UPDATE_REFERENCE_VERSION, tableName);
- if (stmt == null && cacheStatements)
- {
- firstBatch = true;
- stmt = getAndRemoveCachedStatement(StmtType.UPDATE_REFERENCE_VERSION, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- firstBatch = true;
-
- StringBuilder sql = new StringBuilder();
- sql.append("UPDATE ");
- sql.append(tableName);
- sql.append(" SET ");
- sql.append(CDODBSchema.REFERENCES_VERSION);
- sql.append(" = ? ");
- sql.append(" WHERE ");
- sql.append(CDODBSchema.REFERENCES_SOURCE);
- sql.append(" = ?");
-
- stmt = getConnection().prepareStatement(sql.toString());
- }
-
- stmt.setInt(1, newVersion);
- stmt.setLong(2, cdoid);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- if (firstBatch)
- {
- addDirtyStatement(StmtType.UPDATE_REFERENCE_VERSION, tableName, stmt);
- }
-
- stmt.addBatch();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- }
-
- @Override
- protected void doDeleteReferences(String tableName, long metaID, long cdoid)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.DELETE_REFERENCES, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("DELETE FROM ");
- sql.append(tableName);
- sql.append(" WHERE ");
- sql.append(CDODBSchema.REFERENCES_SOURCE);
- sql.append(" = ? ");
-
- if (metaID != 0)
- {
- sql.append("AND");
- sql.append(CDODBSchema.REFERENCES_FEATURE);
- sql.append(" = ? ");
- }
-
- stmt = getConnection().prepareStatement(sql.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.DELETE_REFERENCES, tableName, stmt);
- }
- }
-
- stmt.setLong(1, cdoid);
- if (metaID != 0)
- {
- stmt.setLong(2, metaID);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- @Override
- protected ResultSet doSelectRevisionAttributes(String tableName, long revisionId,
- List<IAttributeMapping> attributeMappings, boolean hasFullRevisionInfo, String where) throws SQLException
- {
- // Because of the variable where clause, statement caching can not be
- // based on table names. Instead, we build the sql in any case and
- // use this as key (similar to what JDBC3 does ...).
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-
- if (hasFullRevisionInfo)
- {
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
- }
-
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- builder.append(", ");
- builder.append(attributeMapping.getField());
- }
-
- builder.append(" FROM ");
- builder.append(tableName);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("= ? AND (");
- builder.append(where);
- builder.append(")");
- String sql = builder.toString();
- if (TRACER.isEnabled())
- {
- TRACER.format("{0} ({1})", sql, revisionId);
- }
-
- PreparedStatement pstmt = null;
- if (cacheStatements)
- {
- pstmt = getCachedStatement(StmtType.GENERAL, sql);
- if (pstmt == null)
- {
- pstmt = getConnection().prepareStatement(sql);
- cacheStatement(StmtType.GENERAL, sql, pstmt);
- }
- }
- else
- {
- /* no caching */
- pstmt = getConnection().prepareStatement(sql);
- }
-
- pstmt.setLong(1, revisionId);
- return pstmt.executeQuery();
- }
-
- @Override
- protected ResultSet doSelectRevisionReferences(String tableName, long sourceId, int version, long metaID, String where)
- throws SQLException
- {
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(CDODBSchema.REFERENCES_TARGET);
- builder.append(" FROM ");
- builder.append(tableName);
- builder.append(" WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append("= ? ");
- if (where != null)
- {
- builder.append(where);
- }
-
- builder.append(" ORDER BY ");
- builder.append(CDODBSchema.REFERENCES_IDX);
-
- String sql = builder.toString();
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- PreparedStatement pstmt = null;
- if (cacheStatements)
- {
- pstmt = getCachedStatement(StmtType.GENERAL, sql);
- if (pstmt == null)
- {
- pstmt = getConnection().prepareStatement(sql);
- cacheStatement(StmtType.GENERAL, sql, pstmt);
- }
- }
- else
- {
- /* no caching */
- pstmt = getConnection().prepareStatement(sql);
- }
-
- int idx = 1;
- if (metaID != 0)
- {
- pstmt.setLong(idx++, metaID);
- }
-
- pstmt.setLong(idx++, sourceId);
- pstmt.setInt(idx++, version);
- return pstmt.executeQuery();
- }
-
- /**
- * Implementation of the hook which is called after selects.
- */
- @Override
- protected void releaseStatement(Statement stmt)
- {
- // leave open cached statements
- if (!cacheStatements || !(stmt instanceof PreparedStatement))
- {
- super.releaseStatement(stmt);
- }
-
- // /* This code would guarantee that releaseStatement is only called
- // for cached statements. However this looks through the whole hashmap
- // and is thus too expensive to do in non-debugging mode. */
- //
- // else {
- // if(!selectStatementsCache.containsValue(stmt)) {
- // super.releaseStatement(stmt);
- // }
- // }
- }
-
- // ----------------------------------------------------------
- // List management helpers
- // ----------------------------------------------------------
-
- private void updateOneIndex(String tableName, long metaID, long cdoid, int newVersion, int oldIndex, int newIndex)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("updateOneIndex ({0},{1},{2},{3},{4})", tableName, cdoid, newVersion, oldIndex, newIndex);
- }
-
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.MOVE_ONE_INDEX, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ?, ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.MOVE_ONE_INDEX, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setInt(idx++, newIndex);
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, cdoid);
- stmt.setLong(idx++, oldIndex);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- /**
- * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with
- * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
- */
- private void move1down(String tableName, long metaID, long cdoid, int newVersion, int index, int upperIndex)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("move1down({0},{1},{2},{3},{4})", tableName, cdoid, newVersion, index, upperIndex);
- }
-
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.MOVE_RANGE_1_DOWN, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("-1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" > ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" <= ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.MOVE_RANGE_1_DOWN, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, cdoid);
- stmt.setInt(idx++, index);
- stmt.setInt(idx++, upperIndex);
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- /**
- * Move references downwards to close a gap at position <code>index</code>. All indexes starting with
- * <code>index + 1</code> are moved down.
- */
- private void move1down(String tableName, long metaID, long cdoid, int newVersion, int index)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("move1down({0},{1},{2},{3})", tableName, cdoid, newVersion, index);
- }
-
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.MOVE_1_DOWN, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("-1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" > ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.MOVE_1_DOWN, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, cdoid);
- stmt.setInt(idx++, index);
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
-
- }
- }
-
- /**
- * Move references upwards to make room at position <code>index</code>. Only indexes starting with <code>index</code>
- * and ending with <code>upperIndex - 1</code> are moved up.
- */
- private void move1up(String tableName, long metaID, long cdoid, int newVersion, int index, int upperIndex)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("move1up({0},{1},{2},{3},{4})", tableName, cdoid, newVersion, index, upperIndex);
- }
-
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.MOVE_RANGE_1_UP, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("+1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" => ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" < ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.MOVE_RANGE_1_UP, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, cdoid);
- stmt.setInt(idx++, index);
- stmt.setInt(idx++, upperIndex);
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
-
- }
- }
-
- /**
- * Move references upwards to make room at position <code>index</code>. Only indexes starting with <code>index</code>.
- */
- private void move1up(String tableName, long metaID, long cdoid, int newVersion, int index)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("move1up({0},{1},{2},{3})", tableName, cdoid, newVersion, index);
- }
-
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.MOVE_1_UP, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("+1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ? WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("= ? AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" >= ?");
-
- stmt = getConnection().prepareStatement(builder.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.MOVE_1_UP, tableName, stmt);
- }
- }
-
- int idx = 1;
- stmt.setInt(idx++, newVersion);
-
- if (metaID != 0)
- {
- stmt.setLong(idx++, metaID);
- }
-
- stmt.setLong(idx++, cdoid);
- stmt.setInt(idx++, index);
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
-
- }
- }
-
- private void deleteReferenceRow(String tableName, long metaID, long cdoid, int index)
- {
- PreparedStatement stmt = null;
- if (cacheStatements)
- {
- stmt = getCachedStatement(StmtType.DELETE_ONE_REFERENCE, tableName);
- }
-
- try
- {
- if (stmt == null)
- {
- StringBuilder sql = new StringBuilder("DELETE FROM ");
- sql.append(tableName);
- sql.append(" WHERE ");
- sql.append(CDODBSchema.REFERENCES_SOURCE);
- sql.append(" = ? AND ");
- sql.append(CDODBSchema.REFERENCES_IDX);
- sql.append(" = ? ");
-
- if (metaID != 0)
- {
- sql.append("AND");
- sql.append(CDODBSchema.REFERENCES_FEATURE);
- sql.append(" = ? ");
- }
-
- stmt = getConnection().prepareStatement(sql.toString());
- if (cacheStatements)
- {
- cacheStatement(StmtType.DELETE_ONE_REFERENCE, tableName, stmt);
- }
- }
-
- stmt.setLong(1, cdoid);
- stmt.setInt(2, index);
- if (metaID != 0)
- {
- stmt.setLong(3, metaID);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- stmt.execute();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- if (!cacheStatements)
- {
- DBUtil.close(stmt);
- }
- }
- }
-
- // ----------------------------------------------------------
- // Statement caching
- // ----------------------------------------------------------
-
- /**
- * Add a dirty statement to the dirty statements container.
- */
- private void addDirtyStatement(StmtType type, String subKey, PreparedStatement stmt)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Adding dirty statement: ({0},{1}) -> {2}", type, subKey, stmt);
- }
-
- dirtyStatements.put(new CacheKey(type, subKey), stmt);
- }
-
- /**
- * Query the dirty statements container.
- *
- * @return
- */
- private PreparedStatement getDirtyStatement(StmtType type, String subKey)
- {
- return dirtyStatements.get(CacheKey.useOnce(type, subKey));
- }
-
- /**
- * Cache a prepared statement.
- */
- private void cacheStatement(StmtType type, String subKey, PreparedStatement stmt)
- {
- cacheStatement(new CacheKey(type, subKey), stmt);
- }
-
- /**
- * Cache a prepared statement with given key.
- */
- private void cacheStatement(CacheKey key, PreparedStatement stmt)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Adding cached statement: {0} -> {1}", key, stmt);
- }
-
- statementCache.put(key, new WrappedPreparedStatement(stmt));
- }
-
- /**
- * Query the cache of prepared statements.
- */
- private PreparedStatement getCachedStatement(StmtType type, String subKey)
- {
- WrappedPreparedStatement wrapped = statementCache.get(CacheKey.useOnce(type, subKey));
- if (wrapped == null)
- {
- return null;
- }
-
- PreparedStatement stmt = wrapped.getWrappedStatement();
- if (TRACER.isEnabled())
- {
- TRACER.format("Using cached statement: ({0},{1}) -> {2}", type, subKey, stmt);
- }
-
- return stmt;
- }
-
- private PreparedStatement getAndRemoveCachedStatement(StmtType type, String subKey)
- {
- WrappedPreparedStatement wrapped = statementCache.remove(CacheKey.useOnce(type, subKey));
- if (wrapped == null)
- {
- return null;
- }
-
- PreparedStatement stmt = wrapped.unwrapStatement();
- if (TRACER.isEnabled())
- {
- TRACER.format("Removing cached statement: ({0},{1}) -> {2}", type, subKey, stmt);
- }
-
- return stmt;
- }
-
- /**
- * @author Stefan Winkler
- */
- public static enum CachingEnablement
- {
- ENABLED, DISABLED, GUESS
- }
-
- /**
- * Statement type as first part of the statement cache key.
- *
- * @author Stefan Winkler
- */
- private static enum StmtType
- {
- INSERT_ATTRIBUTES, DELETE_ATTRIBUTES, INSERT_REFERENCES, DELETE_REFERENCES, DELETE_ONE_REFERENCE, REVISE_VERSION, REVISE_UNREVISED, GENERAL, UPDATE_REFERENCE_VERSION, MOVE_1_UP, MOVE_RANGE_1_UP, MOVE_1_DOWN, MOVE_RANGE_1_DOWN, MOVE_ONE_INDEX, UPDATE_REFERENCE
- }
-
- /**
- * Convenience definition for Pair<StmtType, String>
- *
- * @author Stefan Winkler
- */
- private static class CacheKey extends Pair<StmtType, String>
- {
- public CacheKey(StmtType type, String subKey)
- {
- super(type, subKey);
- }
-
- private static CacheKey useOnceKey = new CacheKey(StmtType.GENERAL, "");
-
- /**
- * Memory-resource-friendly method which uses a single static field, modifies it and returns it to be used at once,
- * e.g., to use it in a cache lookup. Do not store a reference to the result!!!
- */
- public static CacheKey useOnce(StmtType type, String subKey)
- {
- useOnceKey.setElement1(type);
- useOnceKey.setElement2(subKey);
- return useOnceKey;
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java
deleted file mode 100644
index 08b13d3cc8..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider;
-import org.eclipse.emf.cdo.server.internal.db.jdbc.PreparedStatementJDBCDelegate.CachingEnablement;
-
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public class PreparedStatementJDBCDelegateProvider implements IJDBCDelegateProvider
-{
- public static final String CACHE_STATEMENT_PROPERTY_KEY = "cacheStatements";
-
- private CachingEnablement cachingEnablement = CachingEnablement.GUESS;
-
- public PreparedStatementJDBCDelegateProvider()
- {
- }
-
- public IJDBCDelegate getJDBCDelegate()
- {
- PreparedStatementJDBCDelegate delegate = new PreparedStatementJDBCDelegate();
- delegate.setCachingEnablement(cachingEnablement);
- return delegate;
- }
-
- public void setProperties(Map<String, String> properties)
- {
- String value = properties.get(CACHE_STATEMENT_PROPERTY_KEY);
- if (value == null)
- {
- value = "GUESS";
- }
-
- cachingEnablement = CachingEnablement.valueOf(value.toUpperCase());
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java
deleted file mode 100644
index 11d0e0b844..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
-/**
- * @author Stefan Winkler
- * @since 2.0
- */
-public class StatementJDBCDelegate extends AbstractJDBCDelegate
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, StatementJDBCDelegate.class);
-
- public StatementJDBCDelegate()
- {
- }
-
- public void flush(OMMonitor monitor)
- {
- // Do nothing
- }
-
- @Override
- protected void doInsertAttributes(String table, CDORevision revision, List<IAttributeMapping> attributeMappings,
- boolean withFullRevisionInfo)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("INSERT INTO ");
- builder.append(table);
- builder.append(" VALUES (");
-
- builder.append(CDOIDUtil.getLong(revision.getID()));
- builder.append(", ");
- builder.append(revision.getVersion());
-
- if (withFullRevisionInfo)
- {
- CDORevisionData data = revision.data();
- builder.append(", ");
- builder.append(getStoreAccessor().getStore().getMetaID(revision.getEClass()));
- builder.append(", ");
- builder.append(revision.getCreated());
- builder.append(", ");
- builder.append(revision.getRevised());
- builder.append(", ");
- builder.append(CDOIDUtil.getLong(data.getResourceID()));
- builder.append(", ");
- builder.append(CDODBUtil.getLong((CDOID)data.getContainerID()));
- builder.append(", ");
- builder.append(data.getContainingFeatureID());
- }
-
- if (attributeMappings != null)
- {
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- builder.append(", ");
- attributeMapping.appendValue(builder, (InternalCDORevision)revision);
- }
- }
-
- builder.append(")");
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doUpdateAttributes(String tableName, long cdoid, int newVersion, long created,
- List<Pair<IAttributeMapping, Object>> attributeChanges, boolean hasFullRevisionInfo)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(" = ");
- builder.append(created);
-
- for (Pair<IAttributeMapping, Object> attributeChange : attributeChanges)
- {
- IAttributeMapping attributeMapping = attributeChange.getElement1();
- builder.append(", ");
- builder.append(attributeMapping.getField());
- builder.append(" = ");
- attributeMapping.appendValue(builder, attributeChange.getElement2());
- }
-
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" = ");
- builder.append(cdoid);
-
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doUpdateAttributes(String tableName, long cdoid, int newVersion, long created, long newContainerId,
- int newContainingFeatureId, long newResourceId, List<Pair<IAttributeMapping, Object>> attributeChanges,
- boolean hasFullRevisionInfo)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(" = ");
- builder.append(created);
-
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(" = ");
- builder.append(newContainerId);
-
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
- builder.append(" = ");
- builder.append(newContainingFeatureId);
-
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(" = ");
- builder.append(newResourceId);
-
- for (Pair<IAttributeMapping, Object> attributeChange : attributeChanges)
- {
- IAttributeMapping attributeMapping = attributeChange.getElement1();
- builder.append(", ");
- builder.append(attributeMapping.getField());
- builder.append(" = ");
- attributeMapping.appendValue(builder, attributeChange.getElement2());
- }
-
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" = ");
- builder.append(cdoid);
-
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doDeleteAttributes(String name, long cdoid)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("DELETE FROM ");
- builder.append(name);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" = ");
- builder.append(cdoid);
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doUpdateRevisedForReplace(String table, long revisedStamp, long cdoid, int version)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(table);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=");
- builder.append(revisedStamp);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("=");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append("=");
- builder.append(version);
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doUpdateRevisedForDetach(String table, long revisedStamp, long cdoid)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(table);
- builder.append(" SET ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=");
- builder.append(revisedStamp);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("=");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0");
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doInsertReferenceRow(String tableName, long metaID, long cdoid, int newVersion, long target, int index)
- {
- move1up(tableName, metaID, cdoid, newVersion, index, -1);
- doInsertReference(tableName, metaID, cdoid, newVersion, index, target);
- }
-
- @Override
- protected void doInsertReference(String table, long metaID, long source, int version, int i, long target)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("INSERT INTO ");
- builder.append(table);
- builder.append(" VALUES (");
- if (metaID != 0)
- {
- builder.append(metaID);
- builder.append(", ");
- }
- builder.append(source);
- builder.append(", ");
- builder.append(version);
- builder.append(", ");
- builder.append(i);
- builder.append(", ");
- builder.append(target);
- builder.append(")");
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doMoveReferenceRow(String tableName, long metaID, long cdoid, int newVersion, int oldPosition,
- int newPosition)
- {
- if (oldPosition == newPosition)
- {
- return;
- }
-
- // move element away temporarily
- updateOneIndex(tableName, metaID, cdoid, newVersion, oldPosition, -1);
-
- // move elements in between
- if (oldPosition < newPosition)
- {
- move1down(tableName, metaID, cdoid, newVersion, oldPosition, newPosition);
- }
- else
- {
- // oldPosition > newPosition -- equal case is handled above
- move1up(tableName, metaID, cdoid, newVersion, newPosition, oldPosition);
- }
-
- // move temporary element to new position
- updateOneIndex(tableName, metaID, cdoid, newVersion, -1, newPosition);
- }
-
- @Override
- protected void doDeleteReferences(String name, long metaID, long cdoid)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("DELETE FROM ");
- builder.append(name);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append(" = ");
- builder.append(cdoid);
- if (metaID != 0)
- {
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append(" = ");
- builder.append(metaID);
- }
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doRemoveReferenceRow(String tableName, long metaID, long cdoid, int index, int newVersion)
- {
- deleteReferenceRow(tableName, metaID, cdoid, index);
- move1down(tableName, metaID, cdoid, newVersion, index, -1);
- }
-
- @Override
- protected void doUpdateReferenceVersion(String tableName, long cdoid, int newVersion)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append(" = ");
- builder.append(cdoid);
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected void doUpdateReference(String tableName, long metaID, long sourceId, int newVersion, int index,
- long targetId)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_TARGET);
- builder.append(" = ");
- builder.append(targetId);
- builder.append(", ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append(" = ");
- builder.append(sourceId);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(index);
-
- if (metaID != 0)
- {
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append(" = ");
- builder.append(metaID);
- }
-
- sqlUpdate(builder.toString());
- }
-
- @Override
- protected ResultSet doSelectRevisionAttributes(String tableName, long revisionId,
- List<IAttributeMapping> attributeMappings, boolean hasFullRevisionInfo, String where) throws SQLException
- {
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- if (hasFullRevisionInfo)
- {
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(", ");
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
- }
- else
- {
- if (attributeMappings == null)
- {
- // Only references return
- return null;
- }
- }
-
- if (attributeMappings != null)
- {
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- builder.append(", ");
- builder.append(attributeMapping.getField());
- }
- }
-
- builder.append(" FROM ");
- builder.append(tableName);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("=");
- builder.append(revisionId);
- builder.append(" AND (");
- builder.append(where);
- builder.append(")");
- String sql = builder.toString();
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- return getStatement().executeQuery(sql);
- }
-
- @Override
- protected ResultSet doSelectRevisionReferences(String tableName, long sourceId, int version, long metaID, String where)
- throws SQLException
- {
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(CDODBSchema.REFERENCES_TARGET);
- builder.append(" FROM ");
- builder.append(tableName);
- builder.append(" WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("=");
- builder.append(metaID);
- builder.append(" AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("=");
- builder.append(sourceId);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append("=");
- builder.append(version);
-
- if (where != null)
- {
- builder.append(where);
- }
-
- builder.append(" ORDER BY ");
- builder.append(CDODBSchema.REFERENCES_IDX);
-
- String sql = builder.toString();
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- return getStatement().executeQuery(sql);
- }
-
- private int sqlUpdate(String sql) throws DBException
- {
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- Statement statement = null;
- try
- {
- statement = getConnection().createStatement();
- return statement.executeUpdate(sql);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- try
- {
- statement.close();
- }
- catch (SQLException e)
- {
- if (TRACER.isEnabled())
- {
- TRACER.trace(e);
- }
- }
- }
- }
-
- private void deleteReferenceRow(String name, long metaID, long cdoid, int index)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("DELETE FROM ");
- builder.append(name);
- builder.append(" WHERE ");
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append(" = ");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(index);
- if (metaID != 0)
- {
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append(" = ");
- builder.append(metaID);
- }
- sqlUpdate(builder.toString());
- }
-
- /**
- * Move references upwards to make room at position <code>index</code>. If <code>upperIndex</code> is <code>-1</code>,
- * then all indices beginning with <code>index</code> are moved. Else, only indexes starting with <code>index</code>
- * and ending with <code>upperIndex - 1</code> are moved up.
- */
- private void move1up(String tableName, long metaID, long cdoid, int newVersion, int index, int upperIndex)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("+1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(" WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("=");
- builder.append(metaID);
- builder.append(" AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("=");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" >= ");
- builder.append(index);
-
- if (upperIndex != -1)
- {
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" < ");
- builder.append(upperIndex);
- }
-
- sqlUpdate(builder.toString());
- }
-
- /**
- * Move references downwards to close a gap at position <code>index</code>. If <code>upperIndex</code> is
- * <code>-1</code>, then all indices beginning with <code>index + 1</code> are moved. Else, only indexes starting with
- * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
- */
- private void move1down(String tableName, long metaID, long cdoid, int newVersion, int index, int upperIndex)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append("-1 ,");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(" WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("=");
- builder.append(metaID);
- builder.append(" AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("=");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" > ");
- builder.append(index);
-
- if (upperIndex != -1)
- {
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" <= ");
- builder.append(upperIndex);
- }
-
- sqlUpdate(builder.toString());
- }
-
- private void updateOneIndex(String tableName, long metaID, long cdoid, int newVersion, int oldIndex, int newIndex)
- {
- StringBuilder builder = new StringBuilder();
-
- builder.append("UPDATE ");
- builder.append(tableName);
- builder.append(" SET ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(newIndex);
- builder.append(", ");
- builder.append(CDODBSchema.REFERENCES_VERSION);
- builder.append(" = ");
- builder.append(newVersion);
- builder.append(" WHERE ");
- if (metaID != 0)
- {
- builder.append(CDODBSchema.REFERENCES_FEATURE);
- builder.append("=");
- builder.append(metaID);
- builder.append(" AND ");
- }
-
- builder.append(CDODBSchema.REFERENCES_SOURCE);
- builder.append("=");
- builder.append(cdoid);
- builder.append(" AND ");
- builder.append(CDODBSchema.REFERENCES_IDX);
- builder.append(" = ");
- builder.append(oldIndex);
-
- sqlUpdate(builder.toString());
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegateProvider.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegateProvider.java
deleted file mode 100644
index ecb83538b2..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegateProvider.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider;
-
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class StatementJDBCDelegateProvider implements IJDBCDelegateProvider
-{
- public StatementJDBCDelegateProvider()
- {
- }
-
- public IJDBCDelegate getJDBCDelegate()
- {
- return new StatementJDBCDelegate();
- }
-
- public void setProperties(Map<String, String> properties)
- {
- // ignore -- no properties for this delegate
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
new file mode 100644
index 0000000000..12dfdd8235
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
@@ -0,0 +1,454 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
+import org.eclipse.emf.cdo.server.db.IDBStore;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.ObjectIDIterator;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.collection.CloseableIterator;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.ENamedElement;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This abstract base class implements those methods which are most likely common to most mapping strategies. It can be
+ * used to derive custom mapping strategy implementation.
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public abstract class AbstractMappingStrategy extends Lifecycle implements IMappingStrategy
+{
+ // --------- database name generation strings --------------
+ protected static final String NAME_SEPARATOR = "_";
+
+ protected static final String TYPE_PREFIX_FEATURE = "F";
+
+ protected static final String TYPE_PREFIX_CLASS = "C";
+
+ protected static final String TYPE_PREFIX_PACKAGE = "P";
+
+ protected static final String FEATEURE_TABLE_SUFFIX = "_list";
+
+ private IDBStore store;
+
+ private Map<String, String> properties;
+
+ private Map<EClass, IClassMapping> classMappings;
+
+ public AbstractMappingStrategy()
+ {
+ classMappings = new HashMap<EClass, IClassMapping>();
+ }
+
+ // -- property related methods -----------------------------------------
+
+ public synchronized Map<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new HashMap<String, String>();
+ }
+
+ return properties;
+ }
+
+ public synchronized void setProperties(Map<String, String> properties)
+ {
+ this.properties = properties;
+ }
+
+ private int getMaxTableNameLength()
+ {
+ String value = getProperties().get(PROP_MAX_TABLE_NAME_LENGTH);
+ return value == null ? store.getDBAdapter().getMaxTableNameLength() : Integer.valueOf(value);
+ }
+
+ private int getMaxFieldNameLength()
+ {
+ String value = getProperties().get(PROP_MAX_FIELD_NAME_LENGTH);
+ return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value);
+ }
+
+ private boolean isQualifiedNames()
+ {
+ String value = getProperties().get(PROP_QUALIFIED_NAMES);
+ return value == null ? false : Boolean.valueOf(value);
+ }
+
+ private boolean isForceNamesWithID()
+ {
+ String value = getProperties().get(PROP_FORCE_NAMES_WITH_ID);
+ return value == null ? false : Boolean.valueOf(value);
+ }
+
+ private String getTableNamePrefix()
+ {
+ String value = getProperties().get(PROP_TABLE_NAME_PREFIX);
+ return StringUtil.safe(value);
+ }
+
+ // -- getters and setters ----------------------------------------------
+
+ public final IDBStore getStore()
+ {
+ return store;
+ }
+
+ public final void setStore(IDBStore dbStore)
+ {
+ checkInactive();
+ store = dbStore;
+ }
+
+ protected final IMetaDataManager getMetaDataManager()
+ {
+ return getStore().getMetaDataManager();
+ }
+
+ public abstract boolean hasAuditSupport();
+
+ public abstract boolean hasDeltaSupport();
+
+ // -- object id related methods ----------------------------------------
+
+ public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor dbStoreAccessor)
+ {
+ Collection<EClass> classes = getClassesWithObjectInfo();
+ final Iterator<EClass> classIt = classes.iterator();
+
+ return new ObjectIDIterator(this, dbStoreAccessor)
+ {
+ private PreparedStatement currentStatement = null;
+
+ @Override
+ protected ResultSet getNextResultSet()
+ {
+ while (classIt.hasNext())
+ {
+ EClass eClass = classIt.next();
+ IClassMapping mapping = getClassMapping(eClass);
+ currentStatement = mapping.createObjectIdStatement(getAccessor());
+
+ ResultSet rset = null;
+ try
+ {
+ rset = currentStatement.executeQuery();
+ return rset;
+ }
+ catch (SQLException ex)
+ {
+ DBUtil.close(rset); // only on error
+ getAccessor().getStatementCache().releasePreparedStatement(currentStatement);
+ throw new DBException(ex);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void closeCurrentResultSet()
+ {
+ super.closeCurrentResultSet();
+ getAccessor().getStatementCache().releasePreparedStatement(currentStatement);
+ currentStatement = null;
+ }
+ };
+ };
+
+ public abstract CDOClassifierRef readObjectType(IDBStoreAccessor dbStoreAccessor, CDOID id);
+
+ public abstract long repairAfterCrash(IDBAdapter dbAdapter, Connection connection);
+
+ protected abstract Collection<EClass> getClassesWithObjectInfo();
+
+ // -- resource query handling ------------------------------------------
+
+ public abstract void queryResources(IDBStoreAccessor dbStoreAccessor, QueryResourcesContext context);
+
+ // -- database name demangling methods ---------------------------------
+
+ public String getTableName(ENamedElement element)
+ {
+ String name = null;
+ String typePrefix = null;
+
+ if (element instanceof EClass)
+ {
+ name = isQualifiedNames() ? EMFUtil.getQualifiedName((EClass)element, NAME_SEPARATOR) : element.getName();
+ typePrefix = TYPE_PREFIX_CLASS;
+ }
+ else if (element instanceof EPackage)
+ {
+ name = isQualifiedNames() ? EMFUtil.getQualifiedName((EPackage)element, NAME_SEPARATOR) : element.getName();
+ typePrefix = TYPE_PREFIX_PACKAGE;
+ }
+ else
+ {
+ throw new ImplementationError("Unknown element: " + element);
+ }
+
+ String prefix = getTableNamePrefix();
+ if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR))
+ {
+ prefix += NAME_SEPARATOR;
+ }
+
+ return getName(prefix + name, typePrefix + getMetaDataManager().getMetaID(element), getMaxTableNameLength());
+ }
+
+ public String getTableName(EClass eClass, EStructuralFeature feature)
+ {
+ String name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName();
+ name += NAME_SEPARATOR;
+ name += feature.getName();
+ name += FEATEURE_TABLE_SUFFIX;
+
+ String prefix = getTableNamePrefix();
+ if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR))
+ {
+ prefix += NAME_SEPARATOR;
+ }
+
+ return getName(prefix + name, TYPE_PREFIX_FEATURE + getMetaDataManager().getMetaID(feature),
+ getMaxTableNameLength());
+ }
+
+ public String getFieldName(EStructuralFeature feature)
+ {
+ return getName(feature.getName(), TYPE_PREFIX_FEATURE + getMetaDataManager().getMetaID(feature),
+ getMaxFieldNameLength());
+ }
+
+ private String getName(String name, String suffix, int maxLength)
+ {
+ boolean forceNamesWithID = isForceNamesWithID();
+ if (store.getDBAdapter().isReservedWord(name))
+ {
+ forceNamesWithID = true;
+ }
+
+ if (name.length() > maxLength || forceNamesWithID)
+ {
+ suffix = NAME_SEPARATOR + suffix.replace('-', 'S');
+ int length = Math.min(name.length(), maxLength - suffix.length());
+ name = name.substring(0, length) + suffix;
+ }
+
+ return name;
+ }
+
+ // -- factories for mapping of classes, values, lists ------------------
+
+ public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
+ {
+ monitor.begin();
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ mapPackageUnits(packageUnits);
+ getStore().getDBAdapter().createTables(getModelTables(), connection);
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ private void mapPackageInfos(InternalCDOPackageInfo[] packageInfos)
+ {
+ for (InternalCDOPackageInfo packageInfo : packageInfos)
+ {
+ EPackage ePackage = packageInfo.getEPackage();
+ if (!CDOModelUtil.isCorePackage(ePackage))
+ {
+ mapClasses(EMFUtil.getPersistentClasses(ePackage));
+ }
+ }
+ }
+
+ private void mapClasses(EClass... eClasses)
+ {
+ for (EClass eClass : eClasses)
+ {
+ if (!(eClass.isInterface() || eClass.isAbstract()))
+ {
+ createClassMapping(eClass);
+ }
+ }
+ }
+
+ private void mapPackageUnits(InternalCDOPackageUnit[] packageUnits)
+ {
+ if (packageUnits != null && packageUnits.length != 0)
+ {
+ for (InternalCDOPackageUnit packageUnit : packageUnits)
+ {
+ mapPackageInfos(packageUnit.getPackageInfos());
+ }
+ }
+ }
+
+ private Set<IDBTable> getModelTables()
+ {
+ Set<IDBTable> tables = new HashSet<IDBTable>();
+
+ for (IClassMapping mapping : classMappings.values())
+ {
+ tables.addAll(mapping.getDBTables());
+ }
+
+ return tables;
+ }
+
+ private IClassMapping createClassMapping(EClass eClass)
+ {
+ IClassMapping mapping = doCreateClassMapping(eClass);
+
+ if (mapping != null)
+ {
+ classMappings.put(eClass, mapping);
+ }
+
+ return mapping;
+ }
+
+ protected abstract IClassMapping doCreateClassMapping(EClass eClass);
+
+ public final Map<EClass, IClassMapping> getClassMappings()
+ {
+ return classMappings;
+ }
+
+ public final IClassMapping getClassMapping(EClass eClass)
+ {
+ IClassMapping result = classMappings.get(eClass);
+ if (result != null)
+ {
+ return result;
+ }
+ else
+ {
+ // create class mapping on demand ...
+ return createClassMapping(eClass);
+ }
+ }
+
+ public ITypeMapping createValueMapping(EStructuralFeature feature)
+ {
+ CDOType type = CDOModelUtil.getType(feature.getEType());
+
+ if (type == CDOType.BOOLEAN || type == CDOType.BOOLEAN_OBJECT)
+ {
+ return new TypeMapping.TMBoolean(this, feature);
+ }
+ else if (type == CDOType.BYTE || type == CDOType.BYTE_OBJECT)
+ {
+ return new TypeMapping.TMByte(this, feature);
+ }
+ else if (type == CDOType.CHAR || type == CDOType.CHARACTER_OBJECT)
+ {
+ return new TypeMapping.TMCharacter(this, feature);
+ }
+ else if (type == CDOType.DATE)
+ {
+ return new TypeMapping.TMDate(this, feature);
+ }
+ else if (type == CDOType.DOUBLE || type == CDOType.DOUBLE_OBJECT)
+ {
+ return new TypeMapping.TMDouble(this, feature);
+ }
+ else if (type == CDOType.FLOAT || type == CDOType.FLOAT_OBJECT)
+ {
+ return new TypeMapping.TMFloat(this, feature);
+ }
+ else if (type == CDOType.INT || type == CDOType.INTEGER_OBJECT)
+ {
+ return new TypeMapping.TMInteger(this, feature);
+ }
+ else if (type == CDOType.LONG || type == CDOType.LONG_OBJECT)
+ {
+ return new TypeMapping.TMLong(this, feature);
+ }
+ else if (type == CDOType.OBJECT)
+ {
+ return new TypeMapping.TMObject(this, feature);
+ }
+ else if (type == CDOType.SHORT || type == CDOType.SHORT_OBJECT)
+ {
+ return new TypeMapping.TMShort(this, feature);
+ }
+ else if (type == CDOType.ENUM)
+ {
+ return new TypeMapping.TMEnum(this, feature);
+ }
+ else if (type == CDOType.STRING || type == CDOType.CUSTOM)
+ {
+ return new TypeMapping.TMString(this, feature);
+ }
+ else if (type == CDOType.BYTE_ARRAY)
+ {
+ return new TypeMapping.TMBytes(this, feature);
+ }
+
+ throw new ImplementationError("Unrecognized CDOType: " + type);
+ }
+
+ public final IListMapping createListMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ checkArg(feature.isMany(), "Only many-valued features allowed.");
+ IListMapping mapping = doCreateListMapping(containingClass, feature);
+ return mapping;
+ }
+
+ public abstract IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature);
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AttributeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AttributeMapping.java
deleted file mode 100644
index b1c1a05022..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AttributeMapping.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.ddl.IDBField;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-
-/**
- * @author Eike Stepper
- */
-public abstract class AttributeMapping extends FeatureMapping implements IAttributeMapping
-{
- private IDBField field;
-
- public AttributeMapping(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- field = classMapping.addField(feature, classMapping.getTable());
- }
-
- public IDBField getField()
- {
- return field;
- }
-
- public void appendValue(StringBuilder builder, InternalCDORevision revision)
- {
- IDBAdapter dbAdapter = getDBAdapter();
- Object value = getRevisionValue(revision);
- dbAdapter.appendValue(builder, field, value);
- }
-
- public void appendValue(StringBuilder builder, Object value)
- {
- IDBAdapter dbAdapter = getDBAdapter();
- Object dbValue = convertToDBType(value);
- dbAdapter.appendValue(builder, field, dbValue);
- }
-
- public Object getRevisionValue(InternalCDORevision revision)
- {
- EStructuralFeature feature = getFeature();
- return revision.getValue(feature);
- }
-
- public void extractValue(ResultSet resultSet, int column, InternalCDORevision revision)
- {
- try
- {
- Object value = getResultSetValue(resultSet, column);
- if (resultSet.wasNull())
- {
- value = null;
- }
-
- revision.setValue(getFeature(), value);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("AttributeMapping[feature={0}, field={1}]", getFeature(), getField());
- }
-
- protected abstract Object getResultSetValue(ResultSet resultSet, int column) throws SQLException;
-
- /**
- * Convert a value to a DB compatible format. Needs to be overridden by those AttributeMappings for which
- * <code>value.toString()</code> is not sufficient (e.g. for CDOID).
- */
- protected Object convertToDBType(Object value)
- {
- return value;
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMEnum extends AttributeMapping
- {
- public AMEnum(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getInt(column);
- // EEnum type = (EEnum)getFeature().getEType();
- // int value = resultSet.getInt(column);
- // return type.getEEnumLiteral(value);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMString extends AttributeMapping
- {
- public AMString(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getString(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMShort extends AttributeMapping
- {
- public AMShort(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getShort(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMObject extends AttributeMapping
- {
- public AMObject(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- long id = resultSet.getLong(column);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return CDOIDUtil.createLong(id);
- }
-
- @Override
- protected Object convertToDBType(Object value)
- {
- return CDODBUtil.getLong((CDOID)value);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMLong extends AttributeMapping
- {
- public AMLong(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getLong(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMInteger extends AttributeMapping
- {
- public AMInteger(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getInt(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMFloat extends AttributeMapping
- {
- public AMFloat(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getFloat(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMDouble extends AttributeMapping
- {
- public AMDouble(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getDouble(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMDate extends AttributeMapping
- {
- public AMDate(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getTimestamp(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMCharacter extends AttributeMapping
- {
- public AMCharacter(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- String str = resultSet.getString(column);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return str.charAt(0);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMByte extends AttributeMapping
- {
- public AMByte(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getByte(column);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class AMBoolean extends AttributeMapping
- {
- public AMBoolean(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
- {
- return resultSet.getBoolean(column);
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ClassMapping.java
deleted file mode 100644
index 396bfe58b6..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ClassMapping.java
+++ /dev/null
@@ -1,708 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOType;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IFeatureMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.DBStore;
-import org.eclipse.emf.cdo.server.internal.db.ToMany;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBIndex;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public abstract class ClassMapping implements IClassMapping
-{
- private MappingStrategy mappingStrategy;
-
- private EClass eClass;
-
- private IDBTable table;
-
- private Set<IDBTable> affectedTables = new HashSet<IDBTable>();
-
- private List<IAttributeMapping> attributeMappings;
-
- private List<IReferenceMapping> referenceMappings;
-
- private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
- {
- @Override
- protected FeatureDeltaWriter initialValue()
- {
- return new FeatureDeltaWriter();
- };
- };
-
- public ClassMapping(MappingStrategy mappingStrategy, EClass eClass, EStructuralFeature[] features)
- {
- this.mappingStrategy = mappingStrategy;
- this.eClass = eClass;
-
- String tableName = mappingStrategy.getTableName(eClass);
- table = addTable(tableName);
- initTable(table, hasFullRevisionInfo());
-
- if (features != null)
- {
- attributeMappings = createAttributeMappings(features);
- referenceMappings = createReferenceMappings(features);
-
- // // Special handling of CDOResource table
- // CDOResourceClass resourceClass = getResourceClass();
- // if (eClass == resourceClass)
- // {
- // // Create a unique ids to prevent duplicate resource paths
- // for (IAttributeMapping attributeMapping : attributeMappings)
- // {
- // if (attributeMapping.getFeature() == resourceClass.getCDOPathFeature())
- // {
- // IDBField versionField = table.getField(CDODBSchema.ATTRIBUTES_VERSION);
- // IDBField pathField = attributeMapping.getField();
- // pathField.setPrecision(760);// MYSQL key limitation 767
- // pathField.setNotNull(true);
- //
- // // Example: Currently a store can not specify that it does not support non-auditing mode!
- // if (false && !mappingStrategy.getStore().getRepository().isSupportingAudits())
- // {
- // // Create a unique ids to prevent duplicate resource paths
- // table.addIndex(IDBIndex.Type.UNIQUE, versionField, pathField);
- // }
- //
- // break;
- // }
- // }
- // }
- }
- }
-
- public MappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public EClass getEClass()
- {
- return eClass;
- }
-
- public IDBTable getTable()
- {
- return table;
- }
-
- public Set<IDBTable> getAffectedTables()
- {
- return affectedTables;
- }
-
- protected void initTable(IDBTable table, boolean full)
- {
- IDBField idField = table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true);
- if (full)
- {
- table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true);
- IDBField revisedField = table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true);
-
- table.addIndex(IDBIndex.Type.NON_UNIQUE, idField, revisedField);
- }
- }
-
- protected IDBTable addTable(String name)
- {
- IDBTable table = mappingStrategy.getStore().getDBSchema().addTable(name);
- affectedTables.add(table);
- return table;
- }
-
- protected IDBField addField(EStructuralFeature feature, IDBTable table) throws DBException
- {
- String fieldName = mappingStrategy.getFieldName(feature);
- DBType fieldType = getDBType(feature);
- int fieldLength = getDBLength(feature);
-
- IDBField field = table.addField(fieldName, fieldType, fieldLength);
- affectedTables.add(table);
- return field;
- }
-
- protected DBType getDBType(EStructuralFeature feature)
- {
- return DBStore.getDBType(feature.getEType());
- }
-
- protected int getDBLength(EStructuralFeature feature)
- {
- // Derby: The maximum length for a VARCHAR string is 32,672 characters.
- CDOType type = CDOModelUtil.getType(feature.getEType());
- return type == CDOType.STRING || type == CDOType.CUSTOM ? 32672 : IDBField.DEFAULT;
- }
-
- protected IDBAdapter getDBAdapter()
- {
- IDBStore store = mappingStrategy.getStore();
- return store.getDBAdapter();
- }
-
- public IFeatureMapping getFeatureMapping(EStructuralFeature feature)
- {
- if (feature instanceof EReference && mappingStrategy.getToMany() != ToMany.LIKE_ATTRIBUTES)
- {
- return getReferenceMapping(feature);
- }
-
- return getAttributeMapping(feature);
- }
-
- public List<IAttributeMapping> getAttributeMappings()
- {
- return attributeMappings;
- }
-
- public List<IReferenceMapping> getReferenceMappings()
- {
- return referenceMappings;
- }
-
- public IReferenceMapping getReferenceMapping(EStructuralFeature feature)
- {
- // TODO Optimize this?
- for (IReferenceMapping referenceMapping : referenceMappings)
- {
- if (referenceMapping.getFeature() == feature)
- {
- return referenceMapping;
- }
- }
-
- return null;
- }
-
- public IAttributeMapping getAttributeMapping(EStructuralFeature feature)
- {
- // TODO Optimize this?
- for (IAttributeMapping attributeMapping : attributeMappings)
- {
- if (attributeMapping.getFeature() == feature)
- {
- return attributeMapping;
- }
- }
-
- return null;
- }
-
- protected List<IAttributeMapping> createAttributeMappings(EStructuralFeature[] features)
- {
- List<IAttributeMapping> attributeMappings = new ArrayList<IAttributeMapping>();
- for (EStructuralFeature feature : features)
- {
- if (feature instanceof EReference)
- {
- if (!feature.isMany())
- {
- attributeMappings.add(createToOneReferenceMapping(feature));
- }
- }
- else
- {
- attributeMappings.add(createAttributeMapping(feature));
- }
- }
-
- return attributeMappings.isEmpty() ? null : attributeMappings;
- }
-
- protected List<IReferenceMapping> createReferenceMappings(EStructuralFeature[] features)
- {
- List<IReferenceMapping> referenceMappings = new ArrayList<IReferenceMapping>();
- for (EStructuralFeature feature : features)
- {
- if (feature instanceof EReference && feature.isMany())
- {
- referenceMappings.add(createReferenceMapping(feature));
- }
- }
-
- return referenceMappings.isEmpty() ? null : referenceMappings;
- }
-
- protected AttributeMapping createAttributeMapping(EStructuralFeature feature)
- {
- CDOType type = CDOModelUtil.getType(feature.getEType());
- if (type == CDOType.BOOLEAN || type == CDOType.BOOLEAN_OBJECT)
- {
- return new AttributeMapping.AMBoolean(this, feature);
- }
- else if (type == CDOType.BYTE || type == CDOType.BYTE_OBJECT)
- {
- return new AttributeMapping.AMByte(this, feature);
- }
- else if (type == CDOType.CHAR || type == CDOType.CHARACTER_OBJECT)
- {
- return new AttributeMapping.AMCharacter(this, feature);
- }
- else if (type == CDOType.DATE)
- {
- return new AttributeMapping.AMDate(this, feature);
- }
- else if (type == CDOType.DOUBLE || type == CDOType.DOUBLE_OBJECT)
- {
- return new AttributeMapping.AMDouble(this, feature);
- }
- else if (type == CDOType.FLOAT || type == CDOType.FLOAT_OBJECT)
- {
- return new AttributeMapping.AMFloat(this, feature);
- }
- else if (type == CDOType.INT || type == CDOType.INTEGER_OBJECT)
- {
- return new AttributeMapping.AMInteger(this, feature);
- }
- else if (type == CDOType.LONG || type == CDOType.LONG_OBJECT)
- {
- return new AttributeMapping.AMLong(this, feature);
- }
- else if (type == CDOType.OBJECT)
- {
- return new AttributeMapping.AMObject(this, feature);
- }
- else if (type == CDOType.SHORT || type == CDOType.SHORT_OBJECT)
- {
- return new AttributeMapping.AMShort(this, feature);
- }
- else if (type == CDOType.ENUM)
- {
- return new AttributeMapping.AMEnum(this, feature);
- }
- else if (type == CDOType.STRING || type == CDOType.CUSTOM)
- {
- return new AttributeMapping.AMString(this, feature);
- }
-
- throw new ImplementationError("Unrecognized CDOType: " + type);
- }
-
- protected ToOneReferenceMapping createToOneReferenceMapping(EStructuralFeature feature)
- {
- return new ToOneReferenceMapping(this, feature);
- }
-
- protected ReferenceMapping createReferenceMapping(EStructuralFeature feature)
- {
- return new ReferenceMapping(this, feature, ToMany.PER_REFERENCE);
- }
-
- public Object createReferenceMappingKey(EStructuralFeature feature)
- {
- return feature;
- }
-
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
- {
- try
- {
- // TODO Better monitoring
- monitor.begin(10);
-
- if (revision.getVersion() > 1 && hasFullRevisionInfo() && isAuditing())
- {
- writeRevisedRow(accessor, revision);
- }
-
- monitor.worked();
-
- if (revision.isResourceFolder() || revision.isResource())
- {
- checkDuplicateResources(accessor, revision);
- }
-
- monitor.worked();
-
- // Write attribute table always (even without modeled attributes!)
- writeAttributes(accessor, revision);
-
- monitor.worked();
-
- // Write reference tables only if they exist
- if (referenceMappings != null)
- {
- writeReferences(accessor, revision);
- }
-
- monitor.worked(7);
- }
- finally
- {
- monitor.done();
- }
- }
-
- private boolean isAuditing()
- {
- return mappingStrategy.getStore().getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
- }
-
- protected abstract void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision)
- throws IllegalStateException;
-
- public void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor)
- {
- try
- {
- monitor.begin();
- if (hasFullRevisionInfo())
- {
- if (isAuditing())
- {
- writeRevisedRow(accessor, id, revised);
- monitor.worked(1);
- }
- else
- {
- deleteRevision(accessor, id, monitor.fork(1));
- }
- }
-
- // TODO Handle !hasFullRevisionInfo() case
- }
- finally
- {
- monitor.done();
- }
- }
-
- protected void deleteRevision(IDBStoreAccessor accessor, CDOID id, OMMonitor monitor)
- {
- try
- {
- monitor.begin(2);
- deleteAttributes(accessor, id);
- monitor.worked(1);
- deleteReferences(accessor, id);
- monitor.worked(1);
- }
- finally
- {
- monitor.done();
- }
- }
-
- protected final void writeRevisedRow(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- accessor.getJDBCDelegate().updateRevisedForReplace(revision, this);
- }
-
- protected final void writeRevisedRow(IDBStoreAccessor accessor, CDOID id, long revised)
- {
- accessor.getJDBCDelegate().updateRevisedForDetach(id, revised, this);
- }
-
- protected final void writeAttributes(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- if (revision.getVersion() == 1 || isAuditing())
- {
- accessor.getJDBCDelegate().insertAttributes(revision, this);
- }
- else
- {
- accessor.getJDBCDelegate().updateAttributes(revision, this);
- }
- }
-
- protected final void deleteAttributes(IDBStoreAccessor accessor, CDOID id)
- {
- accessor.getJDBCDelegate().deleteAttributes(id, this);
- }
-
- protected final void deleteReferences(IDBStoreAccessor accessor, CDOID id)
- {
- if (referenceMappings != null)
- {
- for (IReferenceMapping referenceMapping : referenceMappings)
- {
- referenceMapping.deleteReference(accessor, id);
- }
- }
- }
-
- protected void writeReferences(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- if (mappingStrategy.getStore().getRevisionTemporality() == IStore.RevisionTemporality.NONE)
- {
- deleteReferences(accessor, revision.getID());
- }
-
- for (IReferenceMapping referenceMapping : referenceMappings)
- {
- referenceMapping.writeReference(accessor, revision);
- }
- }
-
- public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
- OMMonitor monitor)
- {
- monitor.begin();
- Async async = monitor.forkAsync();
-
- try
- {
- FeatureDeltaWriter writer = deltaWriter.get();
- writer.process(accessor, delta, created);
- }
- finally
- {
- async.stop();
- monitor.done();
- }
- }
-
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
- String where = mappingStrategy.createWhereClause(CDORevision.UNSPECIFIED_DATE);
- return readRevision(accessor, revision, where, referenceChunk);
- }
-
- public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
- int referenceChunk)
- {
- String where = mappingStrategy.createWhereClause(timeStamp);
- return readRevision(accessor, revision, where, referenceChunk);
- }
-
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
- int referenceChunk)
- {
- String where = CDODBSchema.ATTRIBUTES_VERSION + "=" + version;
- return readRevision(accessor, revision, where, referenceChunk);
- }
-
- /**
- * Read a revision.
- *
- * @return <code>true</code> if the revision has been read successfully.<br>
- * <code>false</code> if the revision does not exist in the DB.
- */
- protected boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, String where,
- int referenceChunk)
- {
- // Read attribute table always (even without modeled attributes!)
- boolean success = readAttributes(accessor, revision, where);
-
- // Read reference tables only if revision exists and if references exist
- if (success && referenceMappings != null)
- {
- readReferences(accessor, revision, referenceChunk);
- }
-
- return success;
- }
-
- /**
- * Read the revision's attributes from the DB.
- *
- * @return <code>true</code> if the revision has been read successfully.<br>
- * <code>false</code> if the revision does not exist in the DB.
- */
- protected final boolean readAttributes(IDBStoreAccessor accessor, InternalCDORevision revision, String where)
- {
- return accessor.getJDBCDelegate().selectRevisionAttributes(revision, this, where);
- }
-
- protected void readReferences(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
- for (IReferenceMapping referenceMapping : referenceMappings)
- {
- referenceMapping.readReference(accessor, revision, referenceChunk);
- }
- }
-
- private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
- {
- private CDOID id;
-
- private int newVersion;
-
- private long created;
-
- private IDBStoreAccessor accessor;
-
- private boolean updateContainer = false;
-
- private List<Pair<IAttributeMapping, Object>> attributeChanges;
-
- private int newContainingFeatureID;
-
- private CDOID newContainerID;
-
- private CDOID newResourceID;
-
- public FeatureDeltaWriter()
- {
- attributeChanges = new ArrayList<Pair<IAttributeMapping, Object>>();
- }
-
- protected void reset()
- {
- attributeChanges.clear();
- updateContainer = false;
- }
-
- public void process(IDBStoreAccessor a, CDORevisionDelta d, long c)
- {
- // set context
-
- reset();
- id = d.getID();
- newVersion = d.getDirtyVersion();
- created = c;
- accessor = a;
-
- // process revision delta tree
- d.accept(this);
-
- // update attributes
- if (updateContainer)
- {
- accessor.getJDBCDelegate().updateAttributes(id, newVersion, created, newContainerID, newContainingFeatureID,
- newResourceID, attributeChanges, ClassMapping.this);
- }
- else
- {
- accessor.getJDBCDelegate().updateAttributes(id, newVersion, created, attributeChanges, ClassMapping.this);
- }
-
- // update version number of all references to current version
- if (referenceMappings != null)
- {
- for (IReferenceMapping referenceMapping : getReferenceMappings())
- {
- referenceMapping.updateReferenceVersion(accessor, id, newVersion);
- }
- }
- }
-
- public void visit(CDOMoveFeatureDelta delta)
- {
- getReferenceMapping(delta.getFeature()).moveReferenceEntry(accessor, id, newVersion, delta.getOldPosition(),
- delta.getNewPosition());
- }
-
- public void visit(CDOSetFeatureDelta delta)
- {
- if (delta.getFeature().isMany())
- {
- IReferenceMapping rm = getReferenceMapping(delta.getFeature());
- if (rm == null)
- {
- throw new IllegalArgumentException("ReferenceMapping for " + delta.getFeature() + " is null!");
- }
- rm.updateReference(accessor, id, newVersion, delta.getIndex(), (CDOID)delta.getValue());
- }
- else
- {
- IAttributeMapping am = getAttributeMapping(delta.getFeature());
- if (am == null)
- {
- throw new IllegalArgumentException("AttributeMapping for " + delta.getFeature() + " is null!");
- }
- attributeChanges.add(new Pair<IAttributeMapping, Object>(am, delta.getValue()));
- }
- }
-
- public void visit(CDOUnsetFeatureDelta delta)
- {
- // TODO Correct this when DBStore implements unsettable features
- // see Bugs 259868 and 263010
- IAttributeMapping am = getAttributeMapping(delta.getFeature());
- attributeChanges.add(new Pair<IAttributeMapping, Object>(am, null));
- }
-
- public void visit(CDOListFeatureDelta delta)
- {
- for (CDOFeatureDelta listChange : delta.getListChanges())
- {
- listChange.accept(this);
- }
- }
-
- public void visit(CDOClearFeatureDelta delta)
- {
- getReferenceMapping(delta.getFeature()).deleteReference(accessor, id);
- }
-
- public void visit(CDOAddFeatureDelta delta)
- {
- getReferenceMapping(delta.getFeature()).insertReferenceEntry(accessor, id, newVersion, delta.getIndex(),
- (CDOID)delta.getValue());
- }
-
- public void visit(CDORemoveFeatureDelta delta)
- {
- getReferenceMapping(delta.getFeature()).removeReferenceEntry(accessor, id, delta.getIndex(), newVersion);
- }
-
- public void visit(CDOContainerFeatureDelta delta)
- {
- newContainingFeatureID = delta.getContainerFeatureID();
- newContainerID = (CDOID)delta.getContainerID();
- newResourceID = delta.getResourceID();
- updateContainer = true;
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/FeatureMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/FeatureMapping.java
deleted file mode 100644
index 58bfd68d77..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/FeatureMapping.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.net4j.db.IDBAdapter;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- */
-public class FeatureMapping
-{
- private ClassMapping classMapping;
-
- private EStructuralFeature feature;
-
- public FeatureMapping(ClassMapping classMapping, EStructuralFeature feature)
- {
- this.classMapping = classMapping;
- this.feature = feature;
- }
-
- public ClassMapping getClassMapping()
- {
- return classMapping;
- }
-
- public EStructuralFeature getFeature()
- {
- return feature;
- }
-
- protected IDBAdapter getDBAdapter()
- {
- return getClassMapping().getMappingStrategy().getStore().getDBAdapter();
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalClassMapping.java
deleted file mode 100644
index fb92edc5f6..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalClassMapping.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.text.MessageFormat;
-
-/**
- * @author Eike Stepper
- */
-public class HorizontalClassMapping extends ClassMapping
-{
- public HorizontalClassMapping(HorizontalMappingStrategy mappingStrategy, EClass eClass)
- {
- super(mappingStrategy, eClass, CDOModelUtil.getAllPersistentFeatures(eClass));
- }
-
- @Override
- public HorizontalMappingStrategy getMappingStrategy()
- {
- return (HorizontalMappingStrategy)super.getMappingStrategy();
- }
-
- @Override
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
- {
- try
- {
- monitor.begin(5);
- super.writeRevision(accessor, revision, monitor.fork(4));
- if (revision.getVersion() == 1)
- {
- CDOID id = revision.getID();
- EClass type = revision.getEClass();
- getMappingStrategy().getObjectTypeCache().putObjectType(accessor, id, type);
- }
-
- // TODO Better monitoring
- monitor.worked();
- }
- finally
- {
- monitor.done();
- }
- }
-
- @Override
- protected void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
- {
- CDOID folderID = (CDOID)revision.data().getContainerID();
- String name = (String)revision.data().get(EresourcePackage.eINSTANCE.getCDOResourceNode_Name(), 0);
-
- CDOID existingID = accessor.readResourceID(folderID, name, revision.getCreated());
- if (existingID != null && !existingID.equals(revision.getID()))
- {
- throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID);
- }
- }
-
- @Override
- public Object createReferenceMappingKey(EStructuralFeature feature)
- {
- return new Pair<EClass, EStructuralFeature>(getEClass(), feature);
- }
-
- public boolean hasFullRevisionInfo()
- {
- return true;
- }
-
- @Override
- protected void deleteRevision(IDBStoreAccessor accessor, CDOID id, OMMonitor monitor)
- {
- try
- {
- monitor.begin(2);
- super.deleteRevision(accessor, id, monitor.fork(1));
- getMappingStrategy().getObjectTypeCache().removeObjectType(accessor, id);
- monitor.worked(1);
- }
- finally
- {
- monitor.done();
- }
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("HorizontalClassMapping[class={0}, table={1}]", getEClass(), getTable());
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalMappingStrategy.java
deleted file mode 100644
index 8b9da80ff1..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/HorizontalMappingStrategy.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IObjectTypeCache;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.ObjectTypeCache;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EPackage;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class HorizontalMappingStrategy extends MappingStrategy
-{
- private IObjectTypeCache objectTypeCache;
-
- public HorizontalMappingStrategy()
- {
- }
-
- public String getType()
- {
- return "horizontal";
- }
-
- public IObjectTypeCache getObjectTypeCache()
- {
- return objectTypeCache;
- }
-
- public void setObjectTypeCache(IObjectTypeCache objectTypeCache)
- {
- this.objectTypeCache = objectTypeCache;
- }
-
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- return objectTypeCache.getObjectType(accessor, id);
- }
-
- /**
- * TODO Stefan: Is this method still needed?
- */
- @Deprecated
- protected final CDOClassifierRef readObjectTypeFromClassesWithObjectInfo(IDBStoreAccessor accessor, CDOID id)
- {
- // String prefix = "SELECT DISTINCT " + CDODBSchema.ATTRIBUTES_CLASS + " FROM ";
- // String suffix = " WHERE " + CDODBSchema.ATTRIBUTES_ID + "=" + id;
- // for (EClass eClass : getClassesWithObjectInfo())
- // {
- // IClassMapping mapping = getClassMapping(eClass);
- // if (mapping != null)
- // {
- // IDBTable table = mapping.getTable();
- // if (table != null)
- // {
- // String sql = prefix + table + suffix;
- // if (TRACER.isEnabled())
- // {
- // TRACER.trace(sql);
- // }
- //
- // ResultSet resultSet = null;
- //
- // try
- // {
- // resultSet = accessor.getJDBCDelegate().getStatement().executeQuery(sql);
- // if (resultSet.next())
- // {
- // int classID = resultSet.getInt(1);
- // return getClassifierRef(accessor, classID);
- // }
- // }
- // catch (SQLException ex)
- // {
- // throw new DBException(ex);
- // }
- // finally
- // {
- // DBUtil.close(resultSet);
- // }
- // }
- // }
- // }
-
- throw new DBException("No object with id " + id);
- }
-
- @Override
- protected IClassMapping createClassMapping(EClass eClass)
- {
- if (eClass.isAbstract() || eClass.isInterface())
- {
- return null;
- }
-
- return new HorizontalClassMapping(this, eClass);
- }
-
- @Override
- protected List<EClass> getClassesWithObjectInfo()
- {
- List<EClass> result = new ArrayList<EClass>();
- InternalCDOPackageRegistry packageRegistry = (InternalCDOPackageRegistry)getStore().getRepository()
- .getPackageRegistry();
- for (EPackage ePackage : packageRegistry.getEPackages())
- {
- for (EClass eClass : EMFUtil.getConcreteClasses(ePackage))
- {
- // if (!CDOModelUtil.isRoot(eClass))
- {
- result.add(eClass);
- }
- }
- }
-
- return result;
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- if (objectTypeCache == null)
- {
- objectTypeCache = createObjectTypeCache(getStore());
- LifecycleUtil.activate(objectTypeCache);
- }
- }
-
- @Override
- protected String[] getResourceQueries(CDOID folderID, String name, boolean exactMatch)
- {
- String[] queries = new String[2];
-
- IClassMapping resourceFolderMapping = getClassMapping(EresourcePackage.eINSTANCE.getCDOResourceFolder());
- queries[0] = getResourceQuery(folderID, name, exactMatch, resourceFolderMapping);
-
- IClassMapping resourceMapping = getClassMapping(EresourcePackage.eINSTANCE.getCDOResource());
- queries[1] = getResourceQuery(folderID, name, exactMatch, resourceMapping);
-
- return queries;
- }
-
- protected String getResourceQuery(CDOID folderID, String name, boolean exactMatch, IClassMapping classMapping)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM ");
- builder.append(classMapping.getTable());
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append("=");
- builder.append(CDOIDUtil.getLong(folderID));
- if (exactMatch || name != null)
- {
- builder.append(" AND ");
- builder.append(classMapping.getAttributeMapping(EresourcePackage.eINSTANCE.getCDOResourceNode_Name()).getField());
- if (exactMatch)
- {
- if (name == null)
- {
- builder.append(" IS NULL");
- }
- else
- {
- builder.append("=\'");
- builder.append(name);
- builder.append("\'");
- }
- }
- else
- {
- // Here: name != null
- builder.append(" LIKE \'");
- builder.append(name);
- builder.append("%\'");
- }
- }
-
- String sql = builder.toString();
- return sql;
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(objectTypeCache);
- objectTypeCache = null;
- super.doDeactivate();
- }
-
- protected IObjectTypeCache createObjectTypeCache(IDBStore store)
- {
- ObjectTypeCache cache = new ObjectTypeCache();
- cache.setMappingStrategy(this);
- return cache;
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/MappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/MappingStrategy.java
deleted file mode 100644
index fe5e0d6585..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/MappingStrategy.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Victor Roldan Betancort - http://bugs.eclipse.org/208689
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.ObjectIDIterator;
-import org.eclipse.emf.cdo.server.internal.db.ToMany;
-import org.eclipse.emf.cdo.server.internal.db.ToOne;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.StringUtil;
-import org.eclipse.net4j.util.collection.CloseableIterator;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public abstract class MappingStrategy extends Lifecycle implements IMappingStrategy
-{
- public static final String NAME_SEPARATOR = "_";
-
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, MappingStrategy.class);
-
- private IDBStore store;
-
- private Map<String, String> properties;
-
- private Map<Object, IDBTable> referenceTables = new HashMap<Object, IDBTable>();
-
- private Map<EClass, IClassMapping> classMappings = new HashMap<EClass, IClassMapping>();
-
- public MappingStrategy()
- {
- }
-
- public IDBStore getStore()
- {
- return store;
- }
-
- public void setStore(IDBStore store)
- {
- this.store = store;
- }
-
- public synchronized Map<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new HashMap<String, String>();
- }
-
- return properties;
- }
-
- public synchronized void setProperties(Map<String, String> properties)
- {
- this.properties = properties;
- }
-
- public int getMaxTableNameLength()
- {
- String value = getProperties().get(PROP_MAX_TABLE_NAME_LENGTH);
- return value == null ? store.getDBAdapter().getMaxTableNameLength() : Integer.valueOf(value);
- }
-
- public int getMaxFieldNameLength()
- {
- String value = getProperties().get(PROP_MAX_FIELD_NAME_LENGTH);
- return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value);
- }
-
- public String getTableNamePrefix()
- {
- String value = getProperties().get(PROP_TABLE_NAME_PREFIX);
- return StringUtil.safe(value);
- }
-
- public boolean isQualifiedNames()
- {
- String value = getProperties().get(PROP_QUALIFIED_NAMES);
- return value == null ? false : Boolean.valueOf(value);
- }
-
- public boolean isForceNamesWithID()
- {
- String value = getProperties().get(PROP_FORCE_NAMES_WITH_ID);
- return value == null ? false : Boolean.valueOf(value);
- }
-
- public ToMany getToMany()
- {
- String value = getProperties().get(PROP_TO_MANY_REFERENCE_MAPPING);
- return value == null ? ToMany.PER_REFERENCE : ToMany.valueOf(value);
- }
-
- public ToOne getToOne()
- {
- String value = getProperties().get(PROP_TO_ONE_REFERENCE_MAPPING);
- return value == null ? ToOne.LIKE_ATTRIBUTES : ToOne.valueOf(value);
- }
-
- public Map<Object, IDBTable> getReferenceTables()
- {
- return referenceTables;
- }
-
- public IClassMapping getClassMapping(EClass eClass)
- {
- synchronized (classMappings)
- {
- IClassMapping mapping = classMappings.get(eClass);
- if (mapping == null)
- {
- mapping = createClassMapping(eClass);
- classMappings.put(eClass, mapping);
- }
-
- if (mapping == NoClassMapping.INSTANCE)
- {
- return null;
- }
-
- return mapping;
- }
- }
-
- public String getTableName(EPackage ePackage)
- {
- String name = isQualifiedNames() ? EMFUtil.getQualifiedName(ePackage, NAME_SEPARATOR) : ePackage.getName();
- return getTableName(name, "P" + getStore().getMetaID(ePackage));
- }
-
- public String getTableName(EClass eClass)
- {
- String name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName();
- return getTableName(name, "C" + getStore().getMetaID(eClass));
- }
-
- public String getReferenceTableName(EClass eClass, EStructuralFeature feature)
- {
- String name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName();
- name += NAME_SEPARATOR;
- name += feature.getName();
- name += "_refs";
- return getTableName(name, "F" + getStore().getMetaID(feature));
- }
-
- public String getReferenceTableName(EClass eClass)
- {
- String name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName();
- name += "_refs";
- return getTableName(name, "F" + getStore().getMetaID(eClass));
- }
-
- public String getReferenceTableName(EPackage ePackage)
- {
- String name = isQualifiedNames() ? EMFUtil.getQualifiedName(ePackage, NAME_SEPARATOR) : ePackage.getName();
- name += "_refs";
- return getTableName(name, "F" + getStore().getMetaID(ePackage));
- }
-
- public String getFieldName(EStructuralFeature feature)
- {
- return getName(feature.getName(), "F" + getStore().getMetaID(feature), getMaxFieldNameLength());
- }
-
- private String getTableName(String name, String suffix)
- {
- String prefix = getTableNamePrefix();
- if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR))
- {
- prefix += NAME_SEPARATOR;
- }
-
- return getName(prefix + name, suffix, getMaxTableNameLength());
- }
-
- private String getName(String name, String suffix, int maxLength)
- {
- boolean forceNamesWithID = isForceNamesWithID();
- if (store.getDBAdapter().isReservedWord(name))
- {
- forceNamesWithID = true;
- }
-
- if (name.length() > maxLength || forceNamesWithID)
- {
- suffix = NAME_SEPARATOR + suffix.replace('-', 'S');
- int length = Math.min(name.length(), maxLength - suffix.length());
- name = name.substring(0, length) + suffix;
- }
-
- return name;
- }
-
- public String createWhereClause(long timeStamp)
- {
- StringBuilder builder = new StringBuilder();
- if (timeStamp == CDORevision.UNSPECIFIED_DATE)
- {
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0");
- }
- else
- {
- builder.append("(");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0 OR ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(">=");
- builder.append(timeStamp);
- builder.append(") AND ");
- builder.append(timeStamp);
- builder.append(">=");
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- }
-
- return builder.toString();
- }
-
- public final CloseableIterator<CDOID> readObjectIDs(final IDBStoreAccessor accessor)
- {
- List<EClass> classes = getClassesWithObjectInfo();
- final Iterator<EClass> classIt = classes.iterator();
- return new ObjectIDIterator(this, accessor)
- {
- @Override
- protected ResultSet getNextResultSet()
- {
- while (classIt.hasNext())
- {
- EClass eClass = classIt.next();
- IClassMapping mapping = getClassMapping(eClass);
- if (mapping != null)
- {
- IDBTable table = mapping.getTable();
- if (table != null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT DISTINCT ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM ");
- builder.append(table);
- String sql = builder.toString();
-
- try
- {
- return accessor.getJDBCDelegate().getStatement().executeQuery(sql);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
- }
- }
-
- return null;
- }
- };
- }
-
- public final void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context)
- {
- CDOID folderID = context.getFolderID();
- String name = context.getName();
- boolean exactMatch = context.exactMatch();
- String where = createWhereClause(context.getTimeStamp());
-
- String[] queries = getResourceQueries(folderID, name, exactMatch);
- for (String query : queries)
- {
- StringBuilder builder = new StringBuilder();
- builder.append(query);
- builder.append(" AND (");
- builder.append(where);
- builder.append(")");
-
- String sql = builder.toString();
- if (TRACER.isEnabled())
- {
- TRACER.trace(sql);
- }
-
- ResultSet resultSet = null;
-
- try
- {
- resultSet = accessor.getJDBCDelegate().getStatement().executeQuery(sql);
- while (resultSet.next())
- {
- long longID = resultSet.getLong(1);
- CDOID id = CDOIDUtil.createLong(longID);
- if (!context.addResource(id))
- {
- // No more results allowed
- return;
- }
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- }
- }
- }
-
- protected abstract String[] getResourceQueries(CDOID folderID, String name, boolean exactMatch);
-
- public long repairAfterCrash(IDBAdapter dbAdapter, Connection connection)
- {
- long maxCDOID = 0L;
- for (EClass idClass : getClassesWithObjectInfo())
- {
- IClassMapping classMapping = getClassMapping(idClass);
- IDBTable table = classMapping.getTable();
- IDBField idField = table.getField(CDODBSchema.ATTRIBUTES_ID);
- long classMaxCDOID = DBUtil.selectMaximumLong(connection, idField);
- if (TRACER.isEnabled())
- {
- TRACER.format("Max CDOID of table {0}: {1}", table, classMaxCDOID);
- }
-
- maxCDOID = Math.max(maxCDOID, classMaxCDOID);
- }
-
- return maxCDOID + 2L;
- }
-
- @Override
- public String toString()
- {
- return getType();
- }
-
- /**
- * The implementation of this method must take care of creating a unique ids to prevent duplicate resource paths.
- */
- protected abstract IClassMapping createClassMapping(EClass eClass);
-
- protected abstract List<EClass> getClassesWithObjectInfo();
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkState(store, "store");
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/NoClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/NoClassMapping.java
deleted file mode 100644
index d6f286f2e7..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/NoClassMapping.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IAttributeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IFeatureMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class NoClassMapping implements IClassMapping
-{
- public static final IClassMapping INSTANCE = new NoClassMapping();
-
- private NoClassMapping()
- {
- }
-
- public IMappingStrategy getMappingStrategy()
- {
- return null;
- }
-
- public EClass getEClass()
- {
- return null;
- }
-
- public IDBTable getTable()
- {
- return null;
- }
-
- public Set<IDBTable> getAffectedTables()
- {
- return Collections.emptySet();
- }
-
- public boolean hasFullRevisionInfo()
- {
- return false;
- }
-
- public IFeatureMapping getFeatureMapping(EStructuralFeature feature)
- {
- return null;
- }
-
- public List<IAttributeMapping> getAttributeMappings()
- {
- return null;
- }
-
- public List<IReferenceMapping> getReferenceMappings()
- {
- return null;
- }
-
- public IAttributeMapping getAttributeMapping(EStructuralFeature feature)
- {
- return null;
- }
-
- public IReferenceMapping getReferenceMapping(EStructuralFeature feature)
- {
- return null;
- }
-
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
- {
- }
-
- public void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor)
- {
- }
-
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
- return false;
- }
-
- public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
- int referenceChunk)
- {
- return false;
- }
-
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
- int referenceChunk)
- {
- return false;
- }
-
- public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
- OMMonitor monitor)
- {
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ReferenceMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ReferenceMapping.java
deleted file mode 100644
index 026b63b6a6..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ReferenceMapping.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegate;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.ToMany;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.db.ddl.IDBIndex.Type;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public class ReferenceMapping extends FeatureMapping implements IReferenceMapping
-{
- private IDBTable table;
-
- private ToMany toMany;
-
- private boolean withFeature;
-
- public ReferenceMapping(ClassMapping classMapping, EStructuralFeature feature, ToMany toMany)
- {
- super(classMapping, feature);
- this.toMany = toMany;
- mapReference(classMapping.getEClass(), feature);
- }
-
- public IDBTable getTable()
- {
- return table;
- }
-
- public boolean isWithFeature()
- {
- return withFeature;
- }
-
- protected void mapReference(EClass eClass, EStructuralFeature feature)
- {
- MappingStrategy mappingStrategy = getClassMapping().getMappingStrategy();
- switch (toMany)
- {
- case PER_REFERENCE:
- {
- withFeature = false;
- String tableName = mappingStrategy.getReferenceTableName(eClass, feature);
- Object referenceMappingKey = getReferenceMappingKey(feature);
- table = mapReferenceTable(referenceMappingKey, tableName);
- break;
- }
-
- case PER_CLASS:
- withFeature = true;
- table = mapReferenceTable(eClass, mappingStrategy.getReferenceTableName(eClass));
- break;
-
- case PER_PACKAGE:
- withFeature = true;
- EPackage ePackage = eClass.getEPackage();
- table = mapReferenceTable(ePackage, mappingStrategy.getReferenceTableName(ePackage));
- break;
-
- case PER_REPOSITORY:
- withFeature = true;
- IRepository repository = mappingStrategy.getStore().getRepository();
- table = mapReferenceTable(repository, repository.getName() + "_refs");
- break;
-
- default:
- throw new IllegalArgumentException("Invalid mapping: " + toMany);
- }
- }
-
- protected Object getReferenceMappingKey(EStructuralFeature feature)
- {
- return getClassMapping().createReferenceMappingKey(feature);
- }
-
- protected IDBTable mapReferenceTable(Object key, String tableName)
- {
- Map<Object, IDBTable> referenceTables = getClassMapping().getMappingStrategy().getReferenceTables();
- IDBTable table = referenceTables.get(key);
- if (table == null)
- {
- table = addReferenceTable(tableName);
- referenceTables.put(key, table);
- }
-
- return table;
- }
-
- protected IDBTable addReferenceTable(String tableName)
- {
- IDBTable table = getClassMapping().addTable(tableName);
- if (withFeature)
- {
- table.addField(CDODBSchema.REFERENCES_FEATURE, DBType.BIGINT);
- }
-
- IDBField sourceField = table.addField(CDODBSchema.REFERENCES_SOURCE, DBType.BIGINT);
- IDBField versionField = table.addField(CDODBSchema.REFERENCES_VERSION, DBType.INTEGER);
- IDBField idxField = table.addField(CDODBSchema.REFERENCES_IDX, DBType.INTEGER);
- table.addField(CDODBSchema.REFERENCES_TARGET, DBType.BIGINT);
-
- table.addIndex(Type.NON_UNIQUE, sourceField, versionField);
- table.addIndex(Type.NON_UNIQUE, idxField);
- return table;
- }
-
- public final void writeReference(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- int idx = 0;
- for (Object element : revision.getList(getFeature()))
- {
- writeReferenceEntry(accessor, revision.getID(), revision.getVersion(), idx++, (CDOID)element);
- }
- }
-
- public final void writeReferenceEntry(IDBStoreAccessor accessor, CDOID id, int version, int idx, CDOID targetId)
- {
- IJDBCDelegate jdbcDelegate = accessor.getJDBCDelegate();
- jdbcDelegate.insertReference(id, version, idx++, targetId, this);
- }
-
- public void insertReferenceEntry(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, CDOID value)
- {
- accessor.getJDBCDelegate().insertReferenceRow(id, newVersion, index, value, this);
- }
-
- public void moveReferenceEntry(IDBStoreAccessor accessor, CDOID id, int newVersion, int oldPosition, int newPosition)
- {
- accessor.getJDBCDelegate().moveReferenceRow(id, newVersion, oldPosition, newPosition, this);
- }
-
- public void removeReferenceEntry(IDBStoreAccessor accessor, CDOID id, int index, int newVersion)
- {
- accessor.getJDBCDelegate().removeReferenceRow(id, index, newVersion, this);
- }
-
- public void updateReference(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, CDOID value)
- {
- accessor.getJDBCDelegate().updateReference(id, newVersion, index, value, this);
- }
-
- public void updateReferenceVersion(IDBStoreAccessor accessor, CDOID id, int newVersion)
- {
- accessor.getJDBCDelegate().updateReferenceVersion(id, newVersion, this);
- }
-
- public void deleteReference(IDBStoreAccessor accessor, CDOID id)
- {
- accessor.getJDBCDelegate().deleteReferences(id, this);
- }
-
- public final void readReference(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
- accessor.getJDBCDelegate().selectRevisionReferences(revision, this, referenceChunk);
- }
-
- public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where)
- {
- chunkReader.getAccessor().getJDBCDelegate().selectRevisionReferenceChunks(chunkReader, chunks, this, where);
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("ReferenceMapping[feature={0}, table={1}]", getFeature(), getTable());
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/RootClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/RootClassMapping.java
deleted file mode 100644
index ac16396199..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/RootClassMapping.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-
-import org.eclipse.emf.ecore.EcorePackage;
-
-/**
- * @author Eike Stepper
- */
-public class RootClassMapping extends ClassMapping
-{
- public RootClassMapping(VerticalMappingStrategy mappingStrategy)
- {
- super(mappingStrategy, EcorePackage.eINSTANCE.getEObject(), null);
- initTable(getTable(), true);
- }
-
- @Override
- public VerticalMappingStrategy getMappingStrategy()
- {
- return (VerticalMappingStrategy)super.getMappingStrategy();
- }
-
- public boolean hasFullRevisionInfo()
- {
- return true;
- }
-
- @Override
- protected void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
- {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ToOneReferenceMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ToOneReferenceMapping.java
deleted file mode 100644
index 634698a652..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/ToOneReferenceMapping.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- */
-public class ToOneReferenceMapping extends AttributeMapping.AMObject
-{
- public ToOneReferenceMapping(ClassMapping classMapping, EStructuralFeature feature)
- {
- super(classMapping, feature);
- }
-
- @Override
- public Long getRevisionValue(InternalCDORevision revision)
- {
- CDOID id = (CDOID)super.getRevisionValue(revision);
- return CDODBUtil.getLong(id);
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
new file mode 100644
index 0000000000..697e080113
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
@@ -0,0 +1,409 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.MetaDataManager;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+
+/**
+ * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common
+ * types.
+ *
+ * @author Eike Stepper
+ */
+public abstract class TypeMapping implements ITypeMapping
+{
+ private IMappingStrategy mappingStrategy;
+
+ private EStructuralFeature feature;
+
+ private IDBField field;
+
+ /**
+ * Create a new type mapping
+ *
+ * @param mappingStrategy
+ * the associated mapping strategy.
+ * @param feature
+ * the feature to be mapped.
+ */
+ public TypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature)
+ {
+ this.mappingStrategy = mappingStrategy;
+ this.feature = feature;
+ }
+
+ public final void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision revision)
+ throws SQLException
+ {
+ setValue(stmt, index, getRevisionValue(revision));
+ }
+
+ public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ if (value == null)
+ {
+ stmt.setNull(index, getSqlType());
+ }
+ else
+ {
+ doSetValue(stmt, index, value);
+ }
+ }
+
+ public final void createDBField(IDBTable table)
+ {
+ createDBField(table, mappingStrategy.getFieldName(feature));
+ }
+
+ public final void createDBField(IDBTable table, String fieldName)
+ {
+ DBType fieldType = getDBType();
+ int fieldLength = getDBLength(fieldType);
+ field = table.addField(fieldName, fieldType, fieldLength);
+ }
+
+ public final IDBField getField()
+ {
+ return field;
+ }
+
+ public final void readValueToRevision(ResultSet resultSet, int index, InternalCDORevision revision)
+ throws SQLException
+ {
+ Object value = readValue(resultSet, index);
+ revision.setValue(getFeature(), value);
+ }
+
+ public final Object readValue(ResultSet resultSet, int index) throws SQLException
+ {
+ Object value = getResultSetValue(resultSet, index);
+ if (resultSet.wasNull())
+ {
+ value = null;
+ }
+ return value;
+ }
+
+ public final EStructuralFeature getFeature()
+ {
+ return feature;
+ }
+
+ protected final Object getRevisionValue(InternalCDORevision revision)
+ {
+ return revision.getValue(getFeature());
+ }
+
+ protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ stmt.setObject(index, value, getSqlType());
+ }
+
+ /**
+ * Returns the SQL type of this TypeMapping. The default implementation considers the type map hold by the meta-data
+ * manager (@see {@link MetaDataManager#getDBType(org.eclipse.emf.ecore.EClassifier)} Subclasses may override.
+ *
+ * @return The sql type of this TypeMapping.
+ */
+ protected int getSqlType()
+ {
+ return getDBType().getCode();
+ }
+
+ protected DBType getDBType()
+ {
+ return mappingStrategy.getStore().getMetaDataManager().getDBType(feature.getEType());
+ }
+
+ protected int getDBLength(DBType type)
+ {
+ // TODO: implement DBAdapter.getDBLength
+ // mappingStrategy.getStore().getDBAdapter().getDBLength(type);
+ return type == DBType.VARCHAR ? 32672 : IDBField.DEFAULT;
+ }
+
+ protected abstract Object getResultSetValue(ResultSet resultSet, int column) throws SQLException;
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMEnum extends TypeMapping
+ {
+ public TMEnum(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ // see Bug 271941
+ return resultSet.getInt(column);
+ // EEnum type = (EEnum)getFeature().getEType();
+ // int value = resultSet.getInt(column);
+ // return type.getEEnumLiteral(value);
+ }
+
+ @Override
+ protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ super.doSetValue(stmt, index, value);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMString extends TypeMapping
+ {
+ public TMString(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getString(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMShort extends TypeMapping
+ {
+ public TMShort(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getShort(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper <br>
+ * TODO add mapping/unmapping calls for external references here
+ */
+ public static class TMObject extends TypeMapping
+ {
+ public TMObject(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ long id = resultSet.getLong(column);
+ if (resultSet.wasNull())
+ {
+ return null;
+ }
+
+ return CDOIDUtil.createLong(id);
+ }
+
+ @Override
+ protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ super.doSetValue(stmt, index, CDODBUtil.getLong((CDOID)value));
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMLong extends TypeMapping
+ {
+ public TMLong(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getLong(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMInteger extends TypeMapping
+ {
+ public TMInteger(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getInt(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMFloat extends TypeMapping
+ {
+ public TMFloat(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getFloat(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMDouble extends TypeMapping
+ {
+ public TMDouble(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getDouble(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMDate extends TypeMapping
+ {
+ public TMDate(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getTimestamp(column);
+ }
+
+ @Override
+ protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ stmt.setTimestamp(index, new Timestamp(((Date)value).getTime()));
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMCharacter extends TypeMapping
+ {
+ public TMCharacter(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ String str = resultSet.getString(column);
+ if (resultSet.wasNull())
+ {
+ return null;
+ }
+
+ return str.charAt(0);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMByte extends TypeMapping
+ {
+ public TMByte(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getByte(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMBytes extends TypeMapping
+ {
+ public TMBytes(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getBytes(column);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class TMBoolean extends TypeMapping
+ {
+ public TMBoolean(IMappingStrategy strategy, EStructuralFeature feature)
+ {
+ super(strategy, feature);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
+ {
+ return resultSet.getBoolean(column);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalClassMapping.java
deleted file mode 100644
index 7fdd2d4995..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalClassMapping.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class VerticalClassMapping extends ClassMapping
-{
- private List<IClassMapping> superMappings;
-
- public VerticalClassMapping(VerticalMappingStrategy mappingStrategy, EClass eClass)
- {
- super(mappingStrategy, eClass, null);
- for (EClass superType : eClass.getESuperTypes())
- {
- IClassMapping superMapping = mappingStrategy.getClassMapping(superType);
- if (superMapping != null)
- {
- if (superMappings == null)
- {
- superMappings = new ArrayList<IClassMapping>(0);
- }
-
- superMappings.add(superMapping);
- }
- }
- }
-
- @Override
- public VerticalMappingStrategy getMappingStrategy()
- {
- return (VerticalMappingStrategy)super.getMappingStrategy();
- }
-
- public boolean hasFullRevisionInfo()
- {
- return false;
- }
-
- public List<IClassMapping> getSuperMappings()
- {
- return superMappings;
- }
-
- @Override
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
- {
- if (superMappings != null)
- {
- try
- {
- monitor.begin(1 + superMappings.size());
- super.writeRevision(accessor, revision, monitor.fork());
- for (IClassMapping superMapping : superMappings)
- {
- superMapping.writeRevision(accessor, revision, monitor.fork());
- }
- }
- finally
- {
- monitor.done();
- }
- }
- else
- {
- super.writeRevision(accessor, revision, monitor);
- }
- }
-
- @Override
- protected void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
- {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalMappingStrategy.java
deleted file mode 100644
index 34dd89aed3..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/VerticalMappingStrategy.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class VerticalMappingStrategy extends MappingStrategy
-{
- private RootClassMapping rootClassMapping;
-
- public VerticalMappingStrategy()
- {
- throw new UnsupportedOperationException();
- }
-
- public String getType()
- {
- return "vertical";
- }
-
- public RootClassMapping getRootClassMapping()
- {
- if (rootClassMapping == null)
- {
- rootClassMapping = new RootClassMapping(this);
- }
-
- return rootClassMapping;
- }
-
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected IClassMapping createClassMapping(EClass eClass)
- {
- return new VerticalClassMapping(this, eClass);
- }
-
- @Override
- protected List<EClass> getClassesWithObjectInfo()
- {
- return Collections.singletonList(rootClassMapping.getEClass());
- }
-
- @Override
- protected String[] getResourceQueries(CDOID folderID, String name, boolean exactMatch)
- {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
new file mode 100644
index 0000000000..2dec43fb55
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
@@ -0,0 +1,370 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBIndex;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public abstract class AbstractHorizontalClassMapping implements IClassMapping
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalClassMapping.class);
+
+ private EClass eClass;
+
+ private IDBTable table;
+
+ private AbstractHorizontalMappingStrategy mappingStrategy;
+
+ private List<ITypeMapping> valueMappings;
+
+ private List<IListMapping> listMappings;
+
+ public AbstractHorizontalClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ this.mappingStrategy = mappingStrategy;
+ this.eClass = eClass;
+
+ initTable();
+ initFeatures();
+ }
+
+ private void initTable()
+ {
+ String name = getMappingStrategy().getTableName(eClass);
+ table = getMappingStrategy().getStore().getDBSchema().addTable(name);
+
+ IDBField idField = table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true);
+ IDBField revisedField = table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true);
+
+ table.addIndex(IDBIndex.Type.NON_UNIQUE, idField, revisedField);
+ }
+
+ private void initFeatures()
+ {
+ EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
+
+ if (features == null)
+ {
+ valueMappings = Collections.emptyList();
+ listMappings = Collections.emptyList();
+ }
+ else
+ {
+ valueMappings = createValueMappings(features);
+ listMappings = createListMappings(features);
+ }
+ }
+
+ private List<ITypeMapping> createValueMappings(EStructuralFeature[] features)
+ {
+ List<ITypeMapping> mappings = new ArrayList<ITypeMapping>();
+ for (EStructuralFeature feature : features)
+ {
+ if (!feature.isMany())
+ {
+ ITypeMapping mapping = mappingStrategy.createValueMapping(feature);
+ mapping.createDBField(getTable());
+ mappings.add(mapping);
+ }
+ }
+
+ return mappings;
+ }
+
+ private List<IListMapping> createListMappings(EStructuralFeature[] features)
+ {
+ List<IListMapping> listMappings = new ArrayList<IListMapping>();
+ for (EStructuralFeature feature : features)
+ {
+ if (feature.isMany())
+ {
+ listMappings.add(mappingStrategy.createListMapping(eClass, feature));
+ }
+ }
+
+ return listMappings;
+ }
+
+ /**
+ * Read the revision's values from the DB.
+ *
+ * @return <code>true</code> if the revision has been read successfully.<br>
+ * <code>false</code> if the revision does not exist in the DB.
+ */
+ protected final boolean readValuesFromStatement(PreparedStatement pstmt, InternalCDORevision revision)
+ {
+ ResultSet resultSet = null;
+ try
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Executing Query: {0}", pstmt.toString());
+ }
+
+ pstmt.setMaxRows(1); // Optimization: only 1 row
+
+ resultSet = pstmt.executeQuery();
+ if (!resultSet.next())
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Resultset was empty.");
+ }
+
+ return false;
+ }
+
+ int i = 1;
+ revision.setVersion(resultSet.getInt(i++));
+ revision.setCreated(resultSet.getLong(i++));
+ revision.setRevised(resultSet.getLong(i++));
+ revision.setResourceID(CDOIDUtil.createLong(resultSet.getLong(i++)));
+
+ // TODO add mapping for external container CDOIDs here ->
+ revision.setContainerID(CDOIDUtil.createLong(resultSet.getLong(i++)));
+ revision.setContainingFeatureID(resultSet.getInt(i++));
+
+ for (ITypeMapping mapping : valueMappings)
+ {
+ mapping.readValueToRevision(resultSet, i++, revision);
+ }
+
+ return true;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ }
+ }
+
+ protected final void readLists(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ for (IListMapping listMapping : listMappings)
+ {
+ listMapping.readValues(accessor, revision, listChunk);
+ }
+ }
+
+ public final void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor)
+ {
+ Async async = null;
+ try
+ {
+ monitor.begin(getListMappings().size() + 1);
+ async = monitor.forkAsync();
+ reviseObject(accessor, id, revised);
+ async.stop();
+ async = monitor.forkAsync(getListMappings().size());
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ protected final IMetaDataManager getMetaDataManager()
+ {
+ return getMappingStrategy().getStore().getMetaDataManager();
+ }
+
+ protected final IMappingStrategy getMappingStrategy()
+ {
+ return mappingStrategy;
+ }
+
+ protected final EClass getEClass()
+ {
+ return eClass;
+ }
+
+ public final List<ITypeMapping> getValueMappings()
+ {
+ return valueMappings;
+ }
+
+ public final ITypeMapping getValueMapping(EStructuralFeature feature)
+ {
+ for (ITypeMapping mapping : valueMappings)
+ {
+ if (mapping.getFeature() == feature)
+ {
+ return mapping;
+ }
+ }
+ return null;
+ }
+
+ public final List<IListMapping> getListMappings()
+ {
+ return listMappings;
+ }
+
+ public final IListMapping getListMapping(EStructuralFeature feature)
+ {
+ for (IListMapping mapping : listMappings)
+ {
+ if (mapping.getFeature() == feature)
+ {
+ return mapping;
+ }
+ }
+
+ throw new IllegalArgumentException("List mapping for feature " + feature + " does not exist.");
+ }
+
+ protected final IDBTable getTable()
+ {
+ return table;
+ }
+
+ public Collection<IDBTable> getDBTables()
+ {
+ ArrayList<IDBTable> tables = new ArrayList<IDBTable>();
+ tables.add(table);
+
+ for (IListMapping listMapping : listMappings)
+ {
+ tables.addAll(listMapping.getDBTables());
+ }
+
+ return tables;
+ }
+
+ private void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
+ {
+ CDOID folderID = (CDOID)revision.data().getContainerID();
+ String name = (String)revision.data().get(EresourcePackage.eINSTANCE.getCDOResourceNode_Name(), 0);
+
+ CDOID existingID = accessor.readResourceID(folderID, name, CDORevision.UNSPECIFIED_DATE);
+ if (existingID != null && !existingID.equals(revision.getID()))
+ {
+ throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID);
+ }
+ }
+
+ protected void writeLists(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ for (IListMapping listMapping : listMappings)
+ {
+ listMapping.writeValues(accessor, revision);
+ }
+ }
+
+ public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
+ {
+ Async async = null;
+ try
+ {
+ monitor.begin(10);
+ async = monitor.forkAsync();
+
+ CDOID id = revision.getID();
+ if (revision.getVersion() == 1)
+ {
+ mappingStrategy.putObjectType(accessor, id, eClass);
+ }
+ else
+ {
+ long revised = revision.getCreated() - 1;
+ reviseObject(accessor, id, revised);
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ }
+
+ async.stop();
+ async = monitor.forkAsync();
+
+ if (revision.isResourceFolder() || revision.isResource())
+ {
+ checkDuplicateResources(accessor, revision);
+ }
+
+ async.stop();
+ async = monitor.forkAsync();
+
+ // Write attribute table always (even without modeled attributes!)
+ writeValues(accessor, revision);
+
+ async.stop();
+ async = monitor.forkAsync(7);
+
+ // Write list tables only if they exist
+ if (listMappings != null)
+ {
+ writeLists(accessor, revision);
+ }
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ protected abstract void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision);
+
+ protected abstract void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java
new file mode 100644
index 0000000000..f42f390504
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResourceNode;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IObjectTypeCache;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+
+/**
+ * * This abstract base class refines {@link AbstractMappingStrategy} by implementing aspects common to horizontal
+ * mapping strategies -- namely:
+ * <ul>
+ * <li>object type cache (table cdo_objects)
+ * <li>resource query handling
+ * </ul>
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingStrategy
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalMappingStrategy.class);
+
+ /**
+ * The associated object type cache.
+ */
+ private IObjectTypeCache objectTypeCache;
+
+ @Override
+ public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id)
+ {
+ return objectTypeCache.getObjectType(accessor, id);
+ }
+
+ public void putObjectType(IDBStoreAccessor accessor, CDOID id, EClass type)
+ {
+ objectTypeCache.putObjectType(accessor, id, type);
+ }
+
+ @Override
+ public long repairAfterCrash(IDBAdapter dbAdapter, Connection connection)
+ {
+ return objectTypeCache.getMaxId(connection) + 1;
+ }
+
+ @Override
+ protected Collection<EClass> getClassesWithObjectInfo()
+ {
+ return getClassMappings().keySet();
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+ if (objectTypeCache == null)
+ {
+ objectTypeCache = createObjectTypeCache();
+ LifecycleUtil.activate(objectTypeCache);
+ }
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ LifecycleUtil.deactivate(objectTypeCache);
+ objectTypeCache = null;
+ super.doDeactivate();
+ }
+
+ private IObjectTypeCache createObjectTypeCache()
+ {
+ ObjectTypeCache cache = new ObjectTypeCache();
+ cache.setMappingStrategy(this);
+ return cache;
+ }
+
+ @Override
+ public void queryResources(IDBStoreAccessor dbStoreAccessor, QueryResourcesContext context)
+ {
+ // only support timestamp in audit mode
+ if (context.getTimeStamp() != CDORevision.UNSPECIFIED_DATE && !hasAuditSupport())
+ {
+ throw new UnsupportedOperationException("Mapping Strategy does not support audits.");
+ }
+
+ EresourcePackage resourcesPackage = EresourcePackage.eINSTANCE;
+
+ // first query folders
+ boolean shallContinue = queryResources(dbStoreAccessor, getClassMapping(resourcesPackage.getCDOResourceFolder()),
+ context);
+
+ // not enough results? -> query resources
+ if (shallContinue)
+ {
+ queryResources(dbStoreAccessor, getClassMapping(resourcesPackage.getCDOResource()), context);
+ }
+ }
+
+ /**
+ * This is an intermediate implementation. It should be changed after classmappings support a general way to implement
+ * queries ...
+ *
+ * @param accessor
+ * the accessor to use.
+ * @param classMapping
+ * the class mapping of a class instanceof {@link CDOResourceNode} which should be queried.
+ * @param context
+ * the query context containing the parameters and the result.
+ * @return <code>true</code> if result context is not yet full and query should continue false, if result context is
+ * full and query should stop.
+ */
+ private boolean queryResources(IDBStoreAccessor accessor, IClassMapping classMapping, QueryResourcesContext context)
+ {
+ PreparedStatement stmt = null;
+ ResultSet rset = null;
+
+ CDOID folderID = context.getFolderID();
+ String name = context.getName();
+ boolean exactMatch = context.exactMatch();
+ long timeStamp = context.getTimeStamp();
+
+ try
+ {
+ stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, timeStamp);
+ rset = stmt.executeQuery();
+
+ while (rset.next())
+ {
+ long longID = rset.getLong(1);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Resource Query returned ID {0}", longID);
+ }
+
+ CDOID id = CDOIDUtil.createLong(longID);
+ if (!context.addResource(id))
+ {
+ // No more results allowed
+ return false; // don't continue
+ }
+ }
+
+ return true; // continue with other results
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(rset);
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java
new file mode 100644
index 0000000000..1c2509c51d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java
@@ -0,0 +1,522 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.db.ddl.IDBIndex.Type;
+import org.eclipse.net4j.util.collection.MoveableList;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * This abstract base class provides basic behavior needed for mapping many-valued attributes to tables.
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public abstract class AbstractListTableMapping implements IListMapping
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractListTableMapping.class);
+
+ /**
+ * The feature for this mapping.
+ */
+ private EStructuralFeature feature;
+
+ /**
+ * The table of this mapping.
+ */
+ private IDBTable table;
+
+ /**
+ * The type mapping for the value field.
+ */
+ private ITypeMapping typeMapping;
+
+ /**
+ * The associated mapping strategy.
+ */
+ private IMappingStrategy mappingStrategy;
+
+ // --------- SQL strings - see initSqlStrings() -----------------
+ private String sqlSelectChunksPrefix;
+
+ private String sqlOrderByIndex;
+
+ private String sqlInsertEntry;
+
+ private EClass containingClass;
+
+ private String sqlGetListLastIndex;
+
+ public AbstractListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ this.mappingStrategy = mappingStrategy;
+ this.feature = feature;
+ containingClass = eClass;
+
+ initTable();
+ initSqlStrings();
+ }
+
+ private void initTable()
+ {
+ String tableName = mappingStrategy.getTableName(containingClass, feature);
+ table = mappingStrategy.getStore().getDBSchema().addTable(tableName);
+
+ // add fields for keys (cdo_id, version, feature_id)
+ FieldInfo[] fields = getKeyFields();
+ IDBField[] dbFields = new IDBField[fields.length];
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ dbFields[i] = table.addField(fields[i].getName(), fields[i].getDbType());
+ }
+
+ // add field for list index
+ IDBField idxField = table.addField(CDODBSchema.LIST_IDX, DBType.INTEGER);
+
+ // add field for value
+ typeMapping = mappingStrategy.createValueMapping(feature);
+ typeMapping.createDBField(table, CDODBSchema.LIST_VALUE);
+
+ // add table indexes
+ table.addIndex(Type.NON_UNIQUE, dbFields);
+ table.addIndex(Type.NON_UNIQUE, idxField);
+ }
+
+ protected abstract FieldInfo[] getKeyFields();
+
+ protected abstract void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException;
+
+ public Collection<IDBTable> getDBTables()
+ {
+ return Arrays.asList(table);
+ }
+
+ private void initSqlStrings()
+ {
+ String tableName = getTable().getName();
+ FieldInfo[] fields = getKeyFields();
+
+ // ---------------- SELECT to read chunks ----------------------------
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.LIST_VALUE);
+ builder.append(" FROM ");
+ builder.append(tableName);
+ builder.append(" WHERE ");
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ builder.append(fields[i].getName());
+ if (i + 1 < fields.length)
+ {
+ // more to come
+ builder.append("= ? AND ");
+ }
+ else
+ {
+ // last one
+ builder.append("= ? ");
+ }
+ }
+
+ sqlSelectChunksPrefix = builder.toString();
+
+ sqlOrderByIndex = " ORDER BY " + CDODBSchema.LIST_IDX;
+
+ // ----------------- count list size --------------------------
+
+ builder = new StringBuilder("SELECT max(");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(") FROM ");
+ builder.append(tableName);
+ builder.append(" WHERE ");
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ builder.append(fields[i].getName());
+ if (i + 1 < fields.length)
+ {
+ // more to come
+ builder.append("= ? AND ");
+ }
+ else
+ {
+ // last one
+ builder.append("= ? ");
+ }
+ }
+
+ sqlGetListLastIndex = builder.toString();
+
+ // ----------------- INSERT - reference entry -----------------
+ builder = new StringBuilder("INSERT INTO ");
+ builder.append(tableName);
+ builder.append(" VALUES (");
+ for (int i = 0; i < fields.length; i++)
+ {
+ builder.append("?, ");
+ }
+ builder.append(" ?, ?)");
+ sqlInsertEntry = builder.toString();
+ }
+
+ public final EStructuralFeature getFeature()
+ {
+ return feature;
+ }
+
+ public final EClass getContainingClass()
+ {
+ return containingClass;
+ }
+
+ protected final IDBTable getTable()
+ {
+ return table;
+ }
+
+ protected final ITypeMapping getTypeMapping()
+ {
+ return typeMapping;
+ }
+
+ public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+
+ MoveableList<Object> list = revision.getList(getFeature());
+ int listSize = -1;
+
+ if (listChunk != CDORevision.UNCHUNKED)
+ {
+ listSize = getListLastIndex(accessor, revision);
+ if (listSize == -1)
+ {
+ // list is empty - take shortcut
+ return;
+ }
+ else
+ {
+ // subtract amount of items we are going to read now
+ listSize -= listChunk;
+ }
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature.getName(),
+ revision.getID(), revision.getVersion());
+ }
+
+ PreparedStatement pstmt = null;
+ ResultSet resultSet = null;
+
+ try
+ {
+ String sql = sqlSelectChunksPrefix + sqlOrderByIndex;
+
+ pstmt = accessor.getStatementCache().getPreparedStatement(sql, ReuseProbability.HIGH);
+
+ setKeyFields(pstmt, revision);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(pstmt.toString());
+ }
+
+ if (listChunk != CDORevision.UNCHUNKED)
+ {
+ pstmt.setMaxRows(listChunk); // optimization - don't read unneeded rows.
+ }
+
+ resultSet = pstmt.executeQuery();
+
+ while ((listChunk == CDORevision.UNCHUNKED || --listChunk >= 0) && resultSet.next())
+ {
+ Object value = typeMapping.readValue(resultSet, 1);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read value for index {0} from result set: {1}", list.size(), value);
+ }
+ list.add(value);
+ }
+
+ while (listSize-- >= 0)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adding UNINITIALIZED for index {0} ", list.size());
+ }
+ list.add(InternalCDORevision.UNINITIALIZED);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature
+ .getName(), revision.getID(), revision.getVersion());
+ }
+ }
+
+ /**
+ * Return the last (maximum) list index. (euals to size-1)
+ *
+ * @param accessor
+ * the accessor to use
+ * @param revision
+ * the revision to which the feature list belongs
+ * @return the last index or <code>-1</code> if the list is empty.
+ */
+ private int getListLastIndex(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ PreparedStatement pstmt = null;
+ ResultSet resultSet = null;
+
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlGetListLastIndex, ReuseProbability.HIGH);
+
+ setKeyFields(pstmt, revision);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(pstmt.toString());
+ }
+
+ resultSet = pstmt.executeQuery();
+
+ if (!resultSet.next())
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("No last index found -> list is empty. ");
+ }
+ return -1;
+ }
+ else
+ {
+ int result = resultSet.getInt(1);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Read list last index = " + result);
+ }
+ return result;
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature
+ .getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion());
+ }
+
+ PreparedStatement pstmt = null;
+ ResultSet resultSet = null;
+
+ try
+ {
+ StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix);
+ if (where != null)
+ {
+ builder.append(where);
+ }
+ builder.append(sqlOrderByIndex);
+
+ String sql = builder.toString();
+
+ pstmt = chunkReader.getAccessor().getStatementCache().getPreparedStatement(sql, ReuseProbability.LOW);
+
+ setKeyFields(pstmt, chunkReader.getRevision());
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(pstmt.toString());
+ }
+
+ resultSet = pstmt.executeQuery();
+
+ Chunk chunk = null;
+ int chunkSize = 0;
+ int chunkIndex = 0;
+ int indexInChunk = 0;
+
+ while (resultSet.next())
+ {
+ Object value = typeMapping.readValue(resultSet, 1);
+
+ if (chunk == null)
+ {
+ chunk = chunks.get(chunkIndex++);
+ chunkSize = chunk.size();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(),
+ chunkSize);
+ }
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value);
+ }
+ chunk.add(indexInChunk++, value);
+
+ if (indexInChunk == chunkSize)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Chunk finished.");
+ }
+
+ chunk = null;
+ indexInChunk = 0;
+ }
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}v{3}", containingClass.getName(),
+ feature.getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion());
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ chunkReader.getAccessor().getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ CDOList values = revision.getList(getFeature());
+
+ int idx = 0;
+ for (Object element : values)
+ {
+ writeValue(accessor, revision, idx++, element);
+ }
+ }
+
+ protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value)
+ {
+ PreparedStatement stmt = null;
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing value for feature {0}.{1} index {2} of {3}v{4} : {5}", containingClass.getName(), feature
+ .getName(), idx, revision.getID(), revision.getVersion(), value);
+ }
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertEntry, ReuseProbability.HIGH);
+
+ setKeyFields(stmt, revision);
+ int stmtIndex = getKeyFields().length + 1;
+ stmt.setInt(stmtIndex++, idx);
+ typeMapping.setValue(stmt, stmtIndex++, value);
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Used by subclasses to indicate which fields should be in the table. I.e. just a pair of name and DBType ...
+ *
+ * @author Stefan Winkler
+ */
+ protected static class FieldInfo
+ {
+ private String name;
+
+ private DBType dbType;
+
+ public FieldInfo(String name, DBType dbType)
+ {
+ this.name = name;
+ this.dbType = dbType;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public DBType getDbType()
+ {
+ return dbType;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java
new file mode 100644
index 0000000000..d3a3d4cd7d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * This is a list-table mapping for audit mode. It has ID and version columns and no delta support.
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class AuditListTableMapping extends AbstractListTableMapping
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.LIST_REVISION_ID, DBType.BIGINT),
+ new FieldInfo(CDODBSchema.LIST_REVISION_VERSION, DBType.INTEGER) };
+
+ public AuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(2, revision.getVersion());
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ // the audit list mapping does not care about revised references -> NOP
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
new file mode 100644
index 0000000000..32b0d58c27
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
@@ -0,0 +1,401 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * TODO use async monitors
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping implements IClassMapping,
+ IClassMappingAuditSupport
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalAuditClassMapping.class);
+
+ private String sqlInsertAttributes;
+
+ private String sqlSelectCurrentAttributes;
+
+ private String sqlSelectAllObjectIds;
+
+ private String sqlSelectAttributesByTime;
+
+ private String sqlSelectAttributesByVersion;
+
+ private String sqlReviseAttributes;
+
+ public HorizontalAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ super(mappingStrategy, eClass);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ // ----------- Select Revision ---------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", ");
+ builder.append(singleMapping.getField().getName());
+ }
+
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ? AND (");
+
+ String sqlSelectAttributesPrefix = builder.toString();
+
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 )");
+
+ sqlSelectCurrentAttributes = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 OR ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" >= ?))");
+
+ sqlSelectAttributesByTime = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(" = ?)");
+
+ sqlSelectAttributesByVersion = builder.toString();
+
+ // ----------- Insert Attributes -------------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO ");
+ builder.append(getTable().getName());
+ builder.append(" VALUES (?, ?, ");
+ builder.append("?, ?, ?, ?, ?, ?");
+ for (int i = 0; i < getValueMappings().size(); i++)
+ {
+ builder.append(", ?");
+ }
+ builder.append(")");
+ sqlInsertAttributes = builder.toString();
+
+ // ----------- Update to set revised ----------------
+ builder = new StringBuilder("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = ? WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? AND ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0");
+ sqlReviseAttributes = builder.toString();
+
+ // ----------- Select all unrevised Object IDs ------
+ builder = new StringBuilder("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0");
+ sqlSelectAllObjectIds = builder.toString();
+ }
+
+ public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
+ int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setLong(2, timeStamp);
+ pstmt.setLong(3, timeStamp);
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
+ int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setInt(2, version);
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, long timeStamp)
+ {
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
+ {
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("= ? AND ");
+ builder.append(nameValueMapping.getField().getName());
+ if (name == null)
+ {
+ builder.append(" IS NULL");
+ }
+ else
+ {
+ builder.append(exactMatch ? " = ? " : " LIKE ? ");
+ }
+
+ builder.append(" AND ( ");
+
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 )");
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 OR ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" >= ?))");
+ }
+
+ PreparedStatement pstmt = null;
+ try
+ {
+ int idx = 1;
+
+ pstmt = accessor.getStatementCache().getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
+ pstmt.setLong(idx++, CDOIDUtil.getLong(folderId));
+
+ if (name != null)
+ {
+ String queryName = exactMatch ? name : name + "%";
+ nameValueMapping.setValue(pstmt, idx++, queryName);
+ }
+
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ pstmt.setLong(idx++, timeStamp);
+ pstmt.setLong(idx++, timeStamp);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", pstmt.toString());
+ }
+
+ return pstmt;
+ }
+ catch (SQLException ex)
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt); // only release on error
+ throw new DBException(ex);
+ }
+ }
+
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIds);
+ }
+
+ return accessor.getStatementCache().getPreparedStatement(sqlSelectAllObjectIds, ReuseProbability.HIGH);
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ @Override
+ protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+ int col = 1;
+
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, revision.getVersion());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revision.getCreated());
+ stmt.setLong(col++, revision.getRevised());
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
+ stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ mapping.setValueFromRevision(stmt, col++, revision);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
+
+ stmt.setLong(1, revised);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
new file mode 100644
index 0000000000..d062dd0c82
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStrategy
+{
+ @Override
+ public IClassMapping doCreateClassMapping(EClass eClass)
+ {
+ return new HorizontalAuditClassMapping(this, eClass);
+ }
+
+ @Override
+ public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ return new AuditListTableMapping(this, containingClass, feature);
+ }
+
+ @Override
+ public boolean hasAuditSupport()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean hasDeltaSupport()
+ {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
new file mode 100644
index 0000000000..ed68197eb7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
@@ -0,0 +1,563 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMapping implements IClassMapping,
+ IClassMappingDeltaSupport
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalNonAuditClassMapping.class);
+
+ private String sqlSelectAllObjectIds;
+
+ private String sqlSelectCurrentAttributes;
+
+ private String sqlInsertAttributes;
+
+ private String sqlDelete;
+
+ private String sqlUpdateAffix;
+
+ private String sqlUpdatePrexix;
+
+ private String sqlUpdateContainerPart;
+
+ private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
+ {
+ @Override
+ protected FeatureDeltaWriter initialValue()
+ {
+ return new FeatureDeltaWriter();
+ };
+ };
+
+ public HorizontalNonAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ super(mappingStrategy, eClass);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ // ----------- Select Revision ---------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", ");
+ builder.append(singleMapping.getField().getName());
+ }
+
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ?");
+
+ sqlSelectCurrentAttributes = builder.toString();
+
+ // ----------- Insert Attributes -------------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO ");
+ builder.append(getTable().getName());
+ builder.append(" VALUES (?, ?, ");
+ builder.append("?, ?, ?, ?, ?, ?");
+ for (int i = 0; i < getValueMappings().size(); i++)
+ {
+ builder.append(", ?");
+ }
+ builder.append(")");
+ sqlInsertAttributes = builder.toString();
+
+ builder = new StringBuilder("DELETE FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? ");
+ sqlDelete = builder.toString();
+
+ // ----------- Select all unrevised Object IDs ------
+ builder = new StringBuilder("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ sqlSelectAllObjectIds = builder.toString();
+
+ // ----------- Update attributes --------------------
+ builder = new StringBuilder("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" =? ");
+ sqlUpdatePrexix = builder.toString();
+
+ builder = new StringBuilder(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+ builder.append(" =? ");
+ sqlUpdateContainerPart = builder.toString();
+
+ builder = new StringBuilder(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? ");
+ sqlUpdateAffix = builder.toString();
+ }
+
+ @Override
+ protected void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+ int col = 1;
+
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, revision.getVersion());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revision.getCreated());
+ stmt.setLong(col++, revision.getRevised());
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
+ stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ mapping.setValueFromRevision(stmt, col++, revision);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIds);
+ }
+
+ return accessor.getStatementCache().getPreparedStatement(sqlSelectAllObjectIds, ReuseProbability.HIGH);
+ }
+
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, long timeStamp)
+ {
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ throw new IllegalArgumentException("Non-audit store does not support explicit timeStamp in resource query");
+ }
+
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
+ {
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("= ? AND ");
+ builder.append(nameValueMapping.getField().getName());
+ if (name == null)
+ {
+ builder.append(" IS NULL");
+ }
+ else
+ {
+ builder.append(exactMatch ? " = ? " : " LIKE ? ");
+ }
+
+ PreparedStatement pstmt = null;
+ try
+ {
+ int idx = 1;
+
+ pstmt = accessor.getStatementCache().getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
+ pstmt.setLong(idx++, CDOIDUtil.getLong(folderId));
+
+ if (name != null)
+ {
+ String queryName = exactMatch ? name : name + "%";
+ nameValueMapping.setValue(pstmt, idx++, queryName);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", pstmt.toString());
+ }
+
+ return pstmt;
+ }
+ catch (SQLException ex)
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt); // only release on error
+ throw new DBException(ex);
+ }
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ // TODO add caching
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ @Override
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlDelete, ReuseProbability.HIGH);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
+ OMMonitor monitor)
+ {
+ monitor.begin();
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ FeatureDeltaWriter writer = deltaWriter.get();
+ writer.process(accessor, delta, created);
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
+ {
+ private CDOID id;
+
+ private int oldVersion;
+
+ private int newVersion;
+
+ private long created;
+
+ private IDBStoreAccessor accessor;
+
+ private boolean updateContainer = false;
+
+ private List<Pair<ITypeMapping, Object>> attributeChanges;
+
+ private int newContainingFeatureID;
+
+ private CDOID newContainerID;
+
+ private CDOID newResourceID;
+
+ public FeatureDeltaWriter()
+ {
+ attributeChanges = new ArrayList<Pair<ITypeMapping, Object>>();
+ }
+
+ protected void reset()
+ {
+ attributeChanges.clear();
+ updateContainer = false;
+ }
+
+ public void process(IDBStoreAccessor a, CDORevisionDelta d, long c)
+ {
+ // set context
+
+ reset();
+ id = d.getID();
+ oldVersion = d.getOriginVersion();
+ newVersion = d.getDirtyVersion();
+ created = c;
+ accessor = a;
+
+ // process revision delta tree
+ d.accept(this);
+
+ // update attributes
+ if (updateContainer)
+ {
+ updateAttributes(accessor, id, newVersion, created, newContainerID, newContainingFeatureID, newResourceID,
+ attributeChanges);
+ }
+ else
+ {
+ updateAttributes(accessor, id, newVersion, created, attributeChanges);
+ }
+ }
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ if (delta.getFeature().isMany())
+ {
+ throw new ImplementationError("Should not be called");
+ }
+ ITypeMapping am = getValueMapping(delta.getFeature());
+ if (am == null)
+ {
+ throw new IllegalArgumentException("AttributeMapping for " + delta.getFeature() + " is null!");
+ }
+ attributeChanges.add(new Pair<ITypeMapping, Object>(am, delta.getValue()));
+
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ // TODO: correct this when DBStore implements unsettable features
+ // see Bugs 259868 and 263010
+ ITypeMapping tm = getValueMapping(delta.getFeature());
+ attributeChanges.add(new Pair<ITypeMapping, Object>(tm, null));
+ }
+
+ public void visit(CDOListFeatureDelta delta)
+ {
+ IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature());
+ listMapping.processDelta(accessor, id, oldVersion, newVersion, created, delta);
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ newContainingFeatureID = delta.getContainerFeatureID();
+ newContainerID = (CDOID)delta.getContainerID();
+ newResourceID = delta.getResourceID();
+ updateContainer = true;
+ }
+ }
+
+ public void updateAttributes(IDBStoreAccessor accessor, CDOID id, int newVersion, long created, CDOID newContainerId,
+ int newContainingFeatureId, CDOID newResourceId, List<Pair<ITypeMapping, Object>> attributeChanges)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(buildUpdateStatement(attributeChanges, true),
+ ReuseProbability.MEDIUM);
+
+ int col = 1;
+
+ stmt.setInt(col++, newVersion);
+ stmt.setLong(col++, created);
+ stmt.setLong(col++, CDODBUtil.getLong(newResourceId));
+ stmt.setLong(col++, CDODBUtil.getLong(newContainerId));
+ stmt.setInt(col++, newContainingFeatureId);
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ change.getElement1().setValue(stmt, col++, change.getElement2());
+ }
+
+ stmt.setLong(col++, CDOIDUtil.getLong(id));
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+
+ }
+
+ public void updateAttributes(IDBStoreAccessor accessor, CDOID id, int newVersion, long created,
+ List<Pair<ITypeMapping, Object>> attributeChanges)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(buildUpdateStatement(attributeChanges, false),
+ ReuseProbability.MEDIUM);
+
+ int col = 1;
+
+ stmt.setInt(col++, newVersion);
+ stmt.setLong(col++, created);
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ change.getElement1().setValue(stmt, col++, change.getElement2());
+ }
+
+ stmt.setLong(col++, CDOIDUtil.getLong(id));
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ private String buildUpdateStatement(List<Pair<ITypeMapping, Object>> attributeChanges, boolean withContainment)
+ {
+ StringBuilder builder = new StringBuilder(sqlUpdatePrexix);
+ if (withContainment)
+ {
+ builder.append(sqlUpdateContainerPart);
+ }
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ builder.append(", ");
+ builder.append(change.getElement1().getField().getName());
+ builder.append(" =? ");
+ }
+
+ builder.append(sqlUpdateAffix);
+ return builder.toString();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
new file mode 100644
index 0000000000..8543cb59a1
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMappingStrategy
+{
+
+ @Override
+ protected IClassMapping doCreateClassMapping(EClass eClass)
+ {
+ return new HorizontalNonAuditClassMapping(this, eClass);
+ }
+
+ @Override
+ public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ return new NonAuditListTableMapping(this, containingClass, feature);
+ }
+
+ @Override
+ public boolean hasAuditSupport()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean hasDeltaSupport()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java
new file mode 100644
index 0000000000..6aaac67414
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java
@@ -0,0 +1,514 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings https://bugs.eclipse.org/bugs/show_bug.cgi?id=271444
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.util.ImplementationError;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * This is a list-to-table mapping optimized for non-audit-mode. It doesn't care about version and has delta support.
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class NonAuditListTableMapping extends AbstractListTableMapping implements IListMapping,
+ IListMappingDeltaSupport
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.LIST_REVISION_ID, DBType.BIGINT) };
+
+ private static final int TEMP_INDEX = -1;
+
+ private static final int UNBOUNDED_MOVE = -1;
+
+ private String sqlClear;
+
+ private String sqlUpdateValue;
+
+ private String sqlUpdateIndex;
+
+ private String sqlInsertValue;
+
+ private String sqlDeleteItem;
+
+ private String sqlMoveDownWithLimit;
+
+ private String sqlMoveDown;
+
+ private String sqlMoveUpWithLimit;
+
+ private String sqlMoveUp;
+
+ public NonAuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ // ----------- clear list -------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("DELETE FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.LIST_REVISION_ID);
+ builder.append(" = ? ");
+
+ sqlClear = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ? ");
+
+ sqlDeleteItem = builder.toString();
+
+ // ----------- update one item --------------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.LIST_VALUE);
+ builder.append(" = ? ");
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.LIST_REVISION_ID);
+ builder.append(" = ? AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ? ");
+ sqlUpdateValue = builder.toString();
+
+ // ----------- insert one item --------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO ");
+ builder.append(getTable().getName());
+ builder.append(" VALUES(?, ?, ?) ");
+ sqlInsertValue = builder.toString();
+
+ // ----------- update one item index --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ? ");
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.LIST_REVISION_ID);
+ builder.append(" = ? AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ? ");
+ sqlUpdateIndex = builder.toString();
+
+ // ----------- move down --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append("-1 WHERE ");
+ builder.append(CDODBSchema.LIST_REVISION_ID);
+ builder.append("= ? AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" > ? ");
+ sqlMoveDown = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" <= ?");
+ sqlMoveDownWithLimit = builder.toString();
+
+ // ----------- move up --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" = ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append("+1 WHERE ");
+ builder.append(CDODBSchema.LIST_REVISION_ID);
+ builder.append("= ? AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" >= ? ");
+ sqlMoveUp = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.LIST_IDX);
+ builder.append(" < ?");
+ sqlMoveUpWithLimit = builder.toString();
+
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ clearList(accessor, id);
+ }
+
+ /**
+ * Clear a list of a given revision.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the id of the revision from which to remove all items
+ */
+ public void clearList(IDBStoreAccessor accessor, CDOID id)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlClear, ReuseProbability.HIGH);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Insert a list item at a specified position.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the id of the revision to insert the value
+ * @param index
+ * the index where to insert the element
+ * @param value
+ * the value to insert.
+ */
+ public void insertListItem(IDBStoreAccessor accessor, CDOID id, int index, Object value)
+ {
+ move1up(accessor, id, index, UNBOUNDED_MOVE);
+ insertValue(accessor, id, index, value);
+ }
+
+ private void insertValue(IDBStoreAccessor accessor, CDOID id, int index, Object value)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertValue, ReuseProbability.HIGH);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ getTypeMapping().setValue(stmt, 3, value);
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Move a list item from one position to another. Indices between both positions are updated so that the list remains
+ * consistent.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the id of the revision in which to move the item
+ * @param oldPosition
+ * the old position of the item.
+ * @param newPosition
+ * the new position of the item.
+ */
+ public void moveListItem(IDBStoreAccessor accessor, CDOID id, int oldPosition, int newPosition)
+ {
+ if (oldPosition == newPosition)
+ {
+ return;
+ }
+
+ // move element away temporarily
+ updateOneIndex(accessor, id, oldPosition, TEMP_INDEX);
+
+ // move elements in between
+ if (oldPosition < newPosition)
+ {
+ move1down(accessor, id, oldPosition, newPosition);
+ }
+ else
+ {
+ // oldPosition > newPosition -- equal case is handled above
+ move1up(accessor, id, newPosition, oldPosition);
+ }
+
+ // move temporary element to new position
+ updateOneIndex(accessor, id, TEMP_INDEX, newPosition);
+ }
+
+ private void updateOneIndex(IDBStoreAccessor accessor, CDOID id, int oldIndex, int newIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlUpdateIndex, ReuseProbability.HIGH);
+ stmt.setInt(1, newIndex);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+ stmt.setInt(3, oldIndex);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Remove a list item from a specified a position.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the id of the revision from which to remove the item
+ * @param index
+ * the index of the item to remoce
+ */
+ public void removeListItem(IDBStoreAccessor accessor, CDOID id, int index)
+ {
+ deleteItem(accessor, id, index);
+ move1down(accessor, id, index, UNBOUNDED_MOVE);
+ }
+
+ /**
+ * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with
+ * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
+ */
+ private void move1down(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(
+ upperIndex == UNBOUNDED_MOVE ? sqlMoveDown : sqlMoveDownWithLimit, ReuseProbability.HIGH);
+
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ if (upperIndex != UNBOUNDED_MOVE)
+ {
+ stmt.setInt(3, upperIndex);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with
+ * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
+ */
+ private void move1up(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(
+ upperIndex == UNBOUNDED_MOVE ? sqlMoveUp : sqlMoveUpWithLimit, ReuseProbability.HIGH);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ if (upperIndex != UNBOUNDED_MOVE)
+ {
+ stmt.setInt(3, upperIndex);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ private void deleteItem(IDBStoreAccessor accessor, CDOID id, int index)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlDeleteItem, ReuseProbability.HIGH);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ /**
+ * Set a value at a specified position to the given value.
+ *
+ * @param accessor
+ * the accessor to use
+ * @param id
+ * the id of the revision to set the value
+ * @param index
+ * the index of the item to set
+ * @param value
+ * the value to be set.
+ */
+ public void setListItem(IDBStoreAccessor accessor, CDOID id, int index, Object value)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlUpdateValue, ReuseProbability.HIGH);
+ getTypeMapping().setValue(stmt, 1, value);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+ stmt.setInt(3, index);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ public void processDelta(final IDBStoreAccessor accessor, final CDOID id, int oldVersion, final int newVersion,
+ long created, CDOListFeatureDelta listDelta)
+ {
+ CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitor()
+ {
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ moveListItem(accessor, id, delta.getOldPosition(), delta.getNewPosition());
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ insertListItem(accessor, id, delta.getIndex(), delta.getValue());
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ removeListItem(accessor, id, delta.getIndex());
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ setListItem(accessor, id, delta.getIndex(), delta.getValue());
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDOListFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ clearList(accessor, id);
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called");
+ }
+
+ };
+
+ for (CDOFeatureDelta delta : listDelta.getListChanges())
+ {
+ delta.accept(visitor);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java
index ba9cc010f2..512c24f67d 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java
@@ -8,15 +8,19 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
+ * Stefan Winkler - redesign (prepared statements)
*/
-package org.eclipse.emf.cdo.server.internal.db;
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
import org.eclipse.emf.cdo.server.db.IObjectTypeCache;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
@@ -30,12 +34,15 @@ import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.emf.ecore.EClass;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author Eike Stepper
+ * @since 2.0
*/
public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
{
@@ -49,6 +56,14 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
private transient Object initializeLock = new Object();
+ private String sqlDelete;
+
+ private String sqlInsert;
+
+ private String sqlSelect;
+
+ private IMetaDataManager metaDataManager;
+
public ObjectTypeCache()
{
}
@@ -65,26 +80,18 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
public final CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id)
{
- Statement statement = accessor.getJDBCDelegate().getStatement();
- initialize(statement);
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(typeField);
- builder.append(" FROM ");
- builder.append(table);
- builder.append(" WHERE ");
- builder.append(idField);
- builder.append("=");
- builder.append(CDOIDUtil.getLong(id));
- String sql = builder.toString();
- DBUtil.trace(sql);
-
- ResultSet resultSet = null;
+ Connection connection = accessor.getConnection();
+ initialize(connection);
+
+ PreparedStatement stmt = null;
try
{
- resultSet = statement.executeQuery(sql);
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlSelect, ReuseProbability.MAX);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ DBUtil.trace(stmt.toString());
+ ResultSet resultSet = stmt.executeQuery();
+
if (!resultSet.next())
{
DBUtil.trace("ClassID for CDOID " + id + " not found");
@@ -92,7 +99,7 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
}
long classID = resultSet.getLong(1);
- EClass eClass = (EClass)mappingStrategy.getStore().getMetaInstance(classID);
+ EClass eClass = (EClass)metaDataManager.getMetaInstance(classID);
return new CDOClassifierRef(eClass);
}
catch (SQLException ex)
@@ -101,59 +108,55 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
}
finally
{
- DBUtil.close(resultSet);
+ accessor.getStatementCache().releasePreparedStatement(stmt);
}
}
public final void putObjectType(IDBStoreAccessor accessor, CDOID id, EClass type)
{
- Statement statement = accessor.getJDBCDelegate().getStatement();
- initialize(statement);
-
- StringBuilder builder = new StringBuilder();
- builder.append("INSERT INTO ");
- builder.append(table);
- builder.append(" VALUES (");
- builder.append(CDOIDUtil.getLong(id));
- builder.append(", ");
- builder.append(accessor.getStore().getMetaID(type));
- builder.append(")");
- String sql = builder.toString();
- DBUtil.trace(sql);
+ Connection connection = accessor.getConnection();
+ initialize(connection);
+
+ PreparedStatement stmt = null;
try
{
- statement.execute(sql);
- if (statement.getUpdateCount() != 1)
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsert, ReuseProbability.MAX);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setLong(2, metaDataManager.getMetaID(type));
+ DBUtil.trace(stmt.toString());
+ int result = stmt.executeUpdate();
+
+ if (result != 1)
{
- throw new DBException("Object type not inserted: " + id + " -> " + type);
+ throw new DBException("Object type could not be deleted: " + id);
}
}
catch (SQLException ex)
{
throw new DBException(ex);
}
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
}
public final void removeObjectType(IDBStoreAccessor accessor, CDOID id)
{
- Statement statement = accessor.getJDBCDelegate().getStatement();
- initialize(statement);
-
- StringBuilder builder = new StringBuilder();
- builder.append("DELETE FROM ");
- builder.append(table);
- builder.append(" WHERE ");
- builder.append(idField);
- builder.append(" = ");
- builder.append(CDOIDUtil.getLong(id));
- String sql = builder.toString();
- DBUtil.trace(sql);
+ Connection connection = accessor.getConnection();
+ initialize(connection);
+
+ PreparedStatement stmt = null;
try
{
- statement.execute(sql);
- if (statement.getUpdateCount() != 1)
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlDelete, ReuseProbability.MAX);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ DBUtil.trace(stmt.toString());
+ int result = stmt.executeUpdate();
+
+ if (result != 1)
{
throw new DBException("Object type could not be deleted: " + id);
}
@@ -162,10 +165,16 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
{
throw new DBException(ex);
}
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
}
- private void initialize(Statement statement)
+ private void initialize(Connection connection)
{
+ // TODO - is there a better way to initialize this
+ // e.g. doActivate() - only problem there is to get hold of a statement ....
synchronized (initializeLock)
{
if (table == null)
@@ -177,11 +186,37 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
table.addIndex(IDBIndex.Type.UNIQUE, idField);
IDBAdapter dbAdapter = mappingStrategy.getStore().getDBAdapter();
- dbAdapter.createTable(table, statement);
+
+ Statement statement = null;
+ try
+ {
+ statement = connection.createStatement();
+ dbAdapter.createTable(table, statement);
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(statement);
+ }
}
+
+ sqlSelect = "SELECT " + typeField.getName() + " FROM " + table.getName() + " WHERE " + idField.getName() + " = ?";
+
+ sqlInsert = "INSERT INTO " + table.getName() + " VALUES (?,?)";
+
+ sqlDelete = "DELETE FROM " + table.getName() + " WHERE " + idField.getName() + " = ?";
}
}
+ public long getMaxId(Connection connection)
+ {
+ initialize(connection);
+ return DBUtil.selectMaximumLong(connection, idField);
+ }
+
@Override
protected void doBeforeActivate() throws Exception
{
@@ -190,6 +225,12 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
}
@Override
+ protected void doActivate() throws Exception
+ {
+ metaDataManager = getMappingStrategy().getStore().getMetaDataManager();
+ }
+
+ @Override
protected void doDeactivate() throws Exception
{
table = null;
@@ -197,4 +238,5 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache
typeField = null;
super.doDeactivate();
}
+
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (Hsqldb).launch b/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (Hsqldb).launch
index 619b47ff83..6aaff2769c 100644
--- a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (Hsqldb).launch
+++ b/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (Hsqldb).launch
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java"/>
+<listEntry value="/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
@@ -14,7 +14,7 @@
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.cdo.tests.AllTestsDBHsqldbPrepStmt"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.cdo.tests.AllTestsDBHsqldb"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.emf.cdo.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m&#13;&#10;-Xmx512m"/>
</launchConfiguration>
diff --git a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
index 4114614b04..84358ea184 100644
--- a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
@@ -9,7 +9,8 @@ Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.emf.cdo.tests.bundle.OM$Activator
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ClassPath: .
-Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
+Require-Bundle: com.springsource.com.mysql.jdbc;bundle-version="[5.0.0,6.0.0)";visibility:=reexport,
+ org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.emf.ecore.xmi;bundle-version="[2.4.0,3.0.0)";visibility:=reexport,
org.eclipse.net4j.db.hsqldb;bundle-version="[2.0.0,3.0.0)";visibility:=reexport,
org.eclipse.net4j.db.derby;bundle-version="[2.0.0,3.0.0)";visibility:=reexport,
@@ -48,8 +49,7 @@ Export-Package: base;version="2.0.0",
reference;version="2.0.0",
reference.impl;version="2.0.0",
reference.util;version="2.0.0"
-Import-Package: com.mysql.jdbc.jdbc2.optional;version="[5.1.0,6.0.0)";resolution:=optional,
- org.apache.commons.collections;version="[3.2.0,4.0.0)";resolution:=optional,
+Import-Package: org.apache.commons.collections;version="[3.2.0,4.0.0)";resolution:=optional,
org.apache.commons.logging;version="[1.1.0,2.0.0)";resolution:=optional,
org.apache.derby.jdbc;resolution:=optional,
org.dom4j;version="[1.6.0,2.0.0)";resolution:=optional,
diff --git a/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java b/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java
index 4774092d4c..91873ca852 100644
--- a/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/net4j/org/eclipse/net4j/tests/AbstractOMTest.java
@@ -42,7 +42,9 @@ public abstract class AbstractOMTest extends TestCase
if (!SUPPRESS_OUTPUT)
{
IOUtil.OUT().println("*******************************************************");
+ sleep(1L);
IOUtil.ERR().println(this);
+ sleep(1L);
IOUtil.OUT().println("*******************************************************");
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
index 3570b1f9b3..efb5f42fd8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
@@ -39,13 +39,19 @@ public abstract class AbstractCDOTest extends ConfigTest
@Override
protected void doSetUp() throws Exception
{
- super.doSetUp();
- org.eclipse.emf.internal.cdo.bundle.OM.PREF_COMMIT_MONITOR_PROGRESS_SECONDS.setValue(60);
- org.eclipse.emf.internal.cdo.bundle.OM.PREF_COMMIT_MONITOR_TIMEOUT_SECONDS.setValue(60 * 60);
- org.eclipse.internal.net4j.bundle.OM.DEBUG.setEnabled(false);
- org.eclipse.net4j.internal.tcp.bundle.OM.DEBUG.setEnabled(false);
- CDOPackageTypeRegistry.INSTANCE.reset();
- startTransport();
+ try
+ {
+ super.doSetUp();
+ }
+ finally
+ {
+ org.eclipse.emf.internal.cdo.bundle.OM.PREF_COMMIT_MONITOR_PROGRESS_SECONDS.setValue(60);
+ org.eclipse.emf.internal.cdo.bundle.OM.PREF_COMMIT_MONITOR_TIMEOUT_SECONDS.setValue(60 * 60);
+ org.eclipse.internal.net4j.bundle.OM.DEBUG.setEnabled(false);
+ org.eclipse.net4j.internal.tcp.bundle.OM.DEBUG.setEnabled(false);
+ CDOPackageTypeRegistry.INSTANCE.reset();
+ startTransport();
+ }
}
public static void assertEquals(Object expected, Object actual)
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
index 2a75eee075..1e019c2f51 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
*/
@@ -26,6 +26,6 @@ public class AllTests extends AllTestsAllConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, COMBINED, MEM, TCP, NATIVE);
+ addScenario(parent, COMBINED, MEM, JVM, NATIVE);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
index 857d86f437..7e8b829253 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
@@ -4,12 +4,17 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.tests;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_266982_Test;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
+
+import java.util.List;
+
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -26,6 +31,15 @@ public class AllTestsDBHsqldb extends AllTestsAllConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, COMBINED, DB_HSQL_HORIZONTAL, TCP, NATIVE);
+ addScenario(parent, COMBINED, DB_HSQL, TCP, NATIVE);
+ }
+
+ @Override
+ protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses)
+ {
+ super.initTestClasses(testClasses);
+
+ // this takes ages ...
+ testClasses.remove(Bugzilla_266982_Test.class);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbNonAudit.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbNonAudit.java
index 751b35c9e5..4e9ff8b383 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbNonAudit.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbNonAudit.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Stefan Winkler - initial API and implementation
*/
@@ -33,7 +33,7 @@ public class AllTestsDBHsqldbNonAudit extends AllTestsAllConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, COMBINED, DB_HSQL_HORIZONTAL_NONAUDIT, TCP, NATIVE);
+ addScenario(parent, COMBINED, DB_HSQL_NONAUDIT, TCP, NATIVE);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java
deleted file mode 100644
index 0402d4a8b1..0000000000
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.tests;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * @author Eike Stepper
- */
-public class AllTestsDBHsqldbPrepStmt extends AllTestsAllConfigs
-{
- public static Test suite()
- {
- return new AllTestsDBHsqldbPrepStmt().getTestSuite("CDO Tests (DB Hsql Horizontal PrepStmt)");
- }
-
- @Override
- protected void initConfigSuites(TestSuite parent)
- {
- addScenario(parent, COMBINED, DB_HSQL_HORIZONTAL_PREPSTMT, TCP, NATIVE);
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmtNonAudit.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmtNonAudit.java
deleted file mode 100644
index 412d9c9a5d..0000000000
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmtNonAudit.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.tests;
-
-import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_252214_Test;
-import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_261218_Test;
-import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
-
-import java.util.List;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * @author Stefan Winkler
- */
-public class AllTestsDBHsqldbPrepStmtNonAudit extends AllTestsAllConfigs
-{
- public static Test suite()
- {
- return new AllTestsDBHsqldbPrepStmtNonAudit().getTestSuite("CDO Tests (DB Hsql Horizontal PrepStmt Non-Audit)");
- }
-
- @Override
- protected void initConfigSuites(TestSuite parent)
- {
- addScenario(parent, COMBINED, DB_HSQL_HORIZONTAL_PREPSTMT_NONAUDIT, TCP, NATIVE);
- }
-
- @Override
- protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses)
- {
- super.initTestClasses(testClasses);
-
- // non-audit mode - remove audit tests
- testClasses.remove(AuditTest.class);
- testClasses.remove(AuditTest.LocalAuditTest.class);
- testClasses.remove(Bugzilla_252214_Test.class);
-
- // this takes ages - so for now, we disable it
- testClasses.remove(Bugzilla_261218_Test.class);
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
index 79be96a5a2..969f443749 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
*/
@@ -14,13 +14,18 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.SalesOrder;
+import org.eclipse.emf.cdo.tests.model5.GenListOfInt;
+import org.eclipse.emf.cdo.tests.model5.Model5Factory;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
/**
* @author Eike Stepper
@@ -235,4 +240,127 @@ public class ChunkingTest extends AbstractCDOTest
assertEquals(i - 20, saleOrders.getId());
}
}
+
+ private static final String RESOURCE_PATH = "/test";
+
+ public void testPartiallyLoadedAdd()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().add(9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ }
+
+ public void testPartiallyLoadedAddAtIndex()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().add(5, 9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 9, 5, 6, 7, 8);
+ }
+
+ public void testPartiallyLoadedSet()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().set(5, 9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 9, 6, 7, 8);
+ }
+
+ public void testPartiallyLoadedRemoveIndex()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().remove(5);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 6, 7, 8);
+ }
+
+ private void createInitialList()
+ {
+ CDOSession session = openSession(getModel5Package());
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.createResource(RESOURCE_PATH);
+
+ GenListOfInt list = Model5Factory.eINSTANCE.createGenListOfInt();
+
+ list.getElements().addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8));
+
+ resource.getContents().add(list);
+
+ tx.commit();
+ tx.close();
+ session.close();
+
+ clearCache(getRepository().getRevisionManager());
+ }
+
+ private void testListResult(Integer... expected)
+ {
+ List<Integer> expectedList = Arrays.asList(expected);
+
+ CDOSession session = openSession(getModel5Package());
+ CDOView view = session.openView();
+ CDOResource resource = view.getResource(RESOURCE_PATH);
+
+ EList<Integer> actualList = ((GenListOfInt)resource.getContents().get(0)).getElements();
+
+ assertEquals("List sizes differ", expectedList.size(), actualList.size());
+
+ for (int index = 0; index < expectedList.size(); index++)
+ {
+ assertEquals("Entry at index " + index + " differs", expectedList.get(index), actualList.get(index));
+ }
+
+ view.close();
+ session.close();
+ }
+
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java
index ced470c777..100684fb78 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java
@@ -13,7 +13,6 @@ package org.eclipse.emf.cdo.tests;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model3.MetaRef;
-import org.eclipse.emf.cdo.tests.model3.Model3Package;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
/**
@@ -29,19 +28,39 @@ public class MetaTest extends AbstractCDOTest
CDOResource res = transaction.createResource("/res");
MetaRef metaRef = getModel3Factory().createMetaRef();
- metaRef.setEPackageRef(Model3Package.eINSTANCE);
+ metaRef.setEPackageRef(getModel3Package());
res.getContents().add(metaRef);
transaction.commit();
session.close();
}
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource res = transaction.getResource("/res");
+
+ MetaRef metaRef = (MetaRef)res.getContents().get(0);
+ assertEquals(getModel3Package(), metaRef.getEPackageRef());
+ }
+
+ public void testMetaReferenceAttachFirst() throws Exception
+ {
{
- CDOSession session = openSession();
+ CDOSession session = openModel3Session();
CDOTransaction transaction = session.openTransaction();
- CDOResource res = transaction.getResource("/res");
+ CDOResource res = transaction.createResource("/res");
- MetaRef metaRef = (MetaRef)res.getContents().get(0);
- assertEquals(Model3Package.eINSTANCE, metaRef.getEPackageRef());
+ MetaRef metaRef = getModel3Factory().createMetaRef();
+ res.getContents().add(metaRef);
+ metaRef.setEPackageRef(getModel3Package());
+ transaction.commit();
+ session.close();
}
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource res = transaction.getResource("/res");
+
+ MetaRef metaRef = (MetaRef)res.getContents().get(0);
+ assertEquals(getModel3Package(), metaRef.getEPackageRef());
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_248052_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_248052_Test.java
index f86ba81a33..24c04f0eb6 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_248052_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_248052_Test.java
@@ -11,17 +11,9 @@
*/
package org.eclipse.emf.cdo.tests.bugzilla;
-import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.internal.common.revision.CDORevisionResolverImpl;
import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
-import org.eclipse.emf.cdo.tests.model1.Customer;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
-
-import org.eclipse.emf.internal.cdo.util.FSMUtil;
-
-import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.cdo.tests.bundle.OM;
import java.util.Map;
@@ -42,26 +34,21 @@ public class Bugzilla_248052_Test extends AbstractCDOTest
return testProperties;
}
- public void testNoSupportingDeltas() throws Exception
+ @Override
+ protected void doSetUp() throws Exception
{
- CDOSession session = openModel1Session();
-
- CDOTransaction transaction1 = session.openTransaction();
- CDOResource res = transaction1.createResource("/test1");
-
- Customer customer = getModel1Factory().createCustomer();
-
- res.getContents().add(customer);
-
- msg("Committing");
- transaction1.commit();
-
- InternalCDOObject cdoCustomer = FSMUtil.adapt(customer, transaction1);
- CDORevisionResolverImpl revisionManager = (CDORevisionResolverImpl)getRepository().getRevisionManager();
- revisionManager.removeCachedRevision(cdoCustomer.cdoID(), cdoCustomer.cdoRevision().getVersion());
-
- customer.setName("OTTAWA");
+ try
+ {
+ super.doSetUp();
+ }
+ catch (IllegalStateException ex)
+ {
+ OM.LOG.info("Expected IllegalStateException", ex);
+ }
+ }
- transaction1.commit();
+ public void testNoSupportingDeltas() throws Exception
+ {
+ // Possible failure already in doSetup()
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_251752_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_251752_Test.java
index 8ea6944453..e3105d86a8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_251752_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_251752_Test.java
@@ -28,7 +28,6 @@ import org.eclipse.emf.cdo.util.CDOUtil;
*/
public class Bugzilla_251752_Test extends AbstractCDOTest
{
-
public void testBug_251752() throws Exception
{
CDOSession session = openSession();
@@ -36,11 +35,13 @@ public class Bugzilla_251752_Test extends AbstractCDOTest
CDOResource res = transaction1.createResource("/test1");
res.getContents().add(getModel1Factory().createCompany());
transaction1.commit();
+
CDOTransaction transaction2 = session.openTransaction();
CDOResource res2 = transaction2.getResource("/test1");
res.getContents().add(getModel1Factory().createCompany());
res2.getContents().add(getModel1Factory().createCompany());
transaction2.commit();
+
try
{
transaction1.commit();
@@ -49,6 +50,7 @@ public class Bugzilla_251752_Test extends AbstractCDOTest
catch (Exception ex)
{
}
+
assertTrue(res.cdoRevision().isTransactional());
}
@@ -61,6 +63,7 @@ public class Bugzilla_251752_Test extends AbstractCDOTest
CDOResource res = transaction1.createResource("/test1");
res.getContents().add(getModel1Factory().createCompany());
transaction1.commit();
+
CDOTransaction transaction2 = session.openTransaction();
CDOResource res2 = transaction2.getResource("/test1");
res.getContents().add(getModel1Factory().createCompany());
@@ -75,6 +78,7 @@ public class Bugzilla_251752_Test extends AbstractCDOTest
catch (Exception ex)
{
}
+
assertTrue(res.cdoRevision().isTransactional());
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_272861_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_272861_Test.java
index 9d76619c9b..ef0b340d09 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_272861_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_272861_Test.java
@@ -24,39 +24,37 @@ public class Bugzilla_272861_Test extends AbstractCDOTest
{
public void test_Bugzilla_271861_Case1() throws IOException
{
-
CDOSession session = openModel1Session();
CDOTransaction trans = session.openTransaction();
CDOResource res = trans.createResource("/test/1");
-
trans.commit();
res.delete(null);
res = trans.createResource("/test/1");
trans.commit();
+
trans.close();
session.close();
-
}
// TODO SIMON Is it a bug or not??
public void te2st_Bugzilla_272861_Case2() throws IOException
{
-
CDOSession session = openModel1Session();
CDOTransaction trans1 = session.openTransaction();
-
CDOTransaction trans2 = session.openTransaction();
- CDOResource res1 = trans1.createResource("/test1");
- CDOResource res2 = trans2.createResource("/test2");
+
+ trans1.createResource("/test1");
+ trans2.createResource("/test2");
trans1.commit();
trans2.commit();
+
trans1.close();
trans2.close();
- session.close();
+ session.close();
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java
index 0f771df9bb..be3a16810f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java
@@ -33,21 +33,13 @@ public interface IConstants
public static final RepositoryConfig MEM = RepositoryConfig.MEM.INSTANCE;
- public static final RepositoryConfig DB_HSQL_HORIZONTAL = RepositoryConfig.DB.Hsqldb.Stmt.INSTANCE;
+ public static final RepositoryConfig DB_HSQL = RepositoryConfig.DB.Hsqldb.INSTANCE;
- public static final RepositoryConfig DB_HSQL_HORIZONTAL_NONAUDIT = RepositoryConfig.DB.Hsqldb.StmtNonAudit.INSTANCE;
+ public static final RepositoryConfig DB_HSQL_NONAUDIT = RepositoryConfig.DB.HsqldbNonAudit.INSTANCE;
- public static final RepositoryConfig DB_HSQL_HORIZONTAL_PREPSTMT = RepositoryConfig.DB.Hsqldb.PrepStmt.INSTANCE;
+ public static final RepositoryConfig DB_DERBY = RepositoryConfig.DB.Derby.INSTANCE;
- public static final RepositoryConfig DB_HSQL_HORIZONTAL_PREPSTMT_NONAUDIT = RepositoryConfig.DB.Hsqldb.PrepStmtNonAudit.INSTANCE;
-
- public static final RepositoryConfig DB_DERBY_HORIZONTAL = RepositoryConfig.DB.Derby.Stmt.INSTANCE;
-
- public static final RepositoryConfig DB_DERBY_HORIZONTAL_PREPSTMT = RepositoryConfig.DB.Derby.PrepStmt.INSTANCE;
-
- // public static final RepositoryConfig DB_MYSQL_HORIZONTAL = RepositoryConfig.DB.Mysql.Stmt.INSTANCE;
- //
- // public static final RepositoryConfig DB_MYSQL_HORIZONTAL_PREPSTMT = RepositoryConfig.DB.Mysql.PrepStmt.INSTANCE;
+ public static final RepositoryConfig DB_MYSQL = RepositoryConfig.DB.Mysql.INSTANCE;
public static final SessionConfig JVM = SessionConfig.JVM.INSTANCE;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index b29a90ecb9..18c926abe4 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Eike Stepper - initial API and implementation
* Stefan Winkler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=259402
@@ -19,11 +19,11 @@ import org.eclipse.emf.cdo.server.IRepositoryProvider;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IRepository.Props;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.mem.MEMStoreUtil;
import org.eclipse.emf.cdo.tests.bundle.OM;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.store.verifier.AbstractDBStoreVerifier;
import org.eclipse.emf.cdo.tests.store.verifier.AuditDBStoreIntegrityVerifier;
import org.eclipse.emf.cdo.tests.store.verifier.NonAuditDBStoreIntegrityVerifier;
@@ -32,12 +32,15 @@ import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.derby.EmbeddedDerbyAdapter;
import org.eclipse.net4j.db.hsqldb.HSQLDBAdapter;
import org.eclipse.net4j.db.hsqldb.HSQLDBDataSource;
+import org.eclipse.net4j.db.mysql.MYSQLAdapter;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.io.TMPUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
+
import org.apache.derby.jdbc.EmbeddedDataSource;
import javax.sql.DataSource;
@@ -57,10 +60,9 @@ import java.util.Map.Entry;
public abstract class RepositoryConfig extends Config implements IRepositoryConfig
{
public static final RepositoryConfig[] CONFIGS = { MEM.INSTANCE, //
- DB.Hsqldb.Stmt.INSTANCE, DB.Hsqldb.PrepStmt.INSTANCE, //
- DB.Derby.Stmt.INSTANCE, DB.Derby.PrepStmt.INSTANCE /*
- * , // DB.Mysql.Stmt.INSTANCE, DB.Mysql.PrepStmt.INSTANCE
- */};
+ DB.Hsqldb.INSTANCE, //
+ DB.Derby.INSTANCE, //
+ DB.Mysql.INSTANCE };
public static final String PROP_TEST_REPOSITORY = "test.repository";
@@ -233,13 +235,9 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
IMappingStrategy mappingStrategy = createMappingStrategy();
IDBAdapter dbAdapter = createDBAdapter();
DataSource dataSource = createDataSource();
- IJDBCDelegateProvider delegateProvider = createDelegateProvider();
- return CDODBUtil.createStore(mappingStrategy, dbAdapter, DBUtil.createConnectionProvider(dataSource),
- delegateProvider);
+ return CDODBUtil.createStore(mappingStrategy, dbAdapter, DBUtil.createConnectionProvider(dataSource));
}
- protected abstract IJDBCDelegateProvider createDelegateProvider();
-
protected abstract IMappingStrategy createMappingStrategy();
protected abstract IDBAdapter createDBAdapter();
@@ -249,10 +247,14 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
/**
* @author Eike Stepper
*/
- public abstract static class Hsqldb extends DB
+ public static class Hsqldb extends DB
{
private static final long serialVersionUID = 1L;
+ public static boolean USE_VERIFIER = false;
+
+ public static final Hsqldb INSTANCE = new Hsqldb("HSQLDB");
+
private transient HSQLDBDataSource dataSource;
public Hsqldb(String name)
@@ -294,8 +296,33 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
@Override
public void tearDown() throws Exception
{
- super.tearDown();
- shutDownHsqldb();
+ try
+ {
+ if (USE_VERIFIER)
+ {
+ IRepository testRepository = getRepository(REPOSITORY_NAME);
+ if (testRepository != null)
+ {
+ getVerifier(testRepository).verify();
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ shutDownHsqldb();
+ }
+ }
+ }
+
+ protected AbstractDBStoreVerifier getVerifier(IRepository repository)
+ {
+ return new AuditDBStoreIntegrityVerifier(repository);
}
private void shutDownHsqldb() throws SQLException
@@ -319,143 +346,48 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
}
}
}
+ }
- public static class Stmt extends Hsqldb
- {
- private static final long serialVersionUID = 1L;
-
- public static final Stmt INSTANCE = new Stmt("HsqldbHorizontalStmt");
+ public static class HsqldbNonAudit extends Hsqldb
+ {
+ private static final long serialVersionUID = 1L;
- public Stmt(String name)
- {
- super(name);
- }
+ public static final HsqldbNonAudit INSTANCE = new HsqldbNonAudit("DBStore: Hsqldb (non audit)");
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
- {
- return CDODBUtil.createStatementJDBCDelegateProvider();
- }
+ public HsqldbNonAudit(String name)
+ {
+ super(name);
}
- public static class StmtNonAudit extends Hsqldb
+ @Override
+ protected void initRepositoryProperties(Map<String, String> props)
{
- private static final long serialVersionUID = 1L;
-
- public static final StmtNonAudit INSTANCE = new StmtNonAudit("HsqldbHorizontalNonAudit");
-
- public StmtNonAudit(String name)
- {
- super(name);
- }
-
- @Override
- protected void initRepositoryProperties(Map<String, String> props)
- {
- super.initRepositoryProperties(props);
- props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
- }
-
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
- {
- return CDODBUtil.createStatementJDBCDelegateProvider();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- // verify DB integrity
- new NonAuditDBStoreIntegrityVerifier(getRepository(REPOSITORY_NAME)).verify();
- }
- finally
- {
- super.tearDown();
- }
- }
+ super.initRepositoryProperties(props);
+ props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
}
- public static class PrepStmt extends Hsqldb
+ @Override
+ protected IMappingStrategy createMappingStrategy()
{
- private static final long serialVersionUID = 1L;
-
- public static final PrepStmt INSTANCE = new PrepStmt("HsqldbHorizontalPrepStmt");
-
- public PrepStmt(String name)
- {
- super(name);
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- // verify DB integrity
- new AuditDBStoreIntegrityVerifier(getRepository(REPOSITORY_NAME)).verify();
- }
- finally
- {
- super.tearDown();
- }
- }
-
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
- {
- return CDODBUtil.createPreparedStatementJDBCDelegateProvider();
- }
+ return CDODBUtil.createHorizontalNonAuditMappingStrategy();
}
- public static class PrepStmtNonAudit extends Hsqldb
+ @Override
+ protected AbstractDBStoreVerifier getVerifier(IRepository repository)
{
- private static final long serialVersionUID = 1L;
-
- public static final PrepStmtNonAudit INSTANCE = new PrepStmtNonAudit("HsqldbHorizontalPrepStmtNonAudit");
-
- public PrepStmtNonAudit(String name)
- {
- super(name);
- }
-
- @Override
- protected void initRepositoryProperties(Map<String, String> props)
- {
- super.initRepositoryProperties(props);
- props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
- }
-
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
- {
- return CDODBUtil.createPreparedStatementJDBCDelegateProvider();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- // verify DB integrity
- new NonAuditDBStoreIntegrityVerifier(getRepository(REPOSITORY_NAME)).verify();
- }
- finally
- {
- super.tearDown();
- }
- }
+ return new NonAuditDBStoreIntegrityVerifier(repository);
}
}
/**
* @author Eike Stepper
*/
- public abstract static class Derby extends DB
+ public static class Derby extends DB
{
private static final long serialVersionUID = 1L;
+ public static final Derby INSTANCE = new Derby("DBStore: Derby");
+
private transient File dbFolder;
private transient EmbeddedDataSource dataSource;
@@ -500,176 +432,105 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
{
IOUtil.delete(dbFolder);
}
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class Mysql extends DB
+ {
+ private static final long serialVersionUID = 1L;
+
+ public static final Mysql INSTANCE = new Mysql("DBStore: Mysql");
+
+ private transient MysqlDataSource setupDataSource;
+
+ private transient MysqlDataSource dataSource;
+
+ public Mysql(String name)
+ {
+ super(name);
+ }
- public static class Stmt extends Derby
+ @Override
+ protected IMappingStrategy createMappingStrategy()
+ {
+ return CDODBUtil.createHorizontalMappingStrategy();
+ }
+
+ @Override
+ protected IDBAdapter createDBAdapter()
+ {
+ return new MYSQLAdapter();
+ }
+
+ private MysqlDataSource getSetupDataSource()
{
- private static final long serialVersionUID = 1L;
+ if (setupDataSource == null)
+ {
+ setupDataSource = new MysqlDataSource();
+ setupDataSource.setUrl("jdbc:mysql://localhost");
+ setupDataSource.setUser("sa");
+ }
- public static final Stmt INSTANCE = new Stmt("DerbyHorizontalStmt");
+ return setupDataSource;
+ }
- public Stmt(String name)
+ @Override
+ public void setUp() throws Exception
+ {
+ dropDatabase();
+ Connection connection = null;
+ try
{
- super(name);
+ connection = getSetupDataSource().getConnection();
+ connection.prepareStatement("create database cdodb1").execute();
}
+ catch (SQLException ignore)
+ {
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
+ }
+ finally
{
- return CDODBUtil.createStatementJDBCDelegateProvider();
+ connection.close();
}
+ super.setUp();
}
- public static class PrepStmt extends Derby
+ @Override
+ protected DataSource createDataSource()
{
- private static final long serialVersionUID = 1L;
+ dataSource = new MysqlDataSource();
+ dataSource.setUrl("jdbc:mysql://localhost/cdodb1");
+ dataSource.setUser("sa");
+ return dataSource;
+ }
- public static final PrepStmt INSTANCE = new PrepStmt("DerbyHorizontalPrepStmt");
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ dropDatabase();
+ }
- public PrepStmt(String name)
+ private void dropDatabase() throws Exception
+ {
+ Connection connection = null;
+ try
{
- super(name);
+ connection = getSetupDataSource().getConnection();
+ connection.prepareStatement("DROP database cdodb1").execute();
}
+ catch (SQLException ignore)
+ {
- @Override
- protected IJDBCDelegateProvider createDelegateProvider()
+ }
+ finally
{
- return CDODBUtil.createPreparedStatementJDBCDelegateProvider();
+ connection.close();
}
}
- }
- // XXX
- // /**
- // * @author Simon McDuff
- // */
- // public static abstract class Mysql extends DB
- // {
- // private static final long serialVersionUID = 1L;
- //
- // private transient MysqlDataSource setupDataSource;
- //
- // private transient MysqlDataSource dataSource;
- //
- // public Mysql(String name)
- // {
- // super(name);
- // }
- //
- // @Override
- // protected IMappingStrategy createMappingStrategy()
- // {
- // return CDODBUtil.createHorizontalMappingStrategy();
- // }
- //
- // @Override
- // protected IDBAdapter createDBAdapter()
- // {
- // return new MYSQLAdapter();
- // }
- //
- // private MysqlDataSource getSetupDataSource()
- // {
- // if (setupDataSource == null)
- // {
- // setupDataSource = new MysqlDataSource();
- // setupDataSource.setUrl("jdbc:mysql://localhost");
- // setupDataSource.setUser("sa");
- // }
- //
- // return setupDataSource;
- // }
- //
- // @Override
- // public void setUp() throws Exception
- // {
- // dropDatabase();
- // Connection connection = null;
- // try
- // {
- // connection = getSetupDataSource().getConnection();
- // connection.prepareStatement("create database cdodb1").execute();
- // }
- // catch (SQLException ignore)
- // {
- //
- // }
- // finally
- // {
- // connection.close();
- // }
- // super.setUp();
- // }
- //
- // @Override
- // protected DataSource createDataSource()
- // {
- // dataSource = new MysqlDataSource();
- // dataSource.setUrl("jdbc:mysql://localhost/cdodb1");
- // dataSource.setUser("sa");
- // return dataSource;
- // }
- //
- // @Override
- // public void tearDown() throws Exception
- // {
- // super.tearDown();
- // dropDatabase();
- // }
- //
- // private void dropDatabase() throws Exception
- // {
- // Connection connection = null;
- // try
- // {
- // connection = getSetupDataSource().getConnection();
- // connection.prepareStatement("DROP database cdodb1").execute();
- // }
- // catch (SQLException ignore)
- // {
- //
- // }
- // finally
- // {
- // connection.close();
- // }
- // }
- //
- // public static class Stmt extends Mysql
- // {
- // private static final long serialVersionUID = 1L;
- //
- // public static final Stmt INSTANCE = new Stmt("MysqlHorizontalStmt");
- //
- // public Stmt(String name)
- // {
- // super(name);
- // }
- //
- // @Override
- // protected IJDBCDelegateProvider createDelegateProvider()
- // {
- // return CDODBUtil.createStatementJDBCDelegateProvider();
- // }
- // }
- //
- // public static class PrepStmt extends Mysql
- // {
- // private static final long serialVersionUID = 1L;
- //
- // public static final PrepStmt INSTANCE = new PrepStmt("MysqlHorizontalPrepStmt");
- //
- // public PrepStmt(String name)
- // {
- // super(name);
- // }
- //
- // @Override
- // protected IJDBCDelegateProvider createDelegateProvider()
- // {
- // return CDODBUtil.createPreparedStatementJDBCDelegateProvider();
- // }
- // }
- // }
+ }
}
-
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Scenario.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Scenario.java
index 25a4a7b079..a37437d150 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Scenario.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/Scenario.java
@@ -179,10 +179,28 @@ public class Scenario implements IScenario
public synchronized void setUp() throws Exception
{
- getContainerConfig().setUp();
- getRepositoryConfig().setUp();
- getSessionConfig().setUp();
- getModelConfig().setUp();
+ try
+ {
+ getContainerConfig().setUp();
+ }
+ finally
+ {
+ try
+ {
+ getRepositoryConfig().setUp();
+ }
+ finally
+ {
+ try
+ {
+ getSessionConfig().setUp();
+ }
+ finally
+ {
+ getModelConfig().setUp();
+ }
+ }
+ }
}
public synchronized void tearDown() throws Exception
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
index b64be0a821..0408de451f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java
@@ -138,16 +138,19 @@ public abstract class SessionConfig extends Config implements ISessionConfig
{
try
{
- for (CDOSession session : sessions)
+ if (sessions != null)
{
- session.removeListener(sessionListener);
- LifecycleUtil.deactivate(session);
+ for (CDOSession session : sessions)
+ {
+ session.removeListener(sessionListener);
+ LifecycleUtil.deactivate(session);
+ }
+
+ sessions.clear();
+ sessions = null;
}
sessionListener = null;
- sessions.clear();
- sessions = null;
-
stopTransport();
super.tearDown();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AbstractDBStoreVerifier.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AbstractDBStoreVerifier.java
index 87f2babdb8..01af44df1a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AbstractDBStoreVerifier.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AbstractDBStoreVerifier.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Stefan Winkler - initial API and implementation
*/
@@ -45,7 +45,10 @@ public abstract class AbstractDBStoreVerifier
public AbstractDBStoreVerifier(IRepository repository)
{
this.repository = repository;
- assertTrue(repository.getStore() instanceof IDBStore);
+ if (repository != null)
+ {
+ assertTrue(repository.getStore() instanceof IDBStore);
+ }
}
protected IRepository getRepository()
@@ -65,7 +68,15 @@ public abstract class AbstractDBStoreVerifier
accessor = (IDBStoreAccessor)repository.getStore().getReader(null);
}
- return accessor.getJDBCDelegate().getStatement();
+ try
+ {
+ return accessor.getConnection().createStatement();
+ }
+ catch (SQLException ex)
+ {
+ ex.printStackTrace();
+ return null;
+ }
}
protected List<IClassMapping> getClassMappings()
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
index 06edaf44b4..6b8eb25883 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
@@ -14,11 +14,11 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy;
import org.eclipse.net4j.util.collection.Pair;
@@ -38,9 +38,7 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
super(repo);
// this is a verifier for auditing mode
- assertTrue(getStore().getRevisionTemporality() == IStore.RevisionTemporality.AUDITING);
- // ... and for horizontal class mapping
- assertTrue(getStore().getMappingStrategy() instanceof HorizontalMappingStrategy);
+ assertTrue(getStore().getMappingStrategy() instanceof HorizontalAuditMappingStrategy);
}
@Override
@@ -48,7 +46,7 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
{
for (IClassMapping mapping : getClassMappings())
{
- if (mapping != null && mapping.getTable() != null)
+ if (mapping != null && mapping.getDBTables() != null)
{
verifyClassMapping(mapping);
}
@@ -64,7 +62,7 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
private void verifyAtMostOneUnrevised(IClassMapping mapping) throws Exception
{
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
TRACER.format("verifyAtMostOneUnrevised: {0} ...", tableName);
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", count(1) FROM " + tableName + " WHERE "
@@ -90,7 +88,7 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
*/
private void verifyUniqueIdVersion(IClassMapping mapping) throws Exception
{
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
TRACER.format("verifyUniqueIdVersion: {0} ...", tableName);
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + "," + CDODBSchema.ATTRIBUTES_VERSION + ", count(1) FROM "
@@ -120,13 +118,14 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
private void verifyReferences(IClassMapping mapping) throws Exception
{
- List<IReferenceMapping> referenceMappings = mapping.getReferenceMappings();
- if (referenceMappings == null)
+ List<IListMapping> listMappings = ((HorizontalAuditClassMapping)mapping).getListMappings();
+ if (listMappings == null)
{
return;
}
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
+ ;
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", " + CDODBSchema.ATTRIBUTES_VERSION + " FROM " + tableName;
ArrayList<Pair<Long, Integer>> idVersions = new ArrayList<Pair<Long, Integer>>();
@@ -144,24 +143,23 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
resultSet.close();
}
- for (IReferenceMapping refMapping : referenceMappings)
+ for (IListMapping listMapping : listMappings)
{
for (Pair<Long, Integer> idVersion : idVersions)
{
- verifyCorrectIndices(refMapping, idVersion.getElement1(), idVersion.getElement2());
+ verifyCorrectIndices(listMapping, idVersion.getElement1(), idVersion.getElement2());
}
}
}
- private void verifyCorrectIndices(IReferenceMapping refMapping, long id, int version) throws Exception
+ private void verifyCorrectIndices(IListMapping refMapping, long id, int version) throws Exception
{
- String tableName = refMapping.getTable().getName();
+ String tableName = refMapping.getDBTables().iterator().next().getName();
TRACER.format("verifyUniqueIdVersion: {0} for ID{1}v{2} ...", tableName, id, version);
- String sql = "SELECT " + CDODBSchema.REFERENCES_IDX + " FROM " + tableName + " WHERE "
- + CDODBSchema.REFERENCES_SOURCE + "=" + id + " AND " + CDODBSchema.REFERENCES_VERSION + "=" + version
- + " ORDER BY " + CDODBSchema.REFERENCES_IDX;
+ String sql = "SELECT " + CDODBSchema.LIST_IDX + " FROM " + tableName + " WHERE " + CDODBSchema.LIST_REVISION_ID
+ + "=" + id + " AND " + CDODBSchema.LIST_REVISION_VERSION + "=" + version + " ORDER BY " + CDODBSchema.LIST_IDX;
TRACER.format(" Executing SQL: {0} ", sql);
@@ -178,8 +176,8 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
}
catch (AssertionFailedError e)
{
- sqlDump("SELECT * FROM " + tableName + " WHERE " + CDODBSchema.REFERENCES_SOURCE + "=" + id + " AND "
- + CDODBSchema.REFERENCES_VERSION + "=" + version + " ORDER BY " + CDODBSchema.REFERENCES_IDX);
+ sqlDump("SELECT * FROM " + tableName + " WHERE " + CDODBSchema.LIST_REVISION_ID + "=" + id + " AND "
+ + CDODBSchema.LIST_REVISION_VERSION + "=" + version + " ORDER BY " + CDODBSchema.LIST_IDX);
throw e;
}
finally
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
index 09e30a5128..261482905a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Stefan Winkler - initial API and implementation
*/
@@ -16,9 +16,10 @@ import static junit.framework.Assert.assertTrue;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IReferenceMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditClassMapping;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy;
import org.eclipse.net4j.util.collection.Pair;
@@ -38,7 +39,7 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
// this is a verifier for non-auditing mode
assertTrue(getStore().getRevisionTemporality() == IStore.RevisionTemporality.NONE);
// ... and for horizontal class mapping
- assertTrue(getStore().getMappingStrategy() instanceof HorizontalMappingStrategy);
+ assertTrue(getStore().getMappingStrategy() instanceof HorizontalNonAuditMappingStrategy);
}
@Override
@@ -46,7 +47,7 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
{
for (IClassMapping mapping : getClassMappings())
{
- if (mapping != null && mapping.getTable() != null)
+ if (mapping != null && mapping.getDBTables().size() > 0)
{
verifyClassMapping(mapping);
}
@@ -65,7 +66,7 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
*/
private void verifyNoUnrevisedRevisions(IClassMapping mapping) throws Exception
{
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.ATTRIBUTES_REVISED + " <> 0";
ResultSet resultSet = getStatement().executeQuery(sql);
try
@@ -84,7 +85,7 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
*/
private void verifyUniqueId(IClassMapping mapping) throws Exception
{
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", count(1) FROM " + tableName + " GROUP BY "
+ CDODBSchema.ATTRIBUTES_ID;
@@ -105,13 +106,13 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
private void verifyReferences(IClassMapping mapping) throws Exception
{
- List<IReferenceMapping> referenceMappings = mapping.getReferenceMappings();
+ List<IListMapping> referenceMappings = ((HorizontalNonAuditClassMapping)mapping).getListMappings();
if (referenceMappings == null)
{
return;
}
- String tableName = mapping.getTable().getName();
+ String tableName = mapping.getDBTables().iterator().next().getName();
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", " + CDODBSchema.ATTRIBUTES_VERSION + " FROM " + tableName;
ArrayList<Pair<Long, Integer>> idVersions = new ArrayList<Pair<Long, Integer>>();
@@ -129,43 +130,20 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
resultSet.close();
}
- for (IReferenceMapping refMapping : referenceMappings)
+ for (IListMapping refMapping : referenceMappings)
{
for (Pair<Long, Integer> idVersion : idVersions)
{
- verifyOnlyLatestReferences(refMapping, idVersion.getElement1(), idVersion.getElement2());
verifyCorrectIndices(refMapping, idVersion.getElement1());
}
}
}
- /**
- * Verify that no reference with sourceId == ID exist which have another version
- */
- private void verifyOnlyLatestReferences(IReferenceMapping refMapping, long id, int version) throws Exception
- {
- String tableName = refMapping.getTable().getName();
- String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.REFERENCES_SOURCE + "=" + id + " AND "
- + CDODBSchema.REFERENCES_VERSION + "<>" + version;
-
- ResultSet resultSet = getStatement().executeQuery(sql);
- try
- {
- assertTrue(resultSet.next());
- assertEquals("Table " + tableName + " contains old references for id " + id + "(version should be " + version
- + ")", 0, resultSet.getInt(1));
- }
- finally
- {
- resultSet.close();
- }
- }
-
- private void verifyCorrectIndices(IReferenceMapping refMapping, long id) throws Exception
+ private void verifyCorrectIndices(IListMapping refMapping, long id) throws Exception
{
- String tableName = refMapping.getTable().getName();
- String sql = "SELECT " + CDODBSchema.REFERENCES_IDX + " FROM " + tableName + " WHERE "
- + CDODBSchema.REFERENCES_SOURCE + "=" + id + " ORDER BY " + CDODBSchema.REFERENCES_IDX;
+ String tableName = refMapping.getDBTables().iterator().next().getName();
+ String sql = "SELECT " + CDODBSchema.LIST_IDX + " FROM " + tableName + " WHERE " + CDODBSchema.LIST_REVISION_ID
+ + "=" + id + " ORDER BY " + CDODBSchema.LIST_IDX;
ResultSet resultSet = getStatement().executeQuery(sql);
int indexShouldBe = 0;

Back to the top