summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Winkler2010-02-01 10:29:17 (EST)
committerStefan Winkler2010-02-01 10:29:17 (EST)
commitbf15720a48d1d48b0fead2f69a8a70be62aea427 (patch)
treef5b2f4563cbbabfd699c8e087ad5438f4ce64b8e
parent9316fc3b2db728331399f7d51f66349007ba127e (diff)
downloadcdo-bf15720a48d1d48b0fead2f69a8a70be62aea427.zip
cdo-bf15720a48d1d48b0fead2f69a8a70be62aea427.tar.gz
cdo-bf15720a48d1d48b0fead2f69a8a70be62aea427.tar.bz2
[270716] Provide support for branching
https://bugs.eclipse.org/bugs/show_bug.cgi?id=270716
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java62
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java77
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java8
6 files changed, 149 insertions, 36 deletions
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 4837553..c37266a 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,6 +10,7 @@
*/
package org.eclipse.emf.cdo.server.db;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.IStoreAccessor;
import java.sql.Connection;
@@ -27,4 +28,9 @@ public interface IDBStoreAccessor extends IStoreAccessor
* @since 2.0
*/
public IPreparedStatementCache getStatementCache();
+
+ /**
+ * @since 3.0
+ */
+ public boolean isNewObject(CDOID id);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java
index 80f5b29..3c5d15e 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java
@@ -14,6 +14,7 @@ package org.eclipse.emf.cdo.server.db.mapping;
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.server.db.IDBStoreAccessor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
@@ -47,4 +48,20 @@ public interface IClassMappingBranchingSupport extends IClassMappingAuditSupport
* the monitor to indicate progress.
*/
public void detachObject(IDBStoreAccessor dbStoreAccessor, CDOID id, long revised, CDOBranch branch, OMMonitor monitor);
+
+ /**
+ * Write a special placeholder revision which is used to indicate that a revision is detached in a branch.
+ *
+ * @param accessor
+ * the accessor to use.
+ * @param revision
+ * the old revision about to be detached
+ * @param revised
+ * the timeStamp when this object became detached.
+ * @param monitor
+ * the monitor to indicate progress.
+ * @since 3.0
+ */
+ public void detachFirstVersion(IDBStoreAccessor accessor, CDORevision revision, long revised, OMMonitor monitor);
+
}
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 559ef13..08ee03f 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
@@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.server.IRepository;
@@ -36,18 +37,16 @@ import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.spi.server.LongIDStoreAccessor;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.ProgressDistributable;
-import org.eclipse.net4j.util.om.monitor.ProgressDistributor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -62,7 +61,9 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@@ -79,25 +80,7 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
private Timer connectionKeepAliveTimer = null;
- @ExcludeFromDump
- @SuppressWarnings("unchecked")
- private final ProgressDistributable<CommitContext>[] ops = ProgressDistributor.array( //
- new ProgressDistributable.Default<CommitContext>()
- {
- public void runLoop(int index, CommitContext commitContext, OMMonitor monitor) throws Exception
- {
- DBStoreAccessor.super.write(commitContext, monitor.fork());
- }
- }, //
-
- new ProgressDistributable.Default<CommitContext>()
- {
- public void runLoop(int index, CommitContext commitContext, OMMonitor monitor) throws Exception
- {
- // TODO - reenable when reimplementing stmt caching
- // flush(monitor.fork());
- }
- });
+ private Set<CDOID> newObjects = new HashSet<CDOID>();
public DBStoreAccessor(DBStore store, ISession session) throws DBException
{
@@ -189,6 +172,10 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
if (mapping.readRevision(this, revision, listChunk))
{
+ if (revision.getVersion() == -1)
+ {
+ return new DetachedCDORevision(id, branchPoint.getBranch(), 1, branchPoint.getTimeStamp());
+ }
return revision;
}
@@ -277,8 +264,14 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
@Override
public void write(CommitContext context, OMMonitor monitor)
{
- ProgressDistributor distributor = getStore().getAccessorWriteDistributor();
- distributor.run(ops, context, monitor);
+ // remember CDOIDs of new objects
+ newObjects.clear();
+ for (InternalCDORevision revision : context.getNewObjects())
+ {
+ newObjects.add(revision.getID());
+ }
+
+ super.write(context, monitor);
}
@Override
@@ -403,11 +396,23 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
TRACER.format("Detaching object: {0} in branch {1}", id, branch); //$NON-NLS-1$
}
- EClass eClass = getObjectType(id);
+ InternalCDORevision oldRevision = (InternalCDORevision)getStore().getRepository().getRevisionManager().getRevision(
+ id, branch.getPoint(revised), 0, CDORevision.DEPTH_NONE, true);
+ EClass eClass = oldRevision.getEClass();
+
IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
IClassMappingBranchingSupport mapping = (IClassMappingBranchingSupport)mappingStrategy.getClassMapping(eClass);
- mapping.detachObject(this, id, revised, branch, monitor);
+ if (oldRevision.getVersion() == 1)
+ {
+ // version 1 in branch gets deleted -> write placebo revision.
+ mapping.detachFirstVersion(this, oldRevision, revised, monitor);
+ }
+ else
+ {
+ // default detach behavior
+ mapping.detachObject(this, id, revised, branch, monitor);
+ }
}
public Connection getConnection()
@@ -657,4 +662,9 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
}
}
}
+
+ public boolean isNewObject(CDOID id)
+ {
+ return newObjects.contains(id);
+ }
}
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 fa88fc1..b6d420f 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
@@ -92,7 +92,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping
IDBField idField = table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true);
IDBField versionField = table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true);
- addBranchingField(table);
+ IDBField branchField = addBranchingField(table);
table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.BIGINT, true);
table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true);
@@ -101,12 +101,21 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping
table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true);
table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true);
- table.addIndex(IDBIndex.Type.UNIQUE, idField, versionField);
+ if (branchField != null)
+ {
+ table.addIndex(IDBIndex.Type.UNIQUE, idField, versionField, branchField);
+ }
+ else
+ {
+ table.addIndex(IDBIndex.Type.UNIQUE, idField, versionField);
+ }
+
table.addIndex(IDBIndex.Type.NON_UNIQUE, idField, revisedField);
}
- protected void addBranchingField(IDBTable table)
+ protected IDBField addBranchingField(IDBTable table)
{
+ return null;
}
private void initFeatures()
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
index 749d0ea..22d721c 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
@@ -34,7 +34,6 @@ import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.db.ddl.IDBIndex.Type;
import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
@@ -77,10 +76,9 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp
}
@Override
- protected void addBranchingField(IDBTable table)
+ protected IDBField addBranchingField(IDBTable table)
{
- IDBField branch = table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
- table.addIndex(Type.NON_UNIQUE, branch);
+ return table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
}
private void initSqlStrings()
@@ -485,6 +483,69 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp
}
}
+ public void detachFirstVersion(IDBStoreAccessor accessor, CDORevision rev, long revised, OMMonitor monitor)
+ {
+ PreparedStatement stmt = null;
+
+ InternalCDORevision revision = (InternalCDORevision)rev;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+ int col = 1;
+
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, -1); // cdo_version
+ stmt.setInt(col++, revision.getBranch().getID());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revised); // cdo_created
+ stmt.setLong(col++, 0); // cdo_revised
+ stmt.setLong(col++, CDODBUtil.convertCDOIDToLong(getExternalReferenceManager(), accessor, revision
+ .getResourceID()));
+ stmt.setLong(col++, CDODBUtil.convertCDOIDToLong(getExternalReferenceManager(), accessor, (CDOID)revision
+ .getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
+
+ // XXX Eike: what to do with attributes?
+ // the following is currently a copy of writeValues ...
+
+ int isSetCol = col + getValueMappings().size();
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ EStructuralFeature feature = mapping.getFeature();
+ if (feature.isUnsettable())
+ {
+ if (revision.getValue(feature) == null)
+ {
+ stmt.setBoolean(isSetCol++, false);
+
+ // also set value column to default value
+ mapping.setDefaultValue(stmt, col++);
+
+ continue;
+ }
+ else
+ {
+ stmt.setBoolean(isSetCol++, true);
+ }
+ }
+ mapping.setValueFromRevision(stmt, col++, revision);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
protected void reviseObject(IDBStoreAccessor accessor, CDOID id, int branchId, long revised)
{
PreparedStatement stmt = null;
@@ -525,13 +586,15 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp
async = monitor.forkAsync();
CDOID id = revision.getID();
- if (revision.getVersion() == CDORevision.FIRST_VERSION)
+
+ if (accessor.isNewObject(id))
{
- // XXX Assumption no longer valid with branches!
+ // put new objects into objectTypeCache
((HorizontalBranchingMappingStrategy)getMappingStrategy()).putObjectType(accessor, id, getEClass());
}
- else
+ else if (revision.getVersion() > 1)
{
+ // if revision is not the first one, revise the old revision
long revised = revision.getTimeStamp() - 1;
reviseObject(accessor, id, revision.getBranch().getID(), revised);
for (IListMapping mapping : getListMappings())
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
index 01b6568..6f73502 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
@@ -67,14 +67,22 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle
/**
* Returns the conflicting objects.
+ *
+ * @since 3.0
*/
public Set<CDOObject> handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
Collection<CDOID> detachedOIDs, boolean async);
+ /**
+ * @since 3.0
+ */
public Set<CDOObject> handleInvalidationWithoutNotification(Set<CDOIDAndVersion> dirtyOIDs,
Collection<CDOID> detachedOIDs, Set<InternalCDOObject> dirtyObjects, Set<InternalCDOObject> detachedObjects,
boolean async);
+ /**
+ * @since 3.0
+ */
public void handleChangeSubscription(Collection<CDORevisionDelta> deltas, Collection<CDOID> detachedObjects,
boolean async);