Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2020-04-11 06:14:52 +0000
committerEike Stepper2020-04-11 06:14:52 +0000
commita15e3037b02b0066d7dfe47e52430249bce07448 (patch)
tree9d426b0a21cb329eb20258cf369de420fba5f870 /plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db
parent595f4da41f3e034916d3071ffd88d66ed59ad288 (diff)
downloadcdo-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')
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java605
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMapping.java108
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java1218
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMapping.java112
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java1511
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/IMappingConstants.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditFeatureMapTableMapping.java583
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);
- }
- }
-}

Back to the top