Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--features/org.eclipse.emf.cdo.server.db-feature/feature.xml2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy2.java29
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java36
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java79
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java897
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java29
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java50
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java1046
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/MongoDBStore.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java43
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalStore.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java18
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.all/META-INF/MANIFEST.MF6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.all/src/org/eclipse/emf/cdo/tests/all/GerritTests.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AbstractSetupDBConfig.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Audit.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2BranchingUUIDs.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2NonAudit.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBMysql.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AnyTestManyTimesDB.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Bugzilla_351068_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DerbyConfig.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/HsqldbConfig.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/MysqlConfig.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/OracleConfig.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/performance/AllPerformanceTestsH2NonAudit.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.lissome/META-INF/MANIFEST.MF6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.mongodb/src/org/eclipse/emf/cdo/tests/mongodb/MongoDBConfig.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CDOIDTest.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingClearCachedRevisionTest.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CrossReferenceTest.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java18
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FeatureMapTest.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java108
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MetaTest.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MultiValuedOfAttributeTest.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_306998_Test.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_322218_Test.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_323930_Test.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_335675_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337054_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337587_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_351393_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405606_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_436246_Test.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485394_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IRepositoryConfig.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/ConfigTest.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java20
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java42
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java3
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java6
77 files changed, 1653 insertions, 1073 deletions
diff --git a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml
index 54b7add447..b093772ecc 100644
--- a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml
+++ b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml
@@ -12,7 +12,7 @@
<feature
id="org.eclipse.emf.cdo.server.db"
label="%featureName"
- version="4.4.100.qualifier"
+ version="4.5.0.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.emf.cdo.license"
license-feature-version="0.0.0">
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 080b953d5a..a80fee0aae 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
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.server.db;singleton:=true
-Bundle-Version: 4.4.100.qualifier
+Bundle-Version: 4.5.0.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -12,10 +12,10 @@ Bundle-ClassPath: .
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
org.eclipse.net4j.db;bundle-version="[4.0.0,5.0.0)";visibility:=reexport,
org.eclipse.emf.cdo.server;bundle-version="[4.0.0,5.0.0)";visibility:=reexport
-Export-Package: org.eclipse.emf.cdo.server.db;version="4.4.100",
- org.eclipse.emf.cdo.server.db.mapping;version="4.4.100",
- org.eclipse.emf.cdo.server.internal.db;version="4.4.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui",
- org.eclipse.emf.cdo.server.internal.db.bundle;version="4.4.100";x-internal:=true,
- org.eclipse.emf.cdo.server.internal.db.mapping;version="4.4.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db",
- org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.4.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db",
- org.eclipse.emf.cdo.server.internal.db.messages;version="4.4.100";x-internal:=true
+Export-Package: org.eclipse.emf.cdo.server.db;version="4.5.0",
+ org.eclipse.emf.cdo.server.db.mapping;version="4.5.0",
+ org.eclipse.emf.cdo.server.internal.db;version="4.5.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui",
+ org.eclipse.emf.cdo.server.internal.db.bundle;version="4.5.0";x-internal:=true,
+ org.eclipse.emf.cdo.server.internal.db.mapping;version="4.5.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db",
+ org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.5.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db",
+ org.eclipse.emf.cdo.server.internal.db.messages;version="4.5.0";x-internal:=true
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 19fb5be943..3f158fccab 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
@@ -10,11 +10,14 @@
*/
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.IStoreAccessor.UnitSupport;
import org.eclipse.net4j.db.IDBConnection;
+import org.eclipse.emf.ecore.EClass;
+
import java.sql.Connection;
/**
@@ -36,6 +39,11 @@ public interface IDBStoreAccessor extends IStoreAccessor.Raw2, UnitSupport
public Connection getConnection();
/**
+ * @since 4.5
+ */
+ public EClass getObjectType(CDOID id);
+
+ /**
* @since 2.0
* @deprecated As of 4.2 use {@link IDBConnection#prepareStatement(String, org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability)}.
*/
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy2.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy2.java
new file mode 100644
index 0000000000..cbf383ba98
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy2.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 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.cdo.server.IStoreAccessor.CommitContext;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+/**
+ * Interface to complement {@link IMappingStrategy}.
+ *
+ * @author Eike Stepper
+ * @since 4.5
+ */
+public interface IMappingStrategy2 extends IMappingStrategy
+{
+ public boolean needsRevisionPostProcessing();
+
+ public void postProcessRevisions(IDBStoreAccessor accessor, CommitContext context, OMMonitor monitor);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
index 154bf1243d..ff53f34073 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
@@ -28,7 +28,8 @@ public enum DBAnnotation
COLUMN_NAME("columnName"), //
COLUMN_TYPE("columnType"), //
COLUMN_LENGTH("columnLength"), //
- TYPE_MAPPING("typeMapping");
+ TYPE_MAPPING("typeMapping"), //
+ INVERSE_LIST("inverseList");
public static final String SOURCE_URI = "http://www.eclipse.org/CDO/DBStore";
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 c658103dbc..39a8c36597 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
@@ -39,6 +39,7 @@ import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.IStoreAccessor.DurableLocking2;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.IView;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
@@ -47,6 +48,7 @@ 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.db.mapping.IMappingStrategy2;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.UnitMappingTable;
@@ -209,7 +211,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
return mappingStrategy.readObjectType(this, id);
}
- protected EClass getObjectType(CDOID id)
+ public EClass getObjectType(CDOID id)
{
IRepository repository = getStore().getRepository();
if (id.equals(repository.getRootResourceID()))
@@ -223,6 +225,16 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
return result;
}
+ CommitContext commitContext = StoreThreadLocal.getCommitContext();
+ if (commitContext != null)
+ {
+ InternalCDORevision revision = commitContext.getNewRevisions().get(id);
+ if (revision != null)
+ {
+ return revision.getEClass();
+ }
+ }
+
CDOClassifierRef type = readObjectType(id);
if (type != null)
{
@@ -603,6 +615,28 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
mapping.writeRevision(this, revision, mapType, revise, monitor);
}
+ @Override
+ protected boolean needsRevisionPostProcessing()
+ {
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+ if (mappingStrategy instanceof IMappingStrategy2)
+ {
+ return ((IMappingStrategy2)mappingStrategy).needsRevisionPostProcessing();
+ }
+
+ return super.needsRevisionPostProcessing();
+ }
+
+ @Override
+ protected void postProcessRevisions(InternalCommitContext context, OMMonitor monitor)
+ {
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+ if (mappingStrategy instanceof IMappingStrategy2)
+ {
+ ((IMappingStrategy2)mappingStrategy).postProcessRevisions(this, context, monitor);
+ }
+ }
+
/*
* XXX Eike: change API from CDOID[] to CDOIDAndVersion[]
*/
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
index fa26cae563..1de3e75ff8 100644
--- 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
@@ -508,7 +508,7 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
{
async = monitor.forkAsync();
- boolean isInitialCommit = passedPackageUnits && contains(packageUnits, EresourcePackage.eINSTANCE.getNsURI());
+ boolean isInitialCommit = passedPackageUnits && containsPackageUnit(packageUnits, EresourcePackage.eINSTANCE.getNsURI());
if (isInitialCommit)
{
systemPackageMappingInfo = new SystemPackageMappingInfo();
@@ -629,42 +629,33 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
return store.getDBSchema().getTable(tableName) != null;
}
- private boolean contains(InternalCDOPackageUnit[] packageUnits, String packageUnitID)
+ protected Set<IClassMapping> mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap)
{
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- if (packageUnit.getID().equals(packageUnitID))
- {
- return true;
- }
- }
+ Set<IClassMapping> classMappings = new HashSet<IClassMapping>();
- return false;
- }
-
- private void mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap)
- {
if (packageUnits != null && packageUnits.length != 0)
{
for (InternalCDOPackageUnit packageUnit : packageUnits)
{
InternalCDOPackageInfo[] packageInfos = packageUnit.getPackageInfos();
- mapPackageInfos(packageInfos, connection, unmap);
+ mapPackageInfos(packageInfos, connection, unmap, classMappings);
}
}
+
+ return classMappings;
}
- private void mapPackageInfos(InternalCDOPackageInfo[] packageInfos, Connection connection, boolean unmap)
+ private void mapPackageInfos(InternalCDOPackageInfo[] packageInfos, Connection connection, boolean unmap, Set<IClassMapping> classMappings)
{
for (InternalCDOPackageInfo packageInfo : packageInfos)
{
EPackage ePackage = packageInfo.getEPackage();
EClass[] persistentClasses = EMFUtil.getPersistentClasses(ePackage);
- mapClasses(connection, unmap, persistentClasses);
+ mapClasses(connection, unmap, persistentClasses, classMappings);
}
}
- private void mapClasses(Connection connection, boolean unmap, EClass... eClasses)
+ private void mapClasses(Connection connection, boolean unmap, EClass[] eClasses, Set<IClassMapping> classMappings)
{
for (EClass eClass : eClasses)
{
@@ -678,13 +669,10 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
continue;
}
- if (unmap)
- {
- removeClassMapping(eClass);
- }
- else
+ IClassMapping classMapping = unmap ? removeClassMapping(eClass) : createClassMapping(eClass);
+ if (classMapping != null)
{
- createClassMapping(eClass);
+ classMappings.add(classMapping);
}
}
}
@@ -692,29 +680,30 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
private IClassMapping createClassMapping(EClass eClass)
{
- IClassMapping mapping = doCreateClassMapping(eClass);
- if (mapping != null)
+ IClassMapping classMapping = doCreateClassMapping(eClass);
+ if (classMapping != null)
{
- classMappings.put(eClass, mapping);
+ classMappings.put(eClass, classMapping);
}
- return mapping;
+ return classMapping;
}
private IClassMapping removeClassMapping(EClass eClass)
{
- IClassMapping mapping = classMappings.get(eClass);
- if (mapping != null)
+ IClassMapping classMapping = classMappings.get(eClass);
+ if (classMapping != null)
{
IDBSchema schema = getStore().getDBSchema();
- for (IDBTable table : mapping.getDBTables())
+ for (IDBTable table : classMapping.getDBTables())
{
schema.removeTable(table.getName());
}
classMappings.remove(eClass);
}
- return mapping;
+
+ return classMapping;
}
protected abstract IClassMapping doCreateClassMapping(EClass eClass);
@@ -781,17 +770,14 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false);
for (InternalCDOPackageInfo packageInfo : packageRegistry.getPackageInfos())
{
- if (!packageInfo.isSystemPackage())
+ for (EClassifier eClassifier : packageInfo.getEPackage().getEClassifiers())
{
- for (EClassifier eClassifier : packageInfo.getEPackage().getEClassifiers())
+ if (eClassifier instanceof EClass)
{
- if (eClassifier instanceof EClass)
+ EClass eClass = (EClass)eClassifier;
+ if (isMapped(eClass))
{
- EClass eClass = (EClass)eClassifier;
- if (isMapped(eClass))
- {
- getClassMapping(eClass); // Get or create it
- }
+ getClassMapping(eClass); // Get or create it
}
}
}
@@ -842,6 +828,19 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
}
}
+ private static boolean containsPackageUnit(InternalCDOPackageUnit[] packageUnits, String packageUnitID)
+ {
+ for (InternalCDOPackageUnit packageUnit : packageUnits)
+ {
+ if (packageUnit.getID().equals(packageUnitID))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
private static Set<CDOFeatureType> doGetForceIndexes(IMappingStrategy mappingStrategy)
{
return CDOFeatureType.readCombination(mappingStrategy.getProperties().get(Props.FORCE_INDEXES));
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
index d872901630..266089cada 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
@@ -12,14 +12,40 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
+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.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMapping3;
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.bundle.OM;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBUtil;
+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.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
/**
* @author Stefan Winkler
*/
@@ -75,4 +101,875 @@ public abstract class AbstractBasicListTableMapping implements IListMapping3, IM
}
public abstract void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version);
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class AbstractListDeltaWriter implements CDOFeatureDeltaVisitor
+ {
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractListDeltaWriter.class);
+
+ private static final int UNBOUNDED_SHIFT = -1;
+
+ private static final int NO_INDEX = Integer.MIN_VALUE;
+
+ private static final int NONE = 0;
+
+ private static final int SET = 1 << 1;
+
+ private static final int MOVE = 1 << 2;
+
+ private static final int INSERT = 1 << 3;
+
+ private static final int DELETE = 1 << 4;
+
+ protected final IDBStoreAccessor accessor;
+
+ protected final CDOID id;
+
+ private final List<CDOFeatureDelta> listChanges;
+
+ private final List<Manipulation> manipulations;
+
+ private boolean clearFirst;
+
+ private int offsetBefore;
+
+ /**
+ * Start of a range [tempIndex, tempIndex-1, ...] which lies outside of the normal list indexes and which serve as
+ * temporary space to move items temporarily to get them out of the way of other operations.
+ */
+ private int tmpIndex = -1;
+
+ private int newListSize;
+
+ public AbstractListDeltaWriter(IDBStoreAccessor accessor, CDOID id, List<CDOFeatureDelta> listChanges, int oldListSize)
+ {
+ this.accessor = accessor;
+ this.id = id;
+ this.listChanges = listChanges;
+
+ manipulations = createManipulations(id, listChanges, oldListSize);
+ newListSize = oldListSize;
+ }
+
+ public void writeListDeltas()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Processing list deltas..."); //$NON-NLS-1$
+ }
+
+ for (CDOFeatureDelta listDelta : listChanges)
+ {
+ listDelta.accept(this);
+ }
+
+ boolean zeroBasedIndex = ((HorizontalNonAuditMappingStrategy)accessor.getStore().getMappingStrategy()).shallForceZeroBasedIndex();
+ if (!zeroBasedIndex)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Optimizing list indexes..."); //$NON-NLS-1$
+ }
+
+ optimizeListIndexes();
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Result to be written to DB:");
+ for (Manipulation manipulation : manipulations)
+ {
+ TRACER.trace(manipulation.toString());
+ }
+ }
+
+ try
+ {
+ writeResultToDatabase();
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+
+ throw new NewListSizeResult(newListSize);
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - insert at {0} value {1}", delta.getIndex(), delta.getValue()); //$NON-NLS-1$
+ }
+
+ // Make room for the new item
+ shiftIndexes(delta.getIndex(), UNBOUNDED_SHIFT, +1);
+
+ // Create the item
+ manipulations.add(Manipulation.createInsertedElement(delta.getIndex(), delta.getValue()));
+ ++newListSize;
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - remove at {0}", delta.getIndex()); //$NON-NLS-1$
+ }
+
+ Manipulation e = findManipulation(delta.getIndex());
+ deleteItem(e);
+
+ // Fill the gap by shifting all subsequent items down
+ shiftIndexes(delta.getIndex() + 1, UNBOUNDED_SHIFT, -1);
+ --newListSize;
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - set at {0} value {1}", delta.getIndex(), delta.getValue()); //$NON-NLS-1$
+ }
+
+ Manipulation manipulation = findManipulation(delta.getIndex());
+
+ // Set the new value
+ manipulation.value = delta.getValue();
+
+ // If the item is freshly inserted we do not set the SET-mark.
+ // Setting the value of a new item results in inserting with the new value at once.
+ if (!manipulation.is(INSERT))
+ {
+ // Else mark the existing item to be set to a new value
+ manipulation.addType(SET);
+ }
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ // TODO Shouldn't that be "!unsettable"?!
+ if (delta.getFeature().isUnsettable())
+ {
+ throw new IllegalArgumentException("Feature is unsettable: " + delta);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - unset list"); //$NON-NLS-1$
+ }
+
+ // Set the clear-flag
+ clearFirst = true;
+
+ // And also clear all manipulation items
+ manipulations.clear();
+ newListSize = 0;
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - clear list"); //$NON-NLS-1$
+ }
+
+ // Set the clear-flag
+ clearFirst = true;
+
+ // And also clear all manipulation items
+ manipulations.clear();
+ newListSize = 0;
+ }
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ int fromIdx = delta.getOldPosition();
+ int toIdx = delta.getNewPosition();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - move {0} -> {1}", fromIdx, toIdx); //$NON-NLS-1$
+ }
+
+ // Ignore the trivial case
+ if (fromIdx == toIdx)
+ {
+ return;
+ }
+
+ Manipulation manipulation = findManipulation(fromIdx);
+
+ // Adjust indexes and shift either up or down
+ if (fromIdx < toIdx)
+ {
+ shiftIndexes(fromIdx + 1, toIdx, -1);
+ }
+ else
+ {
+ // fromIdx > toIdx here
+ shiftIndexes(toIdx, fromIdx - 1, +1);
+ }
+
+ // Set the new index
+ manipulation.dstIndex = toIdx;
+
+ // If it is a new element, no MOVE mark needed, because we insert it at the new position
+ if (!manipulation.is(INSERT))
+ {
+ // Else we need to handle the move of an existing item
+ manipulation.addType(MOVE);
+ }
+ }
+
+ @Deprecated
+ public void visit(CDOListFeatureDelta delta)
+ {
+ throw new UnsupportedOperationException("Should never be called");
+ }
+
+ @Deprecated
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ throw new UnsupportedOperationException("Should never be called");
+ }
+
+ protected List<Manipulation> createManipulations(CDOID id, List<CDOFeatureDelta> listChanges, int oldListSize)
+ {
+ List<Manipulation> manipulations = new ArrayList<Manipulation>(oldListSize);
+
+ // Create list and initialize with original indexes
+ for (int i = 0; i < oldListSize; i++)
+ {
+ manipulations.add(Manipulation.createOriginalElement(i));
+ }
+
+ return manipulations;
+ }
+
+ /**
+ * Helper method: shift all (destination) indexes in the interval [from,to] (inclusive at both ends) by offset
+ * (positive or negative).
+ */
+ private void shiftIndexes(int from, int to, int offset)
+ {
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.dstIndex >= from && (to == UNBOUNDED_SHIFT || manipulation.dstIndex <= to))
+ {
+ manipulation.dstIndex += offset;
+ }
+ }
+ }
+
+ /**
+ * Find a manipulation item by destination index).
+ */
+ private Manipulation findManipulation(int index)
+ {
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.dstIndex == index)
+ {
+ return manipulation;
+ }
+ }
+
+ throw new IllegalStateException("Should never be reached");
+ }
+
+ /**
+ * Delete an element (used in remove and clear)
+ */
+ private void deleteItem(Manipulation manipulation)
+ {
+ if (manipulation.is(INSERT))
+ {
+ // Newly inserted items are simply removed, as removing inserted items is equal to no change at all.
+ manipulations.remove(manipulation);
+ }
+ else
+ {
+ // Mark the existing item as to be deleted.
+ // Previous MOVE and SET conditions are overridden by setting the exclusive DELETE type.
+ manipulation.types = DELETE;
+ manipulation.dstIndex = NO_INDEX;
+ }
+ }
+
+ /**
+ * Called after all deltas are applied and before the results are written to the database. This method post-processes
+ * the manipulation elements in order to minimize database access.
+ */
+ private void optimizeListIndexes()
+ {
+ /*
+ * This is an optimization which reduces the amount of modifications on the database to maintain list indexes. For
+ * the optimization, we let go of the assumption that indexes are zero-based. Instead, we work with an offset at
+ * the database level which can change with every change to the list (e.g. if the second element is removed from a
+ * list with 1000 elements, instead of shifting down indexes 2 to 1000 by 1, we shift up index 0 by 1 and have now
+ * a list with indexes starting at 1 instead of 0. This optimization is applied by modifying the list of
+ * Manipulations, which can be seen as the database modification plan.
+ */
+
+ // First, get the current offset.
+ offsetBefore = getCurrentIndexOffset();
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Offset optimization."); //$NON-NLS-1$
+ TRACER.trace("Current offset = " + offsetBefore); //$NON-NLS-1$
+ }
+
+ applyOffsetToSourceIndexes(offsetBefore);
+
+ int offsetAfter;
+
+ if ((long)Math.abs(offsetBefore) + (long)manipulations.size() > Integer.MAX_VALUE)
+ {
+ // Safety belt for really huge collections or for collections that have been manipulated lots of times
+ // -> Do not optimize after this border is crossed. Instead, reset offset for the whole list to a zero-based
+ // index.
+ offsetAfter = 0;
+ }
+ else
+ {
+ offsetAfter = calculateOptimalOffset();
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("New offset = " + offsetAfter); //$NON-NLS-1$
+ }
+
+ applyOffsetToDestinationIndexes(offsetAfter);
+
+ // Make sure temporary indexes do not get in the way of the other operations.
+ tmpIndex = Math.min(offsetBefore, offsetAfter) - 1;
+ }
+
+ /**
+ * Calculate the optimal offset w.r.t. the manipulations planned. The optimal offset is the offset which occurs the
+ * most in the manipulations (because letting this offset be neutral leads to the least manipulations. Note: the
+ * zero offset is also regarded as an offset as any other, because selecting an offset != 0 would also lead to
+ * elements with original offset 0 to be moved.
+ */
+ private int calculateOptimalOffset()
+ {
+ HashMap<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
+ int bestOffset = 0;
+ int bestOffsetOccurrence = 0;
+
+ for (Manipulation manipulation : manipulations)
+ {
+ int srcIndex = manipulation.srcIndex;
+ int dstIndex = manipulation.dstIndex;
+
+ if (srcIndex != NO_INDEX && dstIndex != NO_INDEX)
+ {
+ int offset = dstIndex - srcIndex;
+ Integer oldOccurrence = occurrences.get(offset);
+
+ int newOccurrence;
+ if (oldOccurrence == null)
+ {
+ newOccurrence = 1;
+ }
+ else
+ {
+ newOccurrence = oldOccurrence + 1;
+ }
+
+ occurrences.put(offset, newOccurrence);
+
+ // Remember maximum along the way
+ if (newOccurrence > bestOffsetOccurrence)
+ {
+ bestOffsetOccurrence = newOccurrence;
+ bestOffset = offset;
+ }
+ }
+ }
+
+ // The offset which has occurred the most has to be applied negatively to normalize the list
+ // therefore return the negative offset as the new offset to be applied
+ return -bestOffset;
+ }
+
+ private void applyOffsetToSourceIndexes(int offsetBefore)
+ {
+ if (offsetBefore != 0)
+ {
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.srcIndex != NO_INDEX)
+ {
+ manipulation.srcIndex += offsetBefore;
+ }
+ }
+ }
+ }
+
+ private void applyOffsetToDestinationIndexes(int offsetAfter)
+ {
+ if (offsetAfter != 0)
+ {
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.dstIndex != NO_INDEX)
+ {
+ // Apply the offset to all indices to make them relative to the new offset
+ manipulation.dstIndex += offsetAfter;
+ }
+ }
+ }
+ }
+
+ protected final int getOffsetBefore()
+ {
+ return offsetBefore;
+ }
+
+ protected final int getNextTmpIndex()
+ {
+ return --tmpIndex;
+ }
+
+ /**
+ * Write calculated changes to the database
+ */
+ protected void writeResultToDatabase() throws SQLException
+ {
+ IIDHandler idHandler = accessor.getStore().getIDHandler();
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Writing to database:"); //$NON-NLS-1$
+ }
+
+ if (clearFirst)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" - clear list"); //$NON-NLS-1$
+ }
+
+ clearList();
+ }
+
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.is(DELETE))
+ {
+ /*
+ * Step 1: DELETE all elements e which have e.is(DELETE) by e.srcIndex
+ */
+ dbDelete(idHandler, manipulation.srcIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - delete at {0} ", manipulation.srcIndex); //$NON-NLS-1$
+ }
+ }
+
+ if (manipulation.is(MOVE))
+ {
+ /*
+ * Step 2: MOVE all elements e (by e.srcIndex) which have e.is(MOVE) to tmpIndex (-1, -2, -3, -4, ...) and
+ * store tmpIndex in e.tempIndex
+ */
+ manipulation.tmpIndex = getNextTmpIndex();
+ dbMove(idHandler, manipulation.srcIndex, manipulation.tmpIndex, manipulation.srcIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - move {0} -> {1} ", manipulation.srcIndex, manipulation.tmpIndex); //$NON-NLS-1$
+ }
+ }
+ }
+
+ writeShifts(idHandler);
+
+ ITypeMapping typeMapping = getTypeMapping();
+ for (Manipulation manipulation : manipulations)
+ {
+ if (manipulation.is(MOVE))
+ {
+ /*
+ * Step 4: MOVE all elements e have e.is(MOVE) from e.tempIdx to e.dstIndex (because we have moved them
+ * before, moveStmt is always initialized
+ */
+ dbMove(idHandler, manipulation.tmpIndex, manipulation.dstIndex, manipulation.srcIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - move {0} -> {1} ", manipulation.tmpIndex, manipulation.dstIndex); //$NON-NLS-1$
+ }
+ }
+
+ if (manipulation.is(SET))
+ {
+ /*
+ * Step 5: SET all elements which have e.type == SET by index == e.dstIndex
+ */
+ dbSet(idHandler, typeMapping, manipulation.dstIndex, manipulation.value, manipulation.srcIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - set value at {0} to {1} ", manipulation.dstIndex, manipulation.value); //$NON-NLS-1$
+ }
+ }
+
+ if (manipulation.is(INSERT))
+ {
+ /*
+ * Step 6: INSERT all elements which have e.type == INSERT.
+ */
+ dbInsert(idHandler, typeMapping, manipulation.dstIndex, manipulation.value);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - insert value at {0} : value {1} ", manipulation.dstIndex, manipulation.value); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ /**
+ * Perform the shift operations to adjust indexes resulting from remove, insert, and move operations.
+ *
+ * @see #writeResultToDatabase(IDBStoreAccessor, CDOID)
+ * @throws SQLException
+ */
+ protected void writeShifts(IIDHandler idHandler) throws SQLException
+ {
+ /*
+ * Step 3: shift all elements which have to be shifted up or down because of add, remove or move of other elements
+ * to their proper position. This has to be done in two phases to avoid collisions, as the index has to be unique
+ * and shift up operations have to be executed in top to bottom order.
+ */
+ LinkedList<Shift> shiftOperations = new LinkedList<Shift>();
+
+ /*
+ * If a necessary shift is detected (source and destination indices differ), firstIndex is set to the current
+ * index and currentOffset is set to the offset of the shift operation. When a new offset is detected or the range
+ * is interrupted, we record the range and start a new one if needed.
+ */
+ int rangeStartIndex = NO_INDEX;
+ int rangeOffset = 0;
+ int lastElementIndex = NO_INDEX;
+
+ // Iterate through the manipulationElements and collect the necessary operations
+ for (Manipulation manipulation : manipulations)
+ {
+ /*
+ * Shift applies only to elements which are not moved, inserted or deleted (i.e. only plain SET and NONE are
+ * affected)
+ */
+ if (manipulation.types == NONE || manipulation.types == SET)
+ {
+ int elementOffset = manipulation.dstIndex - manipulation.srcIndex;
+
+ /*
+ * First make sure if we have to close a previous range. This is the case, if the current element's offset
+ * differs from the rangeOffset and a range is open.
+ */
+ if (elementOffset != rangeOffset && rangeStartIndex != NO_INDEX)
+ {
+ // There is an open range but the rangeOffset differs. We have to close the open range
+ shiftOperations.add(new Shift(rangeStartIndex, lastElementIndex, rangeOffset));
+
+ // And reset the state
+ rangeStartIndex = NO_INDEX;
+ rangeOffset = 0;
+ }
+
+ /*
+ * At this point, either a range is open, which means that the current element also fits in the range (i.e.
+ * the offsets match) or no range is open. In the latter case, we have to open one if the current element's
+ * offset is not 0.
+ */
+ if (elementOffset != 0 && rangeStartIndex == NO_INDEX)
+ {
+ rangeStartIndex = manipulation.srcIndex;
+ rangeOffset = elementOffset;
+ }
+ }
+ else
+ {
+ // Shift does not apply to this element because of its type
+ if (rangeStartIndex != NO_INDEX)
+ {
+ // If there is an open range, we have to close and remember it
+ shiftOperations.add(new Shift(rangeStartIndex, lastElementIndex, rangeOffset));
+
+ // And reset the state
+ rangeStartIndex = NO_INDEX;
+ rangeOffset = 0;
+ }
+ }
+
+ lastElementIndex = manipulation.srcIndex;
+ }
+
+ // After the iteration, we have to make sure that we remember the last open range, if it is there
+ if (rangeStartIndex != NO_INDEX)
+ {
+ shiftOperations.add(new Shift(rangeStartIndex, lastElementIndex, rangeOffset));
+ }
+
+ /*
+ * Now process the operations. Move down operations can be performed directly, move up operations need to be
+ * performed later in the reverse direction
+ */
+ ListIterator<Shift> operationIt = shiftOperations.listIterator();
+ writeShiftsDown(idHandler, operationIt);
+ writeShiftsUp(idHandler, operationIt);
+ }
+
+ protected void writeShiftsDown(IIDHandler idHandler, ListIterator<Shift> operationIt) throws SQLException
+ {
+ while (operationIt.hasNext())
+ {
+ Shift operation = operationIt.next();
+ if (operation.offset < 0)
+ {
+ dbShiftDown(idHandler, operation.offset, operation.startIndex, operation.endIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - shift down {0} ", operation); //$NON-NLS-1$
+ }
+
+ operationIt.remove();
+ }
+ }
+ }
+
+ protected void writeShiftsUp(IIDHandler idHandler, ListIterator<Shift> operationIt) throws SQLException
+ {
+ while (operationIt.hasPrevious())
+ {
+ Shift operation = operationIt.previous();
+ dbShiftUp(idHandler, operation.offset, operation.startIndex, operation.endIndex);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" - shift up {0} ", operation); //$NON-NLS-1$
+ }
+ }
+ }
+
+ protected abstract void dbDelete(IIDHandler idHandler, int index) throws SQLException;
+
+ protected abstract void dbMove(IIDHandler idHandler, int fromIndex, int toIndex, int srcIndex) throws SQLException;
+
+ protected abstract void dbSet(IIDHandler idHandler, ITypeMapping typeMapping, int index, Object value, int srcIndex) throws SQLException;
+
+ protected abstract void dbInsert(IIDHandler idHandler, ITypeMapping typeMapping, int index, Object value) throws SQLException;
+
+ protected abstract void dbShiftDown(IIDHandler idHandler, int offset, int startIndex, int endIndex) throws SQLException;
+
+ protected abstract void dbShiftUp(IIDHandler idHandler, int offset, int startIndex, int endIndex) throws SQLException;
+
+ protected static void close(PreparedStatement... stmts)
+ {
+ Throwable t = null;
+
+ for (PreparedStatement stmt : stmts)
+ {
+ try
+ {
+ if (stmt != null)
+ {
+ try
+ {
+ stmt.clearBatch();
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+ }
+ catch (Throwable th)
+ {
+ if (t == null)
+ {
+ // Remember first exception
+ t = th;
+ }
+
+ // More exceptions go to the log
+ OM.LOG.error(t);
+ }
+ }
+
+ if (t != null)
+ {
+ throw new DBException(t);
+ }
+ }
+
+ protected abstract ITypeMapping getTypeMapping();
+
+ protected abstract int getCurrentIndexOffset();
+
+ protected abstract void clearList();
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class NewListSizeResult extends RuntimeException
+ {
+ private static final long serialVersionUID = 1L;
+
+ private final int newListSize;
+
+ public NewListSizeResult(int newListSize)
+ {
+ this.newListSize = newListSize;
+ }
+
+ public int getNewListSize()
+ {
+ return newListSize;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Manipulation
+ {
+ private static final Object NIL = new Object()
+ {
+ @Override
+ public String toString()
+ {
+ return "NIL";
+ }
+ };
+
+ public int types;
+
+ public int srcIndex;
+
+ public int tmpIndex;
+
+ public int dstIndex;
+
+ public Object value;
+
+ public Manipulation(int types, int srcIndex, int dstIndex, Object value)
+ {
+ this.types = types;
+ this.srcIndex = srcIndex;
+ tmpIndex = NO_INDEX;
+ this.dstIndex = dstIndex;
+ this.value = value;
+ }
+
+ public boolean is(int type)
+ {
+ return type == NONE ? types == NONE : (types & type) != 0;
+ }
+
+ public void addType(int type)
+ {
+ types |= type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("Manipulation[types={0}, srcIndex={1}, tmpIndex={2}, dstIndex={3}, value={4}]", formatTypes(types), formatIndex(srcIndex),
+ formatIndex(tmpIndex), formatIndex(dstIndex), String.valueOf(value));
+ }
+
+ /**
+ * Create a Manipulation which represents an element which already is in the list.
+ */
+ public static Manipulation createOriginalElement(int index)
+ {
+ return new Manipulation(NONE, index, index, NIL);
+ }
+
+ /**
+ * Create a Manipulation which represents an element which is inserted in the list.
+ */
+ public static Manipulation createInsertedElement(int index, Object value)
+ {
+ return new Manipulation(INSERT, NO_INDEX, index, value);
+ }
+
+ private static String formatTypes(int types)
+ {
+ StringBuilder builder = new StringBuilder();
+ formatType(types, DELETE, "DELETE", builder);
+ formatType(types, INSERT, "INSERT", builder);
+ formatType(types, MOVE, "MOVE", builder);
+ formatType(types, SET, "SET", builder);
+
+ if (builder.length() != 0)
+ {
+ return builder.toString();
+ }
+
+ return "NONE";
+ }
+
+ private static void formatType(int types, int type, String label, StringBuilder builder)
+ {
+ if ((types & type) != 0)
+ {
+ if (builder.length() != 0)
+ {
+ builder.append("|");
+ }
+
+ builder.append(label);
+ }
+ }
+
+ private static String formatIndex(int index)
+ {
+ if (index == NO_INDEX)
+ {
+ return "NONE";
+ }
+
+ return Integer.toString(index);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Shift
+ {
+ public final int startIndex;
+
+ public final int endIndex;
+
+ public final int offset;
+
+ public Shift(int startIndex, int endIndex, int offset)
+ {
+ this.startIndex = startIndex;
+ this.endIndex = endIndex;
+ this.offset = offset;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Shift[" + startIndex + ".." + endIndex + ", offset=" + offset + "]";
+ }
+ }
+ }
}
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
index 4cd9795010..88281b8424 100644
--- 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
@@ -53,7 +53,6 @@ import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBIndex;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.util.lifecycle.IDeactivateable;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
@@ -137,7 +136,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
table.addField(ATTRIBUTES_CREATED, DBType.BIGINT, true);
table.addField(ATTRIBUTES_REVISED, DBType.BIGINT, true);
table.addField(ATTRIBUTES_RESOURCE, idType, idLength, true);
- table.addField(ATTRIBUTES_CONTAINER, idType, idLength, true);
+ addContainerField(table, idType, idLength);
table.addField(ATTRIBUTES_FEATURE, DBType.INTEGER, true);
IDBIndex primaryKey = table.addIndex(IDBIndex.Type.PRIMARY_KEY, ATTRIBUTES_ID, ATTRIBUTES_VERSION);
@@ -179,6 +178,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
mapping = mappingStrategy.createListMapping(eClass, feature);
}
+ if (mapping == null)
+ {
+ continue;
+ }
+
if (mapping instanceof IListMapping3)
{
((IListMapping3)mapping).setClassMapping(this);
@@ -225,8 +229,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
if (!table.hasIndexFor(field))
{
- InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
- index.setOptional(true); // Creation might fail for unsupported column type!
+ IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
+ DBUtil.setOptional(index, true); // Creation might fail for unsupported column type!
}
}
@@ -281,8 +285,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
if (!table.hasIndexFor(fields))
{
- InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, fields);
- index.setOptional(true); // Creation might fail for unsupported column type!
+ IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, fields);
+ DBUtil.setOptional(index, true); // Creation might fail for unsupported column type!
}
}
else
@@ -301,8 +305,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
if (!table.hasIndexFor(field))
{
- InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
- index.setOptional(true); // Creation might fail for unsupported column type!
+ IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
+ DBUtil.setOptional(index, true); // Creation might fail for unsupported column type!
}
}
}
@@ -313,8 +317,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
if (!table.hasIndexFor(field))
{
- InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
- index.setOptional(true); // Creation might fail for unsupported column type!
+ IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
+ DBUtil.setOptional(index, true); // Creation might fail for unsupported column type!
}
}
}
@@ -341,6 +345,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
sqlSelectForChangeSet = builder.toString();
}
+ protected IDBField addContainerField(IDBTable table, DBType idType, int idLength)
+ {
+ return table.addField(ATTRIBUTES_CONTAINER, idType, idLength, true);
+ }
+
protected IDBField addBranchField(IDBTable table)
{
return null;
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
index 877a96cd03..880122d66f 100644
--- 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
@@ -423,7 +423,7 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS
}
/**
- * This is an intermediate implementation. It should be changed after classmappings support a general way to implement
+ * This is an intermediate implementation. It should be changed after class mappings support a general way to implement
* queries ...
*
* @param accessor
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
index ba6d836dbf..901c0cdfee 100644
--- 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
@@ -39,7 +39,6 @@ import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBIndex;
import org.eclipse.net4j.db.ddl.IDBIndex.Type;
import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.util.collection.MoveableList;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -132,8 +131,8 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap
if (!table.hasIndexFor(field))
{
- InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
- index.setOptional(true); // Creation might fail for unsupported column type!
+ IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field);
+ DBUtil.setOptional(index, true); // Creation might fail for unsupported column type!
}
}
}
@@ -272,7 +271,7 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap
{
if (stmt.getMaxRows() != 0)
{
- stmt.setMaxRows(0);
+ stmt.setMaxRows(0); // No limit.
}
}
@@ -472,12 +471,12 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap
CDOID targetId = idHandler.getCDOID(resultSet, 2);
int idx = resultSet.getInt(3);
- boolean more = context.addXRef(targetId, srcId, (EReference)getFeature(), idx);
if (TRACER.isEnabled())
{
TRACER.format(" add XRef to context: src={0}, tgt={1}, idx={2}", srcId, targetId, idx);
}
+ boolean more = context.addXRef(targetId, srcId, (EReference)getFeature(), idx);
if (!more)
{
if (TRACER.isEnabled())
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
index 73ff927688..2879544040 100644
--- 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
@@ -38,7 +38,7 @@ 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.DBStore;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.NonAuditListTableMapping.NewListSizeResult;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractBasicListTableMapping.AbstractListDeltaWriter.NewListSizeResult;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
@@ -447,6 +447,28 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
}
@Override
+ protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long timeStamp)
+ {
+ // do nothing
+ }
+
+ @Override
+ protected String getListXRefsWhere(QueryXRefsContext context)
+ {
+ if (CDORevision.UNSPECIFIED_DATE != context.getTimeStamp())
+ {
+ throw new IllegalArgumentException("Non-audit mode does not support timestamp specification");
+ }
+
+ if (!context.getBranch().isMainBranch())
+ {
+ throw new IllegalArgumentException("Non-audit mode does not support branch specification");
+ }
+
+ return ATTRIBUTES_REVISED + "=0";
+ }
+
+ @Override
protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, OMMonitor monitor)
{
rawDelete(accessor, id, version, branch, monitor);
@@ -570,6 +592,7 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
}
}
+ @Deprecated
public void visit(CDOMoveFeatureDelta delta)
{
throw new ImplementationError("Should not be called"); //$NON-NLS-1$
@@ -621,16 +644,19 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
}
}
+ @Deprecated
public void visit(CDOClearFeatureDelta delta)
{
throw new ImplementationError("Should not be called"); //$NON-NLS-1$
}
+ @Deprecated
public void visit(CDOAddFeatureDelta delta)
{
throw new ImplementationError("Should not be called"); //$NON-NLS-1$
}
+ @Deprecated
public void visit(CDORemoveFeatureDelta delta)
{
throw new ImplementationError("Should not be called"); //$NON-NLS-1$
@@ -755,26 +781,4 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
return col;
}
}
-
- @Override
- protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long timeStamp)
- {
- // do nothing
- }
-
- @Override
- protected String getListXRefsWhere(QueryXRefsContext context)
- {
- if (CDORevision.UNSPECIFIED_DATE != context.getTimeStamp())
- {
- throw new IllegalArgumentException("Non-audit mode does not support timestamp specification");
- }
-
- if (!context.getBranch().isMainBranch())
- {
- throw new IllegalArgumentException("Non-audit mode does not support branch specification");
- }
-
- return ATTRIBUTES_REVISED + "=0";
- }
}
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
index 14db7837e1..15216499a6 100644
--- 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
@@ -15,20 +15,13 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
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.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
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.bundle.OM;
import org.eclipse.net4j.db.DBException;
@@ -41,15 +34,9 @@ import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.core.runtime.Assert;
-
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -63,8 +50,6 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, NonAuditListTableMapping.class);
- private static final int UNBOUNDED_SHIFT = -1;
-
private String sqlClear;
private String sqlUpdateValue;
@@ -197,7 +182,7 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
@Override
protected void addKeyFields(List<FieldInfo> list)
{
- // Do nothing
+ // Do nothing.
}
@Override
@@ -212,6 +197,27 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
clearList(accessor, id);
}
+ @Override
+ public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version)
+ {
+ clearList(accessor, id);
+ }
+
+ public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, long created, CDOListFeatureDelta delta)
+ {
+ List<CDOFeatureDelta> listChanges = delta.getListChanges();
+ int oldListSize = delta.getOriginSize();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("ListTableMapping.processDelta for object {0} - original list size: {1}", id, //$NON-NLS-1$
+ oldListSize);
+ }
+
+ ListDeltaWriter writer = new ListDeltaWriter(accessor, id, listChanges, oldListSize);
+ writer.writeListDeltas();
+ }
+
/**
* Clear a list of a given revision.
*
@@ -220,7 +226,7 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
* @param id
* the id of the revision from which to remove all items
*/
- public void clearList(IDBStoreAccessor accessor, CDOID id)
+ private void clearList(IDBStoreAccessor accessor, CDOID id)
{
IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH);
@@ -240,13 +246,7 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
}
}
- @Override
- public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version)
- {
- clearList(accessor, id);
- }
-
- public int getCurrentIndexOffset(IDBStoreAccessor accessor, CDOID id)
+ private int getCurrentIndexOffset(IDBStoreAccessor accessor, CDOID id)
{
IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReadCurrentIndexOffset, ReuseProbability.HIGH);
@@ -258,11 +258,11 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
rset = stmt.executeQuery();
if (!rset.next())
{
- // list is empty. Return the default offset of 0.
+ // List is empty. Return the default offset of 0.
return 0;
}
- // return the minimum index which is equal to the current offset.
+ // Return the minimum index which is equal to the current offset.
return rset.getInt(1);
}
catch (SQLException e)
@@ -272,991 +272,257 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
finally
{
DBUtil.close(rset);
- close(stmt);
- }
- }
-
- public void processDelta(final IDBStoreAccessor accessor, final CDOID id, int branchId, int oldVersion, final int newVersion, long created,
- CDOListFeatureDelta delta)
- {
- int oldListSize = delta.getOriginSize();
-
- if (TRACER.isEnabled())
- {
- TRACER.format("ListTableMapping.processDelta for object {0} - original list size: {1}", id, //$NON-NLS-1$
- oldListSize);
- }
-
- // let the visitor collect the changes
- ListDeltaVisitor visitor = new ListDeltaVisitor(oldListSize);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("Processing deltas..."); //$NON-NLS-1$
- }
-
- for (CDOFeatureDelta listDelta : delta.getListChanges())
- {
- listDelta.accept(visitor);
- }
-
- visitor.postProcess(accessor, id);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("Result to be written to DB:");
- for (ManipulationElement e : visitor.manipulations)
- {
- TRACER.trace(e.toString());
- }
- }
-
- // finally, write results to the database
- visitor.writeResultToDatabase(accessor, id);
-
- throw new NewListSizeResult(visitor.getNewListSize());
- }
-
- private void close(PreparedStatement... stmts)
- {
- Throwable t = null;
-
- for (PreparedStatement stmt : stmts)
- {
- try
- {
- if (stmt != null)
- {
- try
- {
- stmt.clearBatch();
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(stmt);
- }
- }
- }
- catch (Throwable th)
- {
- if (t == null)
- {
- // Remember first exception
- t = th;
- }
-
- // More exceptions go to the log
- OM.LOG.error(t);
- }
- }
-
- if (t != null)
- {
- throw new DBException(t);
+ DBUtil.close(stmt);
}
}
/**
* @author Eike Stepper
*/
- static final class NewListSizeResult extends RuntimeException
+ private final class ListDeltaWriter extends AbstractListDeltaWriter
{
- private static final long serialVersionUID = 1L;
+ private IDBPreparedStatement stmtDelete;
- private final int newListSize;
+ private IDBPreparedStatement stmtMove;
- public NewListSizeResult(int newListSize)
- {
- this.newListSize = newListSize;
- }
+ private IDBPreparedStatement stmtSet;
- public int getNewListSize()
- {
- return newListSize;
- }
- }
+ private IDBPreparedStatement stmtInsert;
- /**
- * @author Eike Stepper
- */
- private final class ListDeltaVisitor implements CDOFeatureDeltaVisitor
- {
- private boolean clearFirst;
+ private IDBPreparedStatement stmtShiftDown;
- private ArrayList<ManipulationElement> manipulations;
+ private IDBPreparedStatement stmtShiftUp;
- /**
- * Start of a range [tempIndex, tempIndex-1, ...] which lies outside of the normal list indexes and which serve as
- * temporary space to move items temporarily to get them out of the way of other operations.
- */
- private int tempIndex = -1;
+ private int countDelete;
- private int newListSize;
+ private int countMove;
- public ListDeltaVisitor(int oldListSize)
- {
- // Reset the clear-flag
- clearFirst = false;
- manipulations = new ArrayList<ManipulationElement>(oldListSize);
+ private int countSet;
- // Create list and initialize with original indexes
- for (int i = 0; i < oldListSize; i++)
- {
- manipulations.add(ManipulationElement.createOriginalElement(i));
- }
+ private int countInsert;
- newListSize = oldListSize;
- }
+ private int countShiftDown;
- public int getNewListSize()
- {
- return newListSize;
- }
+ private int countShiftUp;
- public void visit(CDOAddFeatureDelta delta)
+ public ListDeltaWriter(IDBStoreAccessor accessor, CDOID id, List<CDOFeatureDelta> listChanges, int oldListSize)
{
- if (TRACER.isEnabled())
- {
- TRACER.format(" - insert at {0} value {1}", delta.getIndex(), delta.getValue()); //$NON-NLS-1$
- }
-
- // Make room for the new item
- shiftIndexes(delta.getIndex(), UNBOUNDED_SHIFT, +1);
-
- // Create the item
- manipulations.add(ManipulationElement.createInsertedElement(delta.getIndex(), delta.getValue()));
- ++newListSize;
- }
-
- public void visit(CDORemoveFeatureDelta delta)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(" - remove at {0}", delta.getIndex()); //$NON-NLS-1$
- }
-
- ManipulationElement e = findElement(delta.getIndex());
- deleteItem(e);
-
- // Fill the gap by shifting all subsequent items down
- shiftIndexes(delta.getIndex() + 1, UNBOUNDED_SHIFT, -1);
- --newListSize;
- }
-
- public void visit(CDOSetFeatureDelta delta)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(" - set at {0} value {1}", delta.getIndex(), delta.getValue()); //$NON-NLS-1$
- }
-
- ManipulationElement e = findElement(delta.getIndex());
-
- // Set the new value
- e.value = delta.getValue();
-
- // If the item is freshly inserted we do not set the SET-mark.
- // Setting the value of a new item results in inserting with the new value at once.
- if (!e.is(ManipulationConstants.INSERT))
- {
- // Else mark the existing item to be set to a new value
- e.addType(ManipulationConstants.SET_VALUE);
- }
- }
-
- public void visit(CDOUnsetFeatureDelta delta)
- {
- if (delta.getFeature().isUnsettable())
- {
- Assert.isTrue(false);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - unset list"); //$NON-NLS-1$
- }
-
- // Set the clear-flag
- clearFirst = true;
-
- // And also clear all manipulation items
- manipulations.clear();
- newListSize = 0;
- }
-
- public void visit(CDOClearFeatureDelta delta)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(" - clear list"); //$NON-NLS-1$
- }
-
- // Set the clear-flag
- clearFirst = true;
-
- // And also clear all manipulation items
- manipulations.clear();
- newListSize = 0;
- }
-
- public void visit(CDOMoveFeatureDelta delta)
- {
- int fromIdx = delta.getOldPosition();
- int toIdx = delta.getNewPosition();
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - move {0} -> {1}", fromIdx, toIdx); //$NON-NLS-1$
- }
-
- // Ignore the trivial case
- if (fromIdx == toIdx)
- {
- return;
- }
-
- ManipulationElement e = findElement(fromIdx);
-
- // Adjust indexes and shift either up or down
- if (fromIdx < toIdx)
- {
- shiftIndexes(fromIdx + 1, toIdx, -1);
- }
- else
- {
- // fromIdx > toIdx here
- shiftIndexes(toIdx, fromIdx - 1, +1);
- }
-
- // Set the new index
- e.destinationIndex = toIdx;
-
- // If it is a new element, no MOVE mark needed, because we insert it at the new position
- if (!e.is(ManipulationConstants.INSERT))
- {
- // Else we need to handle the move of an existing item
- e.addType(ManipulationConstants.MOVE);
- }
- }
-
- public void visit(CDOListFeatureDelta delta)
- {
- // Never called
- Assert.isTrue(false);
- }
-
- public void visit(CDOContainerFeatureDelta delta)
- {
- // Never called
- Assert.isTrue(false);
- }
-
- /**
- * Helper method: shift all (destination) indexes in the interval [from,to] (inclusive at both ends) by offset
- * (positive or negative).
- */
- private void shiftIndexes(int from, int to, int offset)
- {
- for (ManipulationElement e : manipulations)
- {
- if (e.destinationIndex >= from && (to == UNBOUNDED_SHIFT || e.destinationIndex <= to))
- {
- e.destinationIndex += offset;
- }
- }
- }
-
- /**
- * Find a manipulation item by destination index).
- */
- private ManipulationElement findElement(int index)
- {
- for (ManipulationElement e : manipulations)
- {
- if (e.destinationIndex == index)
- {
- return e;
- }
- }
-
- // never reached
- Assert.isTrue(false);
- return null;
- }
-
- /**
- * Delete an element (used in remove and clear)
- */
- private void deleteItem(ManipulationElement e)
- {
- if (e.is(ManipulationConstants.INSERT))
- {
- // Newly inserted items are simply removed, as removing inserted items is equal to no change at all.
- manipulations.remove(e);
- }
- else
- {
- // Mark the existing item as to be deleted.
- // Previous MOVE and SET conditions are overridden by setting the exclusive DELETE type.
- e.type = ManipulationConstants.DELETE;
- e.destinationIndex = ManipulationConstants.NO_INDEX;
- }
- }
-
- /**
- * Called after all deltas are applied an before the results are written to the database. This method post-processes
- * the manipulation elements in order to minimize database access.
- */
- public void postProcess(IDBStoreAccessor accessor, CDOID id)
- {
- if (!((HorizontalNonAuditMappingStrategy)getMappingStrategy()).shallForceZeroBasedIndex())
- {
- /*
- * This is an optimization which reduces the amount of modifications on the database to maintain list indexes.
- * For the optimization, we let go of the assumption that indexes are zero-based. Instead, we work with an
- * offset at the database level which can change with every change to the list (e.g. if the second element is
- * removed from a list with 1000 elements, instead of shifting down indexes 2 to 1000 by 1, we shift up index 0
- * by 1 and have now a list with indexes starting at 1 instead of 0. This optimization is applied by modifying
- * the list of ManipulationElements, which can be seen as the database modification plan.
- */
-
- // First, get the current offset
- int offsetBefore = getCurrentIndexOffset(accessor, id);
- if (TRACER.isEnabled())
- {
- TRACER.trace("Offset optimization."); //$NON-NLS-1$
- TRACER.trace("Current offset = " + offsetBefore); //$NON-NLS-1$
- }
-
- applyOffsetToSourceIndexes(offsetBefore);
-
- int offsetAfter;
-
- if ((long)Math.abs(offsetBefore) + (long)manipulations.size() > Integer.MAX_VALUE)
- {
- // Security belt for really huge collections or for collections that have been manipulated lots of times
- // -> Do not optimize after this border is crossed. Instead, reset offset for the whole list to a zero-based
- // index.
- offsetAfter = 0;
- }
- else
- {
- offsetAfter = calculateOptimalOffset();
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("New offset = " + offsetAfter); //$NON-NLS-1$
- }
-
- applyOffsetToDestinationIndexes(offsetAfter);
-
- // Make sure temporary indexes do not get in the way of the other operations
- tempIndex = Math.min(offsetBefore, offsetAfter) - 1;
- }
+ super(accessor, id, listChanges, oldListSize);
}
- /**
- * Calculate the optimal offset wrt the manipulations planned. The optimal offset is the offset which occurs the
- * most in the manipulations (because letting this offset be neutral leads to the least manipulations. Note: the
- * zero offset is also regarded as an offset as any other, because selecting an offset != 0 would also lead to
- * elements with original offset 0 to be moved.
- */
- private int calculateOptimalOffset()
+ @Override
+ protected ITypeMapping getTypeMapping()
{
- HashMap<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
- int bestOffset = 0;
- int bestOffsetOccurrence = 0;
-
- for (ManipulationElement element : manipulations)
- {
- int srcIdx = element.sourceIndex;
- int destIdx = element.destinationIndex;
- if (srcIdx != ManipulationConstants.NO_INDEX && destIdx != ManipulationConstants.NO_INDEX)
- {
- int offset = destIdx - srcIdx;
- Integer oldOccurrence = occurrences.get(offset);
- int newOccurrence;
- if (oldOccurrence == null)
- {
- newOccurrence = 1;
- }
- else
- {
- newOccurrence = oldOccurrence + 1;
- }
- occurrences.put(offset, newOccurrence);
-
- // Remember maximum along the way
- if (newOccurrence > bestOffsetOccurrence)
- {
- bestOffsetOccurrence = newOccurrence;
- bestOffset = offset;
- }
- }
- }
-
- // The offset which has occurred the most has to be applied negatively to normalize the list
- // therefore return the negative offset as the new offset to be applied
- return -bestOffset;
+ return NonAuditListTableMapping.this.getTypeMapping();
}
- private void applyOffsetToSourceIndexes(int offsetBefore)
+ @Override
+ protected int getCurrentIndexOffset()
{
- if (offsetBefore != 0)
- {
- for (ManipulationElement element : manipulations)
- {
- if (element.sourceIndex != ManipulationConstants.NO_INDEX)
- {
- element.sourceIndex += offsetBefore;
- }
- }
- }
+ return NonAuditListTableMapping.this.getCurrentIndexOffset(accessor, id);
}
- private void applyOffsetToDestinationIndexes(int offsetAfter)
+ @Override
+ protected void clearList()
{
- if (offsetAfter != 0)
- {
- for (ManipulationElement element : manipulations)
- {
- if (element.destinationIndex != ManipulationConstants.NO_INDEX)
- {
- // Apply the offset to all indices to make them relative to the new offset
- element.destinationIndex += offsetAfter;
- }
- }
- }
+ NonAuditListTableMapping.this.clearList(accessor, id);
}
- /**
- * Write calculated changes to the database
- */
- private void writeResultToDatabase(IDBStoreAccessor accessor, CDOID id)
+ @Override
+ protected void writeResultToDatabase() throws SQLException
{
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IDBPreparedStatement deleteStmt = null;
- IDBPreparedStatement moveStmt = null;
- IDBPreparedStatement setValueStmt = null;
- IDBPreparedStatement insertStmt = null;
-
- int deleteCounter = 0;
- int moveCounter = 0;
- int setValueCounter = 0;
- int insertCounter = 0;
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("Writing to database:"); //$NON-NLS-1$
- }
-
- if (clearFirst)
- {
- if (TRACER.isEnabled())
- {
- TRACER.trace(" - clear list"); //$NON-NLS-1$
- }
-
- clearList(accessor, id);
- }
-
try
{
- for (ManipulationElement element : manipulations)
- {
- if (element.is(ManipulationConstants.DELETE))
- {
- /*
- * Step 1: DELETE all elements e which have e.is(DELETE) by e.sourceIdx
- */
-
- if (deleteStmt == null)
- {
- deleteStmt = accessor.getDBConnection().prepareStatement(sqlDeleteItem, ReuseProbability.HIGH);
- idHandler.setCDOID(deleteStmt, 1, id);
- }
-
- deleteStmt.setInt(2, element.sourceIndex);
- deleteStmt.addBatch();
- deleteCounter++;
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - delete at {0} ", element.sourceIndex); //$NON-NLS-1$
- }
- }
-
- if (element.is(ManipulationConstants.MOVE))
- {
- /*
- * Step 2: MOVE all elements e (by e.sourceIdx) which have e.is(MOVE) to temporary idx (-1, -2, -3, -4, ...)
- * and store temporary idx in e.tempIndex
- */
- if (moveStmt == null)
- {
- moveStmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH);
- idHandler.setCDOID(moveStmt, 2, id);
- }
-
- moveStmt.setInt(3, element.sourceIndex); // from index
- moveStmt.setInt(1, --tempIndex); // to index
- element.tempIndex = tempIndex;
- moveStmt.addBatch();
- moveCounter++;
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - move {0} -> {1} ", element.sourceIndex, element.tempIndex); //$NON-NLS-1$
- }
- }
- }
-
- /* Now perform deletes and moves ... */
- if (deleteCounter > 0)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Performing {0} delete operations", deleteCounter); //$NON-NLS-1$
- }
-
- DBUtil.executeBatch(deleteStmt, deleteCounter);
- }
-
- if (moveCounter > 0)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Performing {0} move operations", moveCounter); //$NON-NLS-1$
- }
-
- DBUtil.executeBatch(moveStmt, moveCounter);
- moveStmt.clearBatch();
- moveCounter = 0;
- }
-
- writeShiftOperations(accessor, id);
+ super.writeResultToDatabase();
- for (ManipulationElement element : manipulations)
- {
- if (element.is(ManipulationConstants.MOVE))
- {
- /*
- * Step 4: MOVE all elements e have e.is(MOVE) from e.tempIdx to e.destinationIdx (because we have moved
- * them before, moveStmt is always initialized
- */
- moveStmt.setInt(3, element.tempIndex); // from index
- moveStmt.setInt(1, element.destinationIndex); // to index
- moveStmt.addBatch();
- moveCounter++;
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - move {0} -> {1} ", element.tempIndex, element.destinationIndex); //$NON-NLS-1$
- }
- }
-
- if (element.is(ManipulationConstants.SET_VALUE))
- {
- /*
- * Step 5: SET all elements which have e.type == SET_VALUE by index == e.destinationIdx
- */
- if (setValueStmt == null)
- {
- setValueStmt = accessor.getDBConnection().prepareStatement(sqlUpdateValue, ReuseProbability.HIGH);
- idHandler.setCDOID(setValueStmt, 2, id);
- }
-
- setValueStmt.setInt(3, element.destinationIndex);
- getTypeMapping().setValue(setValueStmt, 1, element.value);
- setValueStmt.addBatch();
- setValueCounter++;
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - set value at {0} to {1} ", element.destinationIndex, element.value); //$NON-NLS-1$
- }
- }
-
- if (element.is(ManipulationConstants.INSERT))
- {
- /*
- * Step 6: INSERT all elements which have e.type == INSERT.
- */
- if (insertStmt == null)
- {
- insertStmt = accessor.getDBConnection().prepareStatement(sqlInsertValue, ReuseProbability.HIGH);
- idHandler.setCDOID(insertStmt, 1, id);
- }
-
- insertStmt.setInt(2, element.destinationIndex);
- getTypeMapping().setValue(insertStmt, 3, element.value);
- insertStmt.addBatch();
- insertCounter++;
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - insert value at {0} : value {1} ", element.destinationIndex, element.value); //$NON-NLS-1$
- }
- }
- }
-
- if (moveCounter > 0)
+ if (countMove > 0)
{
if (TRACER.isEnabled())
{
- TRACER.format("Performing {0} move operations", moveCounter); //$NON-NLS-1$
+ TRACER.format("Performing {0} move operations", countMove); //$NON-NLS-1$
}
- DBUtil.executeBatch(moveStmt, moveCounter);
+ DBUtil.executeBatch(stmtMove, countMove);
}
- if (insertCounter > 0)
+ if (countInsert > 0)
{
if (TRACER.isEnabled())
{
- TRACER.format("Performing {0} insert operations", insertCounter); //$NON-NLS-1$
+ TRACER.format("Performing {0} insert operations", countInsert); //$NON-NLS-1$
}
- DBUtil.executeBatch(insertStmt, insertCounter);
+ DBUtil.executeBatch(stmtInsert, countInsert);
}
- if (setValueCounter > 0)
+ if (countSet > 0)
{
if (TRACER.isEnabled())
{
- TRACER.format("Performing {0} set operations", setValueCounter); //$NON-NLS-1$
+ TRACER.format("Performing {0} set operations", countSet); //$NON-NLS-1$
}
- DBUtil.executeBatch(setValueStmt, setValueCounter);
+ DBUtil.executeBatch(stmtSet, countSet);
}
}
- catch (SQLException e)
- {
- throw new DBException(e);
- }
finally
{
- close(deleteStmt, moveStmt, insertStmt, setValueStmt);
+ close(stmtDelete, stmtMove, stmtInsert, stmtSet);
}
}
- /**
- * Perform the shift operations to adjust indexes resulting from remove, insert, and move operations.
- *
- * @see #writeResultToDatabase(IDBStoreAccessor, CDOID)
- * @throws SQLException
- */
- private void writeShiftOperations(IDBStoreAccessor accessor, CDOID id) throws SQLException
+ @Override
+ protected void writeShifts(IIDHandler idHandler) throws SQLException
{
- /*
- * Step 3: shift all elements which have to be shifted up or down because of add, remove or move of other elements
- * to their proper position. This has to be done in two phases to avoid collisions, as the index has to be unique
- * and shift up operations have to be executed in top to bottom order.
- */
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- LinkedList<ShiftOperation> shiftOperations = new LinkedList<ShiftOperation>();
-
- /*
- * If a necessary shift is detected (source and destination indices differ), firstIndex is set to the current
- * index and currentOffset is set to the offset of the shift operation. When a new offset is detected or the range
- * is interrupted, we record the range and start a new one if needed.
- */
- int rangeStartIndex = ManipulationConstants.NO_INDEX;
- int rangeOffset = 0;
- int lastElementIndex = ManipulationConstants.NO_INDEX;
-
- // Iterate through the manipulationElements and collect the necessary operations
- for (ManipulationElement element : manipulations)
+ if (countDelete > 0)
{
- /*
- * Shift applies only to elements which are not moved, inserted or deleted (i.e. only plain SET_VALUE and NONE
- * are affected)
- */
- if (element.type == ManipulationConstants.NONE || element.type == ManipulationConstants.SET_VALUE)
- {
- int elementOffset = element.destinationIndex - element.sourceIndex;
-
- /*
- * First make sure if we have to close a previous range. This is the case, if the current element's offset
- * differs from the rangeOffset and a range is open.
- */
- if (elementOffset != rangeOffset && rangeStartIndex != ManipulationConstants.NO_INDEX)
- {
- // There is an open range but the rangeOffset differs. We have to close the open range
- shiftOperations.add(new ShiftOperation(rangeStartIndex, lastElementIndex, rangeOffset));
-
- // And reset the state
- rangeStartIndex = ManipulationConstants.NO_INDEX;
- rangeOffset = 0;
- }
-
- /*
- * At this point, either a range is open, which means that the current element also fits in the range (i.e.
- * the offsets match) or no range is open. In the latter case, we have to open one if the current element's
- * offset is not 0.
- */
- if (elementOffset != 0 && rangeStartIndex == ManipulationConstants.NO_INDEX)
- {
- rangeStartIndex = element.sourceIndex;
- rangeOffset = elementOffset;
- }
- }
- else
+ if (TRACER.isEnabled())
{
- // Shift does not apply to this element because of its type
- if (rangeStartIndex != ManipulationConstants.NO_INDEX)
- {
- // If there is an open range, we have to close and remember it
- shiftOperations.add(new ShiftOperation(rangeStartIndex, lastElementIndex, rangeOffset));
-
- // And reset the state
- rangeStartIndex = ManipulationConstants.NO_INDEX;
- rangeOffset = 0;
- }
+ TRACER.format("Performing {0} delete operations", countDelete); //$NON-NLS-1$
}
- lastElementIndex = element.sourceIndex;
+ DBUtil.executeBatch(stmtDelete, countDelete);
}
- // After the iteration, we have to make sure that we remember the last open range, if it is there
- if (rangeStartIndex != ManipulationConstants.NO_INDEX)
+ if (countMove > 0)
{
- shiftOperations.add(new ShiftOperation(rangeStartIndex, lastElementIndex, rangeOffset));
- }
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Performing {0} move operations", countMove); //$NON-NLS-1$
+ }
- /*
- * Now process the operations. Move down operations can be performed directly, move up operations need to be
- * performed later in the reverse direction
- */
- ListIterator<ShiftOperation> operationIt = shiftOperations.listIterator();
+ DBUtil.executeBatch(stmtMove, countMove);
+ countMove = 0;
+ }
- IDBPreparedStatement shiftDownStmt = null;
- int operationCounter = 0;
+ super.writeShifts(idHandler);
+ }
+ @Override
+ protected void writeShiftsDown(IIDHandler idHandler, ListIterator<Shift> operationIt) throws SQLException
+ {
try
{
- while (operationIt.hasNext())
- {
- ShiftOperation operation = operationIt.next();
- if (operation.offset < 0)
- {
- if (shiftDownStmt == null)
- {
- shiftDownStmt = accessor.getDBConnection().prepareStatement(sqlShiftDownIndex, ReuseProbability.HIGH);
- idHandler.setCDOID(shiftDownStmt, 2, id);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - shift down {0} ", operation); //$NON-NLS-1$
- }
-
- shiftDownStmt.setInt(1, operation.offset);
- shiftDownStmt.setInt(3, operation.startIndex);
- shiftDownStmt.setInt(4, operation.endIndex);
- shiftDownStmt.addBatch();
- operationCounter++;
-
- operationIt.remove();
- }
- }
+ super.writeShiftsDown(idHandler, operationIt);
- if (operationCounter > 0)
+ if (countShiftDown > 0)
{
- DBUtil.executeBatch(shiftDownStmt, operationCounter, false);
+ DBUtil.executeBatch(stmtShiftDown, countShiftDown, false);
}
}
finally
{
- close(shiftDownStmt);
+ close(stmtShiftDown);
}
+ }
- IDBPreparedStatement shiftUpStmt = null;
- operationCounter = 0;
-
+ @Override
+ protected void writeShiftsUp(IIDHandler idHandler, ListIterator<Shift> operationIt) throws SQLException
+ {
try
{
- while (operationIt.hasPrevious())
- {
- ShiftOperation operation = operationIt.previous();
- if (shiftUpStmt == null)
- {
- shiftUpStmt = accessor.getDBConnection().prepareStatement(sqlShiftUpIndex, ReuseProbability.HIGH);
- idHandler.setCDOID(shiftUpStmt, 2, id);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format(" - shift up {0} ", operation); //$NON-NLS-1$
- }
+ super.writeShiftsUp(idHandler, operationIt);
- shiftUpStmt.setInt(1, operation.offset);
- shiftUpStmt.setInt(3, operation.startIndex);
- shiftUpStmt.setInt(4, operation.endIndex);
- shiftUpStmt.addBatch();
- operationCounter++;
- }
-
- if (operationCounter > 0)
+ if (countShiftUp > 0)
{
- DBUtil.executeBatch(shiftUpStmt, operationCounter, false);
+ DBUtil.executeBatch(stmtShiftUp, countShiftUp, false);
}
}
finally
{
- close(shiftUpStmt);
+ close(stmtShiftUp);
}
}
- }
-
- /**
- * @author Eike Stepper
- */
- private static interface ManipulationConstants
- {
- public static final int NO_INDEX = Integer.MIN_VALUE;
-
- public static final Object NIL = new Object();
-
- public static final int NONE = 0;
-
- public static final int SET_VALUE = 1 << 1;
-
- public static final int MOVE = 1 << 2;
-
- public static final int INSERT = 1 << 3;
-
- public static final int DELETE = 1 << 4;
- }
-
- /**
- * @author Eike Stepper
- */
- private static final class ManipulationElement implements ManipulationConstants
- {
- public int type;
-
- public int sourceIndex;
-
- public int tempIndex;
-
- public int destinationIndex;
-
- public Object value;
-
- public ManipulationElement(int t, int srcIdx, int dstIdx, Object val)
- {
- sourceIndex = srcIdx;
- tempIndex = NO_INDEX;
- destinationIndex = dstIdx;
- value = val;
- type = t;
- }
- /**
- * Create a ManipulationElement which represents an element which already is in the list.
- */
- public static ManipulationElement createOriginalElement(int index)
+ @Override
+ protected void dbDelete(IIDHandler idHandler, int index) throws SQLException
{
- return new ManipulationElement(NONE, index, index, NIL);
- }
+ if (stmtDelete == null)
+ {
+ stmtDelete = accessor.getDBConnection().prepareStatement(sqlDeleteItem, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtDelete, 1, id);
+ }
- /**
- * Create a ManipulationElement which represents an element which is inserted in the list.
- */
- public static ManipulationElement createInsertedElement(int index, Object value)
- {
- return new ManipulationElement(ManipulationConstants.INSERT, NO_INDEX, index, value);
+ stmtDelete.setInt(2, index);
+ stmtDelete.addBatch();
+ ++countDelete;
}
- public boolean is(int t)
+ @Override
+ protected void dbMove(IIDHandler idHandler, int fromIndex, int toIndex, int srcIndex) throws SQLException
{
- return (type & t) > 0;
- }
+ if (stmtMove == null)
+ {
+ stmtMove = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtMove, 2, id);
+ }
- public void addType(int t)
- {
- type |= t;
+ stmtMove.setInt(3, fromIndex);
+ stmtMove.setInt(1, toIndex);
+ stmtMove.addBatch();
+ ++countMove;
}
@Override
- public String toString()
+ protected void dbSet(IIDHandler idHandler, ITypeMapping typeMapping, int index, Object value, int srcIndex) throws SQLException
{
- return MessageFormat.format("Manipulation[type={0}, sourceIndex={1}, tempIndex={2}, destinationIndex={3}, value={4}]", formatType(type),
- formatIndex(sourceIndex), formatIndex(tempIndex), formatIndex(destinationIndex), formatValue(value));
- }
-
- private static String formatType(int type)
- {
- switch (type)
+ if (stmtSet == null)
{
- case NONE:
- return "none";
-
- case DELETE:
- return "DELETE";
-
- case INSERT:
- return "INSERT";
-
- case MOVE:
- return "MOVE";
-
- case SET_VALUE:
- return "SET_VALUE";
+ stmtSet = accessor.getDBConnection().prepareStatement(sqlUpdateValue, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtSet, 2, id);
}
- return "<invalid>";
+ stmtSet.setInt(3, index);
+ typeMapping.setValue(stmtSet, 1, value);
+ stmtSet.addBatch();
+ ++countSet;
}
- private static String formatIndex(int index)
+ @Override
+ protected void dbInsert(IIDHandler idHandler, ITypeMapping typeMapping, int index, Object value) throws SQLException
{
- if (index == NO_INDEX)
+ if (stmtInsert == null)
{
- return "NONE";
+ stmtInsert = accessor.getDBConnection().prepareStatement(sqlInsertValue, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtInsert, 1, id);
}
- return Integer.toString(index);
+ stmtInsert.setInt(2, index);
+ typeMapping.setValue(stmtInsert, 3, value);
+ stmtInsert.addBatch();
+ ++countInsert;
}
- private static String formatValue(Object val)
+ @Override
+ protected void dbShiftDown(IIDHandler idHandler, int offset, int startIndex, int endIndex) throws SQLException
{
- if (val == NIL)
+ if (stmtShiftDown == null)
{
- return "NIL";
+ stmtShiftDown = accessor.getDBConnection().prepareStatement(sqlShiftDownIndex, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtShiftDown, 2, id);
}
- return String.valueOf(val);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private static class ShiftOperation
- {
- final int startIndex;
-
- final int endIndex;
-
- final int offset;
-
- ShiftOperation(int startIndex, int endIndex, int offset)
- {
- this.startIndex = startIndex;
- this.endIndex = endIndex;
- this.offset = offset;
+ stmtShiftDown.setInt(1, offset);
+ stmtShiftDown.setInt(3, startIndex);
+ stmtShiftDown.setInt(4, endIndex);
+ stmtShiftDown.addBatch();
+ ++countShiftDown;
}
@Override
- public String toString()
+ protected void dbShiftUp(IIDHandler idHandler, int offset, int startIndex, int endIndex) throws SQLException
{
- return "range [" + startIndex + ".." + endIndex + "] offset " + offset;
+ if (stmtShiftUp == null)
+ {
+ stmtShiftUp = accessor.getDBConnection().prepareStatement(sqlShiftUpIndex, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmtShiftUp, 2, id);
+ }
+
+ stmtShiftUp.setInt(1, offset);
+ stmtShiftUp.setInt(3, startIndex);
+ stmtShiftUp.setInt(4, endIndex);
+ stmtShiftUp.addBatch();
+ ++countShiftUp;
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
index ab8a2bfcbd..3089107c43 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
@@ -217,6 +217,16 @@ public class HibernateRawCommitContext implements InternalCommitContext
return new CDOBranchVersion[0];
}
+ public Map<CDOID, InternalCDORevision> getOldRevisions()
+ {
+ return null;
+ }
+
+ public Map<CDOID, InternalCDORevision> getNewRevisions()
+ {
+ return null;
+ }
+
public ExtendedDataInputStream getLobs()
{
return null;
@@ -292,6 +302,11 @@ public class HibernateRawCommitContext implements InternalCommitContext
return new InternalCDORevision[0];
}
+ public InternalCDORevision[] getDetachedRevisions(boolean check)
+ {
+ return getDetachedRevisions();
+ }
+
public void setClearResourcePathCache(boolean clearResourcePathCache)
{
}
diff --git a/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/MongoDBStore.java b/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/MongoDBStore.java
index dab5a722f3..eb8e6f3176 100644
--- a/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/MongoDBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/MongoDBStore.java
@@ -21,7 +21,6 @@ import org.eclipse.emf.cdo.server.internal.mongodb.bundle.OM;
import org.eclipse.emf.cdo.server.mongodb.IMongoDBStore;
import org.eclipse.emf.cdo.server.mongodb.IMongoDBStoreAccessor;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalStore.NoExternalReferences;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoFeatureMaps;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoHandleRevisions;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoLargeObjects;
@@ -66,7 +65,7 @@ import java.util.Set;
* @author Eike Stepper
*/
public class MongoDBStore extends Store implements IMongoDBStore, //
- NoExternalReferences, NoQueryXRefs, NoLargeObjects, NoFeatureMaps, NoHandleRevisions, NoRawAccess
+ NoQueryXRefs, NoLargeObjects, NoFeatureMaps, NoHandleRevisions, NoRawAccess
{
public static final String TYPE = "mongodb"; //$NON-NLS-1$
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index e2f88189ed..35cd1dab7f 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -2112,7 +2112,7 @@ public class Repository extends Container<Object> implements InternalRepository,
initSystemPackages(true);
}
- public void initSystemPackages(boolean firstStart)
+ public void initSystemPackages(final boolean firstStart)
{
IStoreAccessor writer = store.getWriter(null);
StoreThreadLocal.setAccessor(writer);
@@ -2149,6 +2149,19 @@ public class Repository extends Container<Object> implements InternalRepository,
{
StoreThreadLocal.release();
}
+
+ fireEvent(new PackagesInitializedEvent()
+ {
+ public InternalRepository getSource()
+ {
+ return Repository.this;
+ }
+
+ public boolean isFirstStart()
+ {
+ return firstStart;
+ }
+ });
}
protected InternalCDOPackageUnit initPackage(EPackage ePackage)
@@ -2420,6 +2433,7 @@ public class Repository extends Container<Object> implements InternalRepository,
{
readPackageUnits();
initSystemPackages(false);
+
readRootResource();
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
index 327737b0e2..50b6110799 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
@@ -165,6 +165,10 @@ public class TransactionCommitContext implements InternalCommitContext
private Map<CDOID, InternalCDORevision> cachedRevisions;
+ private Map<CDOID, InternalCDORevision> oldRevisions = CDOIDUtil.createMap();
+
+ private Map<CDOID, InternalCDORevision> newRevisions;
+
private Set<Object> lockedObjects = new HashSet<Object>();
private List<CDOID> lockedTargets;
@@ -325,12 +329,20 @@ public class TransactionCommitContext implements InternalCommitContext
public InternalCDORevision[] getDetachedRevisions()
{
- // This array can contain null values as they only come from the cache!
- for (InternalCDORevision cachedDetachedRevision : cachedDetachedRevisions)
+ return getDetachedRevisions(true);
+ }
+
+ public InternalCDORevision[] getDetachedRevisions(boolean check)
+ {
+ if (check)
{
- if (cachedDetachedRevision == null)
+ // This array can contain null values as they only come from the cache!
+ for (InternalCDORevision cachedDetachedRevision : cachedDetachedRevisions)
{
- throw new AssertionError("Detached revisions are incomplete");
+ if (cachedDetachedRevision == null)
+ {
+ throw new AssertionError("Detached revisions are incomplete");
+ }
}
}
@@ -342,6 +354,27 @@ public class TransactionCommitContext implements InternalCommitContext
return dirtyObjectDeltas;
}
+ public Map<CDOID, InternalCDORevision> getOldRevisions()
+ {
+ return oldRevisions;
+ }
+
+ public Map<CDOID, InternalCDORevision> getNewRevisions()
+ {
+ if (newRevisions == null)
+ {
+ newRevisions = CDOIDUtil.createMap();
+
+ for (int i = 0; i < newObjects.length; i++)
+ {
+ InternalCDORevision revision = newObjects[i];
+ newRevisions.put(revision.getID(), revision);
+ }
+ }
+
+ return newRevisions;
+ }
+
public InternalCDORevision getRevision(CDOID id)
{
if (cachedRevisions == null)
@@ -1204,6 +1237,8 @@ public class TransactionCommitContext implements InternalCommitContext
// Make sure all chunks are loaded
repository.ensureChunks(oldRevision, CDORevision.UNCHUNKED);
+ oldRevisions.put(id, oldRevision);
+
InternalCDORevision newRevision = oldRevision.copy();
newRevision.adjustForCommit(branch, timeStamp);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
index f8d408a2e0..b21141d0e6 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
@@ -385,6 +385,16 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader, Com
public CDOBranchVersion[] getDetachedObjectVersions();
/**
+ * @since 4.6
+ */
+ public Map<CDOID, InternalCDORevision> getOldRevisions();
+
+ /**
+ * @since 4.6
+ */
+ public Map<CDOID, InternalCDORevision> getNewRevisions();
+
+ /**
* Returns a stream that all {@link CDOLob lobs} can be read from. The format of the data delivered through the
* stream is:
* <p>
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
index f9238d24a2..dbb9078daa 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
@@ -103,6 +103,11 @@ public interface InternalCommitContext extends IStoreAccessor.CommitContext, CDO
public InternalCDORevision[] getDetachedRevisions();
/**
+ * @since 4.6
+ */
+ public InternalCDORevision[] getDetachedRevisions(boolean check);
+
+ /**
* @since 4.2
*/
public void setClearResourcePathCache(boolean clearResourcePathCache);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
index 3c389f839d..406201d695 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
@@ -43,6 +43,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager.Revisi
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.emf.ecore.EClass;
@@ -321,4 +322,15 @@ public interface InternalRepository extends IRepository, PackageProcessor, Packa
* @since 4.3
*/
public void setOptimisticLockingTimeout(long optimisticLockingTimeout);
+
+ /**
+ * @author Eike Stepper
+ * @since 4.6
+ */
+ public interface PackagesInitializedEvent extends IEvent
+ {
+ public InternalRepository getSource();
+
+ public boolean isFirstStart();
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalStore.java
index 0391fa05f2..89e0611fe6 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalStore.java
@@ -70,7 +70,9 @@ public interface InternalStore extends IStore, ILifecycle
*
* @author Eike Stepper
* @since 4.0
+ * @deprecated As of 4.6 use IRepositoryConfig.CAPABILITY_EXTERNAL_REFS.
*/
+ @Deprecated
public interface NoExternalReferences
{
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java
index 02f519b839..eff729a0b2 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java
@@ -73,11 +73,13 @@ public abstract class StoreAccessor extends StoreAccessorBase
CDOID[] detachedObjects = context.getDetachedObjects();
InternalCDORevisionDelta[] dirtyObjectDeltas = context.getDirtyObjectDeltas();
InternalCDORevision[] dirtyObjects = context.getDirtyObjects();
+
int dirtyCount = deltas ? dirtyObjectDeltas.length : dirtyObjects.length;
+ int postProcessCount = needsRevisionPostProcessing() ? newObjects.length + detachedObjects.length + dirtyCount : 0;
try
{
- monitor.begin(1 + newPackageUnits.length + 2 + newObjects.length + detachedObjects.length + dirtyCount + 1);
+ monitor.begin(1 + newPackageUnits.length + 2 + newObjects.length + detachedObjects.length + dirtyCount + postProcessCount + 1);
writeCommitInfo(branch, timeStamp, previousTimeStamp, userID, commitComment, mergeSource, monitor.fork());
writePackageUnits(newPackageUnits, monitor.fork(newPackageUnits.length));
@@ -112,6 +114,11 @@ public abstract class StoreAccessor extends StoreAccessorBase
}
}
+ if (needsRevisionPostProcessing())
+ {
+ postProcessRevisions(context, monitor.fork(postProcessCount));
+ }
+
ExtendedDataInputStream in = context.getLobs();
if (in != null)
{
@@ -154,6 +161,15 @@ public abstract class StoreAccessor extends StoreAccessorBase
}
}
+ protected boolean needsRevisionPostProcessing()
+ {
+ return false;
+ }
+
+ protected void postProcessRevisions(InternalCommitContext context, OMMonitor monitor)
+ {
+ }
+
/**
* @since 3.0
*/
diff --git a/plugins/org.eclipse.emf.cdo.tests.all/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests.all/META-INF/MANIFEST.MF
index afff98aa00..9d43c7cedd 100644
--- a/plugins/org.eclipse.emf.cdo.tests.all/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests.all/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.tests.all;singleton:=true
-Bundle-Version: 4.1.300.qualifier
+Bundle-Version: 4.1.400.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -12,5 +12,5 @@ Bundle-ClassPath: .
Require-Bundle: org.eclipse.net4j.tests;bundle-version="[4.0.0,5.0.0)";visibility:=reexport,
org.eclipse.emf.cdo.tests;bundle-version="[4.0.0,5.0.0)";visibility:=reexport,
org.eclipse.emf.cdo.tests.db;bundle-version="[4.0.0,5.0.0)";visibility:=reexport
-Export-Package: org.eclipse.emf.cdo.tests.all;version="4.1.300";x-internal:=true,
- org.eclipse.emf.cdo.tests.all.bundle;version="4.1.300";x-internal:=true
+Export-Package: org.eclipse.emf.cdo.tests.all;version="4.1.400";x-internal:=true,
+ org.eclipse.emf.cdo.tests.all.bundle;version="4.1.400";x-internal:=true
diff --git a/plugins/org.eclipse.emf.cdo.tests.all/src/org/eclipse/emf/cdo/tests/all/GerritTests.java b/plugins/org.eclipse.emf.cdo.tests.all/src/org/eclipse/emf/cdo/tests/all/GerritTests.java
index b44cf7b985..139c8f9cbd 100644
--- a/plugins/org.eclipse.emf.cdo.tests.all/src/org/eclipse/emf/cdo/tests/all/GerritTests.java
+++ b/plugins/org.eclipse.emf.cdo.tests.all/src/org/eclipse/emf/cdo/tests/all/GerritTests.java
@@ -31,7 +31,7 @@ public class GerritTests extends DBConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, new H2Config(false, false, true, false, IDGenerationLocation.STORE), JVM, NATIVE);
- addScenario(parent, new H2Config(true, true, true, false, IDGenerationLocation.STORE), JVM, NATIVE);
+ addScenario(parent, new H2Config(false, false, true, false, false, IDGenerationLocation.STORE), JVM, NATIVE);
+ addScenario(parent, new H2Config(true, true, true, false, false, IDGenerationLocation.STORE), JVM, NATIVE);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AbstractSetupDBConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AbstractSetupDBConfig.java
index 7948b5cd89..18192d8c60 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AbstractSetupDBConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AbstractSetupDBConfig.java
@@ -31,9 +31,9 @@ public abstract class AbstractSetupDBConfig extends DBConfig
private transient DataSource setupDataSource;
public AbstractSetupDBConfig(String name, boolean supportingAudits, boolean supportingBranches, boolean withRanges, boolean copyOnBranch,
- IDGenerationLocation idGenerationLocation)
+ boolean inverseLists, IDGenerationLocation idGenerationLocation)
{
- super(name, supportingAudits, supportingBranches, withRanges, copyOnBranch, idGenerationLocation);
+ super(name, supportingAudits, supportingBranches, withRanges, copyOnBranch, inverseLists, idGenerationLocation);
}
protected String getDBName(String repoName)
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Audit.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Audit.java
index ce92cf494b..d0105fdb7f 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Audit.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Audit.java
@@ -30,10 +30,10 @@ public class AllTestsDBH2Audit extends DBConfigs
public static void initConfigSuites(ConfigTestSuite suite, TestSuite parent, IDGenerationLocation idGenerationLocation)
{
// Without ranges
- suite.addScenario(parent, new H2Config(true, false, false, false, idGenerationLocation), JVM, NATIVE);
+ suite.addScenario(parent, new H2Config(true, false, false, false, false, idGenerationLocation), JVM, NATIVE);
// With ranges
- suite.addScenario(parent, new H2Config(true, false, true, false, idGenerationLocation), JVM, NATIVE);
+ suite.addScenario(parent, new H2Config(true, false, true, false, false, idGenerationLocation), JVM, NATIVE);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java
index 8b27926dc4..26e658e3e7 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java
@@ -29,10 +29,10 @@ public class AllTestsDBH2Branching extends DBConfigs
public static void initConfigSuites(ConfigTestSuite suite, TestSuite parent, IDGenerationLocation idGenerationLocation)
{
// Without ranges
- suite.addScenario(parent, new H2Config(true, true, false, false, idGenerationLocation), JVM, NATIVE);
+ suite.addScenario(parent, new H2Config(true, true, false, false, false, idGenerationLocation), JVM, NATIVE);
// With ranges
- suite.addScenario(parent, new H2Config(true, true, true, false, idGenerationLocation), JVM, NATIVE);
+ suite.addScenario(parent, new H2Config(true, true, true, false, false, idGenerationLocation), JVM, NATIVE);
// With ranges and copy-on-branch
// suite.addScenario(parent, new H2Config(true, true, true, true, idGenerationLocation), JVM, NATIVE);
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2BranchingUUIDs.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2BranchingUUIDs.java
index 2c46aa7c37..a587a52153 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2BranchingUUIDs.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2BranchingUUIDs.java
@@ -28,6 +28,6 @@ public class AllTestsDBH2BranchingUUIDs extends DBConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, new H2Config(true, true, false, false, IDGenerationLocation.CLIENT), JVM, NATIVE);
+ addScenario(parent, new H2Config(true, true, false, false, false, IDGenerationLocation.CLIENT), JVM, NATIVE);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2NonAudit.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2NonAudit.java
index d188a04b3a..f1a0f668a2 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2NonAudit.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2NonAudit.java
@@ -28,7 +28,7 @@ public class AllTestsDBH2NonAudit extends DBConfigs
public static void initConfigSuites(ConfigTestSuite suite, TestSuite parent, IDGenerationLocation idGenerationLocation)
{
- suite.addScenario(parent, new H2Config(false, false, false, false, idGenerationLocation), JVM, NATIVE);
+ suite.addScenario(parent, new H2Config(false, false, false, false, false, idGenerationLocation), JVM, NATIVE);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBMysql.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBMysql.java
index ec4500aa7a..6d1386cfd6 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBMysql.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBMysql.java
@@ -36,7 +36,7 @@ public class AllTestsDBMysql extends DBConfigs
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, new MysqlConfig(false, false, IDGenerationLocation.STORE), JVM, NATIVE);
+ addScenario(parent, new MysqlConfig(false, false, false, IDGenerationLocation.STORE), JVM, NATIVE);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AnyTestManyTimesDB.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AnyTestManyTimesDB.java
index 0406ec07c9..5b017c0079 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AnyTestManyTimesDB.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AnyTestManyTimesDB.java
@@ -36,9 +36,11 @@ public class AnyTestManyTimesDB extends TestSuite implements IConstants
private static final boolean COPY_ON_BRANCH = false;
+ private static final boolean INVERSE_LISTS = false;
+
private static final IDGenerationLocation ID_GENERATION_LOCATION = IDGenerationLocation.STORE;
- private static final RepositoryConfig REPOSITORY_CONFIG = new H2Config(SUPPORTING_AUDITS, SUPPORTING_BRANCHES, WITH_RANGES, COPY_ON_BRANCH,
+ private static final RepositoryConfig REPOSITORY_CONFIG = new H2Config(SUPPORTING_AUDITS, SUPPORTING_BRANCHES, WITH_RANGES, COPY_ON_BRANCH, INVERSE_LISTS,
ID_GENERATION_LOCATION);
private static final SessionConfig SESSION_CONFIG = JVM;
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Bugzilla_351068_Test.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Bugzilla_351068_Test.java
index e9455bfa7d..46353cc411 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Bugzilla_351068_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Bugzilla_351068_Test.java
@@ -40,7 +40,7 @@ import java.sql.Statement;
*
* @author Eike Stepper
*/
-@Skips(IRepositoryConfig.CAPABILITY_AUDITING)
+@Skips({ IRepositoryConfig.CAPABILITY_AUDITING, "DB.inverse.lists" })
public class Bugzilla_351068_Test extends AbstractCDOTest
{
@CleanRepositoriesBefore(reason = "Row counting")
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java
index cf4b5696d6..8a34e65832 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java
@@ -39,6 +39,8 @@ public abstract class DBConfig extends RepositoryConfig
public static final String CAPABILITY_COPY_ON_BRANCH = "DB.copy.on.branch";
+ public static final String CAPABILITY_INVERSE_LISTS = "DB.inverse.lists";
+
public static final String PROP_TEST_MAPPING_STRATEGY = "test.repository.MappingStrategy";
private static final long serialVersionUID = 1L;
@@ -47,14 +49,17 @@ public abstract class DBConfig extends RepositoryConfig
private boolean copyOnBranch;
+ private boolean inverseLists;
+
private transient IDBAdapter dbAdapter;
- public DBConfig(String name, boolean supportingAudits, boolean supportingBranches, boolean withRanges, boolean copyOnBranch,
+ public DBConfig(String name, boolean supportingAudits, boolean supportingBranches, boolean withRanges, boolean copyOnBranch, boolean inverseLists,
IDGenerationLocation idGenerationLocation)
{
super(name, supportingAudits, supportingBranches, idGenerationLocation);
this.withRanges = withRanges;
this.copyOnBranch = copyOnBranch;
+ this.inverseLists = inverseLists;
}
@Override
@@ -73,6 +78,11 @@ public abstract class DBConfig extends RepositoryConfig
{
capabilities.add(CAPABILITY_COPY_ON_BRANCH);
}
+
+ if (isInverseLists())
+ {
+ capabilities.add(CAPABILITY_INVERSE_LISTS);
+ }
}
protected IDBAdapter getDBAdapter()
@@ -103,6 +113,11 @@ public abstract class DBConfig extends RepositoryConfig
return copyOnBranch;
}
+ public boolean isInverseLists()
+ {
+ return inverseLists;
+ }
+
@Override
public void setUp() throws Exception
{
@@ -161,7 +176,7 @@ public abstract class DBConfig extends RepositoryConfig
@Override
protected String getMappingStrategySpecialization()
{
- return (withRanges ? "-ranges" : "") + (copyOnBranch ? "-copy" : "");
+ return (withRanges ? "-ranges" : "") + (copyOnBranch ? "-copy" : "") + (inverseLists ? "-inverse" : "");
}
protected abstract IDBAdapter createDBAdapter();
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DerbyConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DerbyConfig.java
index 3d3839c952..a9e591d4bc 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DerbyConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DerbyConfig.java
@@ -43,7 +43,7 @@ public class DerbyConfig extends DBConfig
public DerbyConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, false, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
index d2f28227fb..027808fcd7 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
@@ -36,9 +36,10 @@ public class H2Config extends DBConfig
private static JdbcDataSource defaultDataSource;
- public H2Config(boolean supportingAudits, boolean supportingBranches, boolean withRanges, boolean copyOnBranch, IDGenerationLocation idGenerationLocation)
+ public H2Config(boolean supportingAudits, boolean supportingBranches, boolean withRanges, boolean copyOnBranch, boolean inverseLists,
+ IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, withRanges, copyOnBranch, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, withRanges, copyOnBranch, inverseLists, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/HsqldbConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/HsqldbConfig.java
index 88d050547c..42951cdbe9 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/HsqldbConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/HsqldbConfig.java
@@ -47,7 +47,7 @@ public class HsqldbConfig extends DBConfig
public HsqldbConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, false, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/MysqlConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/MysqlConfig.java
index 5e3c33fc85..72e7252120 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/MysqlConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/MysqlConfig.java
@@ -35,7 +35,7 @@ public class MysqlConfig extends AbstractSetupDBConfig
*/
public static final String HOST = "localhost";
- public static final String SCHEMA = "test";
+ public static final String SCHEMA = "big";
public static final String USER = "test";
@@ -43,9 +43,9 @@ public class MysqlConfig extends AbstractSetupDBConfig
private static final long serialVersionUID = 1L;
- public MysqlConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation)
+ public MysqlConfig(boolean supportingAudits, boolean supportingBranches, boolean inverseLists, IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, inverseLists, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/OracleConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/OracleConfig.java
index 3e0afc8529..03240bb814 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/OracleConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/OracleConfig.java
@@ -51,7 +51,7 @@ public abstract class OracleConfig extends AbstractSetupDBConfig
public OracleConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, false, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java
index 52ce550bfd..541be6617a 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java
@@ -40,7 +40,7 @@ public class PostgresqlConfig extends AbstractSetupDBConfig
public PostgresqlConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation)
{
- super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, idGenerationLocation);
+ super(DB_ADAPTER_NAME, supportingAudits, supportingBranches, false, false, false, idGenerationLocation);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/performance/AllPerformanceTestsH2NonAudit.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/performance/AllPerformanceTestsH2NonAudit.java
index 46714c0fe3..24335f3645 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/performance/AllPerformanceTestsH2NonAudit.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/performance/AllPerformanceTestsH2NonAudit.java
@@ -30,6 +30,6 @@ public class AllPerformanceTestsH2NonAudit extends AllPerformanceTests
@Override
protected void initConfigSuites(TestSuite parent)
{
- addScenario(parent, new H2Config(false, false, false, false, IDGenerationLocation.STORE), JVM, NATIVE);
+ addScenario(parent, new H2Config(false, false, false, false, false, IDGenerationLocation.STORE), JVM, NATIVE);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
index d7468e54cb..12f74d9789 100644
--- a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
+++ b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
@@ -19,7 +19,6 @@ import org.eclipse.emf.cdo.tests.CrossReferenceTest;
import org.eclipse.emf.cdo.tests.DynamicXSDTest;
import org.eclipse.emf.cdo.tests.EMFCompareTest;
import org.eclipse.emf.cdo.tests.ExternalReferenceTest;
-import org.eclipse.emf.cdo.tests.FeatureMapTest;
import org.eclipse.emf.cdo.tests.LockingManagerRestartRepositoryTest;
import org.eclipse.emf.cdo.tests.LockingManagerRestartSessionTest;
import org.eclipse.emf.cdo.tests.LockingManagerRestartTransactionTest;
@@ -187,7 +186,7 @@ public class AllTestsHibernate extends AllConfigs
testClasses.add(Hibernate_Bugzilla_303466_Test.class);
// feature maps are not handled correctly in CDO with auditing
- testClasses.remove(FeatureMapTest.class);
+ // testClasses.remove(FeatureMapTest.class);
}
else
{
diff --git a/plugins/org.eclipse.emf.cdo.tests.lissome/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests.lissome/META-INF/MANIFEST.MF
index 4d35ec6bdc..08547277db 100644
--- a/plugins/org.eclipse.emf.cdo.tests.lissome/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests.lissome/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.tests.lissome;singleton:=true
-Bundle-Version: 4.2.100.qualifier
+Bundle-Version: 4.2.200.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -12,6 +12,6 @@ Bundle-ClassPath: .
Require-Bundle: org.eclipse.emf.cdo.tests;bundle-version="[4.0.0,5.0.0)",
org.eclipse.emf.cdo.server.lissome;bundle-version="[4.2.0,5.0.0)",
org.eclipse.net4j.db.h2;bundle-version="[4.0.0,5.0.0)"
-Export-Package: org.eclipse.emf.cdo.tests.lissome;version="4.2.100",
- org.eclipse.emf.cdo.tests.lissome.bundle;version="4.2.100";x-internal:=true
+Export-Package: org.eclipse.emf.cdo.tests.lissome;version="4.2.200",
+ org.eclipse.emf.cdo.tests.lissome.bundle;version="4.2.200";x-internal:=true
Import-Package: org.h2.jdbcx;version="[1.0.0,2.0.0)"
diff --git a/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java b/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java
index e11d78e62c..8678857c2a 100644
--- a/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java
@@ -63,6 +63,12 @@ public class LissomeConfig extends RepositoryConfig
return true;
}
+ @Override
+ public boolean isSupportingExtRefs()
+ {
+ return false;
+ }
+
public IStore createStore(String repoName)
{
if (reusableFolder == null)
diff --git a/plugins/org.eclipse.emf.cdo.tests.mongodb/src/org/eclipse/emf/cdo/tests/mongodb/MongoDBConfig.java b/plugins/org.eclipse.emf.cdo.tests.mongodb/src/org/eclipse/emf/cdo/tests/mongodb/MongoDBConfig.java
index fafacdfa0e..932cfc0033 100644
--- a/plugins/org.eclipse.emf.cdo.tests.mongodb/src/org/eclipse/emf/cdo/tests/mongodb/MongoDBConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests.mongodb/src/org/eclipse/emf/cdo/tests/mongodb/MongoDBConfig.java
@@ -85,4 +85,10 @@ public class MongoDBConfig extends RepositoryConfig
}
}
}
+
+ @Override
+ public boolean isSupportingExtRefs()
+ {
+ return false;
+ }
}
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 23738fe630..2cfe30a034 100644
--- a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
@@ -37,7 +37,8 @@ Require-Bundle: org.eclipse.net4j.tests;bundle-version="[4.0.0,5.0.0)";visibilit
org.eclipse.gmf.runtime.notation;bundle-version="[1.5.0,2.0.0)";visibility:=reexport,
org.eclipse.ocl.ecore;bundle-version="[3.0.0,4.0.0)",
org.apache.log4j;bundle-version="[1.2.0,2.0.0)",
- com.google.guava;bundle-version="[10.0.0,20.0.0)"
+ com.google.guava;bundle-version="[10.0.0,20.0.0)",
+ org.eclipse.emf.cdo.server.db;bundle-version="[4.0.0,5.0.0)"
Export-Package: base;version="4.0.200",
base.impl;version="4.0.200",
base.util;version="4.0.200",
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
index bdcb9fdcb5..cae164936a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
@@ -99,7 +99,7 @@ public class AllConfigs extends ConfigTestSuite
testClasses.add(LockingSequenceTest.class);
testClasses.add(MultiValuedOfAttributeTest.class);
testClasses.add(MapTest.class);
- testClasses.add(FeatureMapTest.class);
+ // testClasses.add(FeatureMapTest.class);
testClasses.add(AdapterManagerTest.class);
testClasses.add(ConflictResolverTest.class);
testClasses.add(ConflictResolverExtendedTest.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CDOIDTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CDOIDTest.java
index 02bc88869a..bdb0bfba18 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CDOIDTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CDOIDTest.java
@@ -57,12 +57,14 @@ public class CDOIDTest extends AbstractCDOTest
assertIllegalArgument(id);
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testGetLong_ExtTempId()
{
CDOIDTempObjectExternalImpl id = CDOIDTempObjectExternalImpl.create("cdo://repo123/resource456");
assertIllegalArgument(id);
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testGetLong_ExtId()
{
CDOIDExternal id = CDOIDUtil.createExternal("cdo://repo123/resource456");
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingClearCachedRevisionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingClearCachedRevisionTest.java
index e04ecd7d89..04265d01fa 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingClearCachedRevisionTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingClearCachedRevisionTest.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.SalesOrder;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -31,6 +32,7 @@ import java.util.Iterator;
*/
public class ChunkingClearCachedRevisionTest extends AbstractCDOTest
{
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testReadNative() throws Exception
{
CDORevision revisionToRemove = null;
@@ -78,6 +80,7 @@ public class ChunkingClearCachedRevisionTest extends AbstractCDOTest
}
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testWriteNative() throws Exception
{
CDORevision revisionToRemove = null;
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 a3e433fa3c..399fcaa0db 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
@@ -12,6 +12,8 @@ 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.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Customer;
@@ -36,6 +38,7 @@ import java.util.List;
/**
* @author Eike Stepper
*/
+@Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public class ChunkingTest extends AbstractCDOTest
{
private static final String RESOURCE_PATH = "/test";
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CrossReferenceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CrossReferenceTest.java
index 00ef7cd404..5cd0fe5401 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CrossReferenceTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/CrossReferenceTest.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.SalesOrder;
@@ -326,9 +327,9 @@ public class CrossReferenceTest extends AbstractCDOTest
}
@Skips("Hibernate")
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testDetachXRefExternal() throws Exception
{
- skipStoreWithoutExternalReferences();
Customer customer = getModel1Factory().createCustomer();
customer.setName("customer");
@@ -393,9 +394,9 @@ public class CrossReferenceTest extends AbstractCDOTest
}
@Skips("Hibernate")
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testNewMakeExternal() throws Exception
{
- skipStoreWithoutExternalReferences();
Customer customer = getModel1Factory().createCustomer();
customer.setName("customer");
@@ -423,6 +424,7 @@ public class CrossReferenceTest extends AbstractCDOTest
assertEquals(true, id.isExternal());
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testExternalMakeNew() throws Exception
{
Customer customer = getModel1Factory().createCustomer();
@@ -456,10 +458,9 @@ public class CrossReferenceTest extends AbstractCDOTest
}
@Skips("Hibernate")
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testExternalMakeDangling() throws Exception
{
- skipStoreWithoutExternalReferences();
-
Customer customer = getModel1Factory().createCustomer();
customer.setName("customer");
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java
index f01fbb088f..2e7a8cbee8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java
@@ -20,6 +20,8 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.internal.net4j.protocol.LoadRevisionsRequest;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.config.IModelConfig;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
@@ -59,14 +61,13 @@ import java.util.Map;
/**
* @author Simon McDuff
*/
+@Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public class ExternalReferenceTest extends AbstractCDOTest
{
private static final String REPOSITORY_B_NAME = "repo2";
public void testExternalWithDynamicEObject() throws Exception
{
- skipStoreWithoutExternalReferences();
-
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl());
@@ -94,8 +95,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
public void testExternalWithEClass() throws Exception
{
- skipStoreWithoutExternalReferences();
-
{
ResourceSet resourceSet = new ResourceSetImpl();
@@ -129,8 +128,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
public void testExternalWithEPackage() throws Exception
{
- skipStoreWithoutExternalReferences();
-
{
CDOSession sessionA = openSession();
@@ -168,8 +165,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
@Skips("Postgresql")
public void testOneXMIResourceManyViewsOnOneResourceSet() throws Exception
{
- skipStoreWithoutExternalReferences();
-
byte[] dataOfresD = null;
getRepository(REPOSITORY_B_NAME);
@@ -279,8 +274,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
@Skips({ IModelConfig.CAPABILITY_LEGACY, "Postgresql" })
public void testManyViewsOnOneResourceSet() throws Exception
{
- skipStoreWithoutExternalReferences();
-
getRepository(REPOSITORY_B_NAME);
{
@@ -390,8 +383,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
public void testWithXML() throws Exception
{
- skipStoreWithoutExternalReferences();
-
ResourceSet resourceSet = new ResourceSetImpl();
Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
map.put("xml", new XMLResourceFactoryImpl());
@@ -417,7 +408,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
public void testWithXMLAndPrefetching() throws Exception
{
- skipStoreWithoutExternalReferences();
{
ResourceSet resourceSet = new ResourceSetImpl();
@@ -491,8 +481,6 @@ public class ExternalReferenceTest extends AbstractCDOTest
@CleanRepositoriesBefore(reason = "Ref counting")
public void testXRefExternalObject() throws Exception
{
- skipStoreWithoutExternalReferences();
-
ResourceSet resourceSet = new ResourceSetImpl();
Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
map.put("xml", new XMLResourceFactoryImpl());
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FeatureMapTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FeatureMapTest.java
index 7bae3be135..1d1f5863f6 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FeatureMapTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FeatureMapTest.java
@@ -36,6 +36,7 @@ import java.util.List;
/**
* @author Simon McDuff
*/
+@Deprecated
public class FeatureMapTest extends AbstractCDOTest
{
private EPackage pkg;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
index bc74a6b92a..a91a77b1f0 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
@@ -183,6 +183,33 @@ public class InitialTest extends AbstractCDOTest
assertCreatedTime(supplier, commit.getTimeStamp());
}
+ public void testCommitNewInverseList() throws Exception
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+ Category category = getModel1Factory().createCategory();
+ category.setName("Category");
+ resource.getContents().add(category);
+
+ Product1 product = getModel1Factory().createProduct1();
+ product.setName("Product1");
+ category.getProducts().add(product);
+
+ OrderDetail orderDetail = getModel1Factory().createOrderDetail();
+ orderDetail.setPrice(47.11f);
+ orderDetail.setProduct(product);
+ resource.getContents().add(orderDetail);
+
+ CDOCommitInfo commit = transaction.commit();
+ assertEquals(CDOState.CLEAN, resource.cdoState());
+ assertEquals(CDOState.CLEAN, CDOUtil.getCDOObject(orderDetail).cdoState());
+ assertEquals(1, CDOUtil.getCDOObject(orderDetail).cdoRevision().getVersion());
+ assertCreatedTime(resource, commit.getTimeStamp());
+ assertCreatedTime(orderDetail, commit.getTimeStamp());
+ }
+
public void testReadResourceClean() throws Exception
{
CDOSession session = openSession();
@@ -262,6 +289,41 @@ public class InitialTest extends AbstractCDOTest
assertCreatedTime(supplier, commitTime2);
}
+ public void testCommitDirtyInverseList() throws Exception
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+ Category category = getModel1Factory().createCategory();
+ category.setName("Category");
+ resource.getContents().add(category);
+
+ Product1 product = getModel1Factory().createProduct1();
+ product.setName("Product1");
+ category.getProducts().add(product);
+
+ OrderDetail orderDetail = getModel1Factory().createOrderDetail();
+ orderDetail.setPrice(47.11f);
+ orderDetail.setProduct(product);
+ resource.getContents().add(orderDetail);
+
+ CDOCommitInfo commit = transaction.commit();
+ long commitTime1 = commit.getTimeStamp();
+ assertCreatedTime(product, commitTime1);
+
+ OrderDetail orderDetail2 = getModel1Factory().createOrderDetail();
+ orderDetail2.setPrice(0.815f);
+ orderDetail2.setProduct(product);
+ resource.getContents().add(orderDetail2);
+
+ long commitTime2 = transaction.commit().getTimeStamp();
+ assertEquals(true, commitTime1 < commitTime2);
+ assertEquals(CDOState.CLEAN, resource.cdoState());
+ assertEquals(CDOState.CLEAN, CDOUtil.getCDOObject(product).cdoState());
+ assertCreatedTime(product, commitTime2);
+ }
+
public void testGetResource() throws Exception
{
CDOSession session = openSession();
@@ -456,6 +518,52 @@ public class InitialTest extends AbstractCDOTest
assertEquals("Stepper", s.getName());
}
+ public void testLoadObjectInverseList() throws Exception
+ {
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+ Category category = getModel1Factory().createCategory();
+ category.setName("Category");
+ resource.getContents().add(category);
+
+ Product1 product = getModel1Factory().createProduct1();
+ product.setName("Product1");
+ category.getProducts().add(product);
+
+ OrderDetail orderDetail = getModel1Factory().createOrderDetail();
+ orderDetail.setPrice(47.11f);
+ orderDetail.setProduct(product);
+ resource.getContents().add(orderDetail);
+
+ transaction.commit();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+ }
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+ EList<EObject> contents = resource.getContents();
+
+ Category category = (Category)contents.get(0);
+ assertNotNull(category);
+ assertEquals("Category", category.getName());
+ assertEquals(1, category.getProducts().size());
+
+ Product1 product = category.getProducts().get(0);
+ assertNotNull(product);
+ assertEquals("Product1", product.getName());
+ assertEquals(1, product.getOrderDetails().size());
+
+ OrderDetail orderDetail = product.getOrderDetails().get(0);
+ assertNotNull(orderDetail);
+ assertEquals(47.11f, orderDetail.getPrice());
+ assertEquals(product, orderDetail.getProduct());
+ }
+
/**
* bug 226317
*/
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 dfda28180d..1d33264d91 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
@@ -12,6 +12,7 @@ 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.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model3.MetaRef;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -22,10 +23,9 @@ import org.eclipse.emf.ecore.EReference;
*/
public class MetaTest extends AbstractCDOTest
{
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testMetaReference() throws Exception
{
- skipStoreWithoutExternalReferences();
-
{
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
@@ -46,10 +46,9 @@ public class MetaTest extends AbstractCDOTest
assertEquals(getModel3Package(), metaRef.getEPackageRef());
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testMetaReferenceAttachFirst() throws Exception
{
- skipStoreWithoutExternalReferences();
-
{
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
@@ -70,10 +69,9 @@ public class MetaTest extends AbstractCDOTest
assertEquals(getModel3Package(), metaRef.getEPackageRef());
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testMetaReference2() throws Exception
{
- skipStoreWithoutExternalReferences();
-
EReference targetRef = getModel3SubpackagePackage().getClass2_Class1();
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MultiValuedOfAttributeTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MultiValuedOfAttributeTest.java
index f43cf3b917..f65eee1771 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MultiValuedOfAttributeTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MultiValuedOfAttributeTest.java
@@ -13,6 +13,8 @@ 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.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
@@ -31,6 +33,7 @@ import java.util.List;
/**
* @author Simon McDuff
*/
+@Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public class MultiValuedOfAttributeTest extends AbstractCDOTest
{
public void testListOfString() throws Exception
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
index 1db4442fdc..bdd29e4263 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
@@ -98,6 +99,7 @@ public class ViewTest extends AbstractCDOTest
session.close();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testUniqueResourceContents() throws Exception
{
{
@@ -137,6 +139,7 @@ public class ViewTest extends AbstractCDOTest
session.close();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testNonUniqueResourceContents() throws Exception
{
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java
index 88d048c12c..9b169596a7 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java
@@ -80,9 +80,9 @@ public class XATransactionTest extends AbstractCDOTest
xaTransaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testRollback_AfterSetpoint() throws Exception
{
- skipStoreWithoutExternalReferences();
getRepository(REPOSITORY2_NAME);
CDOSession sessionA = openSession();
@@ -143,9 +143,9 @@ public class XATransactionTest extends AbstractCDOTest
// XXX disabled because of Bug 290097
@Skips("Postgresql")
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testCommitFromTransactionDisabled() throws Exception
{
- skipStoreWithoutExternalReferences();
getRepository(REPOSITORY2_NAME);
{
@@ -191,9 +191,9 @@ public class XATransactionTest extends AbstractCDOTest
// Skip this test until the problems with XATransactions are solved.
@Skips({ IModelConfig.CAPABILITY_LEGACY, IRepositoryConfig.CAPABILITY_UUIDS, "DB" })
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testNotUsingXATransaction_Exception() throws Exception
{
- skipStoreWithoutExternalReferences();
getRepository(REPOSITORY2_NAME);
{
@@ -236,9 +236,9 @@ public class XATransactionTest extends AbstractCDOTest
// XXX disabled because of Bug 290097
@Skips("Postgresql")
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void test_ExceptionInReadingStream() throws Exception
{
- skipStoreWithoutExternalReferences();
getRepository(REPOSITORY2_NAME);
CDOSession sessionA = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_306998_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_306998_Test.java
index 4cc3b0e3e8..3bb065a980 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_306998_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_306998_Test.java
@@ -15,7 +15,6 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.VAT;
-import org.eclipse.emf.cdo.tests.model1.legacy.Model1Package;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
@@ -36,7 +35,7 @@ public class Bugzilla_306998_Test extends AbstractCDOTest
{
EPackage pkg = createUniquePackage();
EClass cls = EMFUtil.createEClass(pkg, "cls", false, false);
- EAttribute att = EMFUtil.createEAttribute(cls, "att", Model1Package.eINSTANCE.getVAT());
+ EAttribute att = EMFUtil.createEAttribute(cls, "att", getModel1Package().getVAT());
att.setDefaultValueLiteral("vat7");
CDOUtil.prepareDynamicEPackage(pkg);
@@ -75,9 +74,9 @@ public class Bugzilla_306998_Test extends AbstractCDOTest
{
EPackage pkg = createUniquePackage();
EClass cls = EMFUtil.createEClass(pkg, "cls", false, false);
- EAttribute att = EMFUtil.createEAttribute(cls, "att", Model1Package.eINSTANCE.getVAT());
+ EAttribute att = EMFUtil.createEAttribute(cls, "att", getModel1Package().getVAT());
att.setDefaultValueLiteral("vat8");
- att.setDefaultValue(Model1Package.eINSTANCE.getVAT().getEEnumLiteral("vat8"));
+ att.setDefaultValue(getModel1Package().getVAT().getEEnumLiteral("vat8"));
CDOUtil.prepareDynamicEPackage(pkg);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_322218_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_322218_Test.java
index bfb8cf4252..148d678a7e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_322218_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_322218_Test.java
@@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model6.MyEnum;
import org.eclipse.emf.cdo.tests.model6.MyEnumList;
import org.eclipse.emf.cdo.tests.model6.MyEnumListUnsettable;
@@ -73,6 +74,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumListPCL() throws Exception
{
MyEnumList myEnumList = getModel6Factory().createMyEnumList();
@@ -91,6 +93,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumList2PCL() throws Exception
{
CDOSession session = openSession();
@@ -109,6 +112,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumList3PCL() throws Exception
{
CDOSession session = openSession();
@@ -128,6 +132,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumList3PCL_Reload() throws Exception
{
{
@@ -207,6 +212,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumListUnsettablePCL() throws Exception
{
MyEnumListUnsettable myEnumList = getModel6Factory().createMyEnumListUnsettable();
@@ -225,6 +231,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumListUnsettable2PCL() throws Exception
{
CDOSession session = openSession();
@@ -243,6 +250,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumListUnsettable3PCL() throws Exception
{
CDOSession session = openSession();
@@ -262,6 +270,7 @@ public class Bugzilla_322218_Test extends AbstractCDOTest
transaction.commit();
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testMyEnumListUnsettable3PCL_Reload() throws Exception
{
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_323930_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_323930_Test.java
index 66d19bf54d..236c636881 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_323930_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_323930_Test.java
@@ -36,7 +36,6 @@ public class Bugzilla_323930_Test extends AbstractCDOTest
protected void doSetUp() throws Exception
{
super.doSetUp();
- skipStoreWithoutQueryXRefs();
}
public void testChangeIndexesInTargetList() throws Exception
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_335675_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_335675_Test.java
index 10d4791771..daebd19d17 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_335675_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_335675_Test.java
@@ -15,6 +15,8 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.revision.BaseCDORevision;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IModelConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Model1Package;
import org.eclipse.emf.cdo.tests.model1.OrderDetail;
@@ -37,6 +39,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil;
/**
* @author Caspar De Groot
*/
+@Requires(IModelConfig.CAPABILITY_LEGACY)
public class Bugzilla_335675_Test extends AbstractCDOTest
{
public void test0() throws Exception
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337054_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337054_Test.java
index adc5782cca..6f931a7b31 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337054_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337054_Test.java
@@ -30,7 +30,7 @@ public class Bugzilla_337054_Test extends AbstractCDOTest
private static final int LIST_SIZE = 3;
- @Requires({ IRepositoryConfig.CAPABILITY_BRANCHING, IRepositoryConfig.CAPABILITY_RESTARTABLE })
+ @Requires({ IRepositoryConfig.CAPABILITY_BRANCHING, IRepositoryConfig.CAPABILITY_CHUNKING, IRepositoryConfig.CAPABILITY_RESTARTABLE })
public void testCDOElementProxies() throws Exception
{
CDOSession session = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337587_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337587_Test.java
index 69ab6970da..4dcefcdbf7 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337587_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_337587_Test.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.SalesOrder;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -29,6 +30,7 @@ import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
*/
public class Bugzilla_337587_Test extends AbstractCDOTest
{
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testRevisionCompare() throws CommitException
{
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java
index 9037ba2aab..f2ecf67141 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java
@@ -28,7 +28,7 @@ public class Bugzilla_347964_Test extends AbstractCDOTest
{
private static final String RESOURCE_NAME = "res347964";
- @Requires(IRepositoryConfig.CAPABILITY_RESTARTABLE)
+ @Requires({ IRepositoryConfig.CAPABILITY_RESTARTABLE, IRepositoryConfig.CAPABILITY_CHUNKING })
public void testIndexDeletion() throws Exception
{
CDOSession session = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_351393_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_351393_Test.java
index de1be03a69..d75d99d79d 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_351393_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_351393_Test.java
@@ -33,10 +33,9 @@ public class Bugzilla_351393_Test extends AbstractCDOTest
{
// Ext-Refs with client-side UUIDs are stored "in sito", where the tests use even less chars.
@Skips(IRepositoryConfig.CAPABILITY_UUIDS)
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testExtRef() throws Exception
{
- skipStoreWithoutExternalReferences();
-
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl());
URI uri = URI.createURI("test:///tmp/file.xmi?" + "12345678901234567890" + // 41
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java
index 2c9777e920..5512cdeae4 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java
@@ -15,6 +15,8 @@ import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
@@ -52,6 +54,7 @@ import java.util.Map;
*
* @author Esteban Dugueperoux
*/
+@Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public class Bugzilla_362270_Test extends AbstractCDOTest
{
private final EReference SUPPLIERS = getModel1Package().getCompany_Suppliers();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java
index cf9ffb77d9..474a9a413b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java
@@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
@@ -53,6 +54,7 @@ public class Bugzilla_362270c_Test extends AbstractCDOTest
{
private static final String RESOURCE_PATH = "/test1";
+ @Requires(IRepositoryConfig.CAPABILITY_EXTERNAL_REFS)
public void testNotifierNotACDOLegacyAdapter() throws Exception
{
TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
index 7f3d024ec3..6f96be741e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
@@ -64,6 +64,7 @@ public class Bugzilla_369646_Test extends AbstractCDOTest
transaction.setBranch(sub1);
}
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testSetBranchWithPCL() throws Exception
{
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405606_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405606_Test.java
index 14bbb71813..8f578d9f1d 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405606_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405606_Test.java
@@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
@@ -26,6 +27,7 @@ import org.eclipse.net4j.util.io.IOUtil;
*/
public class Bugzilla_405606_Test extends AbstractCDOTest
{
+ @Requires(IRepositoryConfig.CAPABILITY_CHUNKING)
public void testUnchunkedRevisionWithPCL() throws Exception
{
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_436246_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_436246_Test.java
index 079cb4876d..7654764a51 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_436246_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_436246_Test.java
@@ -250,9 +250,11 @@ public class Bugzilla_436246_Test extends AbstractCDOTest
protocol.removeListener(signalCounter);
}
+ /**
+ * @author Eike Stepper
+ */
private class CustomCDOFetchRuleManager implements CDOFetchRuleManager
{
-
private CDOID companyCDOID;
public CustomCDOFetchRuleManager(CDOID companyCDOID)
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485394_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485394_Test.java
index 626410cc73..247179de8d 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485394_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485394_Test.java
@@ -36,6 +36,8 @@ public class Bugzilla_485394_Test extends AbstractCDOTest
return map;
}
+ // With inverse list mappings there is no referential integrity violation in this case.
+ @Skips("DB.inverse.lists")
public void testReferentialIntegrityWithContainmentProxy() throws Exception
{
skipStoreWithoutQueryXRefs();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IRepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IRepositoryConfig.java
index 4cac391e45..e9344a7042 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IRepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IRepositoryConfig.java
@@ -35,6 +35,10 @@ public interface IRepositoryConfig extends IConfig, IRepositoryProvider
public static final String CAPABILITY_BRANCHING = "repository.branching";
+ public static final String CAPABILITY_CHUNKING = "repository.chunking";
+
+ public static final String CAPABILITY_EXTERNAL_REFS = "repository.external.refs";
+
public static final String CAPABILITY_UUIDS = "repository.uuids";
public static final String CAPABILITY_OFFLINE = "repository.offline";
@@ -49,6 +53,10 @@ public interface IRepositoryConfig extends IConfig, IRepositoryProvider
public boolean isSupportingBranches();
+ public boolean isSupportingChunks();
+
+ public boolean isSupportingExtRefs();
+
public IDGenerationLocation getIDGenerationLocation();
public Map<String, String> getRepositoryProperties();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/ConfigTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/ConfigTest.java
index 40601e442b..aeffedfeb2 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/ConfigTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/ConfigTest.java
@@ -20,7 +20,6 @@ import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoChangeSets;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoCommitInfos;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoDurableLocking;
-import org.eclipse.emf.cdo.spi.server.InternalStore.NoExternalReferences;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoFeatureMaps;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoHandleRevisions;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoLargeObjects;
@@ -726,11 +725,6 @@ public abstract class ConfigTest extends AbstractOMTest implements IConstants
|| ObjectUtil.equals(getModelConfig(), config);
}
- protected void skipStoreWithoutExternalReferences()
- {
- skipTest(getRepository().getStore() instanceof NoExternalReferences);
- }
-
protected void skipStoreWithoutQueryXRefs()
{
skipTest(getRepository().getStore() instanceof NoQueryXRefs);
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 ad9f618b85..2dec90aa22 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
@@ -179,6 +179,16 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
}
}
+ if (isSupportingChunks())
+ {
+ capabilities.add(CAPABILITY_CHUNKING);
+ }
+
+ if (isSupportingExtRefs())
+ {
+ capabilities.add(CAPABILITY_EXTERNAL_REFS);
+ }
+
if (getIDGenerationLocation() == IDGenerationLocation.CLIENT)
{
capabilities.add(CAPABILITY_UUIDS);
@@ -209,6 +219,16 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
return supportingBranches;
}
+ public boolean isSupportingChunks()
+ {
+ return true;
+ }
+
+ public boolean isSupportingExtRefs()
+ {
+ return true;
+ }
+
public IDGenerationLocation getIDGenerationLocation()
{
return idGenerationLocation;
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
index b9c5e53481..c3b0736f6c 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.net4j.db;
+import org.eclipse.net4j.db.ddl.IDBElement;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBNamedElement;
import org.eclipse.net4j.db.ddl.IDBSchema;
@@ -22,6 +23,7 @@ import org.eclipse.net4j.internal.db.bundle.OM;
import org.eclipse.net4j.internal.db.ddl.DBIndex;
import org.eclipse.net4j.internal.db.ddl.DBNamedElement;
import org.eclipse.net4j.spi.db.DBAdapter;
+import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.io.ExtendedDataInput;
@@ -469,6 +471,35 @@ public final class DBUtil
}
/**
+ * @since 4.6
+ */
+ public static boolean isOptional(IDBElement element)
+ {
+ if (element instanceof InternalDBIndex)
+ {
+ InternalDBIndex index = (InternalDBIndex)element;
+ return index.isOptional();
+ }
+
+ return false;
+ }
+
+ /**
+ * @since 4.6
+ */
+ public static boolean setOptional(IDBElement element, boolean optional)
+ {
+ if (element instanceof InternalDBIndex)
+ {
+ InternalDBIndex index = (InternalDBIndex)element;
+ index.setOptional(optional);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* @since 4.2
*/
public static boolean setAutoCommit(Connection connection, boolean autoCommit)
@@ -876,6 +907,17 @@ public final class DBUtil
{
throw new DBException(ex);
}
+ finally
+ {
+ try
+ {
+ stmt.clearBatch();
+ }
+ catch (SQLException ex)
+ {
+ OM.LOG.warn(ex);
+ }
+ }
}
public static int update(Connection connection, String sql)
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java
index c48e835fed..19dfe0e24a 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java
@@ -25,7 +25,6 @@ import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.db.ddl.SchemaElementNotFoundException;
import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta;
-import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.spi.db.ddl.InternalDBSchema;
import javax.sql.DataSource;
@@ -75,7 +74,7 @@ public class DBSchema extends DBSchemaElement implements InternalDBSchema
for (IDBIndex sourceIndex : sourceTable.getIndices())
{
IDBIndex index = table.addIndexEmpty(sourceIndex.getName(), sourceIndex.getType());
- ((InternalDBIndex)index).setOptional(((InternalDBIndex)sourceIndex).isOptional());
+ DBUtil.setOptional(index, DBUtil.isOptional(sourceIndex));
for (IDBField sourceField : sourceIndex.getFields())
{
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
index 74e4143d00..7695755cb0 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
@@ -11,6 +11,7 @@
package org.eclipse.net4j.internal.db.ddl.delta;
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.IDBIndexField;
@@ -23,7 +24,6 @@ import org.eclipse.net4j.db.ddl.delta.IDBIndexDelta;
import org.eclipse.net4j.db.ddl.delta.IDBIndexFieldDelta;
import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.db.ddl.delta.IDBTableDelta;
-import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
import org.eclipse.net4j.spi.db.ddl.InternalDBSchema;
import java.text.MessageFormat;
@@ -204,8 +204,8 @@ public final class DBSchemaDelta extends DBDelta implements IDBSchemaDelta
Boolean optional = delta.getPropertyValue(IDBIndexDelta.OPTIONAL_PROPERTY);
IDBTable table = delta.getParent().getSchemaElement(schema);
- InternalDBIndex index = (InternalDBIndex)table.addIndexEmpty(name, type);
- index.setOptional(optional == Boolean.TRUE);
+ IDBIndex index = table.addIndexEmpty(name, type);
+ DBUtil.setOptional(index, optional == Boolean.TRUE);
}
@Override

Back to the top