diff options
26 files changed, 580 insertions, 209 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 c2dfedbe5d..7ce0873b58 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.6.100.qualifier" + version="4.7.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.emf.cdo.license" license-feature-version="0.0.0"> diff --git a/features/org.eclipse.emf.cdo.server.db-feature/pom.xml b/features/org.eclipse.emf.cdo.server.db-feature/pom.xml index d4945ad79f..d06f51e1ce 100644 --- a/features/org.eclipse.emf.cdo.server.db-feature/pom.xml +++ b/features/org.eclipse.emf.cdo.server.db-feature/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo.features</groupId> <artifactId>org.eclipse.emf.cdo.server.db</artifactId> - <version>4.6.100-SNAPSHOT</version> + <version>4.7.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java index db530e093d..72431b6116 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java @@ -22,6 +22,7 @@ import org.eclipse.emf.cdo.common.id.CDOWithID; import org.eclipse.emf.cdo.common.model.CDOClassInfo; 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.CDOListFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.common.util.CDOCommonUtil; import org.eclipse.emf.cdo.internal.common.commit.CDOChangeSetDataImpl; @@ -597,6 +598,14 @@ public final class CDORevisionUtil } /** + * @since 4.8 + */ + public static CDOListFeatureDelta compareLists(CDORevision originRevision, CDORevision dirtyRevision, EStructuralFeature feature) + { + return CDORevisionDeltaImpl.compareLists((InternalCDORevision)originRevision, (InternalCDORevision)dirtyRevision, feature); + } + + /** * @since 3.0 */ public static String dumpAllRevisions(Map<CDOBranch, List<CDORevision>> map) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java index 7799f7cf08..4b69884c7d 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java @@ -265,6 +265,27 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi } } + public InternalCDORevision getBaseRevision(CDORevision revision, int referenceChunk, boolean loadOnDemand) + { + CDOID id = revision.getID(); + CDOBranch branch = revision.getBranch(); + int version = revision.getVersion(); + + if (version == CDOBranchVersion.FIRST_VERSION) + { + if (branch.isMainBranch()) + { + return null; + } + + CDOBranchPoint basePoint = branch.getBase(); + return getRevision(id, basePoint, referenceChunk, CDORevision.DEPTH_NONE, loadOnDemand); + } + + CDOBranchVersion baseVersion = branch.getVersion(version - 1); + return getRevisionByVersion(id, baseVersion, referenceChunk, loadOnDemand); + } + public CDOBranchPointRange getObjectLifetime(CDOID id, CDOBranchPoint branchPoint) { if (revisionLoader instanceof RevisionLoader2) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java index 0c1b50bff4..1a9468f1bb 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java @@ -23,7 +23,6 @@ import org.eclipse.emf.cdo.common.revision.CDOElementProxy; import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevisable; import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.common.revision.CDORevisionData; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta; @@ -68,7 +67,7 @@ import java.util.Map; /** * @author Eike Stepper */ -public class CDORevisionDeltaImpl implements InternalCDORevisionDelta +public class CDORevisionDeltaImpl implements InternalCDORevisionDelta, ListComparisonHandler { private static final boolean WORK_AROUND_BUG_308618 = OMPlatform.INSTANCE.isProperty("org.eclipse.emf.cdo.common.revision.delta.WORK_AROUND_BUG_308618"); @@ -122,22 +121,21 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta version = sourceRevision.getVersion(); target = CDORevisionUtil.copyRevisable(targetRevision); - compare((InternalCDORevision)sourceRevision, (InternalCDORevision)targetRevision); + InternalCDORevision internalSourceRevision = (InternalCDORevision)sourceRevision; + InternalCDORevision internalTargetRevision = (InternalCDORevision)targetRevision; + compare(internalSourceRevision, internalTargetRevision); - CDORevisionData originData = sourceRevision.data(); - CDORevisionData dirtyData = targetRevision.data(); - - Object dirtyContainerID = dirtyData.getContainerID(); + Object dirtyContainerID = internalTargetRevision.getContainerID(); if (dirtyContainerID instanceof CDOWithID) { dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID(); } - CDOID dirtyResourceID = dirtyData.getResourceID(); - int dirtyContainingFeatureID = dirtyData.getContainingFeatureID(); - if (!compareValue(CDOContainerFeatureDelta.CONTAINER_FEATURE, originData.getContainerID(), dirtyContainerID) - || !compareValue(null, originData.getContainingFeatureID(), dirtyContainingFeatureID) - || !compareValue(CDOContainerFeatureDelta.CONTAINER_FEATURE, originData.getResourceID(), dirtyResourceID)) + CDOID dirtyResourceID = internalTargetRevision.getResourceID(); + int dirtyContainingFeatureID = internalTargetRevision.getContainingFeatureID(); + if (!compareValue(CDOContainerFeatureDelta.CONTAINER_FEATURE, internalSourceRevision.getContainerID(), dirtyContainerID) + || !compareValue(null, internalSourceRevision.getContainingFeatureID(), dirtyContainingFeatureID) + || !compareValue(CDOContainerFeatureDelta.CONTAINER_FEATURE, internalSourceRevision.getResourceID(), dirtyResourceID)) { CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(dirtyResourceID, dirtyContainerID, dirtyContainingFeatureID); addFeatureDelta(delta, null); @@ -366,131 +364,28 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta } } - private void compare(final InternalCDORevision originRevision, final InternalCDORevision dirtyRevision) + public void addDelta(CDOListFeatureDelta listFeatureDelta) { - CDORevisionData originData = originRevision.data(); - CDORevisionData dirtyData = dirtyRevision.data(); + featureDeltas.put(listFeatureDelta.getFeature(), listFeatureDelta); + } + + public void addClearDelta(CDOClearFeatureDelta clearFeatureDelta, CDOOriginSizeProvider originSizeProvider) + { + addFeatureDelta(clearFeatureDelta, originSizeProvider); + } - for (final EStructuralFeature feature : originRevision.getClassInfo().getAllPersistentFeatures()) + private void compare(InternalCDORevision originRevision, InternalCDORevision dirtyRevision) + { + for (EStructuralFeature feature : originRevision.getClassInfo().getAllPersistentFeatures()) { if (feature.isMany()) { - final int originSize = originData.size(feature); - if (originSize > 0 && dirtyData.size(feature) == 0) - { - addFeatureDelta(new CDOClearFeatureDeltaImpl(feature), new CDOOriginSizeProvider() - { - public int getOriginSize() - { - return originSize; - } - }); - } - else - { - CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature, originSize); - final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges(); - - ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer() - { - @Override - public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges) - { - checkNoProxies(oldList, originRevision); - checkNoProxies(newList, dirtyRevision); - super.analyzeLists(oldList, newList, listChanges); - } - - @Override - protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value, int index) - { - CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value); - changes.add(delta); - oldList.add(index, value); - } - - @Override - protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value, int index) - { - CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index); - - if (WORK_AROUND_BUG_308618) - { - // Fix until ListDifferenceAnalyzer delivers the correct value (bug 308618). - delta.setValue(oldList.get(index)); - } - else - { - delta.setValue(value); - } - - changes.add(delta); - oldList.remove(index); - } - - @Override - protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value, int index, int toIndex) - { - CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index); - - if (WORK_AROUND_BUG_308618) - { - // Fix until ListDifferenceAnalyzer delivers the correct value (bug 308618). - delta.setValue(oldList.get(index)); - } - else - { - delta.setValue(value); - } - - changes.add(delta); - oldList.move(toIndex, index); - } - - @Override - protected boolean equal(Object originValue, Object dirtyValue) - { - return compareValue(feature, originValue, dirtyValue); - } - - private void checkNoProxies(EList<?> list, CDORevision revision) - { - if (list != null && !((InternalCDORevision)revision).isUnchunked()) - { - for (Object element : list) - { - if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED) - { - throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements"); - } - } - } - } - }; - - CDOList originList = originRevision.getListOrNull(feature); - if (originList == null) - { - originList = new CDOListImpl(0, 0); - } - - CDOList dirtyList = dirtyRevision.getListOrNull(feature); - if (dirtyList == null) - { - dirtyList = new CDOListImpl(0, 0); - } - - analyzer.analyzeLists(originList, dirtyList, new NOOPList()); - if (!changes.isEmpty()) - { - featureDeltas.put(feature, listFeatureDelta); - } - } + compareLists(originRevision, dirtyRevision, feature, this); } else { - Object originValue = originData.get(feature, 0); - Object dirtyValue = dirtyData.get(feature, 0); + Object originValue = originRevision.get(feature, 0); + Object dirtyValue = dirtyRevision.get(feature, 0); if (!compareValue(feature, originValue, dirtyValue)) { @@ -509,7 +404,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta } } - private boolean compareValue(EStructuralFeature feature, Object originValue, Object dirtyValue) + private static boolean compareValue(EStructuralFeature feature, Object originValue, Object dirtyValue) { if (feature != null) { @@ -552,7 +447,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta return originValue.equals(dirtyValue); } - private Object convertEObject(Object value) + private static Object convertEObject(Object value) { CDOID id = CDOIDUtil.getCDOID(value); if (id != null) @@ -563,7 +458,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta return value; } - private Object convertDefaultValue(Object value, Object defaultValue) + private static Object convertDefaultValue(Object value, Object defaultValue) { // if (value == null) // { @@ -573,6 +468,143 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta return value; } + private static void compareLists(final InternalCDORevision originRevision, final InternalCDORevision dirtyRevision, final EStructuralFeature feature, + ListComparisonHandler handler) + { + final int originSize = originRevision.size(feature); + if (originSize > 0 && dirtyRevision.size(feature) == 0) + { + handler.addClearDelta(new CDOClearFeatureDeltaImpl(feature), new CDOOriginSizeProvider() + { + public int getOriginSize() + { + return originSize; + } + }); + } + else + { + CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature, originSize); + final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges(); + + ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer() + { + @Override + public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges) + { + checkNoProxies(oldList, originRevision); + checkNoProxies(newList, dirtyRevision); + super.analyzeLists(oldList, newList, listChanges); + } + + @Override + protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value, int index) + { + CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value); + changes.add(delta); + oldList.add(index, value); + } + + @Override + protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value, int index) + { + CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index); + + if (WORK_AROUND_BUG_308618) + { + // Fix until ListDifferenceAnalyzer delivers the correct value (bug 308618). + delta.setValue(oldList.get(index)); + } + else + { + delta.setValue(value); + } + + changes.add(delta); + oldList.remove(index); + } + + @Override + protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value, int index, int toIndex) + { + CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index); + + if (WORK_AROUND_BUG_308618) + { + // Fix until ListDifferenceAnalyzer delivers the correct value (bug 308618). + delta.setValue(oldList.get(index)); + } + else + { + delta.setValue(value); + } + + changes.add(delta); + oldList.move(toIndex, index); + } + + @Override + protected boolean equal(Object originValue, Object dirtyValue) + { + return compareValue(feature, originValue, dirtyValue); + } + + private void checkNoProxies(EList<?> list, CDORevision revision) + { + if (list != null && !((InternalCDORevision)revision).isUnchunked()) + { + for (Object element : list) + { + if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED) + { + throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements"); + } + } + } + } + }; + + CDOList originList = originRevision.getListOrNull(feature); + if (originList == null) + { + originList = new CDOListImpl(0, 0); + } + + CDOList dirtyList = dirtyRevision.getListOrNull(feature); + if (dirtyList == null) + { + dirtyList = new CDOListImpl(0, 0); + } + + analyzer.analyzeLists(originList, dirtyList, new NOOPList()); + if (!changes.isEmpty()) + { + handler.addDelta(listFeatureDelta); + } + } + } + + public static CDOListFeatureDelta compareLists(final InternalCDORevision originRevision, InternalCDORevision dirtyRevision, final EStructuralFeature feature) + { + final CDOListFeatureDelta[] result = { null }; + compareLists(originRevision, dirtyRevision, feature, new ListComparisonHandler() + { + public void addDelta(CDOListFeatureDelta listFeatureDelta) + { + result[0] = listFeatureDelta; + } + + public void addClearDelta(CDOClearFeatureDelta clearFeatureDelta, CDOOriginSizeProvider originSizeProvider) + { + CDOListFeatureDeltaImpl listFeatureDelta = new CDOListFeatureDeltaImpl(feature, originRevision.size(feature)); + listFeatureDelta.add(clearFeatureDelta); + result[0] = listFeatureDelta; + } + }); + + return result[0]; + } + @Override public String toString() { @@ -713,3 +745,14 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta } } } + +/** + * @author Eike Stepper + * @since 4.8 + */ +interface ListComparisonHandler +{ + public void addDelta(CDOListFeatureDelta listFeatureDelta); + + public void addClearDelta(CDOClearFeatureDelta clearFeatureDelta, CDOOriginSizeProvider originSizeProvider); +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java index 97600f60a9..038cb5fc6f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java @@ -119,6 +119,11 @@ public interface InternalCDOBranchManager extends CDOBranchManager, ILifecycle public SubBranchInfo[] loadSubBranches(int branchID); + /** + * @param startID the {@link CDOBranch#getID() id} of the first branch to load. + * @param endID the {@link CDOBranch#getID() id} of the last branch to load, or 0 (zero) to load all branches + * after and including the first branch. + */ public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler); /** diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java index e638095c22..56bb4f2218 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java @@ -89,6 +89,11 @@ public interface InternalCDORevisionManager extends CDORevisionManager, CDORevis public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk, boolean loadOnDemand); /** + * @since 4.8 + */ + public InternalCDORevision getBaseRevision(CDORevision revision, int referenceChunk, boolean loadOnDemand); + + /** * If the meaning of this type isn't clear, there really should be more of a description here... * * @author Eike Stepper 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 28dbed16d0..483bc116a8 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.6.100.qualifier +Bundle-Version: 4.7.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -12,11 +12,11 @@ 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.6.100", - org.eclipse.emf.cdo.server.db.mapping;version="4.6.100", - org.eclipse.emf.cdo.server.internal.db;version="4.6.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.6.100";x-internal:=true, - org.eclipse.emf.cdo.server.internal.db.mapping;version="4.6.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.6.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", - org.eclipse.emf.cdo.server.internal.db.messages;version="4.6.100";x-internal:=true +Export-Package: org.eclipse.emf.cdo.server.db;version="4.7.0", + org.eclipse.emf.cdo.server.db.mapping;version="4.7.0", + org.eclipse.emf.cdo.server.internal.db;version="4.7.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.7.0";x-internal:=true, + org.eclipse.emf.cdo.server.internal.db.mapping;version="4.7.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.7.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", + org.eclipse.emf.cdo.server.internal.db.messages;version="4.7.0";x-internal:=true Automatic-Module-Name: org.eclipse.emf.cdo.server.db diff --git a/plugins/org.eclipse.emf.cdo.server.db/pom.xml b/plugins/org.eclipse.emf.cdo.server.db/pom.xml index 4479ad80cb..b9bbbb2f03 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/pom.xml +++ b/plugins/org.eclipse.emf.cdo.server.db/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.server.db</artifactId> - <version>4.6.100-SNAPSHOT</version> + <version>4.7.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> 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 e462b09462..fd25c86097 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 @@ -100,7 +100,7 @@ public interface IClassMapping * the accessor to use. * @param revision * the revision to write. - * @param mapType + * @param firstRevision * <code>true</code> if the type of the object is supposed to be mapped, <code>false</code> otherwise. * @param revise * <code>true</code> if the previous revision is supposed to be revised, <code>false</code> otherwise. @@ -108,7 +108,7 @@ public interface IClassMapping * the monitor to indicate progress. * @since 4.0 */ - public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor); + public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean firstRevision, boolean revise, OMMonitor monitor); /** * Detaches (deletes) a CDO object leaving a "ghost" revision behind. diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping4.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping4.java new file mode 100644 index 0000000000..5e53e7e796 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping4.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 Eike Stepper (Loehne, 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.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.IStoreAccessor.Raw; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +/** + * Extension interface to {@link IListMapping3}. + * + * @author Eike Stepper + * @since 4.7 + */ +public interface IListMapping4 +{ + /** + * Write a complete list of values to the database. + * + * @param accessor + * the accessor to use. + * @param revision + * the revision containing the list to be written. + * @param firstRevision + * <code>true</code> if the type of the object is supposed to be mapped, <code>false</code> otherwise. + * @param raw + * <code>true</code> if this method is called as part of the + * {@link Raw#rawStore(InternalCDORevision, org.eclipse.net4j.util.om.monitor.OMMonitor) raw} storage, + * <code>false</code> otherwise. + */ + public void writeValues(IDBStoreAccessor accessor, CDORevision revision, boolean firstRevision, boolean raw); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java index fe6b898f77..b04fa210da 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java @@ -10,8 +10,11 @@ */ package org.eclipse.emf.cdo.server.internal.db; +import org.eclipse.emf.cdo.internal.server.ServerDebugUtil; import org.eclipse.emf.cdo.server.CDOServerBrowser; import org.eclipse.emf.cdo.server.CDOServerBrowser.AbstractPage; +import org.eclipse.emf.cdo.server.IStoreAccessor; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.net4j.db.DBException; @@ -47,10 +50,20 @@ public class DBBrowserPage extends AbstractPage { IDBConnectionProvider connectionProvider = (IDBConnectionProvider)repository.getStore(); Connection connection = null; + boolean closeConnection = false; try { - connection = connectionProvider.getConnection(); + IStoreAccessor accessor = ServerDebugUtil.getAccessor(repository); + if (accessor instanceof IDBStoreAccessor) + { + connection = ((IDBStoreAccessor)accessor).getConnection(); + } + else + { + connection = connectionProvider.getConnection(); + closeConnection = true; + } out.print("<table border=\"0\">\r\n"); out.print("<tr>\r\n"); @@ -75,7 +88,10 @@ public class DBBrowserPage extends AbstractPage } finally { - DBUtil.close(connection); + if (closeConnection) + { + DBUtil.close(connection); + } } } 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 99bfa0f933..b3d1278872 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 @@ -607,7 +607,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, throw new UnsupportedOperationException(); } - protected void writeRevision(InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor) + protected void writeRevision(InternalCDORevision revision, boolean firstRevision, boolean revise, OMMonitor monitor) { if (TRACER.isEnabled()) { @@ -617,7 +617,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, EClass eClass = revision.getEClass(); IClassMapping mapping = getStore().getMappingStrategy().getClassMapping(eClass); - mapping.writeRevision(this, revision, mapType, revise, monitor); + mapping.writeRevision(this, revision, firstRevision, revise, monitor); } @Override @@ -1349,8 +1349,8 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, IMappingStrategy mappingStrategy = getStore().getMappingStrategy(); CDOClassifierRef classifierRef = mappingStrategy.readObjectType(this, id); - boolean isFirstRevision = classifierRef == null; - if (!isFirstRevision) + boolean firstRevision = classifierRef == null; + if (!firstRevision) { boolean namesMatch = classifierRef.getClassifierName().equals(eClass.getName()); boolean packagesMatch = classifierRef.getPackageURI().equals(eClass.getEPackage().getNsURI()); @@ -1360,7 +1360,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, } } - writeRevision(revision, isFirstRevision, false, monitor); + writeRevision(revision, firstRevision, false, monitor); getStore().getIDHandler().adjustLastObjectID(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 fbd69b3ee6..162eb46651 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 @@ -39,6 +39,7 @@ 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.IListMapping; import org.eclipse.emf.cdo.server.db.mapping.IListMapping3; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping4; 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.DBIndexAnnotation; @@ -613,15 +614,22 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I } } - protected void writeLists(IDBStoreAccessor accessor, InternalCDORevision revision) + protected void writeLists(IDBStoreAccessor accessor, InternalCDORevision revision, boolean firstRevision, boolean raw) { for (IListMapping listMapping : listMappings) { - listMapping.writeValues(accessor, revision); + if (listMapping instanceof IListMapping4) + { + ((IListMapping4)listMapping).writeValues(accessor, revision, firstRevision, raw); + } + else + { + listMapping.writeValues(accessor, revision); + } } } - public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor) + public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean firstRevision, boolean revise, OMMonitor monitor) { if (table == null) { @@ -660,7 +668,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I try { async = monitor.forkAsync(); - if (mapType) + if (firstRevision) { mappingStrategy.putObjectType(accessor, timeStamp, id, eClass); } @@ -718,7 +726,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I if (listMappings != null) { async = monitor.forkAsync(7); - writeLists(accessor, revision); + writeLists(accessor, revision, firstRevision, !revise); } else { @@ -796,6 +804,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I } } + builder.append(" ORDER BY "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); ResultSet resultSet = null; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java index 8a27cfa925..96d5c782e2 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java @@ -16,9 +16,12 @@ 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.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionManager; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; 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; @@ -38,12 +41,14 @@ import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; 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.IListMapping4; import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport; import org.eclipse.emf.cdo.server.db.mapping.IListMappingUnitSupport; 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.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.net4j.db.DBException; @@ -74,14 +79,14 @@ import java.util.List; * This is a list-table mapping for audit mode. It is optimized for frequent insert operations at the list's end, which * causes just 1 DB row to be changed. This is achieved by introducing a version range (columns cdo_version_added and * cdo_version_removed) which records for which revisions a particular entry existed. Also, this mapping is mainly - * optimized for potentially very large lists: the need for having the complete list stored in memopy to do + * optimized for potentially very large lists: the need for having the complete list stored in memory to do * in-the-middle-moved and inserts is traded in for a few more DB access operations. * * @author Eike Stepper * @author Stefan Winkler * @author Lothar Werzinger */ -public class AuditListTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport, IListMappingUnitSupport +public class AuditListTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport, IListMappingUnitSupport, IListMapping4 { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AuditListTableMappingWithRanges.class); @@ -503,6 +508,30 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi } } + public void writeValues(IDBStoreAccessor accessor, CDORevision revision, boolean firstRevision, boolean raw) + { + if (firstRevision || !raw) + { + writeValues(accessor, (InternalCDORevision)revision); + } + else + { + InternalCDORevisionManager revisionManager = (InternalCDORevisionManager)getMappingStrategy().getStore().getRepository().getRevisionManager(); + InternalCDORevision baseRevision = revisionManager.getBaseRevision(revision, CDORevision.UNCHUNKED, true); + + EStructuralFeature feature = getFeature(); + CDOListFeatureDelta delta = CDORevisionUtil.compareLists(baseRevision, revision, feature); + + if (delta != null && !delta.getListChanges().isEmpty()) + { + int oldVersion = baseRevision.getVersion(); + int newVersion = revision.getVersion(); + + processDelta(accessor, baseRevision, oldVersion, newVersion, delta.getListChanges()); + } + } + } + public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { CDOList values = revision.getListOrNull(getFeature()); @@ -596,11 +625,11 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi TRACER.format("objectRevised {0}: {1}", id, revised); //$NON-NLS-1$ } - CDOBranch main = getMappingStrategy().getStore().getRepository().getBranchManager().getMainBranch(); + IRepository repository = getMappingStrategy().getStore().getRepository(); + CDOBranch main = repository.getBranchManager().getMainBranch(); // get revision from cache to find out version number - CDORevision revision = getMappingStrategy().getStore().getRepository().getRevisionManager().getRevision(id, main.getHead(), /* chunksize = */0, - CDORevision.DEPTH_NONE, true); + CDORevision revision = repository.getRevisionManager().getRevision(id, main.getHead(), 0, CDORevision.DEPTH_NONE, true); // set cdo_revision_removed for all list items (so we have no NULL values) clearList(accessor, id, revision.getVersion(), FINAL_VERSION); @@ -869,34 +898,37 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi } } - public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion, final int newVersion, long created, - CDOListFeatureDelta delta) + public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, long created, CDOListFeatureDelta delta) { List<CDOFeatureDelta> listChanges = delta.getListChanges(); - int size = listChanges.size(); - if (size == 0) + if (listChanges.size() == 0) { // nothing to do. return; } - if (table == null) - { - initTable(accessor); - } - - IRepository repo = accessor.getStore().getRepository(); - InternalCDORevision originalRevision = (InternalCDORevision)repo.getRevisionManager().getRevision(id, repo.getBranchManager().getMainBranch().getHead(), - /* chunksize = */0, CDORevision.DEPTH_NONE, true); + IRepository repository = accessor.getStore().getRepository(); + CDORevisionManager revisionManager = repository.getRevisionManager(); + CDOBranchPoint head = repository.getBranchManager().getMainBranch().getHead(); - int oldListSize = originalRevision.size(getFeature()); + InternalCDORevision originalRevision = (InternalCDORevision)revisionManager.getRevision(id, head, /* chunksize = */0, CDORevision.DEPTH_NONE, true); + processDelta(accessor, originalRevision, oldVersion, newVersion, listChanges); + } + private void processDelta(IDBStoreAccessor accessor, InternalCDORevision originalRevision, int oldVersion, int newVersion, List<CDOFeatureDelta> listChanges) + { if (TRACER.isEnabled()) { + int oldListSize = originalRevision.size(getFeature()); TRACER.format("ListTableMapping.processDelta for revision {0} - previous list size: {1}", originalRevision, //$NON-NLS-1$ oldListSize); } + if (table == null) + { + initTable(accessor); + } + // let the visitor collect the changes ListDeltaVisitor visitor = new ListDeltaVisitor(accessor, originalRevision, oldVersion, newVersion); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java index 8aa6f61f7f..1f17e24dd9 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java @@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; 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; @@ -38,6 +39,7 @@ import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping4; 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; @@ -84,7 +86,7 @@ import java.util.List; * @author Stefan Winkler * @author Lothar Werzinger */ -public class BranchingListTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport +public class BranchingListTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport, IListMapping4 { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, BranchingListTableMappingWithRanges.class); @@ -648,6 +650,31 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM } } + public void writeValues(IDBStoreAccessor accessor, CDORevision revision, boolean firstRevision, boolean raw) + { + if (firstRevision || !raw) + { + writeValues(accessor, (InternalCDORevision)revision); + } + else + { + InternalCDORevisionManager revisionManager = (InternalCDORevisionManager)getMappingStrategy().getStore().getRepository().getRevisionManager(); + InternalCDORevision baseRevision = revisionManager.getBaseRevision(revision, CDORevision.UNCHUNKED, true); + + EStructuralFeature feature = getFeature(); + CDOListFeatureDelta delta = CDORevisionUtil.compareLists(baseRevision, revision, feature); + + if (delta != null && !delta.getListChanges().isEmpty()) + { + int branchID = revision.getBranch().getID(); + int oldVersion = baseRevision.getVersion(); + int newVersion = revision.getVersion(); + + processDelta(accessor, baseRevision, branchID, oldVersion, newVersion, delta.getListChanges()); + } + } + } + public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { CDOList values = revision.getListOrNull(getFeature()); @@ -761,31 +788,34 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM throw new UnsupportedOperationException("Raw deletion does not work in range-based mappings"); } - public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, final int oldVersion, final int newVersion, long created, - CDOListFeatureDelta delta) + public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, long created, CDOListFeatureDelta delta) { List<CDOFeatureDelta> listChanges = delta.getListChanges(); - int size = listChanges.size(); - if (size == 0) + if (listChanges.size() == 0) { // nothing to do. return; } - if (table == null) - { - initTable(accessor); - } - InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id); - int oldListSize = originalRevision.size(getFeature()); + processDelta(accessor, originalRevision, branchId, oldVersion, newVersion, listChanges); + } + private void processDelta(IDBStoreAccessor accessor, InternalCDORevision originalRevision, int branchId, int oldVersion, int newVersion, + List<CDOFeatureDelta> listChanges) + { if (TRACER.isEnabled()) { + int oldListSize = originalRevision.size(getFeature()); TRACER.format("ListTableMapping.processDelta for revision {0} - previous list size: {1}", originalRevision, //$NON-NLS-1$ oldListSize); } + if (table == null) + { + initTable(accessor); + } + // let the visitor collect the changes ListDeltaVisitor visitor = new ListDeltaVisitor(accessor, originalRevision, branchId, oldVersion, newVersion); @@ -797,7 +827,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM // optimization: it's only necessary to process deltas // starting with the last feature delta which clears the list // (any operation before the clear is cascaded by it anyway) - int index = size - 1; + int index = listChanges.size() - 1; while (index > 0) { CDOFeatureDelta listDelta = listChanges.get(index); @@ -808,7 +838,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM index--; } - while (index < size) + while (index < listChanges.size()) { listChanges.get(index++).accept(visitor); } 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 89938c3fa5..a921177c34 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 @@ -578,7 +578,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp } @Override - public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor) + public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean firstRevision, boolean revise, OMMonitor monitor) { if (getTable() == null) { @@ -617,7 +617,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp try { async = monitor.forkAsync(); - if (mapType) + if (firstRevision) { // Put new objects into objectTypeMapper EClass eClass = getEClass(); @@ -625,11 +625,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy(); if (!mappingStrategy.putObjectType(accessor, timeStamp, id, eClass)) { - mapType = false; + firstRevision = false; } } - if (!mapType && revise && version > CDOBranchVersion.FIRST_VERSION) + if (!firstRevision && revise && version > CDOBranchVersion.FIRST_VERSION) { // If revision is not the first one, revise the old revision long revised = timeStamp - 1; @@ -685,7 +685,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp async = monitor.forkAsync(7); if (getListMappings() != null) { - writeLists(accessor, revision); + writeLists(accessor, revision, firstRevision, !revise); } } finally @@ -757,6 +757,13 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp } } + builder.append(" ORDER BY "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + IRepository repository = accessor.getStore().getRepository(); CDORevisionManager revisionManager = repository.getRevisionManager(); CDOBranchManager branchManager = repository.getBranchManager(); diff --git a/plugins/org.eclipse.emf.cdo.server.embedded/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.embedded/META-INF/MANIFEST.MF index 8e6012e149..438470a9b1 100644 --- a/plugins/org.eclipse.emf.cdo.server.embedded/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.embedded/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.server.embedded;singleton:=true -Bundle-Version: 4.6.100.qualifier +Bundle-Version: 4.6.200.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -13,7 +13,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";resoluti org.eclipse.emf.cdo.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.emf.cdo.server.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.net4j.jvm;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.server.embedded;version="4.6.100", - org.eclipse.emf.cdo.server.internal.embedded;version="4.6.100";x-friends:="org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.server.internal.embedded.bundle;version="4.6.100";x-internal:=true +Export-Package: org.eclipse.emf.cdo.server.embedded;version="4.6.200", + org.eclipse.emf.cdo.server.internal.embedded;version="4.6.200";x-friends:="org.eclipse.emf.cdo.tests", + org.eclipse.emf.cdo.server.internal.embedded.bundle;version="4.6.200";x-internal:=true Automatic-Module-Name: org.eclipse.emf.cdo.server.embedded diff --git a/plugins/org.eclipse.emf.cdo.server.embedded/pom.xml b/plugins/org.eclipse.emf.cdo.server.embedded/pom.xml index f8d0b2ed77..e237e1e82b 100644 --- a/plugins/org.eclipse.emf.cdo.server.embedded/pom.xml +++ b/plugins/org.eclipse.emf.cdo.server.embedded/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.server.embedded</artifactId> - <version>4.6.100-SNAPSHOT</version> + <version>4.6.200-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.server.embedded/src/org/eclipse/emf/cdo/server/internal/embedded/ClientRevisionManager.java b/plugins/org.eclipse.emf.cdo.server.embedded/src/org/eclipse/emf/cdo/server/internal/embedded/ClientRevisionManager.java index beeac2f70d..fe6f89dc6e 100644 --- a/plugins/org.eclipse.emf.cdo.server.embedded/src/org/eclipse/emf/cdo/server/internal/embedded/ClientRevisionManager.java +++ b/plugins/org.eclipse.emf.cdo.server.embedded/src/org/eclipse/emf/cdo/server/internal/embedded/ClientRevisionManager.java @@ -169,6 +169,19 @@ public final class ClientRevisionManager extends AbstractClientManager<InternalC } } + public InternalCDORevision getBaseRevision(CDORevision revision, int referenceChunk, boolean loadOnDemand) + { + try + { + ServerSession.set(serverSession); + return delegate.getBaseRevision(revision, referenceChunk, loadOnDemand); + } + finally + { + ServerSession.unset(); + } + } + public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth, boolean loadOnDemand, SyntheticCDORevision[] synthetics) { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerDebugUtil.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerDebugUtil.java new file mode 100644 index 0000000000..51d304f73a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerDebugUtil.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2004-2018 Eike Stepper (Loehne, 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.internal.server; + +import org.eclipse.emf.cdo.server.IRepository; +import org.eclipse.emf.cdo.server.IStoreAccessor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public final class ServerDebugUtil +{ + private static final Map<IRepository, IStoreAccessor> accessors = new HashMap<IRepository, IStoreAccessor>(); + + private ServerDebugUtil() + { + } + + public static void addAccessor(IStoreAccessor accessor) + { + accessors.put(accessor.getStore().getRepository(), accessor); + } + + public static void removeAccessor(IStoreAccessor accessor) + { + removeAccessor(accessor.getStore().getRepository()); + } + + public static void removeAccessor(IRepository repository) + { + accessors.remove(repository); + } + + public static IStoreAccessor getAccessor(IRepository repository) + { + return accessors.get(repository); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java index 7475d676b2..97ae97afec 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java @@ -419,6 +419,16 @@ public abstract class CDOServerExporter<OUT> public static final String REPOSITORY_COMMITTED = "committed"; + /** + * @since 4.8 + */ + public static final String REPOSITORY_EXPORT_BRANCH = "exportBranch"; + + /** + * @since 4.8 + */ + public static final String REPOSITORY_EXPORT_TIME = "exportTime"; + public static final String MODELS = "models"; public static final String PACKAGE_UNIT = "packageUnit"; @@ -571,6 +581,18 @@ public abstract class CDOServerExporter<OUT> out.attribute(REPOSITORY_CREATED, getRepository().getStore().getCreationTime()); out.attribute(REPOSITORY_COMMITTED, getRepository().getLastCommitTimeStamp()); + String branchPath = getBranchPath(); + if (branchPath != null) + { + out.attribute(REPOSITORY_EXPORT_BRANCH, branchPath); + } + + long timeStamp = getTimeStamp(); + if (timeStamp != CDOBranchPoint.INVALID_DATE) + { + out.attribute(REPOSITORY_EXPORT_TIME, timeStamp); + } + out.push(); super.exportAll(out); out.done(); @@ -997,6 +1019,8 @@ public abstract class CDOServerExporter<OUT> out.writeCDOID(getRepository().getRootResourceID()); out.writeLong(getRepository().getStore().getCreationTime()); out.writeLong(getRepository().getLastCommitTimeStamp()); + out.writeString(getBranchPath()); + out.writeXLong(getTimeStamp()); super.exportAll(out); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java index a2006b8bd7..83fba90662 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java @@ -34,6 +34,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionData; import org.eclipse.emf.cdo.common.revision.CDORevisionFactory; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.internal.server.ServerDebugUtil; import org.eclipse.emf.cdo.server.CDOServerExporter.Statistics; import org.eclipse.emf.cdo.server.IStoreAccessor.Raw2; import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; @@ -95,8 +96,14 @@ import java.util.Map; */ public abstract class CDOServerImporter { + private static final boolean DEBUG_WITH_BROWSER = false; + private InternalRepository repository; + private String branchPath; + + private long timeStamp = CDOBranchPoint.INVALID_DATE; + private final Statistics statistics = new Statistics(); public CDOServerImporter(IRepository repository) @@ -105,6 +112,38 @@ public abstract class CDOServerImporter init(); } + /** + * @since 4.8 + */ + public final String getBranchPath() + { + return branchPath; + } + + /** + * @since 4.8 + */ + protected final void setBranchPath(String branchPath) + { + this.branchPath = branchPath; + } + + /** + * @since 4.8 + */ + public final long getTimeStamp() + { + return timeStamp; + } + + /** + * @since 4.8 + */ + protected final void setTimeStamp(long timeStamp) + { + this.timeStamp = timeStamp; + } + private void init() { LifecycleUtil.checkInactive(repository); @@ -136,6 +175,11 @@ public abstract class CDOServerImporter } finally { + if (DEBUG_WITH_BROWSER) + { + ServerDebugUtil.removeAccessor(repository); + } + StoreThreadLocal.release(); repository = null; } @@ -216,6 +260,11 @@ public abstract class CDOServerImporter accessor = (IStoreAccessor.Raw)repository.getStore().getWriter(null); StoreThreadLocal.setAccessor(accessor); + + if (DEBUG_WITH_BROWSER) + { + ServerDebugUtil.addAccessor(accessor); + } } public InternalCDOPackageUnit handlePackageUnit(String id, Type type, long time, String data) @@ -383,7 +432,7 @@ public abstract class CDOServerImporter @Override protected void importAll(InputStream in, final Handler handler) throws Exception { - DefaultHandler xmlHandler = new XMLHandler(handler); + DefaultHandler xmlHandler = new XMLHandler(this, handler); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); @@ -395,7 +444,9 @@ public abstract class CDOServerImporter */ private static final class XMLHandler extends DefaultHandler { - private Handler handler; + private final XML xml; + + private final Handler handler; private InternalCDOPackageRegistry packageRegistry; @@ -409,8 +460,9 @@ public abstract class CDOServerImporter private Writer clob; - private XMLHandler(Handler handler) + private XMLHandler(XML xml, Handler handler) { + this.xml = xml; this.handler = handler; } @@ -424,6 +476,19 @@ public abstract class CDOServerImporter CDOID root = id(attributes.getValue(REPOSITORY_ROOT)); long created = Long.parseLong(attributes.getValue(REPOSITORY_CREATED)); long committed = Long.parseLong(attributes.getValue(REPOSITORY_COMMITTED)); + + String value = attributes.getValue(REPOSITORY_EXPORT_BRANCH); + if (value != null) + { + xml.setBranchPath(value); + } + + value = attributes.getValue(REPOSITORY_EXPORT_TIME); + if (value != null) + { + xml.setTimeStamp(Long.parseLong(value)); + } + handler.handleRepository(name, uuid, root, created, committed); } else if (PACKAGE_UNIT.equals(qName)) @@ -950,8 +1015,10 @@ public abstract class CDOServerImporter long created = in.readLong(); long committed = in.readLong(); - handler.handleRepository(name, uuid, root, created, committed); + setBranchPath(in.readString()); + setTimeStamp(in.readXLong()); + handler.handleRepository(name, uuid, root, created, committed); } private void handlePackageUnit(CDODataInput in, Handler handler) throws IOException diff --git a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/Hibernate_Failure_Test.java b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/Hibernate_Failure_Test.java index 774e3fe713..41c04a6a0c 100644 --- a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/Hibernate_Failure_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/Hibernate_Failure_Test.java @@ -45,12 +45,6 @@ public class Hibernate_Failure_Test extends AbstractCDOTest super.doTearDown(); } - /** - * TODO - * {@link org.eclipse.emf.cdo.server.IStoreAccessor.Raw#rawStore(org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision, org.eclipse.net4j.util.om.monitor.OMMonitor) - * rawStore()} is not adequate with range-based list mappings because they need deltas! - */ - @Skips("DB.ranges") public void testImport() throws Exception { CDOSession session = openSession(); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java index 62cfdf01ef..a4a652ffed 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java @@ -149,6 +149,8 @@ public class BackupTest extends AbstractCDOTest CDOServerExporter<?> exporter = createExporter(repo1); exporter.exportRepository(baos); + System.out.println(baos); + InternalRepository repo2 = getRepository("repo2", false); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/WorkspaceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/WorkspaceTest.java index 6dffb940a5..723cbac091 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/WorkspaceTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/WorkspaceTest.java @@ -85,7 +85,7 @@ import java.util.Set; * @author Eike Stepper */ @Requires({ IRepositoryConfig.CAPABILITY_AUDITING, IRepositoryConfig.CAPABILITY_UUIDS }) -@Skips("DB.ranges") +@Skips("DB.ranges") // Range-based mappings don't support rawDelete(). public class WorkspaceTest extends AbstractCDOTest { private static final String RESOURCE = "/test1"; |