diff options
author | Eike Stepper | 2020-04-11 06:14:52 +0000 |
---|---|---|
committer | Eike Stepper | 2020-04-11 06:14:52 +0000 |
commit | a15e3037b02b0066d7dfe47e52430249bce07448 (patch) | |
tree | 9d426b0a21cb329eb20258cf369de420fba5f870 /plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db | |
parent | 595f4da41f3e034916d3071ffd88d66ed59ad288 (diff) | |
download | cdo-a15e3037b02b0066d7dfe47e52430249bce07448.tar.gz cdo-a15e3037b02b0066d7dfe47e52430249bce07448.tar.xz cdo-a15e3037b02b0066d7dfe47e52430249bce07448.zip |
[562011] Remove deprecated support for FeatureMaps
https://bugs.eclipse.org/bugs/show_bug.cgi?id=562011
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db')
15 files changed, 2 insertions, 4221 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java index e0e34f3efd..ff20140fc3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java @@ -64,7 +64,6 @@ import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMapUtil; import java.sql.Connection; import java.sql.PreparedStatement; @@ -718,20 +717,8 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp return doCreateListMapping(containingClass, feature); } - public final IListMapping createFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - checkArg(FeatureMapUtil.isFeatureMap(feature), "Only FeatureMaps allowed"); //$NON-NLS-1$ - return doCreateFeatureMapMapping(containingClass, feature); - } - public abstract IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature); - /** - * @deprecated As 4.5 feature maps are no longer supported. - */ - @Deprecated - public abstract IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature); - @Override protected void doDeactivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java index bd5b309a07..4b87c2c18e 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java @@ -50,7 +50,6 @@ import org.eclipse.emf.ecore.EcorePackage; import java.text.MessageFormat; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -86,11 +85,6 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. private Map<String, ITypeMapping.Descriptor> typeMappingsById; /** - * A set of all known mapped DBTypes. This is needed for the feature map mappings. - */ - private Set<DBType> defaultFeatureMapDBTypes; - - /** * A populator which is used to keep the registry in sync with the registered factories of the * {@link IManagedContainer}. */ @@ -125,7 +119,6 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. } }); - defaultFeatureMapDBTypes = new HashSet<>(); typeMappingsById = new HashMap<>(); typeMappingByTypes = new HashMap<>(); classifierDefaultMapping = new HashMap<>(); @@ -264,8 +257,6 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. classifierDefaultMapping.put(eClassifier, dbType); } - defaultFeatureMapDBTypes.add(dbType); - typeMappingByTypes.put(sourceTargetPair, descriptor); } @@ -435,10 +426,11 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. return descriptor; } + @Deprecated @Override public Collection<DBType> getDefaultFeatureMapDBTypes() { - return defaultFeatureMapDBTypes; + throw new UnsupportedOperationException(); } /** diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java deleted file mode 100644 index ae8c5390aa..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (c) 2009-2013, 2015, 2016, 2018, 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 - * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 - * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455 - * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails - * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support - * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy - */ -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.CDOList; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; -import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; -import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; -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.IMetaDataManager; -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.net4j.db.DBException; -import org.eclipse.net4j.db.DBType; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBDatabase; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; -import org.eclipse.net4j.db.ddl.IDBField; -import org.eclipse.net4j.db.ddl.IDBIndex; -import org.eclipse.net4j.db.ddl.IDBIndex.Type; -import org.eclipse.net4j.db.ddl.IDBTable; -import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.collection.MoveableList; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMap; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * This abstract base class provides basic behavior needed for mapping many-valued attributes to tables. - * - * @author Eike Stepper - * @since 3.0 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public abstract class AbstractFeatureMapTableMapping extends AbstractBasicListTableMapping -{ - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractFeatureMapTableMapping.class); - - /** - * The table of this mapping. - */ - private IDBTable table; - - private FieldInfo[] keyFields; - - /** - * The tags mapped to column names. - */ - private Map<CDOID, String> tagMap = CDOIDUtil.createMap(); - - /** - * Column names. - */ - private List<String> columnNames = new ArrayList<>(); - - /** - * The type mappings for the value fields. - */ - private Map<CDOID, ITypeMapping> typeMappings = CDOIDUtil.createMap(); - - // --------- SQL strings - see initSQLStrings() ----------------- - private String sqlSelectChunksPrefix; - - private String sqlOrderByIndex; - - protected String sqlInsert; - - private List<DBType> dbTypes; - - public AbstractFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initDBTypes(); - initTable(); - initSQLStrings(); - } - - private void initDBTypes() - { - // TODO add annotation processing here ... - ITypeMapping.Registry registry = getTypeMappingRegistry(); - dbTypes = new ArrayList<>(registry.getDefaultFeatureMapDBTypes()); - } - - protected ITypeMapping.Registry getTypeMappingRegistry() - { - return ITypeMapping.Registry.INSTANCE; - } - - private void initTable() - { - String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); - DBType idType = getMappingStrategy().getStore().getIDHandler().getDBType(); - int idLength = getMappingStrategy().getStore().getIDColumnLength(); - - IDBDatabase database = getMappingStrategy().getStore().getDatabase(); - table = database.getSchema().getTable(tableName); - if (table == null) - { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - - IDBIndex index = table.addIndexEmpty(Type.NON_UNIQUE); - for (FieldInfo fieldInfo : getKeyFields()) - { - IDBField field = table.addField(fieldInfo.getName(), fieldInfo.getType(), fieldInfo.getPrecision()); - index.addIndexField(field); - } - - // Add field for list index - table.addField(FEATUREMAP_IDX, DBType.INTEGER); - - // Add field for FeatureMap tag (MetaID for Feature in CDO registry) - table.addField(FEATUREMAP_TAG, idType, idLength); - - // Create columns for all DBTypes - initTypeColumns(true); - - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_IDX); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_TAG); - } - else - { - initTypeColumns(false); - } - } - - private void initTypeColumns(boolean create) - { - for (DBType type : getDBTypes()) - { - String column = FEATUREMAP_VALUE + "_" + type.name(); - if (create) - { - table.addField(column, type); - } - - columnNames.add(column); - } - } - - private void initSQLStrings() - { - String tableName = getTable().getName(); - FieldInfo[] fields = getKeyFields(); - - // ---------------- SELECT to read chunks ---------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); - - builder.append(FEATUREMAP_TAG); - builder.append(", "); - - Iterator<String> iter = columnNames.iterator(); - while (iter.hasNext()) - { - builder.append(iter.next()); - if (iter.hasNext()) - { - builder.append(", "); - } - } - - builder.append(" FROM "); - builder.append(tableName); - builder.append(" WHERE "); - - for (int i = 0; i < fields.length; i++) - { - builder.append(fields[i].getName()); - if (i + 1 < fields.length) - { - // more to come - builder.append("=? AND "); - } - else - { - // last one - builder.append("=? "); - } - } - - sqlSelectChunksPrefix = builder.toString(); - - sqlOrderByIndex = " ORDER BY " + FEATUREMAP_IDX; //$NON-NLS-1$ - - // INSERT with dynamic field name - // TODO: Better: universal INSERT-Statement, because of stmt caching! - - // ----------------- INSERT - prefix ----------------- - builder = new StringBuilder("INSERT INTO "); - builder.append(tableName); - builder.append(" ("); //$NON-NLS-1$ - for (int i = 0; i < fields.length; i++) - { - builder.append(fields[i].getName()); - builder.append(", "); //$NON-NLS-1$ - } - - for (int i = 0; i < columnNames.size(); i++) - { - builder.append(columnNames.get(i)); - builder.append(", "); //$NON-NLS-1$ - } - - builder.append(FEATUREMAP_IDX); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - builder.append(") VALUES ("); //$NON-NLS-1$ - for (int i = 0; i < fields.length + columnNames.size(); i++) - { - builder.append("?, "); - } - - builder.append("?, ?)"); - sqlInsert = builder.toString(); - } - - protected final FieldInfo[] getKeyFields() - { - if (keyFields == null) - { - List<FieldInfo> list = new ArrayList<>(3); - - IDBStore store = getMappingStrategy().getStore(); - DBType type = store.getIDHandler().getDBType(); - int precision = store.getIDColumnLength(); - list.add(new FieldInfo(FEATUREMAP_REVISION_ID, type, precision)); - - addKeyFields(list); - - keyFields = list.toArray(new FieldInfo[list.size()]); - } - - return keyFields; - } - - protected abstract void addKeyFields(List<FieldInfo> list); - - protected abstract void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException; - - @Override - public Collection<IDBTable> getDBTables() - { - return Collections.singleton(table); - } - - protected List<DBType> getDBTypes() - { - return dbTypes; - } - - protected final IDBTable getTable() - { - return table; - } - - protected final List<String> getColumnNames() - { - return columnNames; - } - - protected final Map<CDOID, ITypeMapping> getTypeMappings() - { - return typeMappings; - } - - protected final Map<CDOID, String> getTagMap() - { - return tagMap; - } - - @Override - public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - MoveableList<Object> list = revision.getListOrNull(getFeature()); - if (list == null) - { - // Nothing to read take shortcut. - return; - } - - if (listChunk == 0 || list.size() == 0) - { - // Nothing to read take shortcut. - return; - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature().getName(), revision.getID(), - revision.getVersion()); - } - - String sql = sqlSelectChunksPrefix + sqlOrderByIndex; - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.HIGH); - ResultSet resultSet = null; - - try - { - setKeyFields(stmt, revision); - - if (listChunk != CDORevision.UNCHUNKED) - { - stmt.setMaxRows(listChunk); // optimization - don't read unneeded rows. - } - - resultSet = stmt.executeQuery(); - int currentIndex = 0; - - while ((listChunk == CDORevision.UNCHUNKED || --listChunk >= 0) && resultSet.next()) - { - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - - if (TRACER.isEnabled()) - { - TRACER.format("Read value for index {0} from result set: {1}", currentIndex, value); - } - - list.set(currentIndex++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature().getName(), revision.getID(), - revision.getVersion()); - } - } - - private void addFeature(CDOID tag) - { - EStructuralFeature modelFeature = getFeatureByTag(tag); - - ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature); - String column = FEATUREMAP_VALUE + "_" + typeMapping.getDBType(); - - tagMap.put(tag, column); - typeMapping.setDBField(table, column); - typeMappings.put(tag, typeMapping); - } - - @Override - public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where) - { - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature().getName(), - chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion()); - } - - StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix); - if (where != null) - { - builder.append(" AND "); //$NON-NLS-1$ - builder.append(where); - } - - builder.append(sqlOrderByIndex); - String sql = builder.toString(); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = chunkReader.getAccessor().getDBConnection().prepareStatement(sql, ReuseProbability.LOW); - ResultSet resultSet = null; - - try - { - setKeyFields(stmt, chunkReader.getRevision()); - - resultSet = stmt.executeQuery(); - - Chunk chunk = null; - int chunkSize = 0; - int chunkIndex = 0; - int indexInChunk = 0; - - while (resultSet.next()) - { - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - - if (chunk == null) - { - chunk = chunks.get(chunkIndex++); - chunkSize = chunk.size(); - - if (TRACER.isEnabled()) - { - TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(), chunkSize); - } - } - - if (TRACER.isEnabled()) - { - TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value); - } - - chunk.add(indexInChunk++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - if (indexInChunk == chunkSize) - { - if (TRACER.isEnabled()) - { - TRACER.format("Chunk finished"); - } - - chunk = null; - indexInChunk = 0; - } - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}", getContainingClass().getName(), getFeature(), chunkReader.getRevision()); - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - } - - @Override - public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) - { - CDOList values = revision.getListOrNull(getFeature()); - if (values != null) - { - int idx = 0; - for (Object element : values) - { - writeValue(accessor, revision, idx++, element); - } - } - } - - protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value) - { - if (TRACER.isEnabled()) - { - TRACER.format("Writing value for feature {0}.{1} index {2} of {3} : {4}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature(), idx, revision, value); - } - - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, revision.getTimeStamp()); - ITypeMapping typeMapping = getTypeMapping(tag); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.HIGH); - - try - { - setKeyFields(stmt, revision); - int column = getKeyFields().length + 1; - - for (int i = 0; i < columnNames.size(); i++) - { - if (columnNames.get(i).equals(columnName)) - { - typeMapping.setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - stmt.setInt(column++, idx); - idHandler.setCDOID(stmt, column++, tag); - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - /** - * Get column name (lazy) - * - * @param tag - * The feature's MetaID in CDO - * @return the column name where the values are stored - */ - protected String getColumnName(CDOID tag) - { - String column = tagMap.get(tag); - if (column == null) - { - addFeature(tag); - column = tagMap.get(tag); - } - - return column; - } - - /** - * Get type mapping (lazy) - * - * @param tag - * The feature's MetaID in CDO - * @return the corresponding type mapping - */ - protected ITypeMapping getTypeMapping(CDOID tag) - { - ITypeMapping typeMapping = typeMappings.get(tag); - if (typeMapping == null) - { - addFeature(tag); - typeMapping = typeMappings.get(tag); - } - - return typeMapping; - } - - /** - * @param metaID - * @return the column name where the values are stored - */ - private EStructuralFeature getFeatureByTag(CDOID tag) - { - IMetaDataManager metaDataManager = getMappingStrategy().getStore().getMetaDataManager(); - return (EStructuralFeature)metaDataManager.getMetaInstance(tag); - } - - /** - * @param feature - * The EStructuralFeature - * @return The feature's MetaID in CDO - */ - protected CDOID getTagByFeature(EStructuralFeature feature, long timeStamp) - { - IMetaDataManager metaDataManager = getMappingStrategy().getStore().getMetaDataManager(); - return metaDataManager.getMetaID(feature, timeStamp); - } - - @Override - public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) - { - /* - * must never be called (a feature map is not associated with an EReference feature, so XRefs are nor supported - * here) - */ - throw new ImplementationError("Should never be called!"); - } - -} 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 f5cb243d18..06d4e6cbd2 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 @@ -72,7 +72,6 @@ import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMapUtil; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -336,11 +335,6 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I private IListMapping createListMapping(EStructuralFeature feature) { - if (FeatureMapUtil.isFeatureMap(feature)) - { - return mappingStrategy.createFeatureMapMapping(eClass, feature); - } - return mappingStrategy.createListMapping(eClass, feature); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMapping.java deleted file mode 100644 index 6d8adcb093..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMapping.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2009-2013, 2018, 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 - * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 - * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455 - */ -package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; - -import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; -import org.eclipse.emf.cdo.server.db.IIDHandler; -import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; - -import org.eclipse.net4j.db.DBException; -import org.eclipse.net4j.db.DBType; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; - -/** - * This is a featuremap-table mapping for audit mode. It has ID and version columns and no delta support. - * - * @author Eike Stepper - * @since 3.0 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public class AuditFeatureMapTableMapping extends AbstractFeatureMapTableMapping -{ - private String sqlClear; - - public AuditFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initSQLStrings(); - } - - private void initSQLStrings() - { - // ----------- clear list ------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("DELETE FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(LIST_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(LIST_REVISION_VERSION); - builder.append("=? "); //$NON-NLS-1$ - sqlClear = builder.toString(); - } - - @Override - protected void addKeyFields(List<FieldInfo> list) - { - list.add(new FieldInfo(FEATUREMAP_VERSION, DBType.INTEGER)); - } - - @Override - protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getVersion()); - } - - @Override - public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) - { - // the audit list mapping does not care about revised references -> NOP - } - - @Override - public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, version); - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } -} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java deleted file mode 100644 index e3bfa44a71..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Copyright (c) 2010-2013, 2015, 2016, 2018, 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 - * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444 - * Christopher Albert - Bug 254455: [DB] Support FeatureMaps bug 254455 - * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails - * Lothar Werzinger - Bug 296440: [DB] Change RDB schema to improve scalability of to-many references in audit mode - * Stefan Winkler - cleanup, merge and maintenance - * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support - * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy - */ -package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; - -import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.id.CDOIDUtil; -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; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; -import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta; -import org.eclipse.emf.cdo.server.IRepository; -import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; -import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; -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.IListMappingDeltaSupport; -import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; -import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; -import org.eclipse.emf.cdo.server.internal.db.bundle.OM; -import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; - -import org.eclipse.net4j.db.DBException; -import org.eclipse.net4j.db.DBType; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBDatabase; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; -import org.eclipse.net4j.db.ddl.IDBIndex.Type; -import org.eclipse.net4j.db.ddl.IDBTable; -import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.collection.MoveableList; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMap; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * This is a featuremap-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 - * {@link IMappingConstants#LIST_REVISION_VERSION_ADDED cdo_version_added} and - * {@link IMappingConstants#LIST_REVISION_VERSION_REMOVED 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 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 - * @since 3.0 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public class AuditFeatureMapTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport -{ - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AuditFeatureMapTableMappingWithRanges.class); - - /** - * Used to clean up lists for detached objects. - */ - private static final int FINAL_VERSION = Integer.MAX_VALUE; - - /** - * The table of this mapping. - */ - private IDBTable table; - - /** - * Column names. - */ - private List<String> columnNames = new ArrayList<>(); - - /** - * The type mappings for the value fields. - */ - private Map<CDOID, ITypeMapping> typeMappings = CDOIDUtil.createMap(); - - /** - * The tags mapped to column names - */ - private Map<CDOID, String> tagMap = CDOIDUtil.createMap(); - - private List<DBType> dbTypes; - - // --------- SQL strings - see initSQLStrings() ----------------- - private String sqlSelectChunksPrefix; - - private String sqlOrderByIndex; - - private String sqlInsert; - - private String sqlRemoveEntry; - - private String sqlDeleteEntry; - - private String sqlUpdateIndex; - - private String sqlGetValue; - - private String sqlClearList; - - private String sqlDeleteList; - - public AuditFeatureMapTableMappingWithRanges(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initDBTypes(); - initTable(); - initSQLStrings(); - } - - private void initDBTypes() - { - // TODO add annotation processing here ... - ITypeMapping.Registry registry = ITypeMapping.Registry.INSTANCE; - dbTypes = new ArrayList<>(registry.getDefaultFeatureMapDBTypes()); - } - - private void initTable() - { - String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); - IDBStore store = getMappingStrategy().getStore(); - DBType idType = store.getIDHandler().getDBType(); - int idLength = store.getIDColumnLength(); - - IDBDatabase database = getMappingStrategy().getStore().getDatabase(); - table = database.getSchema().getTable(tableName); - if (table == null) - { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - table.addField(FEATUREMAP_REVISION_ID, idType, idLength); - table.addField(FEATUREMAP_VERSION_ADDED, DBType.INTEGER); - table.addField(FEATUREMAP_VERSION_REMOVED, DBType.INTEGER); - table.addField(FEATUREMAP_IDX, DBType.INTEGER); - table.addField(FEATUREMAP_TAG, idType, idLength); - - initTypeColumns(true); - - // TODO think about indices - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_REVISION_ID); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_VERSION_ADDED); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_VERSION_REMOVED); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_IDX); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_TAG); - } - else - { - initTypeColumns(false); - } - } - - private void initTypeColumns(boolean create) - { - for (DBType type : getDBTypes()) - { - String column = FEATUREMAP_VALUE + "_" + type.name(); - if (create) - { - table.addField(column, type); - } - - columnNames.add(column); - } - } - - private void initSQLStrings() - { - String tableName = getTable().getName(); - - // ---------------- SELECT to read chunks ---------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - - builder.append(FEATUREMAP_TAG); - builder.append(", "); //$NON-NLS-1$ - - Iterator<String> iter = columnNames.iterator(); - while (iter.hasNext()) - { - builder.append(iter.next()); - if (iter.hasNext()) - { - builder.append(", "); //$NON-NLS-1$ - } - } - - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL OR "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(">?)"); //$NON-NLS-1$ - sqlSelectChunksPrefix = builder.toString(); - - sqlOrderByIndex = " ORDER BY " + FEATUREMAP_IDX; //$NON-NLS-1$ - - // ----------------- INSERT - prefix ----------------- - builder = new StringBuilder("INSERT INTO "); //$NON-NLS-1$ - builder.append(tableName); - builder.append("("); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - - for (int i = 0; i < columnNames.size(); i++) - { - builder.append(", "); //$NON-NLS-1$ - builder.append(columnNames.get(i)); - } - - builder.append(") VALUES (?, ?, ?, ?, ?"); //$NON-NLS-1$ - for (int i = 0; i < columnNames.size(); i++) - { - builder.append(", ?"); //$NON-NLS-1$ - } - - builder.append(")"); //$NON-NLS-1$ - sqlInsert = builder.toString(); - - // ----------------- remove current entry ----------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append("=? "); //$NON-NLS-1$ - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlRemoveEntry = builder.toString(); - - // ----------------- delete temporary entry ----------------- - builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("=?"); //$NON-NLS-1$ - sqlDeleteEntry = builder.toString(); - - // ----------------- update index ----------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=?"); //$NON-NLS-1$ - sqlUpdateIndex = builder.toString(); - - // ----------------- get current value ----------------- - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - builder.append(", "); //$NON-NLS-1$ - - iter = columnNames.iterator(); - while (iter.hasNext()) - { - builder.append(iter.next()); - if (iter.hasNext()) - { - builder.append(", "); //$NON-NLS-1$ - } - } - - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlGetValue = builder.toString(); - - // ----------- clear list items ------------------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append("=? "); //$NON-NLS-1$ - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlClearList = builder.toString(); - - // ----------- delete temporary list items ------------------------- - builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlDeleteList = builder.toString(); - } - - protected List<DBType> getDBTypes() - { - return dbTypes; - } - - @Override - public Collection<IDBTable> getDBTables() - { - return Collections.singleton(table); - } - - protected final IDBTable getTable() - { - return table; - } - - protected final List<String> getColumnNames() - { - return columnNames; - } - - protected final Map<CDOID, ITypeMapping> getTypeMappings() - { - return typeMappings; - } - - protected final Map<CDOID, String> getTagMap() - { - return tagMap; - } - - @Override - public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - MoveableList<Object> list = revision.getListOrNull(getFeature()); - if (list == null) - { - // Nothing to read take shortcut. - return; - } - - if (listChunk == 0 || list.size() == 0) - { - // Nothing to read take shortcut. - return; - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature() //$NON-NLS-1$ - .getName(), revision.getID(), revision.getVersion()); - } - - String sql = sqlSelectChunksPrefix + sqlOrderByIndex; - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.HIGH); - ResultSet resultSet = null; - - try - { - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getVersion()); - stmt.setInt(3, revision.getVersion()); - - if (listChunk != CDORevision.UNCHUNKED) - { - stmt.setMaxRows(listChunk); // optimization - don't read unneeded rows. - } - - resultSet = stmt.executeQuery(); - - int currentIndex = 0; - while ((listChunk == CDORevision.UNCHUNKED || --listChunk >= 0) && resultSet.next()) - { - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - - if (TRACER.isEnabled()) - { - TRACER.format("Read value for index {0} from result set: {1}", currentIndex, value); //$NON-NLS-1$ - } - - list.set(currentIndex++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature().getName(), revision.getID(), revision.getVersion()); - } - } - - private void addFeature(CDOID tag) - { - EStructuralFeature modelFeature = getFeatureByTag(tag); - - ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature); - String column = FEATUREMAP_VALUE + "_" + typeMapping.getDBType(); //$NON-NLS-1$ - - tagMap.put(tag, column); - typeMapping.setDBField(table, column); - typeMappings.put(tag, typeMapping); - } - - @Override - public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where) - { - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature().getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion()); - } - - StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix); - if (where != null) - { - builder.append(" AND "); //$NON-NLS-1$ - builder.append(where); - } - - builder.append(sqlOrderByIndex); - String sql = builder.toString(); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = chunkReader.getAccessor().getDBConnection().prepareStatement(sql, ReuseProbability.LOW); - ResultSet resultSet = null; - - try - { - idHandler.setCDOID(stmt, 1, chunkReader.getRevision().getID()); - stmt.setInt(2, chunkReader.getRevision().getVersion()); - stmt.setInt(3, chunkReader.getRevision().getVersion()); - - resultSet = stmt.executeQuery(); - - Chunk chunk = null; - int chunkSize = 0; - int chunkIndex = 0; - int indexInChunk = 0; - - while (resultSet.next()) - { - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - - if (chunk == null) - { - chunk = chunks.get(chunkIndex++); - chunkSize = chunk.size(); - - if (TRACER.isEnabled()) - { - TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(), //$NON-NLS-1$ - chunkSize); - } - } - - if (TRACER.isEnabled()) - { - TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value); //$NON-NLS-1$ - } - - chunk.add(indexInChunk++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - if (indexInChunk == chunkSize) - { - if (TRACER.isEnabled()) - { - TRACER.format("Chunk finished"); //$NON-NLS-1$ - } - - chunk = null; - indexInChunk = 0; - } - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature(), chunkReader.getRevision()); - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - } - - @Override - public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) - { - CDOList values = revision.getListOrNull(getFeature()); - if (values != null) - { - int idx = 0; - for (Object element : values) - { - writeValue(accessor, revision, idx++, element); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ - } - } - } - - protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value) - { - if (TRACER.isEnabled()) - { - TRACER.format("Writing value for feature {0}.{1} index {2} of {3} : {4}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature(), idx, revision, value); - } - - addEntry(accessor, revision.getID(), revision.getVersion(), idx, value, revision.getTimeStamp()); - } - - /** - * Get column name (lazy). - * - * @param tag - * The feature's MetaID in CDO - * @return the column name where the values are stored - */ - protected String getColumnName(CDOID tag) - { - String column = tagMap.get(tag); - if (column == null) - { - addFeature(tag); - column = tagMap.get(tag); - } - - return column; - } - - /** - * Get type mapping (lazy). - * - * @param tag - * The feature's MetaID in CDO - * @return the corresponding type mapping - */ - protected ITypeMapping getTypeMapping(CDOID tag) - { - ITypeMapping typeMapping = typeMappings.get(tag); - if (typeMapping == null) - { - addFeature(tag); - typeMapping = typeMappings.get(tag); - } - - return typeMapping; - } - - /** - * @param metaID - * @return the column name where the values are stored - */ - private EStructuralFeature getFeatureByTag(CDOID tag) - { - return (EStructuralFeature)getMappingStrategy().getStore().getMetaDataManager().getMetaInstance(tag); - } - - /** - * @param feature - * The EStructuralFeature - * @return The feature's MetaID in CDO - */ - protected CDOID getTagByFeature(EStructuralFeature feature, long timestamp) - { - return getMappingStrategy().getStore().getMetaDataManager().getMetaID(feature, timestamp); - } - - /** - * Clear a list of a given revision. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision from which to remove all items - */ - public void clearList(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmtDeleteTemp = accessor.getDBConnection().prepareStatement(sqlDeleteList, ReuseProbability.HIGH); - IDBPreparedStatement stmtClear = accessor.getDBConnection().prepareStatement(sqlClearList, ReuseProbability.HIGH); - - try - { - // delete temporary entries - idHandler.setCDOID(stmtDeleteTemp, 1, id); - stmtDeleteTemp.setInt(2, newVersion); - - int result = DBUtil.update(stmtDeleteTemp, false); - if (TRACER.isEnabled()) - { - TRACER.format("DeleteList result: {0}", result); //$NON-NLS-1$ - } - - // clear rest of the list - stmtClear.setInt(1, newVersion); - idHandler.setCDOID(stmtClear, 2, id); - - result = DBUtil.update(stmtClear, false); - if (TRACER.isEnabled()) - { - TRACER.format("ClearList result: {0}", result); //$NON-NLS-1$ - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmtClear); - DBUtil.close(stmtDeleteTemp); - } - } - - @Override - public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) - { - if (TRACER.isEnabled()) - { - TRACER.format("objectRevised {0}: {1}", id, revised); //$NON-NLS-1$ - } - - CDOBranch main = getMappingStrategy().getStore().getRepository().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); - - // set cdo_revision_removed for all list items (so we have no NULL values) - clearList(accessor, id, revision.getVersion(), FINAL_VERSION); - } - - @Override - public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) - { - throw new UnsupportedOperationException("Raw deletion does not work in range-based mappings"); - } - - @Override - public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion, final int newVersion, long created, - CDOListFeatureDelta delta) - { - IRepository repo = accessor.getStore().getRepository(); - InternalCDORevision originalRevision = (InternalCDORevision)repo.getRevisionManager().getRevision(id, repo.getBranchManager().getMainBranch().getHead(), - /* chunksize = */0, CDORevision.DEPTH_NONE, true); - - int oldListSize = originalRevision.size(getFeature()); - - if (TRACER.isEnabled()) - { - TRACER.format("ListTableMapping.processDelta for revision {0} - previous list size: {1}", originalRevision, //$NON-NLS-1$ - oldListSize); - } - - // let the visitor collect the changes - ListDeltaVisitor visitor = new ListDeltaVisitor(accessor, originalRevision, oldVersion, newVersion, created); - - if (TRACER.isEnabled()) - { - TRACER.format("Processing deltas..."); //$NON-NLS-1$ - } - - for (CDOFeatureDelta listDelta : delta.getListChanges()) - { - listDelta.accept(visitor); - } - } - - private class ListDeltaVisitor implements CDOFeatureDeltaVisitor - { - private IDBStoreAccessor accessor; - - private InternalCDORevision originalRevision; - - private CDOID id; - - private int oldVersion; - - private int newVersion; - - private int lastIndex; - - private long timestamp; - - public ListDeltaVisitor(IDBStoreAccessor accessor, InternalCDORevision originalRevision, int oldVersion, int newVersion, long timestamp) - { - this.accessor = accessor; - this.originalRevision = originalRevision; - id = this.originalRevision.getID(); - this.oldVersion = oldVersion; - this.newVersion = newVersion; - lastIndex = originalRevision.size(getFeature()) - 1; - this.timestamp = timestamp; - } - - @Override - public void visit(CDOMoveFeatureDelta delta) - { - int fromIdx = delta.getOldPosition(); - int toIdx = delta.getNewPosition(); - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Moving: {0} to {1}", fromIdx, toIdx); //$NON-NLS-1$ - } - - Object value = getValue(accessor, id, fromIdx); - - // remove the item - removeEntry(accessor, id, oldVersion, newVersion, fromIdx); - - // adjust indexes and shift either up or down - if (fromIdx < toIdx) - { - moveOneUp(accessor, id, oldVersion, newVersion, fromIdx + 1, toIdx); - } - else - { // fromIdx > toIdx here - moveOneDown(accessor, id, oldVersion, newVersion, toIdx, fromIdx - 1); - } - - // create the item - addEntry(accessor, id, newVersion, toIdx, value, timestamp); - } - - @Override - public void visit(CDOAddFeatureDelta delta) - { - int startIndex = delta.getIndex(); - int endIndex = lastIndex; - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Adding at: {0}", startIndex); //$NON-NLS-1$ - } - - if (startIndex <= endIndex) - { - // make room for the new item - moveOneDown(accessor, id, oldVersion, newVersion, startIndex, endIndex); - } - - // create the item - addEntry(accessor, id, newVersion, startIndex, delta.getValue(), timestamp); - - ++lastIndex; - } - - @Override - public void visit(CDORemoveFeatureDelta delta) - { - int startIndex = delta.getIndex(); - int endIndex = lastIndex; - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Removing at: {0}", startIndex); //$NON-NLS-1$ - } - - // remove the item - removeEntry(accessor, id, oldVersion, newVersion, startIndex); - - // make room for the new item - moveOneUp(accessor, id, oldVersion, newVersion, startIndex + 1, endIndex); - - --lastIndex; - } - - @Override - public void visit(CDOSetFeatureDelta delta) - { - int index = delta.getIndex(); - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Setting at: {0}", index); //$NON-NLS-1$ - } - - // remove the item - removeEntry(accessor, id, oldVersion, newVersion, index); - - // create the item - addEntry(accessor, id, newVersion, index, delta.getValue(), timestamp); - } - - @Override - public void visit(CDOUnsetFeatureDelta delta) - { - if (delta.getFeature().isUnsettable()) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Unsetting"); //$NON-NLS-1$ - } - - clearList(accessor, id, oldVersion, newVersion); - lastIndex = -1; - } - - @Override - public void visit(CDOListFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - @Override - public void visit(CDOClearFeatureDelta delta) - { - if (TRACER.isEnabled()) - { - TRACER.format("Delta Clearing"); //$NON-NLS-1$ - } - - clearList(accessor, id, oldVersion, newVersion); - lastIndex = -1; - } - - @Override - public void visit(CDOContainerFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - private void moveOneUp(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, int startIndex, int endIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH); - - try - { - for (int index = startIndex; index <= endIndex; ++index) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp moving: {0} -> {1}", index, index - 1); //$NON-NLS-1$ - } - - int column = 1; - stmt.setInt(column++, index - 1); - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, newVersion); - stmt.setInt(column++, index); - - int result = DBUtil.update(stmt, false); - switch (result) - { - case 0: - Object value = getValue(accessor, id, index); - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp remove: {0}", index); //$NON-NLS-1$ - } - - removeEntry(accessor, id, oldVersion, newVersion, index); - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp add: {0}", index - 1); //$NON-NLS-1$ - } - - addEntry(accessor, id, newVersion, index - 1, value, timestamp); - break; - - case 1: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp updated: {0} -> {1}", index, index - 1); //$NON-NLS-1$ - } - - break; - - default: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp Too many results: {0} -> {1}: {2}", index, index + 1, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void moveOneDown(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, int startIndex, int endIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH); - - try - { - for (int index = endIndex; index >= startIndex; --index) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown moving: {0} -> {1}", index, index + 1); //$NON-NLS-1$ - } - - int column = 1; - stmt.setInt(column++, index + 1); - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, newVersion); - stmt.setInt(column++, index); - - int result = DBUtil.update(stmt, false); - switch (result) - { - case 0: - Object value = getValue(accessor, id, index); - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown remove: {0}", index); //$NON-NLS-1$ - } - - removeEntry(accessor, id, oldVersion, newVersion, index); - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown add: {0}", index + 1); //$NON-NLS-1$ - } - - addEntry(accessor, id, newVersion, index + 1, value, timestamp); - break; - - case 1: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown updated: {0} -> {1}", index, index + 1); //$NON-NLS-1$ - } - - break; - - default: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown Too many results: {0} -> {1}: {2}", index, index + 1, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - } - - private void addEntry(IDBStoreAccessor accessor, CDOID id, int version, int index, Object value, long timestamp) - { - if (TRACER.isEnabled()) - { - TRACER.format("Adding value for feature() {0}.{1} index {2} of {3}v{4} : {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, version, value); - } - - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, timestamp); - ITypeMapping typeMapping = getTypeMapping(tag); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.HIGH); - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, version); - stmt.setNull(column++, DBType.INTEGER.getCode()); // versionRemoved - stmt.setInt(column++, index); - idHandler.setCDOID(stmt, column++, tag); - - for (int i = 0; i < columnNames.size(); i++) - { - if (columnNames.get(i).equals(columnName)) - { - typeMapping.setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - catch (IllegalStateException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void removeEntry(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, int index) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion); - } - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDeleteEntry, ReuseProbability.HIGH); - - try - { - // try to delete a temporary entry first - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, index); - stmt.setInt(column++, newVersion); - - int result = DBUtil.update(stmt, false); - if (result == 1) - { - if (TRACER.isEnabled()) - { - TRACER.format("removeEntry deleted: {0}", index); //$NON-NLS-1$ - } - } - else if (result > 1) - { - if (TRACER.isEnabled()) - { - TRACER.format("removeEntry Too many results: {0}: {1}", index, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - else - { - // no temporary entry found, so mark the entry as removed - DBUtil.close(stmt); - stmt = accessor.getDBConnection().prepareStatement(sqlRemoveEntry, ReuseProbability.HIGH); - - column = 1; - stmt.setInt(column++, newVersion); - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, index); - DBUtil.update(stmt, true); - } - } - catch (SQLException e) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage()); - } - - throw new DBException(e); - } - catch (IllegalStateException e) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage()); - } - - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private FeatureMap.Entry getValue(IDBStoreAccessor accessor, CDOID id, int index) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlGetValue, ReuseProbability.HIGH); - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, index); - - ResultSet resultSet = stmt.executeQuery(); - if (!resultSet.next()) - { - throw new DBException("getValue expects exactly one result"); - } - - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - FeatureMap.Entry result = CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value); - - if (TRACER.isEnabled()) - { - TRACER.format("Read value (index {0}) from result set: {1}", index, result); //$NON-NLS-1$ - } - - return result; - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) - { - // must never be called (a feature map is not associated with an EReference feature, so XRefs are nor supported - // here) - throw new ImplementationError("Should never be called!"); - } -} 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 deleted file mode 100644 index af0746c47f..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010-2013, 2018, 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 - * 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.branch.CDOBranch; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; -import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; - -import org.eclipse.net4j.db.DBException; -import org.eclipse.net4j.db.DBType; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; - -/** - * 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 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public class BranchingFeatureMapTableMapping extends AbstractFeatureMapTableMapping -{ - private String sqlClear; - - public BranchingFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initSQLStrings(); - } - - private void initSQLStrings() - { - // ----------- clear list ------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("DELETE FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(LIST_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(LIST_REVISION_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(LIST_REVISION_VERSION); - builder.append("=?"); //$NON-NLS-1$ - sqlClear = builder.toString(); - } - - @Override - protected void addKeyFields(List<FieldInfo> list) - { - list.add(new FieldInfo(FEATUREMAP_BRANCH, DBType.INTEGER)); - list.add(new FieldInfo(FEATUREMAP_VERSION, DBType.INTEGER)); - } - - @Override - protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException - { - getMappingStrategy().getStore().getIDHandler().setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getBranch().getID()); - stmt.setInt(3, revision.getVersion()); - } - - @Override - public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) - { - // the audit list mapping does not care about revised references -> NOP - } - - @Override - public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) - { - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); - - try - { - getMappingStrategy().getStore().getIDHandler().setCDOID(stmt, 1, id); - stmt.setInt(2, branch.getID()); - stmt.setInt(3, version); - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } -} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java deleted file mode 100644 index ade68a7775..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java +++ /dev/null @@ -1,1511 +0,0 @@ -/* - * Copyright (c) 2010-2013, 2015, 2016, 2018, 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: - * Stefan Winkler - initial API and implementation taken from AuditFeatureMapTableMappingWithRanges - * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy - */ -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.CDOBranchManager; -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.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; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; -import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta; -import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; -import org.eclipse.emf.cdo.server.IStoreChunkReader; -import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; -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.IListMappingDeltaSupport; -import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; -import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; -import org.eclipse.emf.cdo.server.internal.db.bundle.OM; -import org.eclipse.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; -import org.eclipse.net4j.db.DBType; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBDatabase; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; -import org.eclipse.net4j.db.ddl.IDBIndex.Type; -import org.eclipse.net4j.db.ddl.IDBTable; -import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.collection.MoveableList; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMap; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * This is a featuremap-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 - * {@link IMappingConstants#LIST_REVISION_VERSION_ADDED cdo_version_added} and - * {@link IMappingConstants#LIST_REVISION_VERSION_REMOVED 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 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 - * @since 3.0 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport -{ - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, BranchingFeatureMapTableMappingWithRanges.class); - - /** - * Used to clean up lists for detached objects. - */ - private static final int FINAL_VERSION = Integer.MAX_VALUE; - - /** - * The table of this mapping. - */ - private IDBTable table; - - /** - * The tags mapped to column names - */ - private Map<CDOID, String> tagMap; - - /** - * Column name Set - */ - private List<String> columnNames; - - /** - * The type mappings for the value fields. - */ - private Map<CDOID, ITypeMapping> typeMappings; - - private List<DBType> dbTypes; - - // --------- SQL strings - see initSQLStrings() ----------------- - private String sqlSelectChunksPrefix; - - private String sqlOrderByIndex; - - private String sqlInsert; - - private String sqlRemoveEntry; - - private String sqlDeleteEntry; - - private String sqlUpdateIndex; - - private String sqlGetValue; - - private String sqlClearList; - - public BranchingFeatureMapTableMappingWithRanges(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initDBTypes(); - initTable(); - initSQLStrings(); - } - - private void initDBTypes() - { - // TODO add annotation processing here ... - ITypeMapping.Registry registry = ITypeMapping.Registry.INSTANCE; - dbTypes = new ArrayList<>(registry.getDefaultFeatureMapDBTypes()); - } - - private void initTable() - { - String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); - IDBStore store = getMappingStrategy().getStore(); - DBType idType = store.getIDHandler().getDBType(); - int idLength = store.getIDColumnLength(); - - IDBDatabase database = getMappingStrategy().getStore().getDatabase(); - table = database.getSchema().getTable(tableName); - if (table == null) - { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - table.addField(FEATUREMAP_REVISION_ID, idType, idLength); - table.addField(LIST_REVISION_BRANCH, DBType.INTEGER); - table.addField(FEATUREMAP_VERSION_ADDED, DBType.INTEGER); - table.addField(FEATUREMAP_VERSION_REMOVED, DBType.INTEGER); - table.addField(FEATUREMAP_IDX, DBType.INTEGER); - table.addField(FEATUREMAP_TAG, idType, idLength); - - tagMap = CDOIDUtil.createMap(); - typeMappings = CDOIDUtil.createMap(); - columnNames = new ArrayList<>(); - - initTypeColumns(true); - - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_REVISION_ID); - table.addIndex(Type.NON_UNIQUE, LIST_REVISION_BRANCH); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_VERSION_ADDED); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_VERSION_REMOVED); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_IDX); - table.addIndex(Type.NON_UNIQUE, FEATUREMAP_TAG); - } - else - { - initTypeColumns(false); - } - } - - private void initTypeColumns(boolean create) - { - for (DBType type : getDBTypes()) - { - String column = FEATUREMAP_VALUE + "_" + type.name(); - if (create) - { - table.addField(column, type); - } - - columnNames.add(column); - } - } - - private void initSQLStrings() - { - String tableName = getTable().getName(); - - // ---------------- SELECT to read chunks ---------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - - builder.append(FEATUREMAP_IDX); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - builder.append(", "); //$NON-NLS-1$ - - Iterator<String> iter = columnNames.iterator(); - while (iter.hasNext()) - { - builder.append(iter.next()); - if (iter.hasNext()) - { - builder.append(", "); //$NON-NLS-1$ - } - } - - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL OR "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(">?)"); //$NON-NLS-1$ - sqlSelectChunksPrefix = builder.toString(); - - sqlOrderByIndex = " ORDER BY " + FEATUREMAP_IDX; //$NON-NLS-1$ - - // ----------------- INSERT - prefix ----------------- - builder = new StringBuilder("INSERT INTO "); //$NON-NLS-1$ - builder.append(tableName); - builder.append("("); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append(", "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - - for (int i = 0; i < columnNames.size(); i++) - { - builder.append(", "); //$NON-NLS-1$ - builder.append(columnNames.get(i)); - } - - builder.append(") VALUES (?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ - for (int i = 0; i < columnNames.size(); i++) - { - builder.append(", ?"); //$NON-NLS-1$ - } - - builder.append(")"); //$NON-NLS-1$ - sqlInsert = builder.toString(); - - // ----------------- remove current entry ----------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append("=? "); //$NON-NLS-1$ - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlRemoveEntry = builder.toString(); - - // ----------------- delete temporary entry ----------------- - builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("=?"); //$NON-NLS-1$ - sqlDeleteEntry = builder.toString(); - - // ----------------- update index ----------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_ADDED); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=?"); //$NON-NLS-1$ - sqlUpdateIndex = builder.toString(); - - // ----------------- get current value ----------------- - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(FEATUREMAP_TAG); - builder.append(", "); //$NON-NLS-1$ - - iter = columnNames.iterator(); - while (iter.hasNext()) - { - builder.append(iter.next()); - if (iter.hasNext()) - { - builder.append(", "); //$NON-NLS-1$ - } - } - - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlGetValue = builder.toString(); - - // ----------- clear list items ------------------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(tableName); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append("=? "); //$NON-NLS-1$ - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_VERSION_REMOVED); - builder.append(" IS NULL"); //$NON-NLS-1$ - sqlClearList = builder.toString(); - } - - @Override - public Collection<IDBTable> getDBTables() - { - return Collections.singleton(table); - } - - protected List<DBType> getDBTypes() - { - return dbTypes; - } - - protected final IDBTable getTable() - { - return table; - } - - protected final List<String> getColumnNames() - { - return columnNames; - } - - protected final Map<CDOID, ITypeMapping> getTypeMappings() - { - return typeMappings; - } - - protected final Map<CDOID, String> getTagMap() - { - return tagMap; - } - - @Override - public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - MoveableList<Object> list = revision.getListOrNull(getFeature()); - if (list == null) - { - // Nothing to read take shortcut. - return; - } - - int valuesToRead = list.size(); - - if (listChunk != CDORevision.UNCHUNKED && listChunk < valuesToRead) - { - valuesToRead = listChunk; - } - - if (valuesToRead == 0) - { - // Nothing to read take shortcut. - return; - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values for feature {0}.{1} of {2}", getContainingClass().getName(), getFeature() //$NON-NLS-1$ - .getName(), revision); - } - - String sql = sqlSelectChunksPrefix + sqlOrderByIndex; - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.HIGH); - ResultSet resultSet = null; - - IStoreChunkReader baseReader = null; - - try - { - CDOID id = revision.getID(); - int branchID = revision.getBranch().getID(); - - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, branchID); - stmt.setInt(3, revision.getVersion()); - stmt.setInt(4, revision.getVersion()); - - stmt.setMaxRows(valuesToRead); // optimization - don't read unneeded rows. - - resultSet = stmt.executeQuery(); - - int currentIndex = 0; - - while (valuesToRead > 0 && resultSet.next()) - { - int index = resultSet.getInt(1); - if (index > currentIndex) - { - if (baseReader == null) - { - baseReader = createBaseChunkReader(accessor, id, branchID); - } - - baseReader.addRangedChunk(currentIndex, index); - if (TRACER.isEnabled()) - { - TRACER.format("Scheduling range {0}-{1} to be read from base revision", currentIndex, index); //$NON-NLS-1$ - } - - valuesToRead -= index - currentIndex; - currentIndex = index; - } - - CDOID tag = idHandler.getCDOID(resultSet, 2); - Object value = getTypeMapping(tag).readValue(resultSet); - if (TRACER.isEnabled()) - { - TRACER.format("Read value for index {0} from result set: {1}", currentIndex, value); //$NON-NLS-1$ - } - - list.set(currentIndex++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - valuesToRead--; - } - - if (valuesToRead > 0) - { - if (baseReader == null) - { - baseReader = createBaseChunkReader(accessor, id, branchID); - } - - baseReader.addRangedChunk(currentIndex, currentIndex + valuesToRead); - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - - if (baseReader != null) - { - if (TRACER.isEnabled()) - { - TRACER.format("Reading base revision chunks for featureMap {0}.{1} of {2} from base revision {3}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), revision, baseReader.getRevision()); - } - - List<Chunk> baseChunks = baseReader.executeRead(); - for (Chunk chunk : baseChunks) - { - int startIndex = chunk.getStartIndex(); - for (int i = 0; i < chunk.size(); i++) - { - list.set(startIndex + i, chunk.get(i)); - } - } - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list values done for feature {0}.{1} of {2}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature().getName(), revision); - } - } - - @Override - public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where) - { - CDORevision revision = chunkReader.getRevision(); - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values for feature {0}.{1} of {2}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature().getName(), revision); - } - - StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix); - if (where != null) - { - builder.append(" AND "); //$NON-NLS-1$ - builder.append(where); - } - - builder.append(sqlOrderByIndex); - String sql = builder.toString(); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = chunkReader.getAccessor().getDBConnection().prepareStatement(sql, ReuseProbability.LOW); - ResultSet resultSet = null; - IStoreChunkReader baseReader = null; - - try - { - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getBranch().getID()); - stmt.setInt(3, revision.getVersion()); - stmt.setInt(4, revision.getVersion()); - - resultSet = stmt.executeQuery(); - - int nextDBIndex = Integer.MAX_VALUE; // next available DB index - if (resultSet.next()) - { - nextDBIndex = resultSet.getInt(1); - } - - for (Chunk chunk : chunks) - { - int startIndex = chunk.getStartIndex(); - int missingValueStartIndex = -1; - - for (int i = 0; i < chunk.size(); i++) - { - int nextListIndex = startIndex + i; // next expected list index - - if (nextDBIndex == nextListIndex) - { - // DB value is available. check first if missing indexes were present before. - if (missingValueStartIndex != -1) - { - // read missing indexes from missingValueStartIndex to currentIndex - if (baseReader == null) - { - baseReader = createBaseChunkReader(chunkReader.getAccessor(), chunkReader.getRevision().getID(), chunkReader.getRevision().getBranch().getID()); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Scheduling range {0}-{1} to be read from base revision", missingValueStartIndex, //$NON-NLS-1$ - nextListIndex); - } - - baseReader.addRangedChunk(missingValueStartIndex, nextListIndex); - - // reset missingValueStartIndex - missingValueStartIndex = -1; - } - - // now read value and set to chunk - CDOID tag = idHandler.getCDOID(resultSet, 2); - Object value = getTypeMapping(tag).readValue(resultSet); - if (TRACER.isEnabled()) - { - TRACER.format("ChunkReader read value for index {0} from result set: {1}", nextDBIndex, value); //$NON-NLS-1$ - } - - chunk.add(i, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); - - // advance DB cursor and read next available index - if (resultSet.next()) - { - nextDBIndex = resultSet.getInt(1); - } - else - { - // no more DB indexes available, but we have to continue checking for gaps, therefore set to MAX_VALUE - nextDBIndex = Integer.MAX_VALUE; - } - } - else - { - // gap between next DB index and next list index detected. - // skip until end of chunk or until DB value becomes available - if (missingValueStartIndex == -1) - { - missingValueStartIndex = nextListIndex; - } - } - } - - // chunk complete. check for missing values at the end of the chunk. - if (missingValueStartIndex != -1) - { - // read missing indexes from missingValueStartIndex to last chunk index - if (baseReader == null) - { - baseReader = createBaseChunkReader(chunkReader.getAccessor(), chunkReader.getRevision().getID(), chunkReader.getRevision().getBranch().getID()); - } - baseReader.addRangedChunk(missingValueStartIndex, chunk.getStartIndex() + chunk.size()); - } - } - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - - // now read missing values from base revision. - if (baseReader != null) - { - List<Chunk> baseChunks = baseReader.executeRead(); - - Iterator<Chunk> thisIterator = chunks.iterator(); - Chunk thisChunk = thisIterator.next(); - - for (Chunk baseChunk : baseChunks) - { - int baseStartIndex = baseChunk.getStartIndex(); - - while (baseStartIndex > thisChunk.getStartIndex() + thisChunk.size()) - { - // advance thisChunk, because it does not match baseChunk - thisChunk = thisIterator.next(); - } - - // baseChunk now corresponds to this chunk, but startIndex of baseChunk may be higher. - // therefore calculate offset - int offset = thisChunk.getStartIndex() - baseStartIndex; - - // and copy values. - for (int i = 0; i < baseChunk.size(); i++) - { - thisChunk.add(i + offset, baseChunk.get(i)); - } - } // finally, continue with the next baseChunk - - } - - if (TRACER.isEnabled()) - { - TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature(), revision); - } - } - - @Override - public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) - { - CDOList values = revision.getListOrNull(getFeature()); - if (values != null) - { - int idx = 0; - for (Object element : values) - { - writeValue(accessor, revision, idx++, element); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ - } - } - } - - protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value) - { - if (TRACER.isEnabled()) - { - TRACER.format("Writing value for feature {0}.{1} index {2} of {3} : {4}", getContainingClass().getName(), //$NON-NLS-1$ - getFeature(), idx, revision, value); - } - - addEntry(accessor, revision.getID(), revision.getBranch().getID(), revision.getVersion(), idx, value, revision.getTimeStamp()); - } - - /** - * Get column name (lazy). - * - * @param tag - * The feature's MetaID in CDO - * @return the column name where the values are stored - */ - protected String getColumnName(CDOID tag) - { - String column = tagMap.get(tag); - if (column == null) - { - addFeature(tag); - column = tagMap.get(tag); - } - - return column; - } - - /** - * Get type mapping (lazy). - * - * @param tag - * The feature's MetaID in CDO - * @return the corresponding type mapping - */ - protected ITypeMapping getTypeMapping(CDOID tag) - { - ITypeMapping typeMapping = typeMappings.get(tag); - if (typeMapping == null) - { - addFeature(tag); - typeMapping = typeMappings.get(tag); - } - - return typeMapping; - } - - private void addFeature(CDOID tag) - { - EStructuralFeature modelFeature = getFeatureByTag(tag); - - ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature); - String column = FEATUREMAP_VALUE + "_" + typeMapping.getDBType(); //$NON-NLS-1$ - - tagMap.put(tag, column); - typeMapping.setDBField(table, column); - typeMappings.put(tag, typeMapping); - } - - /** - * @param metaID - * @return the column name where the values are stored - */ - private EStructuralFeature getFeatureByTag(CDOID tag) - { - return (EStructuralFeature)getMappingStrategy().getStore().getMetaDataManager().getMetaInstance(tag); - } - - /** - * @param feature - * The EStructuralFeature - * @return The feature's MetaID in CDO - */ - protected CDOID getTagByFeature(EStructuralFeature feature, long created) - { - return getMappingStrategy().getStore().getMetaDataManager().getMetaID(feature, created); - } - - /** - * Clear a list of a given revision. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision from which to remove all items - */ - public void clearList(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, int lastIndex, long timestamp) - { - // check for each index if the value exists in the current branch - for (int i = 0; i <= lastIndex; i++) - { - if (getValue(accessor, id, branchId, i, false) == null) - { - // if not, add a historic entry for missing ones. - addHistoricEntry(accessor, id, branchId, 0, newVersion, i, getValueFromBase(accessor, id, branchId, i), timestamp); - } - } - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClearList, ReuseProbability.HIGH); - - try - { - // clear rest of the list - stmt.setInt(1, newVersion); - idHandler.setCDOID(stmt, 2, id); - stmt.setInt(3, branchId); - - int result = DBUtil.update(stmt, false); - if (TRACER.isEnabled()) - { - TRACER.format("ClearList result: {0}", result); //$NON-NLS-1$ - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) - { - InternalCDORevision revision = (InternalCDORevision)accessor.getTransaction().getRevision(id); - int branchId = accessor.getTransaction().getBranch().getID(); - - if (TRACER.isEnabled()) - { - TRACER.format("objectDetached {1}", revision); //$NON-NLS-1$ - } - - clearList(accessor, id, branchId, revision.getVersion(), FINAL_VERSION, revision.size(getFeature()) - 1, revised); - } - - @Override - public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) - { - throw new UnsupportedOperationException("Raw deletion does not work in range-based mappings"); - } - - @Override - public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion, final int newVersion, long created, - CDOListFeatureDelta delta) - { - List<CDOFeatureDelta> listChanges = delta.getListChanges(); - if (listChanges.size() == 0) - { - // nothing to do. - return; - } - - InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id); - int oldListSize = originalRevision.size(getFeature()); - - if (TRACER.isEnabled()) - { - TRACER.format("ListTableMapping.processDelta for revision {0} - previous list size: {1}", originalRevision, //$NON-NLS-1$ - oldListSize); - } - - // let the visitor collect the changes - ListDeltaVisitor visitor = new ListDeltaVisitor(accessor, originalRevision, branchId, oldVersion, newVersion, created); - - if (TRACER.isEnabled()) - { - TRACER.format("Processing deltas..."); //$NON-NLS-1$ - } - - // 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 = listChanges.size() - 1; - while (index > 0) - { - CDOFeatureDelta listDelta = listChanges.get(index); - if (listDelta instanceof CDOClearFeatureDelta || listDelta instanceof CDOUnsetFeatureDelta) - { - break; - } - index--; - } - while (index < listChanges.size()) - { - listChanges.get(index++).accept(visitor); - } - } - - private class ListDeltaVisitor implements CDOFeatureDeltaVisitor - { - private IDBStoreAccessor accessor; - - private InternalCDORevision originalRevision; - - private CDOID id; - - private int branchID; - - private int oldVersion; - - private int newVersion; - - private int lastIndex; - - private long timestamp; - - public ListDeltaVisitor(IDBStoreAccessor accessor, InternalCDORevision originalRevision, int targetBranchID, int oldVersion, int newVersion, long timestamp) - { - this.accessor = accessor; - this.originalRevision = originalRevision; - id = this.originalRevision.getID(); - branchID = targetBranchID; - this.oldVersion = oldVersion; - this.newVersion = newVersion; - lastIndex = originalRevision.size(getFeature()) - 1; - this.timestamp = timestamp; - } - - @Override - public void visit(CDOMoveFeatureDelta delta) - { - int fromIdx = delta.getOldPosition(); - int toIdx = delta.getNewPosition(); - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Moving: {0} to {1}", fromIdx, toIdx); //$NON-NLS-1$ - } - - Object value = getValue(accessor, id, branchID, fromIdx, true); - - // remove the item - removeEntry(accessor, id, branchID, oldVersion, newVersion, fromIdx, timestamp); - - // adjust indexes and shift either up or down - if (fromIdx < toIdx) - { - moveOneUp(accessor, id, branchID, oldVersion, newVersion, fromIdx + 1, toIdx); - } - else - { // fromIdx > toIdx here - moveOneDown(accessor, id, branchID, oldVersion, newVersion, toIdx, fromIdx - 1); - } - - // create the item - addEntry(accessor, id, branchID, newVersion, toIdx, value, timestamp); - } - - @Override - public void visit(CDOAddFeatureDelta delta) - { - int startIndex = delta.getIndex(); - int endIndex = lastIndex; - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Adding at: {0}", startIndex); //$NON-NLS-1$ - } - - if (startIndex <= endIndex) - { - // make room for the new item - moveOneDown(accessor, id, branchID, oldVersion, newVersion, startIndex, endIndex); - } - - // create the item - addEntry(accessor, id, branchID, newVersion, startIndex, delta.getValue(), timestamp); - - ++lastIndex; - } - - @Override - public void visit(CDORemoveFeatureDelta delta) - { - int startIndex = delta.getIndex(); - int endIndex = lastIndex; - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Removing at: {0}", startIndex); //$NON-NLS-1$ - } - - // remove the item - removeEntry(accessor, id, branchID, oldVersion, newVersion, startIndex, timestamp); - - // make room for the new item - moveOneUp(accessor, id, branchID, oldVersion, newVersion, startIndex + 1, endIndex); - - --lastIndex; - } - - @Override - public void visit(CDOSetFeatureDelta delta) - { - int index = delta.getIndex(); - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Setting at: {0}", index); //$NON-NLS-1$ - } - - // remove the item - removeEntry(accessor, id, branchID, oldVersion, newVersion, index, timestamp); - - // create the item - addEntry(accessor, id, branchID, newVersion, index, delta.getValue(), timestamp); - } - - @Override - public void visit(CDOUnsetFeatureDelta delta) - { - if (delta.getFeature().isUnsettable()) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - if (TRACER.isEnabled()) - { - TRACER.format("Delta Unsetting"); //$NON-NLS-1$ - } - - clearList(accessor, id, branchID, oldVersion, newVersion, lastIndex, timestamp); - lastIndex = -1; - } - - @Override - public void visit(CDOListFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - @Override - public void visit(CDOClearFeatureDelta delta) - { - if (TRACER.isEnabled()) - { - TRACER.format("Delta Clearing"); //$NON-NLS-1$ - } - - clearList(accessor, id, branchID, oldVersion, newVersion, lastIndex, timestamp); - lastIndex = -1; - } - - @Override - public void visit(CDOContainerFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - private void moveOneUp(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, int startIndex, int endIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH); - - try - { - for (int index = startIndex; index <= endIndex; ++index) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp moving: {0} -> {1}", index, index - 1); //$NON-NLS-1$ - } - - int column = 1; - stmt.setInt(column++, index - 1); - idHandler.setCDOID(stmt, startIndex++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, newVersion); - stmt.setInt(column++, index); - - int result = DBUtil.update(stmt, false); - switch (result) - { - case 1: - // entry for current revision was already present. - // index update succeeded. - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp updated: {0} -> {1}", index, index - 1); //$NON-NLS-1$ - } - - break; - case 0: - Object value = getValue(accessor, id, branchId, index, false); - - if (value != null) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp remove: {0}", index); //$NON-NLS-1$ - } - - removeEntry(accessor, id, branchId, oldVersion, newVersion, index, timestamp); - } - else - { - value = getValueFromBase(accessor, id, branchId, index); - { - TRACER.format("moveOneUp add historic entry at: {0}", index); //$NON-NLS-1$ - } - - addHistoricEntry(accessor, id, branchId, 0, newVersion, index, value, timestamp); - } - - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp add: {0}", index - 1); //$NON-NLS-1$ - } - - addEntry(accessor, id, branchId, newVersion, index - 1, value, timestamp); - break; - default: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneUp Too many results: {0} -> {1}: {2}", index, index + 1, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void moveOneDown(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, int startIndex, int endIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH); - - try - { - for (int index = endIndex; index >= startIndex; --index) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown moving: {0} -> {1}", index, index + 1); //$NON-NLS-1$ - } - - int column = 1; - stmt.setInt(column++, index + 1); - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, newVersion); - stmt.setInt(column++, index); - - int result = DBUtil.update(stmt, false); - switch (result) - { - case 1: - // entry for current revision was already present. - // index update succeeded. - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown updated: {0} -> {1}", index, index + 1); //$NON-NLS-1$ - } - - break; - case 0: - Object value = getValue(accessor, id, branchId, index, false); - if (value != null) - { - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown remove: {0}", index); //$NON-NLS-1$ - } - - removeEntry(accessor, id, branchId, oldVersion, newVersion, index, timestamp); - } - else - { - value = getValueFromBase(accessor, id, branchId, index); - { - TRACER.format("moveOneDown add historic entry at: {0}", index); //$NON-NLS-1$ - } - - addHistoricEntry(accessor, id, branchId, 0, newVersion, index, value, timestamp); - } - - addEntry(accessor, id, branchId, newVersion, index + 1, value, timestamp); - break; - default: - if (TRACER.isEnabled()) - { - TRACER.format("moveOneDown Too many results: {0} -> {1}: {2}", index, index + 1, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - } - - private void addEntry(IDBStoreAccessor accessor, CDOID id, int branchId, int version, int index, Object value, long timestamp) - { - if (TRACER.isEnabled()) - { - TRACER.format("Adding value for feature() {0}.{1} index {2} of {3}v{4} : {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, version, value); - } - - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, timestamp); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.HIGH); - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, version); - stmt.setNull(column++, DBType.INTEGER.getCode()); // versionRemoved - stmt.setInt(column++, index); - idHandler.setCDOID(stmt, column++, tag); - - for (int i = 0; i < columnNames.size(); i++) - { - if (columnNames.get(i).equals(columnName)) - { - getTypeMapping(tag).setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - catch (IllegalStateException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void addHistoricEntry(IDBStoreAccessor accessor, CDOID id, int branchId, int versionAdded, int versionRemoved, int index, Object value, - long timestamp) - { - if (TRACER.isEnabled()) - { - TRACER.format("Adding historic value for feature {0}.{1} index {2} of {3}:{4}v{5}-v{6} : {7}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, branchId, versionAdded, versionRemoved, value); - } - - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, timestamp); - ITypeMapping typeMapping = getTypeMapping(tag); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.HIGH); - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, versionAdded); - stmt.setNull(column++, versionRemoved); - stmt.setInt(column++, index); - idHandler.setCDOID(stmt, column++, tag); - - for (int i = 0; i < columnNames.size(); i++) - { - if (columnNames.get(i).equals(columnName)) - { - typeMapping.setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - catch (IllegalStateException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void removeEntry(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, int index, long timestamp) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion); - } - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDeleteEntry, ReuseProbability.HIGH); - - try - { - // try to delete a temporary entry first - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, index); - stmt.setInt(column++, newVersion); - - int result = DBUtil.update(stmt, false); - if (result == 1) - { - if (TRACER.isEnabled()) - { - TRACER.format("removeEntry deleted: {0}", index); //$NON-NLS-1$ - } - } - else if (result > 1) - { - if (TRACER.isEnabled()) - { - TRACER.format("removeEntry Too many results: {0}: {1}", index, result); //$NON-NLS-1$ - } - - throw new DBException("Too many results"); //$NON-NLS-1$ - } - else - { - // no temporary entry found, so mark the entry as removed - DBUtil.close(stmt); - stmt = accessor.getDBConnection().prepareStatement(sqlRemoveEntry, ReuseProbability.HIGH); - - column = 1; - stmt.setInt(column++, newVersion); - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, index); - result = DBUtil.update(stmt, false); - - if (result == 0) - { - // no entry removed -> this means that we are in a branch and - // the entry has not been modified since the branch fork. - // therefore, we have to copy the base value and mark it as removed - Object value = getValueFromBase(accessor, id, branchId, index); - addHistoricEntry(accessor, id, branchId, 0, newVersion, index, value, timestamp); - } - } - } - catch (SQLException e) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage()); - } - - throw new DBException(e); - } - catch (IllegalStateException e) - { - if (TRACER.isEnabled()) - { - TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$ - getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage()); - } - - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private FeatureMap.Entry getValue(IDBStoreAccessor accessor, CDOID id, int branchId, int index, boolean getFromBase) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlGetValue, ReuseProbability.HIGH); - FeatureMap.Entry result = null; - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, branchId); - stmt.setInt(column++, index); - - ResultSet resultSet = stmt.executeQuery(); - if (resultSet.next()) - { - CDOID tag = idHandler.getCDOID(resultSet, 1); - Object value = getTypeMapping(tag).readValue(resultSet); - result = CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value); - } - else - { - // value is not in this branch. - // -> read from base revision - if (getFromBase) - { - result = getValueFromBase(accessor, id, branchId, index); - } // else: result remains null - } - if (TRACER.isEnabled()) - { - TRACER.format("Read value (index {0}) from result set: {1}", index, result); //$NON-NLS-1$ - } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - - return result; - } - - /** - * Read a single value (at a given index) from the base revision - * - * @param accessor - * the DBStoreAccessor - * @param id - * the ID of the revision - * @param branchID - * the ID of the current (child) branch - * @param index - * the index to read the value from - * @return the value which is at index <code>index</code> in revision with ID <code>id</code> in the parent branch at - * the base of this branch (indicated by <code>branchID</code>). - */ - private FeatureMap.Entry getValueFromBase(IDBStoreAccessor accessor, CDOID id, int branchID, int index) - { - IStoreChunkReader chunkReader = createBaseChunkReader(accessor, id, branchID); - chunkReader.addSimpleChunk(index); - List<Chunk> chunks = chunkReader.executeRead(); - return (FeatureMap.Entry)chunks.get(0).get(0); - } - - private IStoreChunkReader createBaseChunkReader(IDBStoreAccessor accessor, CDOID id, int branchID) - { - InternalRepository repository = (InternalRepository)accessor.getStore().getRepository(); - - CDOBranchManager branchManager = repository.getBranchManager(); - CDOBranch branch = branchManager.getBranch(branchID); - CDOBranchPoint base = branch.getBase(); - if (base.getBranch() == null) - { - throw new IllegalArgumentException("Base branch is null: " + branch); - } - - InternalCDORevisionManager revisionManager = repository.getRevisionManager(); - InternalCDORevision baseRevision = revisionManager.getRevision(id, base, 0, CDORevision.DEPTH_NONE, true); - - return accessor.createChunkReader(baseRevision, getFeature()); - } - - @Override - public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) - { - // must never be called (a feature map is not associated with an EReference feature, so XRefs are nor supported - // here) - throw new ImplementationError("Should never be called!"); - } -} 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 b8191d6ece..fa8a7bb75f 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 @@ -57,13 +57,6 @@ public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStr return new AuditListTableMapping(this, containingClass, feature); } - @Deprecated - @Override - public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - return new AuditFeatureMapTableMapping(this, containingClass, feature); - } - @Override public String getListJoin(String attrTable, String listTable) { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java index cb7330b329..757ab22ca5 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java @@ -46,13 +46,6 @@ public class HorizontalAuditMappingStrategyWithRanges extends HorizontalAuditMap return new AuditListTableMappingWithRanges(this, containingClass, feature); } - @Deprecated - @Override - public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - return new AuditFeatureMapTableMappingWithRanges(this, containingClass, feature); - } - @Override protected String modifyListJoin(String attrTable, String listTable, String join) { 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 index 8f7037457a..85b2224ea8 100644 --- 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 @@ -71,13 +71,6 @@ public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappin return new BranchingListTableMapping(this, containingClass, feature); } - @Deprecated - @Override - public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - return new BranchingFeatureMapTableMapping(this, containingClass, feature); - } - @Override public String getListJoin(String attrTable, String listTable) { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java index d4f08c69b3..fa987993e0 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java @@ -77,13 +77,6 @@ public class HorizontalBranchingMappingStrategyWithRanges extends HorizontalBran return new BranchingListTableMappingWithRanges(this, containingClass, feature); } - @Deprecated - @Override - public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - return new BranchingFeatureMapTableMappingWithRanges(this, containingClass, feature); - } - @Override protected void rawExportList(CDODataOutput out, IDBConnection connection, IListMapping listMapping, IDBTable attrTable, String attrSuffix) throws IOException { 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 5dd691400f..5f440fde3f 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 @@ -59,13 +59,6 @@ public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMapping return new NonAuditListTableMapping(this, containingClass, feature); } - @Deprecated - @Override - public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) - { - return new NonAuditFeatureMapTableMapping(this, containingClass, feature); - } - @Override protected IClassMapping doCreateClassMapping(EClass eClass) { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/IMappingConstants.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/IMappingConstants.java index be15895749..96d33a3290 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/IMappingConstants.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/IMappingConstants.java @@ -56,24 +56,4 @@ public interface IMappingConstants public static final String LIST_IDX = "CDO_IDX"; //$NON-NLS-1$ public static final String LIST_VALUE = "CDO_VALUE"; //$NON-NLS-1$ - - /* - * Field names of featuremap tables - */ - - public static final String FEATUREMAP_REVISION_ID = LIST_REVISION_ID; - - public static final String FEATUREMAP_VERSION = LIST_REVISION_VERSION; - - public static final String FEATUREMAP_VERSION_ADDED = LIST_REVISION_VERSION_ADDED; - - public static final String FEATUREMAP_VERSION_REMOVED = LIST_REVISION_VERSION_REMOVED; - - public static final String FEATUREMAP_BRANCH = LIST_REVISION_BRANCH; - - public static final String FEATUREMAP_IDX = LIST_IDX; - - public static final String FEATUREMAP_TAG = LIST_FEATURE; - - public static final String FEATUREMAP_VALUE = LIST_VALUE; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditFeatureMapTableMapping.java deleted file mode 100644 index ea7793847d..0000000000 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditFeatureMapTableMapping.java +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Copyright (c) 2009-2013, 2015, 2016, 2018, 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 - * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 - * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455 - * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy - */ -package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; - -import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; -import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; -import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta; -import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; -import org.eclipse.emf.cdo.server.db.IIDHandler; -import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport; -import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; -import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; - -import org.eclipse.net4j.db.DBException; -import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBPreparedStatement; -import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; -import org.eclipse.net4j.util.ImplementationError; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.FeatureMap; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Iterator; -import java.util.List; - -/** - * This is a featuremap-to-table mapping optimized for non-audit-mode. It doesn't care about version and has delta - * support. - * - * @author Eike Stepper - * @since 3.0 - * @deprecated As 4.5 feature maps are no longer supported. - */ -@Deprecated -public class NonAuditFeatureMapTableMapping extends AbstractFeatureMapTableMapping implements IListMappingDeltaSupport -{ - private static final int TEMP_INDEX = -1; - - private static final int UNBOUNDED_MOVE = -1; - - private String sqlClear; - - private String sqlUpdateIndex; - - private String sqlUpdateValue; - - private String sqlDeleteItem; - - private String sqlMoveDownWithLimit; - - private String sqlMoveDown; - - private String sqlMoveUpWithLimit; - - private String sqlMoveUp; - - public NonAuditFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) - { - super(mappingStrategy, eClass, feature); - initSQLStrings(); - } - - private void initSQLStrings() - { - // TODO: add key fields length support - - StringBuilder builder = new StringBuilder(); - - // ----------- clear list ------------------------- - - builder.append("DELETE FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? "); //$NON-NLS-1$ - - sqlClear = builder.toString(); - - builder.append(" AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? "); //$NON-NLS-1$ - - sqlDeleteItem = builder.toString(); - - // ----------- update one item index -------------- - builder = new StringBuilder(); - builder.append("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? "); //$NON-NLS-1$ - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? "); //$NON-NLS-1$ - sqlUpdateIndex = builder.toString(); - - // ----------- update one item value -------------- - builder = new StringBuilder(); - builder.append("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - - builder.append(FEATUREMAP_TAG); - builder.append("=?,"); //$NON-NLS-1$ - - Iterator<String> iter = getColumnNames().iterator(); - while (iter.hasNext()) - { - String column = iter.next(); - builder.append(column); - builder.append("=?"); //$NON-NLS-1$ - - if (iter.hasNext()) - { - builder.append(", "); //$NON-NLS-1$ - } - } - - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("=? "); //$NON-NLS-1$ - sqlUpdateValue = builder.toString(); - - // ----------- move down -------------- - builder = new StringBuilder(); - builder.append("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("="); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("-1 WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append(">? "); //$NON-NLS-1$ - sqlMoveDown = builder.toString(); - - builder.append(" AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("<=?"); //$NON-NLS-1$ - sqlMoveDownWithLimit = builder.toString(); - - // ----------- move up -------------- - builder = new StringBuilder(); - builder.append("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("="); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("+1 WHERE "); //$NON-NLS-1$ - builder.append(FEATUREMAP_REVISION_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append(">=? "); //$NON-NLS-1$ - sqlMoveUp = builder.toString(); - - builder.append(" AND "); //$NON-NLS-1$ - builder.append(FEATUREMAP_IDX); - builder.append("<?"); //$NON-NLS-1$ - sqlMoveUpWithLimit = builder.toString(); - } - - @Override - protected void addKeyFields(List<FieldInfo> list) - { - // Do nothing - } - - @Override - protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException - { - getMappingStrategy().getStore().getIDHandler().setCDOID(stmt, 1, revision.getID()); - } - - @Override - public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) - { - clearList(accessor, id); - } - - /** - * Clear a list of a given revision. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision from which to remove all items - */ - public void clearList(IDBStoreAccessor accessor, CDOID id) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) - { - clearList(accessor, id); - } - - /** - * Insert a list item at a specified position. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision to insert the value - * @param index - * the index where to insert the element - * @param value - * the value to insert. - */ - public void insertListItem(IDBStoreAccessor accessor, CDOID id, int index, Object value, long timestamp) - { - move1up(accessor, id, index, UNBOUNDED_MOVE); - insertValue(accessor, id, index, value, timestamp); - } - - private void insertValue(IDBStoreAccessor accessor, CDOID id, int index, Object value, long timestamp) - { - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, timestamp); - ITypeMapping typeMapping = getTypeMapping(tag); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - int column = getKeyFields().length + 1; - - for (int i = 0; i < getColumnNames().size(); i++) - { - if (getColumnNames().get(i).equals(columnName)) - { - typeMapping.setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - stmt.setInt(column++, index); - idHandler.setCDOID(stmt, column++, tag); - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - /** - * Move a list item from one position to another. Indices between both positions are updated so that the list remains - * consistent. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision in which to move the item - * @param oldPosition - * the old position of the item. - * @param newPosition - * the new position of the item. - */ - public void moveListItem(IDBStoreAccessor accessor, CDOID id, int oldPosition, int newPosition) - { - if (oldPosition == newPosition) - { - return; - } - - // move element away temporarily - updateOneIndex(accessor, id, oldPosition, TEMP_INDEX); - - // move elements in between - if (oldPosition < newPosition) - { - move1down(accessor, id, oldPosition, newPosition); - } - else - { - // oldPosition > newPosition -- equal case is handled above - move1up(accessor, id, newPosition, oldPosition); - } - - // move temporary element to new position - updateOneIndex(accessor, id, TEMP_INDEX, newPosition); - } - - private void updateOneIndex(IDBStoreAccessor accessor, CDOID id, int oldIndex, int newIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateIndex, ReuseProbability.HIGH); - - try - { - stmt.setInt(1, newIndex); - idHandler.setCDOID(stmt, 2, id); - stmt.setInt(3, oldIndex); - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - /** - * Remove a list item from a specified a position. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision from which to remove the item - * @param index - * the index of the item to remove - */ - public void removeListItem(IDBStoreAccessor accessor, CDOID id, int index) - { - deleteItem(accessor, id, index); - move1down(accessor, id, index, UNBOUNDED_MOVE); - } - - /** - * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with - * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down. - */ - private void move1down(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(upperIndex == UNBOUNDED_MOVE ? sqlMoveDown : sqlMoveDownWithLimit, - ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, index); - if (upperIndex != UNBOUNDED_MOVE) - { - stmt.setInt(3, upperIndex); - } - - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - /** - * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with - * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down. - */ - private void move1up(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(upperIndex == UNBOUNDED_MOVE ? sqlMoveUp : sqlMoveUpWithLimit, - ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, index); - if (upperIndex != UNBOUNDED_MOVE) - { - stmt.setInt(3, upperIndex); - } - - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - private void deleteItem(IDBStoreAccessor accessor, CDOID id, int index) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDeleteItem, ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, index); - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - /** - * Set a value at a specified position to the given value. - * - * @param accessor - * the accessor to use - * @param id - * the id of the revision to set the value - * @param index - * the index of the item to set - * @param value - * the value to be set. - */ - public void setListItem(IDBStoreAccessor accessor, CDOID id, int index, Object value, long timestamp) - { - FeatureMap.Entry entry = (FeatureMap.Entry)value; - EStructuralFeature entryFeature = entry.getEStructuralFeature(); - CDOID tag = getTagByFeature(entryFeature, timestamp); - ITypeMapping mapping = getTypeMapping(tag); - String columnName = getColumnName(tag); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlUpdateValue, ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, tag); - int column = 2; - - for (int i = 0; i < getColumnNames().size(); i++) - { - if (getColumnNames().get(i).equals(columnName)) - { - mapping.setValue(stmt, column++, entry.getValue()); - } - else - { - stmt.setNull(column++, getDBTypes().get(i).getCode()); - } - } - - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, index); - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion, final int newVersion, final long created, - CDOListFeatureDelta listDelta) - { - CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitor() - { - @Override - public void visit(CDOMoveFeatureDelta delta) - { - moveListItem(accessor, id, delta.getOldPosition(), delta.getNewPosition()); - } - - @Override - public void visit(CDOAddFeatureDelta delta) - { - insertListItem(accessor, id, delta.getIndex(), delta.getValue(), created); - } - - @Override - public void visit(CDORemoveFeatureDelta delta) - { - removeListItem(accessor, id, delta.getIndex()); - } - - @Override - public void visit(CDOSetFeatureDelta delta) - { - setListItem(accessor, id, delta.getIndex(), delta.getValue(), created); - } - - @Override - public void visit(CDOUnsetFeatureDelta delta) - { - if (delta.getFeature().isUnsettable()) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - clearList(accessor, id); - } - - @Override - public void visit(CDOListFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - - @Override - public void visit(CDOClearFeatureDelta delta) - { - clearList(accessor, id); - } - - @Override - public void visit(CDOContainerFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - }; - - for (CDOFeatureDelta delta : listDelta.getListChanges()) - { - delta.accept(visitor); - } - } -} |