summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Winkler2010-01-16 07:16:40 (EST)
committerStefan Winkler2010-01-16 07:16:40 (EST)
commit7dae86fb1ac5cb5d59ee92fa3eb2d45ebf50667a (patch)
treec498c0c96abd66e07b17b64299f1899eeac72df9
parent9145be54c4b058613d3848d374556c88c6829801 (diff)
downloadcdo-7dae86fb1ac5cb5d59ee92fa3eb2d45ebf50667a.zip
cdo-7dae86fb1ac5cb5d59ee92fa3eb2d45ebf50667a.tar.gz
cdo-7dae86fb1ac5cb5d59ee92fa3eb2d45ebf50667a.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/CDODBUtil.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java50
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java76
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java67
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java66
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java580
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java60
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java7
-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/Store.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessor.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java216
24 files changed, 1222 insertions, 64 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
index afde3ad..f1a2efe 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
@@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.server.internal.db.DBStore;
import org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalBranchingMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy;
import org.eclipse.net4j.db.DBUtil;
@@ -87,6 +88,25 @@ public final class CDODBUtil
}
/**
+ * @since 3.0
+ */
+ public static IMappingStrategy createHorizontalMappingStrategy(boolean auditing, boolean branching)
+ {
+ if (branching)
+ {
+ if (auditing)
+ {
+ return new HorizontalBranchingMappingStrategy();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Misconfiguration: Branching requires Auditing!");
+ }
+ }
+ return createHorizontalMappingStrategy(auditing);
+ }
+
+ /**
* Can only be used when Eclipse is running. In standalone scenarios create the mapping strategy instance by directly
* calling the constructor of the mapping strategy class.
*
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
index 0f95347..054246b 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
@@ -11,6 +11,8 @@
*/
package org.eclipse.emf.cdo.server.db.mapping;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
@@ -115,13 +117,15 @@ public interface IClassMapping
* @param exactMatch
* if <code>true</code>, <code>name</code> must match exactly, otherwise all resource nodes starting with
* <code>name</code> are returned.
- * @param timeStamp
- * a timestamp in the past if past versions should be looked up. In case of no audit support, this must be
- * {@link CDORevision#UNSPECIFIED_DATE}.
+ * @param a
+ * branchPoint (branch and timestamp) a timestamp in the past if past versions should be looked up. In case
+ * of no audit support, this must be {@link CDORevision#UNSPECIFIED_DATE}. In case of non branching support
+ * the branch id must be equal to {@link CDOBranch#MAIN_BRANCH_ID}.
* @return the prepared statement ready to be executed using <code>result.executeQuery()</code>.
* @throws ImplementationError
* if called on a mapping which does not map an <code>EClass instanceof CDOResourceNode</code>.
+ * @since 3.0
*/
public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, long timeStamp);
+ boolean exactMatch, CDOBranchPoint branchPoint);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java
index 87a3f1a..893b8f5 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java
@@ -1,5 +1,6 @@
/**
- * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ? * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,8 +12,6 @@
*/
package org.eclipse.emf.cdo.server.db.mapping;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -47,8 +46,7 @@ public interface IClassMappingAuditSupport
* could not be found. In this case, the content of <code>revision</code> is undefined.
* @since 3.0
*/
- public boolean readRevisionByVersion(IDBStoreAccessor storeAccessor, InternalCDORevision revision,
- CDOBranchVersion branchVersion, int listChunk);
+ public boolean readRevisionByVersion(IDBStoreAccessor storeAccessor, InternalCDORevision revision, int listChunk);
/**
* Read a specific past version of a revision. If this method returns <code>true</code> it is guaranteed that
@@ -68,6 +66,5 @@ public interface IClassMappingAuditSupport
* could not be found. In this case, the content of <code>revision</code> is undefined.
* @since 3.0
*/
- public boolean readRevision(IDBStoreAccessor storeAccessor, InternalCDORevision revision, CDOBranchPoint branchPoint,
- int listChunk);
+ public boolean readRevision(IDBStoreAccessor storeAccessor, InternalCDORevision revision, int listChunk);
}
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
new file mode 100644
index 0000000..80f5b29
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingBranchingSupport.java
@@ -0,0 +1,50 @@
+/**
+builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ? * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
+ */
+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.server.db.IDBStoreAccessor;
+
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+/**
+ * Interface which complements {@link IClassMappingAuditSupport} with methods to facilitate
+ * branching support.
+ *
+ * @see {@link IMappingStrategy#hasAuditSupport()
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ *
+ * @since 3.0
+ */
+public interface IClassMappingBranchingSupport extends IClassMappingAuditSupport
+{
+ /**
+ * Removes an object from the database. In the case of auditing support the object is just marked as revised, else it
+ * it permanently deleted.
+ *
+ * @param dbStoreAccessor
+ * the accessor to use.
+ * @param id
+ * the ID of the object to remove.
+ * @param branch
+ * the branch in which to work
+ * @param revised
+ * the timeStamp when this object became detached.
+ * @param monitor
+ * the monitor to indicate progress.
+ */
+ public void detachObject(IDBStoreAccessor dbStoreAccessor, CDOID id, long revised, CDOBranch branch, OMMonitor monitor);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
index ab7d181..c67ecc1 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
@@ -180,6 +180,16 @@ public interface IMappingStrategy
public boolean hasAuditSupport();
/**
+ * Query if this mapping supports branches. <br>
+ * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by
+ * {@link #getClassMapping(EClass)} implement {@link IClassMappingBranchingSupport}.
+ *
+ * @return <code>true</code> if branches are supported, <code>false</code> else.
+ * @since 3.0
+ */
+ public boolean hasBranchingSupport();
+
+ /**
* Execute a resource query.
*
* @param dbStoreAccessor
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
index 48564e7..9ed631a 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
@@ -182,6 +182,8 @@ public class CDODBSchema extends DBSchema
public static final String LIST_REVISION_VERSION = "cdo_version"; //$NON-NLS-1$
+ public static final String LIST_REVISION_BRANCH = "cdo_branch"; //$NON-NLS-1$
+
public static final String LIST_IDX = "cdo_idx"; //$NON-NLS-1$
public static final String LIST_VALUE = "cdo_value"; //$NON-NLS-1$
@@ -193,6 +195,8 @@ public class CDODBSchema extends DBSchema
public static final String FEATUREMAP_VERSION = "cdo_version"; //$NON-NLS-1$
+ public static final String FEATUREMAP_BRANCH = "cdo_branch"; //$NON-NLS-1$
+
public static final String FEATUREMAP_IDX = "cdo_idx"; //$NON-NLS-1$
public static final String FEATUREMAP_TAG = "cdo_tag"; //$NON-NLS-1$
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 b632fe8..8260415 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
@@ -20,6 +20,7 @@ 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.cache.CDORevisionCacheAdder;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.ISession;
@@ -31,6 +32,7 @@ import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingBranchingSupport;
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;
@@ -187,9 +189,10 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
EClass eClass = getObjectType(id);
InternalCDORevision revision = getStore().createRevision(eClass, id);
+ revision.setBranchPoint(branchPoint);
IClassMappingAuditSupport mapping = (IClassMappingAuditSupport)mappingStrategy.getClassMapping(eClass);
- if (mapping.readRevision(this, revision, branchPoint, listChunk))
+ if (mapping.readRevision(this, revision, listChunk))
{
return revision;
}
@@ -206,6 +209,8 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
EClass eClass = getObjectType(id);
InternalCDORevision revision = getStore().createRevision(eClass, id);
IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
+ revision.setVersion(branchVersion.getVersion());
+ revision.setBranchPoint(new CDOBranchPointImpl(branchVersion.getBranch(), CDOBranchPoint.UNSPECIFIED_DATE));
boolean success = false;
@@ -217,7 +222,7 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
}
// if audit support is present, just use the audit method
- success = ((IClassMappingAuditSupport)mapping).readRevisionByVersion(this, revision, branchVersion, listChunk);
+ success = ((IClassMappingAuditSupport)mapping).readRevisionByVersion(this, revision, listChunk);
}
else
{
@@ -240,7 +245,6 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
+ " - version requested was " + branchVersion + "."); //$NON-NLS-1$ //$NON-NLS-2$
}
}
-
return success ? revision : null;
}
@@ -349,10 +353,24 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
{
try
{
- monitor.begin(detachedObjects.length);
- for (CDOID id : detachedObjects)
+ if (branch.getID() != CDOBranch.MAIN_BRANCH_ID)
+ {
+ if (getStore().getMappingStrategy().hasBranchingSupport())
+ {
+ monitor.begin(detachedObjects.length);
+ for (CDOID id : detachedObjects)
+ {
+ detachObject(id, revised, branch, monitor.fork());
+ }
+ }
+ }
+ else
{
- detachObject(id, revised, monitor.fork());
+ monitor.begin(detachedObjects.length);
+ for (CDOID id : detachedObjects)
+ {
+ detachObject(id, revised, monitor.fork());
+ }
}
}
finally
@@ -372,10 +390,31 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
}
EClass eClass = getObjectType(id);
- IClassMapping mapping = getStore().getMappingStrategy().getClassMapping(eClass);
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+ IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
+
mapping.detachObject(this, id, revised, monitor);
}
+ /**
+ * Detach Object in branching mode
+ *
+ * @since 3.0
+ */
+ protected void detachObject(CDOID id, long revised, CDOBranch branch, OMMonitor monitor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Detaching object: {0} in branch {1}", id, branch); //$NON-NLS-1$
+ }
+
+ EClass eClass = getObjectType(id);
+ IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
+ IClassMappingBranchingSupport mapping = (IClassMappingBranchingSupport)mappingStrategy.getClassMapping(eClass);
+
+ mapping.detachObject(this, id, revised, branch, monitor);
+ }
+
public Connection getConnection()
{
return connection;
@@ -492,6 +531,11 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
public int createBranch(BranchInfo branchInfo)
{
+ if (!getStore().getMappingStrategy().hasBranchingSupport())
+ {
+ throw new UnsupportedOperationException("Mapping strategy does not support revision deltas."); //$NON-NLS-1$
+ }
+
int id = getStore().getNextBranchID();
PreparedStatement pstmt = null;
@@ -503,18 +547,7 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
pstmt.setInt(3, branchInfo.getBaseBranchID());
pstmt.setLong(4, branchInfo.getBaseTimeStamp());
- int updatedRows = pstmt.executeUpdate();
- if (updatedRows < 1)
- {
- throw new DBException("Branch with name " + branchInfo.getName() + " was not inserted");
- }
-
- if (updatedRows > 1)
- {
- // Should not happen
- throw new DBException("Branch with name " + branchInfo.getName() + " was inserted multiple times");
- }
-
+ CDODBUtil.sqlUpdate(pstmt, true);
return id;
}
catch (SQLException ex)
@@ -561,6 +594,11 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
public SubBranchInfo[] loadSubBranches(int baseID)
{
+ if (!getStore().getMappingStrategy().hasBranchingSupport())
+ {
+ throw new UnsupportedOperationException("Mapping strategy does not support revision deltas."); //$NON-NLS-1$
+ }
+
PreparedStatement pstmt = null;
ResultSet resultSet = null;
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 b6e0a2a..0cace12 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
@@ -9,13 +9,17 @@
* Eike Stepper - initial API and implementation
* Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
* Stefan Winkler - 249610: [DB] Support external references (Implementation)
+ *
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IExternalReferenceManager;
@@ -204,7 +208,13 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping
}
revision.setVersion(resultSet.getInt(CDODBSchema.ATTRIBUTES_VERSION));
- revision.setCreated(resultSet.getLong(CDODBSchema.ATTRIBUTES_CREATED));
+
+ long timeStamp = resultSet.getLong(CDODBSchema.ATTRIBUTES_CREATED);
+
+ // TODO: Utility method createBranchPoint(branch, timestamp) ?
+ CDOBranchPoint branchPoint = new CDOBranchPointImpl(revision.getBranch(), timeStamp);
+
+ revision.setBranchPoint(branchPoint);
revision.setRevised(resultSet.getLong(CDODBSchema.ATTRIBUTES_REVISED));
revision.setResourceID(CDODBUtil.convertLongToCDOID(getExternalReferenceManager(), accessor, resultSet
.getLong(CDODBSchema.ATTRIBUTES_RESOURCE)));
@@ -350,12 +360,19 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping
return tables;
}
- private void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
+ private CDOBranch getBranch(int branchId)
+ {
+ return getMappingStrategy().getStore().getRepository().getBranchManager().getBranch(branchId);
+ }
+
+ protected void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
{
CDOID folderID = (CDOID)revision.data().getContainerID();
String name = (String)revision.data().get(EresourcePackage.eINSTANCE.getCDOResourceNode_Name(), 0);
- CDOID existingID = accessor.readResourceID(folderID, name, CDORevision.UNSPECIFIED_DATE);
+ CDOBranchPoint branchPoint = new CDOBranchPointImpl(revision.getBranch(), CDORevision.UNSPECIFIED_DATE);
+
+ CDOID existingID = accessor.readResourceID(folderID, name, branchPoint);
if (existingID != null && !existingID.equals(revision.getID()))
{
throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID); //$NON-NLS-1$ //$NON-NLS-2$
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 6d192ab..6fd8146 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
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
@@ -111,7 +112,7 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS
public void queryResources(IDBStoreAccessor dbStoreAccessor, QueryResourcesContext context)
{
// only support timestamp in audit mode
- if (context.getTimeStamp() != CDORevision.UNSPECIFIED_DATE && !hasAuditSupport())
+ if (context.getBranchPoint().getTimeStamp() != CDORevision.UNSPECIFIED_DATE && !hasAuditSupport())
{
throw new UnsupportedOperationException("Mapping Strategy does not support audits."); //$NON-NLS-1$
}
@@ -150,11 +151,12 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS
CDOID folderID = context.getFolderID();
String name = context.getName();
boolean exactMatch = context.exactMatch();
- long timeStamp = context.getTimeStamp();
+
+ CDOBranchPoint branchPoint = context.getBranchPoint();
try
{
- stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, timeStamp);
+ stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, branchPoint);
rset = stmt.executeQuery();
while (rset.next())
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java
new file mode 100644
index 0000000..1bac756
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444
+ * Christopher Albert - Bug 254455: [DB] Support FeatureMaps bug 254455
+ * Stefan Winkler - derived branch mapping from audit mapping
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * This is a featuremap-table mapping for audit mode. It has ID and version columns and no delta support.
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public class BranchingFeatureMapTableMapping extends AbstractFeatureMapTableMapping
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.FEATUREMAP_REVISION_ID, DBType.BIGINT),
+ new FieldInfo(CDODBSchema.FEATUREMAP_BRANCH, DBType.INTEGER),
+ new FieldInfo(CDODBSchema.FEATUREMAP_VERSION, DBType.INTEGER) };
+
+ public BranchingFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(2, revision.getBranch().getID());
+ stmt.setInt(3, revision.getVersion());
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ // the audit list mapping does not care about revised references -> NOP
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java
new file mode 100644
index 0000000..c1c955a6
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
+ * Stefan Winkler - derived branch mapping from audit mapping
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * This is a list-table mapping for audit mode. It has ID and version columns and no delta support.
+ *
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public class BranchingListTableMapping extends AbstractListTableMapping
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.LIST_REVISION_ID, DBType.BIGINT),
+ new FieldInfo(CDODBSchema.LIST_REVISION_BRANCH, DBType.INTEGER),
+ new FieldInfo(CDODBSchema.LIST_REVISION_VERSION, DBType.INTEGER) };
+
+ public BranchingListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(2, revision.getBranch().getID());
+ stmt.setInt(3, revision.getVersion());
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ // the audit list mapping does not care about revised references -> NOP
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
index 6607ed5..3344e7f 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
@@ -13,7 +13,6 @@
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
@@ -40,8 +39,6 @@ import java.sql.SQLException;
import java.util.Map;
/**
- * TODO use async monitors
- *
* @author Eike Stepper
* @since 2.0
*/
@@ -109,7 +106,6 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
builder.append(" WHERE "); //$NON-NLS-1$
builder.append(CDODBSchema.ATTRIBUTES_ID);
builder.append("= ? AND ("); //$NON-NLS-1$
-
String sqlSelectAttributesPrefix = builder.toString();
builder.append(CDODBSchema.ATTRIBUTES_REVISED);
@@ -247,15 +243,14 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
}
}
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision,
- CDOBranchVersion branchVersion, int listChunk)
+ public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
{
PreparedStatement pstmt = null;
try
{
pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
- pstmt.setInt(2, branchVersion.getVersion());
+ pstmt.setInt(2, revision.getVersion());
// Read singleval-attribute table always (even without modeled attributes!)
boolean success = readValuesFromStatement(pstmt, revision, accessor);
@@ -279,9 +274,10 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
}
public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, long timeStamp)
+ boolean exactMatch, CDOBranchPoint branchPoint)
{
EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+ long timeStamp = branchPoint.getTimeStamp();
ITypeMapping nameValueMapping = getValueMapping(nameFeature);
if (nameValueMapping == null)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
index 77c90a2..f3f0dec 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
@@ -52,4 +52,9 @@ public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStr
{
return false;
}
+
+ public boolean hasBranchingSupport()
+ {
+ return false;
+ }
}
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
new file mode 100644
index 0000000..dc19a52
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
@@ -0,0 +1,580 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ * Stefan Winkler - 249610: [DB] Support external references (Implementation)
+ * Stefan Winkler - derived branch mapping from audit mapping
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingBranchingSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements IClassMapping,
+ IClassMappingBranchingSupport
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalBranchingClassMapping.class);
+
+ private String sqlInsertAttributes;
+
+ private String sqlSelectCurrentAttributes;
+
+ private String sqlSelectAllObjectIds;
+
+ private String sqlSelectAttributesByTime;
+
+ private String sqlSelectAttributesByVersion;
+
+ private String sqlReviseAttributes;
+
+ public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ super(mappingStrategy, eClass);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ Map<EStructuralFeature, String> unsettableFields = getUnsettableFields();
+
+ // ----------- Select Revision ---------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(singleMapping.getField().getName());
+ }
+
+ if (unsettableFields != null)
+ {
+ for (String fieldName : unsettableFields.values())
+ {
+ builder.append(", ");
+ builder.append(fieldName);
+ }
+ }
+
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable().getName());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ? AND ");
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("= ? AND ("); //$NON-NLS-1$
+ String sqlSelectAttributesPrefix = builder.toString();
+
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 )"); //$NON-NLS-1$
+
+ sqlSelectCurrentAttributes = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" >= ?))"); //$NON-NLS-1$
+
+ sqlSelectAttributesByTime = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(" = ?)"); //$NON-NLS-1$
+
+ sqlSelectAttributesByVersion = builder.toString();
+
+ // ----------- Insert Attributes -------------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO "); //$NON-NLS-1$
+ builder.append(getTable().getName());
+
+ builder.append("("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CLASS);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(singleMapping.getField().getName());
+ }
+
+ if (unsettableFields != null)
+ {
+ for (String fieldName : unsettableFields.values())
+ {
+ builder.append(", ");
+ builder.append(fieldName);
+ }
+ }
+
+ builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$
+
+ for (int i = 0; i < getValueMappings().size(); i++)
+ {
+ builder.append(", ?"); //$NON-NLS-1$
+ }
+
+ if (unsettableFields != null)
+ {
+ for (int i = 0; i < unsettableFields.size(); i++)
+ {
+ builder.append(", ?"); //$NON-NLS-1$
+ }
+ }
+
+ builder.append(")"); //$NON-NLS-1$
+ sqlInsertAttributes = builder.toString();
+
+ // ----------- Update to set revised ----------------
+ builder = new StringBuilder("UPDATE "); //$NON-NLS-1$
+ builder.append(getTable().getName());
+ builder.append(" SET "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = ? WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0"); //$NON-NLS-1$
+ sqlReviseAttributes = builder.toString();
+
+ // ----------- Select all unrevised Object IDs ------
+ builder = new StringBuilder("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable().getName());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0"); //$NON-NLS-1$
+ sqlSelectAllObjectIds = builder.toString();
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, CDOBranchPoint branchPoint,
+ int listChunk)
+ {
+ long timeStamp = branchPoint.getTimeStamp();
+ int branchId = branchPoint.getBranch().getID();
+
+ PreparedStatement pstmt = null;
+
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setLong(2, branchId);
+ pstmt.setLong(3, timeStamp);
+ pstmt.setLong(4, timeStamp);
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision, accessor);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setInt(2, revision.getBranch().getID());
+ pstmt.setInt(3, revision.getVersion());
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision, accessor);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, CDOBranchPoint branchPoint)
+ {
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
+ {
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$
+ }
+
+ int branchId = branchPoint.getBranch().getID();
+ long timeStamp = branchPoint.getTimeStamp();
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable().getName());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("= ? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("= ? AND "); //$NON-NLS-1$
+ builder.append(nameValueMapping.getField().getName());
+ if (name == null)
+ {
+ builder.append(" IS NULL"); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(exactMatch ? " = ? " : " LIKE ? "); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ builder.append(" AND ( "); //$NON-NLS-1$
+
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 )"); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" >= ?))"); //$NON-NLS-1$
+ }
+
+ PreparedStatement pstmt = null;
+ try
+ {
+ int idx = 1;
+
+ pstmt = accessor.getStatementCache().getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
+ pstmt.setInt(idx++, branchId);
+ pstmt.setLong(idx++, CDOIDUtil.getLong(folderId));
+
+ if (name != null)
+ {
+ String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$
+ nameValueMapping.setValue(pstmt, idx++, queryName);
+ }
+
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ pstmt.setLong(idx++, timeStamp);
+ pstmt.setLong(idx++, timeStamp);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", pstmt.toString()); //$NON-NLS-1$
+ }
+
+ return pstmt;
+ }
+ catch (SQLException ex)
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt); // only release on error
+ throw new DBException(ex);
+ }
+ }
+
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIds); //$NON-NLS-1$
+ }
+
+ return accessor.getStatementCache().getPreparedStatement(sqlSelectAllObjectIds, ReuseProbability.HIGH);
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ pstmt = accessor.getStatementCache().getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setInt(2, revision.getBranch().getID());
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision, accessor);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(pstmt);
+ }
+ }
+
+ @Override
+ protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+ int col = 1;
+
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, revision.getVersion());
+ stmt.setInt(col++, revision.getBranch().getID());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revision.getTimeStamp());
+ stmt.setLong(col++, revision.getRevised());
+ stmt.setLong(col++, CDODBUtil.convertCDOIDToLong(getExternalReferenceManager(), accessor, revision
+ .getResourceID()));
+ stmt.setLong(col++, CDODBUtil.convertCDOIDToLong(getExternalReferenceManager(), accessor, (CDOID)revision
+ .getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
+
+ 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);
+ }
+ }
+
+ public final void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, CDOBranch branch, OMMonitor monitor)
+ {
+ Async async = null;
+ try
+ {
+ monitor.begin(getListMappings().size() + 1);
+ async = monitor.forkAsync();
+ reviseObject(accessor, id, branch.getID(), revised);
+ async.stop();
+ async = monitor.forkAsync(getListMappings().size());
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, int branchId, long revised)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getStatementCache().getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
+
+ stmt.setLong(1, revised);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+ stmt.setInt(3, branchId);
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ accessor.getStatementCache().releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ reviseObject(accessor, id, CDOBranch.MAIN_BRANCH_ID, revised);
+ }
+
+ @Override
+ public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
+ {
+ Async async = null;
+ try
+ {
+ monitor.begin(10);
+ async = monitor.forkAsync();
+
+ CDOID id = revision.getID();
+ if (revision.getVersion() == 1)
+ {
+ ((HorizontalBranchingMappingStrategy)getMappingStrategy()).putObjectType(accessor, id, getEClass());
+ }
+ else
+ {
+ long revised = revision.getTimeStamp() - 1;
+ reviseObject(accessor, id, revision.getBranch().getID(), revised);
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ }
+
+ async.stop();
+ async = monitor.forkAsync();
+
+ if (revision.isResourceFolder() || revision.isResource())
+ {
+ checkDuplicateResources(accessor, revision);
+ }
+
+ async.stop();
+ async = monitor.forkAsync();
+
+ // Write attribute table always (even without modeled attributes!)
+ writeValues(accessor, revision);
+
+ async.stop();
+ async = monitor.forkAsync(7);
+
+ // Write list tables only if they exist
+ if (getListMappings() != null)
+ {
+ writeLists(accessor, revision);
+ }
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java
new file mode 100644
index 0000000..76ac99a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappingStrategy
+{
+ @Override
+ public IClassMapping doCreateClassMapping(EClass eClass)
+ {
+ return new HorizontalBranchingClassMapping(this, eClass);
+ }
+
+ @Override
+ public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ return new BranchingListTableMapping(this, containingClass, feature);
+ }
+
+ @Override
+ public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ return new BranchingFeatureMapTableMapping(this, containingClass, feature);
+ }
+
+ @Override
+ public boolean hasAuditSupport()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean hasDeltaSupport()
+ {
+ return false;
+ }
+
+ public boolean hasBranchingSupport()
+ {
+ return true;
+ }
+}
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 96478dc..66f04c6 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
@@ -12,6 +12,7 @@
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
@@ -272,7 +273,7 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
stmt.setBoolean(isSetCol++, true);
}
}
-
+
mapping.setValueFromRevision(stmt, col++, revision);
}
@@ -299,8 +300,9 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
}
public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, long timeStamp)
+ boolean exactMatch, CDOBranchPoint branchPoint)
{
+ long timeStamp = branchPoint.getTimeStamp();
if (timeStamp != CDORevision.UNSPECIFIED_DATE)
{
throw new IllegalArgumentException("Non-audit store does not support explicit timeStamp in resource query"); //$NON-NLS-1$
@@ -608,7 +610,7 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
typeMapping.setValue(stmt, col++, change.getElement2());
}
}
-
+
return col;
}
@@ -662,8 +664,8 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
{
builder.append(", "); //$NON-NLS-1$
builder.append(getUnsettableFields().get(typeMapping.getFeature()));
- builder.append(" =? "); //$NON-NLS-1$
- }
+ builder.append(" =? "); //$NON-NLS-1$
+ }
}
builder.append(sqlUpdateAffix);
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
index 93b4656..0cbcc36 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
@@ -52,4 +52,9 @@ public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMapping
{
return true;
}
+
+ public boolean hasBranchingSupport()
+ {
+ return false;
+ }
}
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 05a6b1b..70ea567 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
@@ -11,6 +11,8 @@
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
@@ -24,6 +26,7 @@ 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.internal.common.branch.CDOBranchPointImpl;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
@@ -199,9 +202,12 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement
public void processDelta(final IDBStoreAccessor accessor, final CDOID id, int oldVersion, final int newVersion,
long created, CDOListFeatureDelta delta)
{
+ // TODO: Utility method createBranchPoint(branch, timestamp) ?
+ CDOBranchPoint main = new CDOBranchPointImpl(accessor.getStore().getRepository().getBranchManager().getBranch(
+ CDOBranch.MAIN_BRANCH_ID), CDOBranchPoint.UNSPECIFIED_DATE);
+
InternalCDORevision originalRevision = (InternalCDORevision)accessor.getStore().getRepository()
- .getRevisionManager().getRevision(id, CDORevision.UNSPECIFIED_DATE, CDORevision.UNCHUNKED,
- CDORevision.DEPTH_NONE, true);
+ .getRevisionManager().getRevision(id, main, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true);
int oldListSize = originalRevision.getList(getFeature()).size();
// reset the clear-flag
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java
index a48eaaf..a5a0a9d 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java
@@ -11,8 +11,10 @@
package org.eclipse.emf.cdo.internal.server;
import org.eclipse.emf.cdo.common.CDOQueryInfo;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
import org.eclipse.emf.cdo.server.IQueryContext;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.server.IStoreAccessor;
@@ -37,9 +39,9 @@ public class ResourcesQueryHandler implements IQueryHandler
IStoreAccessor accessor = StoreThreadLocal.getAccessor();
accessor.queryResources(new IStoreAccessor.QueryResourcesContext()
{
- public long getTimeStamp()
+ public CDOBranchPoint getBranchPoint()
{
- return context.getTimeStamp();
+ return new CDOBranchPointImpl(context.getBranch(), context.getTimeStamp());
}
public CDOID getFolderID()
@@ -79,6 +81,7 @@ public class ResourcesQueryHandler implements IQueryHandler
super(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES);
}
+ @Override
public IQueryHandler create(String description) throws ProductCreationException
{
return new ResourcesQueryHandler();
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
index 203fb9a..9f371c2 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
@@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOModelConstants;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
import org.eclipse.emf.cdo.server.IMEMStore;
import org.eclipse.emf.cdo.server.ISession;
import org.eclipse.emf.cdo.server.IStoreAccessor;
@@ -230,7 +231,9 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader
String revisionName = (String)revision.data().get(feature, 0);
IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- CDOID resourceID = accessor.readResourceID(revisionFolder, revisionName, revision.getTimeStamp());
+
+ CDOBranchPoint branchPoint = new CDOBranchPointImpl(revision.getBranch(), revision.getTimeStamp());
+ CDOID resourceID = accessor.readResourceID(revisionFolder, revisionName, branchPoint);
if (!CDOIDUtil.isNull(resourceID))
{
throw new IllegalStateException("Duplicate resource: " + revisionName + " (folderID=" + revisionFolder + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -301,7 +304,7 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader
InternalCDORevision revision = list.get(0);
if (revision.isResourceNode())
{
- revision = getRevision(list, context.getTimeStamp());
+ revision = getRevision(list, context.getBranchPoint().getTimeStamp());
if (revision != null)
{
CDOID revisionFolder = (CDOID)revision.data().getContainerID();
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 3d29ac5..5519622 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
@@ -106,9 +106,9 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader
* Returns the <code>CDOID</code> of the resource node with the given folderID and name if a resource with this
* folderID and name exists in the store, <code>null</code> otherwise.
*
- * @since 2.0
+ * @since 3.0
*/
- public CDOID readResourceID(CDOID folderID, String name, long timeStamp);
+ public CDOID readResourceID(CDOID folderID, String name, CDOBranchPoint branchPoint);
/**
* @since 2.0
@@ -264,10 +264,12 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader
public interface QueryResourcesContext
{
/**
- * The timeStamp of the view ({@link CDOCommonView#UNSPECIFIED_DATE} if the view is an
+ * The branchPoint of the view ({@link CDOCommonView#UNSPECIFIED_DATE} if the view is an
* {@link CDOCommonView.Type#AUDIT audit} view.
+ *
+ * @since 3.0
*/
- public long getTimeStamp();
+ public CDOBranchPoint getBranchPoint();
public CDOID getFolderID();
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/Store.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/Store.java
index 8f1d85b..398ad40 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/Store.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/Store.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.cdo.spi.server;
import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
@@ -371,8 +372,11 @@ public abstract class Store extends Lifecycle implements IStore
*/
protected abstract IStoreAccessor createWriter(ITransaction transaction);
+ /**
+ * @since 3.0
+ */
public static IStoreAccessor.QueryResourcesContext.ExactMatch createExactMatchContext(final CDOID folderID,
- final String name, final long timeStamp)
+ final String name, final CDOBranchPoint branchPoint)
{
return new IStoreAccessor.QueryResourcesContext.ExactMatch()
{
@@ -383,9 +387,9 @@ public abstract class Store extends Lifecycle implements IStore
return resourceID;
}
- public long getTimeStamp()
+ public CDOBranchPoint getBranchPoint()
{
- return timeStamp;
+ return branchPoint;
}
public CDOID getFolderID()
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 aee219d..b7b0d53 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
@@ -13,6 +13,7 @@
package org.eclipse.emf.cdo.spi.server;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
@@ -96,10 +97,10 @@ public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
return null;
}
- public CDOID readResourceID(CDOID folderID, String name, long timeStamp)
+ public CDOID readResourceID(CDOID folderID, String name, CDOBranchPoint branchPoint)
{
IStoreAccessor.QueryResourcesContext.ExactMatch context = //
- Store.createExactMatchContext(folderID, name, timeStamp);
+ Store.createExactMatchContext(folderID, name, branchPoint);
queryResources(context);
return context.getResourceID();
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
new file mode 100644
index 0000000..70fb1b9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Branching.java
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.db;
+
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
+
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.db.h2.H2Adapter;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.io.IOUtil;
+import org.eclipse.net4j.util.io.TMPUtil;
+
+import org.h2.jdbcx.JdbcDataSource;
+
+import javax.sql.DataSource;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * @author Eike Stepper
+ */
+public class AllTestsDBH2Branching extends DBConfigs
+{
+ public static Test suite()
+ {
+ return new AllTestsDBH2Branching()
+ .getTestSuite("CDO Tests (DBStoreRepositoryConfig H2 Horizontal - non-audit mode)");
+ }
+
+ @Override
+ protected void initConfigSuites(TestSuite parent)
+ {
+ addScenario(parent, COMBINED, AllTestsDBH2Branching.H2NonAudit.ReusableFolder.INSTANCE, JVM, NATIVE);
+ }
+
+ @Override
+ protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses)
+ {
+ super.initTestClasses(testClasses);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class H2NonAudit extends DBStoreRepositoryConfig
+ {
+ private static final long serialVersionUID = 1L;
+
+ public static final AllTestsDBH2Branching.H2NonAudit INSTANCE = new H2NonAudit("DBStore: H2 (non-audit)");
+
+ protected transient File dbFolder;
+
+ public H2NonAudit(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void initRepositoryProperties(Map<String, String> props)
+ {
+ super.initRepositoryProperties(props);
+ props.put(IRepository.Props.SUPPORTING_AUDITS, "true");
+ props.put(IRepository.Props.SUPPORTING_BRANCHES, "true");
+ }
+
+ @Override
+ protected IMappingStrategy createMappingStrategy()
+ {
+ return CDODBUtil.createHorizontalMappingStrategy(true, true);
+ }
+
+ @Override
+ protected IDBAdapter createDBAdapter()
+ {
+ return new H2Adapter();
+ }
+
+ @Override
+ protected DataSource createDataSource(String repoName)
+ {
+ if (dbFolder == null)
+ {
+ dbFolder = createDBFolder();
+ tearDownClean();
+ }
+
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL("jdbc:h2:" + dbFolder.getAbsolutePath() + "/h2test;SCHEMA=" + repoName);
+ return dataSource;
+ }
+
+ protected void tearDownClean()
+ {
+ IOUtil.delete(dbFolder);
+ }
+
+ protected File createDBFolder()
+ {
+ return TMPUtil.createTempFolder("h2_", "_test");
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class ReusableFolder extends H2NonAudit
+ {
+ private static final long serialVersionUID = 1L;
+
+ public static final ReusableFolder INSTANCE = new ReusableFolder("DBStore: H2 (Reusable Folder)");
+
+ private static File reusableFolder;
+
+ private static JdbcDataSource defaultDataSource;
+
+ private transient ArrayList<String> repoNames = new ArrayList<String>();
+
+ public ReusableFolder(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected DataSource createDataSource(String repoName)
+ {
+ if (reusableFolder == null)
+ {
+ reusableFolder = createDBFolder();
+ IOUtil.delete(reusableFolder);
+ }
+
+ dbFolder = reusableFolder;
+ if (defaultDataSource == null)
+ {
+ defaultDataSource = new JdbcDataSource();
+ defaultDataSource.setURL("jdbc:h2:" + dbFolder.getAbsolutePath() + "/h2test");
+ }
+
+ Connection conn = null;
+ Statement stmt = null;
+ try
+ {
+ conn = defaultDataSource.getConnection();
+ stmt = conn.createStatement();
+ stmt.execute("DROP SCHEMA IF EXISTS " + repoName);
+ stmt.execute("CREATE SCHEMA " + repoName);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ DBUtil.close(conn);
+ DBUtil.close(stmt);
+ }
+
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL("jdbc:h2:" + dbFolder.getAbsolutePath() + "/h2test;SCHEMA=" + repoName);
+
+ return dataSource;
+ }
+
+ @Override
+ protected void tearDownClean()
+ {
+ for (String repoName : repoNames)
+ {
+ tearDownClean(repoName);
+ }
+ }
+
+ protected void tearDownClean(String repoName)
+ {
+ reusableFolder.deleteOnExit();
+ Connection connection = null;
+ Statement stmt = null;
+
+ try
+ {
+ connection = defaultDataSource.getConnection();
+ stmt = connection.createStatement();
+ stmt.execute("DROP SCHEMA " + repoName);
+ }
+ catch (Exception ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ DBUtil.close(connection);
+ }
+ }
+ }
+ }
+}