diff options
author | Eike Stepper | 2018-05-02 11:27:46 +0000 |
---|---|---|
committer | Eike Stepper | 2018-05-02 11:27:46 +0000 |
commit | 52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62 (patch) | |
tree | e244ba54a213cd4118b453a16aa2b156cb62c824 /plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo | |
parent | b1cf5c385c916946ea044f0325b74b3907c262ed (diff) | |
download | cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.tar.gz cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.tar.xz cdo-52a62ab5e7e7d8aff1e482a32a453fe67ff3bf62.zip |
[534254] [DB] Create all mapped tables lazily
https://bugs.eclipse.org/bugs/show_bug.cgi?id=534254
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo')
16 files changed, 627 insertions, 411 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java index 3f158fccab..5ea040bfd9 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java @@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.server.IStoreAccessor; import org.eclipse.emf.cdo.server.IStoreAccessor.UnitSupport; import org.eclipse.net4j.db.IDBConnection; +import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.emf.ecore.EClass; @@ -49,4 +50,9 @@ public interface IDBStoreAccessor extends IStoreAccessor.Raw2, UnitSupport */ @Deprecated public IPreparedStatementCache getStatementCache(); + + /** + * @since 4.6 + */ + public void tableCreated(IDBTable table); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java index 111a561b05..9e96dbfc52 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java @@ -33,6 +33,7 @@ import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; import java.io.IOException; @@ -431,5 +432,12 @@ public interface IMappingStrategy * Name of a String property that specifies the name of a {@link ColumnTypeModifier column type modifier}. */ public static final String COLUMN_TYPE_MODIFIER = "columnTypeModifier"; //$NON-NLS-1$ + + /** + * Name of a boolean property that configures whether all tables for a {@link EPackage package} are created eagerly. + * + * @since 4.6 + */ + public static final String EAGER_TABLE_CREATION = "eagerTableCreation"; //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java index 01d50f44b3..2dc3271642 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java @@ -72,8 +72,11 @@ import org.eclipse.net4j.db.BatchedStatement; import org.eclipse.net4j.db.DBException; import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.IDBConnection; +import org.eclipse.net4j.db.IDBDatabase; import org.eclipse.net4j.db.IDBPreparedStatement; import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; +import org.eclipse.net4j.db.IDBSchemaTransaction; +import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.internal.db.ddl.DBField; import org.eclipse.net4j.util.HexUtil; import org.eclipse.net4j.util.ObjectUtil; @@ -126,6 +129,8 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, private InternalObjectAttacher objectAttacher; + private List<IDBTable> createdTables; + public DBStoreAccessor(DBStore store, ISession session) throws DBException { super(store, session); @@ -786,7 +791,9 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, objectAttacher = null; } - getStore().getMetaDataManager().clearMetaIDMappings(); + IDBStore store = getStore(); + IMetaDataManager metaDataManager = store.getMetaDataManager(); + metaDataManager.clearMetaIDMappings(); if (TRACER.isEnabled()) { @@ -795,10 +802,31 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, try { - getConnection().rollback(); + connection.rollback(); // Bug 298632: Must rollback DBSchema to its prior state and drop the tables - getStore().getMappingStrategy().removeMapping(getConnection(), commitContext.getNewPackageUnits()); + IMappingStrategy mappingStrategy = store.getMappingStrategy(); + mappingStrategy.removeMapping(connection, commitContext.getNewPackageUnits()); + + if (createdTables != null) + { + IDBDatabase database = store.getDatabase(); + IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); + + try + { + for (IDBTable table : createdTables) + { + table.remove(); + } + + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } + } } catch (SQLException ex) { @@ -848,6 +876,12 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, // this is called when the accessor is put back into the pool // we want to make sure that no DB lock is held (see Bug 276926) getConnection().rollback(); + + if (createdTables != null) + { + createdTables.clear(); + createdTables = null; + } } @Override @@ -1204,7 +1238,17 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, // rawImportPackageUnits(in, fromCommitTime, toCommitTime, packageUnits, monitor.fork()); - mappingStrategy.rawImport(this, in, fromCommitTime, toCommitTime, monitor.fork(size)); + IDBSchemaTransaction schemaTransaction = store.getDatabase().openSchemaTransaction(); + + try + { + mappingStrategy.rawImport(this, in, fromCommitTime, toCommitTime, monitor.fork(size)); + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } rawCommit(commitWork, monitor); } @@ -1464,6 +1508,16 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, unitMappingTable.writeUnitMappings(this, unitMappings, timeStamp); } + public void tableCreated(IDBTable table) + { + if (createdTables == null) + { + createdTables = new ArrayList<IDBTable>(); + } + + createdTables.add(table); + } + /** * @author Stefan Winkler */ 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 3c88814253..3fc5999933 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 @@ -21,13 +21,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.model.CDOFeatureType; -import org.eclipse.emf.cdo.common.model.CDOModelUtil; -import org.eclipse.emf.cdo.common.model.CDOPackageRegistry; -import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.model.EMFUtil; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; -import org.eclipse.emf.cdo.eresource.EresourcePackage; -import org.eclipse.emf.cdo.etypes.EtypesPackage; import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.IDBStore; @@ -48,12 +43,10 @@ import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.net4j.db.DBException; import org.eclipse.net4j.db.DBUtil; -import org.eclipse.net4j.db.IDBSchemaTransaction; import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.StringUtil; -import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; @@ -67,24 +60,19 @@ 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.EcorePackage; import org.eclipse.emf.ecore.util.FeatureMapUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Semaphore; /** * This abstract base class implements those methods which are most likely common to most mapping strategies. It can be @@ -123,8 +111,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp private boolean allClassMappingsCreated; - private SystemPackageMappingInfo systemPackageMappingInfo; - private Set<CDOFeatureType> forceIndexes; public AbstractMappingStrategy() @@ -149,31 +135,31 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp this.properties = properties; } - private int getMaxTableNameLength() + public int getMaxTableNameLength() { String value = getProperties().get(Props.MAX_TABLE_NAME_LENGTH); return value == null ? store.getDBAdapter().getMaxTableNameLength() : Integer.valueOf(value); } - private int getMaxFieldNameLength() + public int getMaxFieldNameLength() { String value = getProperties().get(Props.MAX_FIELD_NAME_LENGTH); return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value); } - private boolean isQualifiedNames() + public boolean isQualifiedNames() { String value = getProperties().get(Props.QUALIFIED_NAMES); return value == null ? false : Boolean.valueOf(value); } - private boolean isForceNamesWithID() + public boolean isForceNamesWithID() { String value = getProperties().get(Props.FORCE_NAMES_WITH_ID); return value == null ? false : Boolean.valueOf(value); } - private String getTableNamePrefix() + public String getTableNamePrefix() { String value = getProperties().get(Props.TABLE_NAME_PREFIX); return StringUtil.safe(value); @@ -221,25 +207,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp } else { - EPackage ePackage = eClass.getEPackage(); - if (CDOModelUtil.isCorePackage(ePackage)) - { - initSystemPackageMappingInfo(); - if (!systemPackageMappingInfo.ecoreMapped) - { - return; - } - } - - if (CDOModelUtil.isTypesPackage(ePackage)) - { - initSystemPackageMappingInfo(); - if (!systemPackageMappingInfo.etypesMapped) - { - return; - } - } - IClassMapping classMapping = getClassMapping(eClass); classMapping.handleRevisions(accessor, branch, timeStamp, exactTime, handler); } @@ -493,92 +460,18 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp return builder.toString(); } - // -- factories for mapping of classes, values, lists ------------------ - public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) { - boolean passedPackageUnits = packageUnits != null && packageUnits.length != 0; - Semaphore packageRegistryCommitLock = null; - boolean ecoreNew = false; - boolean etypesNew = false; - - Async async = null; monitor.begin(); + Async async = null; try { - async = monitor.forkAsync(); - - boolean isInitialCommit = passedPackageUnits && containsPackageUnit(packageUnits, EresourcePackage.eINSTANCE.getNsURI()); - if (isInitialCommit) - { - systemPackageMappingInfo = new SystemPackageMappingInfo(); - } - else - { - CommitContext commitContext = StoreThreadLocal.getCommitContext(); - if (commitContext != null && (commitContext.isUsingEcore() || commitContext.isUsingEtypes())) - { - InternalRepository repository = (InternalRepository)store.getRepository(); - if (!passedPackageUnits) - { - try - { - packageRegistryCommitLock = repository.getPackageRegistryCommitLock(); - packageRegistryCommitLock.acquire(); - } - catch (InterruptedException ex) - { - throw WrappedException.wrap(ex); - } - } - - initSystemPackageMappingInfo(); - - if (!systemPackageMappingInfo.ecoreMapped || !systemPackageMappingInfo.etypesMapped) - { - CDOPackageRegistry packageRegistry = repository.getPackageRegistry(); - List<InternalCDOPackageUnit> extendedPackageUnits = new ArrayList<InternalCDOPackageUnit>(); - if (passedPackageUnits) - { - extendedPackageUnits.addAll(Arrays.asList(packageUnits)); - } - - if (!systemPackageMappingInfo.ecoreMapped && commitContext.isUsingEcore()) - { - CDOPackageUnit packageUnit = packageRegistry.getPackageUnit(EcorePackage.eINSTANCE); - extendedPackageUnits.add((InternalCDOPackageUnit)packageUnit); - ecoreNew = true; - } - - if (!systemPackageMappingInfo.etypesMapped && commitContext.isUsingEtypes()) - { - CDOPackageUnit packageUnit = packageRegistry.getPackageUnit(EtypesPackage.eINSTANCE); - extendedPackageUnits.add((InternalCDOPackageUnit)packageUnit); - etypesNew = true; - } - - if (ecoreNew || etypesNew) - { - packageUnits = extendedPackageUnits.toArray(new InternalCDOPackageUnit[extendedPackageUnits.size()]); - } - } - } - } - if (packageUnits != null && packageUnits.length != 0) { - IDBSchemaTransaction schemaTransaction = store.getDatabase().openSchemaTransaction(); + async = monitor.forkAsync(); - try - { - mapPackageUnits(packageUnits, connection, false); - schemaTransaction.commit(); - } - finally - { - schemaTransaction.close(); - } + mapPackageUnits(packageUnits, connection, false); } } finally @@ -588,46 +481,13 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp async.stop(); } - if (packageRegistryCommitLock != null) - { - systemPackageMappingInfo.ecoreMapped |= ecoreNew; - systemPackageMappingInfo.etypesMapped |= etypesNew; - packageRegistryCommitLock.release(); - } - monitor.done(); } } - private void initSystemPackageMappingInfo() - { - if (systemPackageMappingInfo == null) - { - systemPackageMappingInfo = new SystemPackageMappingInfo(); - systemPackageMappingInfo.ecoreMapped = hasTableFor(EcorePackage.eINSTANCE.getEPackage()); - systemPackageMappingInfo.etypesMapped = hasTableFor(EtypesPackage.eINSTANCE.getAnnotation()); - } - } - public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits) { - IDBSchemaTransaction schemaTransaction = store.getDatabase().openSchemaTransaction(); - - try - { - mapPackageUnits(packageUnits, connection, true); - schemaTransaction.commit(); - } - finally - { - schemaTransaction.close(); - } - } - - private boolean hasTableFor(EClass eClass) - { - String tableName = getTableName(eClass); - return store.getDBSchema().getTable(tableName) != null; + mapPackageUnits(packageUnits, connection, true); } protected Set<IClassMapping> mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap) @@ -837,19 +697,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp } } - private static boolean containsPackageUnit(InternalCDOPackageUnit[] packageUnits, String packageUnitID) - { - for (InternalCDOPackageUnit packageUnit : packageUnits) - { - if (packageUnit.getID().equals(packageUnitID)) - { - return true; - } - } - - return false; - } - private static Set<CDOFeatureType> doGetForceIndexes(IMappingStrategy mappingStrategy) { return CDOFeatureType.readCombination(mappingStrategy.getProperties().get(Props.FORCE_INDEXES)); @@ -865,13 +712,9 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp return doGetForceIndexes(mappingStrategy); } - /** - * @author Eike Stepper - */ - private static final class SystemPackageMappingInfo + public static boolean isEagerTableCreation(IMappingStrategy mappingStrategy) { - public boolean ecoreMapped; - - public boolean etypesMapped; + String value = mappingStrategy.getProperties().get(Props.EAGER_TABLE_CREATION); + return value == null ? false : Boolean.valueOf(value); } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java index c579cd8377..2f50b8e20b 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java @@ -12,6 +12,8 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.CDOFeatureType; +import org.eclipse.emf.cdo.common.model.CDOModelUtil; 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; @@ -28,7 +30,9 @@ import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; import org.eclipse.emf.cdo.server.db.mapping.IListMapping3; import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; +import org.eclipse.emf.cdo.server.internal.db.DBIndexAnnotation; import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy; import org.eclipse.net4j.db.DBException; import org.eclipse.net4j.db.DBUtil; @@ -45,6 +49,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; +import java.util.Set; /** * @author Stefan Winkler @@ -102,6 +107,33 @@ public abstract class AbstractBasicListTableMapping implements IListMapping3, IM public abstract void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version); + protected final boolean needsIndexOnValueField(EStructuralFeature feature) + { + IMappingStrategy mappingStrategy = getMappingStrategy(); + Set<CDOFeatureType> forceIndexes = AbstractMappingStrategy.getForceIndexes(mappingStrategy); + + if (CDOFeatureType.matchesCombination(feature, forceIndexes)) + { + return true; + } + + EClass eClass = getContainingClass(); + EStructuralFeature[] allPersistentFeatures = CDOModelUtil.getClassInfo(eClass).getAllPersistentFeatures(); + + for (List<EStructuralFeature> features : DBIndexAnnotation.getIndices(eClass, allPersistentFeatures)) + { + if (features.size() == 1) + { + if (features.get(0) == feature) + { + return true; + } + } + } + + return false; + } + /** * @author Eike Stepper */ 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 97d49c19b6..8a53e2bb2e 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 @@ -32,6 +32,8 @@ import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta; import org.eclipse.emf.cdo.eresource.EresourcePackage; import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IIDHandler; import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; @@ -78,6 +80,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -117,222 +120,229 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I this.mappingStrategy = mappingStrategy; this.eClass = eClass; - initTable(); - initFields(); - initSQLStrings(); + IDBStoreAccessor accessor = null; + if (AbstractHorizontalMappingStrategy.isEagerTableCreation(mappingStrategy)) + { + accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + } + + initTable(accessor); } - private void initTable() + protected void initTable(IDBStoreAccessor accessor) { - final String tableName = mappingStrategy.getTableName(eClass); - final DBType idType = mappingStrategy.getStore().getIDHandler().getDBType(); - final int idLength = mappingStrategy.getStore().getIDColumnLength(); + IDBStore store = mappingStrategy.getStore(); + IDBDatabase database = store.getDatabase(); + String tableName = mappingStrategy.getTableName(eClass); - IDBDatabase database = mappingStrategy.getStore().getDatabase(); table = database.getSchema().getTable(tableName); if (table == null) { - IDBSchemaTransaction schemaTransaction = database.getSchemaTransaction(); - IDBSchema workingCopy = schemaTransaction.getWorkingCopy(); - - table = workingCopy.addTable(tableName); - table.addField(ATTRIBUTES_ID, idType, idLength, true); - table.addField(ATTRIBUTES_VERSION, DBType.INTEGER, true); - - IDBField branchField = addBranchField(table); - - table.addField(ATTRIBUTES_CREATED, DBType.BIGINT, true); - table.addField(ATTRIBUTES_REVISED, DBType.BIGINT, true); - table.addField(ATTRIBUTES_RESOURCE, idType, idLength, true); - addContainerField(table, idType, idLength); - table.addField(ATTRIBUTES_FEATURE, DBType.INTEGER, true); - - IDBIndex primaryKey = table.addIndex(IDBIndex.Type.PRIMARY_KEY, ATTRIBUTES_ID, ATTRIBUTES_VERSION); - if (branchField != null) + if (accessor != null) { - primaryKey.addIndexField(branchField); - } + IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); - table.addIndex(IDBIndex.Type.NON_UNIQUE, ATTRIBUTES_REVISED); - } - } + try + { + DBType idType = store.getIDHandler().getDBType(); + int idLength = store.getIDColumnLength(); - private void initFields() - { - final EStructuralFeature[] allPersistentFeatures = CDOModelUtil.getClassInfo(eClass).getAllPersistentFeatures(); - if (allPersistentFeatures == null) - { - valueMappings = Collections.emptyList(); - listMappings = Collections.emptyList(); - } - else - { - valueMappings = new ArrayList<ITypeMapping>(); - listMappings = new ArrayList<IListMapping>(); + IDBSchema workingCopy = schemaTransaction.getWorkingCopy(); + IDBTable table = workingCopy.addTable(tableName); + table.addField(ATTRIBUTES_ID, idType, idLength, true); + table.addField(ATTRIBUTES_VERSION, DBType.INTEGER, true); - boolean hasUnsettableFeatures = false; - for (EStructuralFeature feature : allPersistentFeatures) - { - String fieldName = mappingStrategy.getFieldName(feature); - if (feature.isMany()) - { - IListMapping mapping = null; - if (FeatureMapUtil.isFeatureMap(feature)) - { - mapping = mappingStrategy.createFeatureMapMapping(eClass, feature); - } - else - { - mapping = mappingStrategy.createListMapping(eClass, feature); - } + IDBField branchField = addBranchField(table); - if (mapping == null) - { - continue; - } + table.addField(ATTRIBUTES_CREATED, DBType.BIGINT, true); + table.addField(ATTRIBUTES_REVISED, DBType.BIGINT, true); + table.addField(ATTRIBUTES_RESOURCE, idType, idLength, true); + addContainerField(table, idType, idLength); + table.addField(ATTRIBUTES_FEATURE, DBType.INTEGER, true); - if (mapping instanceof IListMapping3) + IDBIndex primaryKey = table.addIndex(IDBIndex.Type.PRIMARY_KEY, ATTRIBUTES_ID, ATTRIBUTES_VERSION); + if (branchField != null) { - ((IListMapping3)mapping).setClassMapping(this); + primaryKey.addIndexField(branchField); } - listMappings.add(mapping); + table.addIndex(IDBIndex.Type.NON_UNIQUE, ATTRIBUTES_REVISED); - // Add field for list sizes - if (listSizeFields == null) - { - listSizeFields = new LinkedHashMap<EStructuralFeature, IDBField>(); - } + EStructuralFeature[] allPersistentFeatures = CDOModelUtil.getClassInfo(eClass).getAllPersistentFeatures(); + Map<EStructuralFeature, ITypeMapping> valueMappings = new HashMap<EStructuralFeature, ITypeMapping>(); + List<EStructuralFeature> unsettableFeatures = new ArrayList<EStructuralFeature>(); - IDBField field = table.getField(fieldName); - if (field == null) + for (EStructuralFeature feature : allPersistentFeatures) { - field = table.addField(fieldName, DBType.INTEGER); + String fieldName = mappingStrategy.getFieldName(feature); + if (feature.isMany()) + { + IListMapping mapping = createListMapping(feature); + if (mapping != null) + { + // Add field for list sizes. + table.addField(fieldName, DBType.INTEGER); + } + } + else + { + ITypeMapping valueMapping = mappingStrategy.createValueMapping(feature); + valueMapping.createDBField(table, fieldName); + valueMappings.put(feature, valueMapping); + + Set<CDOFeatureType> forceIndexes = AbstractMappingStrategy.getForceIndexes(mappingStrategy); + if (CDOFeatureType.matchesCombination(feature, forceIndexes)) + { + IDBField field = table.getField(fieldName); + if (!table.hasIndexFor(field)) + { + IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); + DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! + } + } + + if (feature.isUnsettable()) + { + unsettableFeatures.add(feature); + } + } } - listSizeFields.put(feature, field); - } - else - { - ITypeMapping mapping = mappingStrategy.createValueMapping(feature); - IDBField field = table.getField(fieldName); - if (field == null) + // Add unsettable fields to end of table. + for (EStructuralFeature feature : unsettableFeatures) { - mapping.createDBField(table, fieldName); - } - else - { - mapping.setDBField(table, fieldName); + String fieldName = mappingStrategy.getUnsettableFieldName(feature); + table.addField(fieldName, DBType.BOOLEAN); } - valueMappings.add(mapping); - - Set<CDOFeatureType> forceIndexes = AbstractMappingStrategy.getForceIndexes(mappingStrategy); - if (CDOFeatureType.matchesCombination(feature, forceIndexes)) + // Create optional feature indices. + for (List<EStructuralFeature> features : DBIndexAnnotation.getIndices(eClass, allPersistentFeatures)) { - if (field == null) + int size = features.size(); + IDBField[] fields = new IDBField[size]; + + for (int i = 0; i < size; i++) { - field = table.getField(fieldName); + EStructuralFeature feature = features.get(i); + + ITypeMapping valueMapping = valueMappings.get(feature); + IDBField field = valueMapping.getField(); + fields[i] = field; } - if (!table.hasIndexFor(field)) + if (!table.hasIndexFor(fields)) { - IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); + IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, fields); DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! } } - if (feature.isUnsettable()) - { - hasUnsettableFeatures = true; - } + schemaTransaction.commit(); } - } - - // Add unsettable fields to end of table - if (hasUnsettableFeatures) - { - unsettableFields = new LinkedHashMap<EStructuralFeature, IDBField>(); - for (EStructuralFeature feature : allPersistentFeatures) + finally { - if (!feature.isMany() && feature.isUnsettable()) - { - String fieldName = mappingStrategy.getUnsettableFieldName(feature); - IDBField field = table.getField(fieldName); - if (field == null) - { - field = table.addField(fieldName, DBType.BOOLEAN); - } - - unsettableFields.put(feature, field); - } + schemaTransaction.close(); } - } - initIndices(allPersistentFeatures); + initTable(null); + accessor.tableCreated(table); + } } - } - - private void initIndices(EStructuralFeature[] allPersistentFeatures) - { - for (List<EStructuralFeature> features : DBIndexAnnotation.getIndices(eClass, allPersistentFeatures)) + else { - int size = features.size(); - if (size > 1) - { - IDBField[] fields = new IDBField[size]; + valueMappings = null; + listMappings = null; + listSizeFields = null; + unsettableFields = null; - for (int i = 0; i < size; i++) - { - EStructuralFeature feature = features.get(i); - - ITypeMapping typeMapping = getValueMapping(feature); - IDBField field = typeMapping.getField(); - fields[i] = field; - } + EStructuralFeature[] allPersistentFeatures = CDOModelUtil.getClassInfo(eClass).getAllPersistentFeatures(); + List<EStructuralFeature> unsettableFeatures = new ArrayList<EStructuralFeature>(); - if (!table.hasIndexFor(fields)) - { - IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, fields); - DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! - } - } - else + for (EStructuralFeature feature : allPersistentFeatures) { - EStructuralFeature feature = features.get(0); + String fieldName = mappingStrategy.getFieldName(feature); if (feature.isMany()) { - IListMapping listMapping = getListMapping(feature); - if (listMapping instanceof AbstractListTableMapping) + IListMapping mapping = createListMapping(feature); + if (mapping != null) { - AbstractListTableMapping mapping = (AbstractListTableMapping)listMapping; + if (mapping instanceof IListMapping3) + { + ((IListMapping3)mapping).setClassMapping(this); + } + + if (listMappings == null) + { + listMappings = new ArrayList<IListMapping>(); + } + + listMappings.add(mapping); - IDBTable table = mapping.getDBTables().iterator().next(); - ITypeMapping typeMapping = mapping.getTypeMapping(); - IDBField field = typeMapping.getField(); + IDBField listSizeField = table.getField(fieldName); - if (!table.hasIndexFor(field)) + if (listSizeFields == null) { - IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); - DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! + listSizeFields = new LinkedHashMap<EStructuralFeature, IDBField>(); } + + listSizeFields.put(feature, listSizeField); } } else { - ITypeMapping typeMapping = getValueMapping(feature); - IDBField field = typeMapping.getField(); + ITypeMapping mapping = mappingStrategy.createValueMapping(feature); + mapping.setDBField(table, fieldName); - if (!table.hasIndexFor(field)) + if (valueMappings == null) { - IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); - DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! + valueMappings = new ArrayList<ITypeMapping>(); } + + valueMappings.add(mapping); + + if (feature.isUnsettable()) + { + unsettableFeatures.add(feature); + } + } + } + + // Register unsettable fields. + if (!unsettableFeatures.isEmpty()) + { + unsettableFields = new LinkedHashMap<EStructuralFeature, IDBField>(); + for (EStructuralFeature feature : unsettableFeatures) + { + String fieldName = mappingStrategy.getUnsettableFieldName(feature); + IDBField field = table.getField(fieldName); + unsettableFields.put(feature, field); } } + + if (valueMappings == null) + { + valueMappings = Collections.emptyList(); + } + + if (listMappings == null) + { + listMappings = Collections.emptyList(); + } + + initSQLStrings(); } } + private IListMapping createListMapping(EStructuralFeature feature) + { + if (FeatureMapUtil.isFeatureMap(feature)) + { + return mappingStrategy.createFeatureMapMapping(eClass, feature); + } + + return mappingStrategy.createListMapping(eClass, feature); + } + protected void initSQLStrings() { // ----------- Select all revisions (for handleRevisions) --- @@ -574,9 +584,12 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I List<IDBTable> tables = new ArrayList<IDBTable>(); tables.add(table); - for (IListMapping listMapping : listMappings) + if (listMappings != null) { - tables.addAll(listMapping.getDBTables()); + for (IListMapping listMapping : listMappings) + { + tables.addAll(listMapping.getDBTables()); + } } return tables; @@ -610,6 +623,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor) { + if (table == null) + { + initTable(accessor); + } + CDOID id = revision.getID(); InternalCDOBranch branch = revision.getBranch(); long timeStamp = revision.getTimeStamp(); @@ -723,6 +741,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, CDORevisionHandler handler) { + if (table == null) + { + return; + } + // branch parameter is ignored, because either it is null or main branch. // this does not make any difference for non-branching store. // see #handleRevisions() implementation in HorizontalBranchingClassMapping @@ -828,6 +851,12 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments) { + Set<CDOID> result = new HashSet<CDOID>(); + if (table == null) + { + return result; + } + StringBuilder builder = new StringBuilder(sqlSelectForChangeSet); boolean isFirst = true; @@ -855,8 +884,6 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); ResultSet resultSet = null; - Set<CDOID> result = new HashSet<CDOID>(); - try { int column = 1; @@ -888,6 +915,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public void detachObject(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, OMMonitor monitor) { + if (table == null) + { + return; + } + Async async = null; monitor.begin(1 + listMappings.size()); @@ -925,6 +957,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public void rawDelete(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, OMMonitor monitor) { + if (table == null) + { + return; + } + Async async = null; monitor.begin(1 + listMappings.size()); @@ -968,6 +1005,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I public final boolean queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context, String idString) { + if (table == null) + { + return true; + } + String tableName = table.getName(); List<EReference> refs = context.getSourceCandidates().get(eClass); List<EReference> scalarRefs = new ArrayList<EReference>(); @@ -1153,6 +1195,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I this.created = created; id = delta.getID(); + if (table == null) + { + initTable(accessor); + } + doProcess(delta); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java index a4e316cad5..d56e94911c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java @@ -443,6 +443,11 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS IIDHandler idHandler = getStore().getIDHandler(); PreparedStatement stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, context); + if (stmt == null) + { + return true; + } + ResultSet resultSet = null; try diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java index 07778bef59..395196fd91 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java @@ -14,11 +14,11 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.model.CDOFeatureType; import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; +import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; @@ -26,7 +26,6 @@ import org.eclipse.emf.cdo.server.db.IIDHandler; 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.server.internal.db.mapping.AbstractMappingStrategy; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.net4j.db.DBException; @@ -35,9 +34,11 @@ 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.IDBSchemaTransaction; 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.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.collection.MoveableList; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -53,7 +54,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Set; /** * This abstract base class provides basic behavior needed for mapping many-valued attributes to tables. @@ -87,11 +87,17 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public AbstractListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initTable(); - initSQLStrings(); + + IDBStoreAccessor accessor = null; + if (AbstractHorizontalMappingStrategy.isEagerTableCreation(mappingStrategy)) + { + accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + } + + initTable(accessor); } - private void initTable() + protected void initTable(IDBStoreAccessor accessor) { IMappingStrategy mappingStrategy = getMappingStrategy(); EStructuralFeature feature = getFeature(); @@ -103,41 +109,59 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap table = database.getSchema().getTable(tableName); if (table == null) { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - - IDBIndex primaryKey = table.addIndexEmpty(Type.PRIMARY_KEY); - for (FieldInfo info : getKeyFields()) + if (accessor != null) { - IDBField field = table.addField(info.getName(), info.getType(), info.getPrecision(), true); - primaryKey.addIndexField(field); - } + IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); + + try + { + IDBSchema workingCopy = schemaTransaction.getWorkingCopy(); + IDBTable table = workingCopy.addTable(tableName); + + IDBIndex primaryKey = table.addIndexEmpty(Type.PRIMARY_KEY); + for (FieldInfo info : getKeyFields()) + { + IDBField field = table.addField(info.getName(), info.getType(), info.getPrecision(), true); + primaryKey.addIndexField(field); + } - // Add field for list index - IDBField field = table.addField(LIST_IDX, DBType.INTEGER, true); - primaryKey.addIndexField(field); + // Add field for list index. + IDBField listIndexField = table.addField(LIST_IDX, DBType.INTEGER, true); + primaryKey.addIndexField(listIndexField); - // Add field for value - typeMapping.createDBField(table, LIST_VALUE); + // Add field for value. + typeMapping.createDBField(table, LIST_VALUE); + + if (needsIndexOnValueField(feature)) + { + IDBField field = table.getField(LIST_VALUE); + + if (!table.hasIndexFor(field)) + { + IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); + DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! + } + } + + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } + + initTable(null); + accessor.tableCreated(table); + } } else { typeMapping.setDBField(table, LIST_VALUE); - } - - Set<CDOFeatureType> forceIndexes = AbstractMappingStrategy.getForceIndexes(mappingStrategy); - if (CDOFeatureType.matchesCombination(feature, forceIndexes)) - { - IDBField field = table.getField(LIST_VALUE); - - if (!table.hasIndexFor(field)) - { - IDBIndex index = table.addIndex(IDBIndex.Type.NON_UNIQUE, field); - DBUtil.setOptional(index, true); // Creation might fail for unsupported column type! - } + initSQLStrings(); } } - private void initSQLStrings() + protected void initSQLStrings() { String tableName = table.getName(); FieldInfo[] fields = getKeyFields(); @@ -233,6 +257,12 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { + if (table == null) + { + // Nothing to read. Take shortcut. + return; + } + if (listChunk == 0) { // Nothing to read. Take shortcut. @@ -397,8 +427,13 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { CDOList values = revision.getListOrNull(getFeature()); - if (values != null) + if (values != null && !values.isEmpty()) { + if (table == null) + { + initTable(accessor); + } + int idx = 0; for (Object element : values) { @@ -437,6 +472,12 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) { + if (table == null) + { + // Nothing to read. Take shortcut. + return true; + } + String tableName = table.getName(); String listJoin = getMappingStrategy().getListJoin("a_t", "l_t"); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java index d004937683..90e7d5d9e7 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java @@ -45,11 +45,13 @@ public class AuditListTableMapping extends AbstractListTableMapping public AuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initSQLStrings(); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + IDBTable table = getTable(); // ----------- clear list ------------------------- @@ -86,6 +88,11 @@ public class AuditListTableMapping extends AbstractListTableMapping @Override public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) { + if (getTable() == null) + { + initTable(accessor); + } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java index ac85dac311..a821408f31 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java @@ -32,6 +32,7 @@ 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.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; @@ -51,7 +52,9 @@ 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.IDBSchemaTransaction; import org.eclipse.net4j.db.ddl.IDBIndex.Type; +import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.collection.MoveableList; @@ -123,11 +126,17 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public AuditListTableMappingWithRanges(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initTable(); - initSQLStrings(); + + IDBStoreAccessor accessor = null; + if (AbstractHorizontalMappingStrategy.isEagerTableCreation(mappingStrategy)) + { + accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + } + + initTable(accessor); } - private void initTable() + private void initTable(IDBStoreAccessor accessor) { String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); typeMapping = getMappingStrategy().createValueMapping(getFeature()); @@ -140,20 +149,40 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi table = database.getSchema().getTable(tableName); if (table == null) { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - table.addField(LIST_REVISION_ID, idType, idLength, true); - table.addField(LIST_REVISION_VERSION_ADDED, DBType.INTEGER); - table.addField(LIST_REVISION_VERSION_REMOVED, DBType.INTEGER); - table.addField(LIST_IDX, DBType.INTEGER, true); + if (accessor != null) + { + IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); - // TODO think about indexes - table.addIndex(Type.NON_UNIQUE, LIST_REVISION_ID, LIST_REVISION_VERSION_ADDED, LIST_REVISION_VERSION_REMOVED, LIST_IDX); + try + { + IDBSchema workingCopy = schemaTransaction.getWorkingCopy(); + IDBTable table = workingCopy.addTable(tableName); + + table.addField(LIST_REVISION_ID, idType, idLength, true); + table.addField(LIST_REVISION_VERSION_ADDED, DBType.INTEGER); + table.addField(LIST_REVISION_VERSION_REMOVED, DBType.INTEGER); + table.addField(LIST_IDX, DBType.INTEGER, true); + + // TODO think about indexes + table.addIndex(Type.NON_UNIQUE, LIST_REVISION_ID, LIST_REVISION_VERSION_ADDED, LIST_REVISION_VERSION_REMOVED, LIST_IDX); - typeMapping.createDBField(table, LIST_VALUE); + typeMapping.createDBField(table, LIST_VALUE); + + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } + + initTable(null); + accessor.tableCreated(table); + } } else { typeMapping.setDBField(table, LIST_VALUE); + initSQLStrings(); } } @@ -278,10 +307,11 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi @Override public void setClassMapping(IClassMapping classMapping) { - InternalRepository repository = (InternalRepository)getMappingStrategy().getStore().getRepository(); + IMappingStrategy mappingStrategy = getMappingStrategy(); + InternalRepository repository = (InternalRepository)mappingStrategy.getStore().getRepository(); if (repository.isSupportingUnits()) { - String listTableName = getTable().getName(); + String listTableName = mappingStrategy.getTableName(getContainingClass(), getFeature()); String attributesTableName = classMapping.getDBTables().get(0).getName(); sqlSelectUnitEntries = "SELECT " + (CHECK_UNIT_ENTRIES ? ATTRIBUTES_ID + ", " : "") + "cdo_list." + LIST_VALUE + // @@ -314,6 +344,12 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { + if (table == null) + { + // Nothing to read. Take shortcut. + return; + } + MoveableList<Object> list = revision.getListOrNull(getFeature()); if (list == null) { @@ -470,8 +506,13 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { CDOList values = revision.getListOrNull(getFeature()); - if (values != null) + if (values != null && !values.isEmpty()) { + if (table == null) + { + initTable(accessor); + } + int idx = 0; for (Object element : values) { @@ -545,6 +586,11 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised) { + if (table == null) + { + initTable(accessor); + } + if (TRACER.isEnabled()) { TRACER.format("objectRevised {0}: {1}", id, revised); //$NON-NLS-1$ @@ -745,6 +791,11 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) { + if (table == null) + { + // Nothing to read. Take shortcut. + return true; + } String tableName = getTable().getName(); String listJoin = getMappingStrategy().getListJoin("a_t", "l_t"); @@ -821,6 +872,19 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion, final int newVersion, long created, CDOListFeatureDelta delta) { + List<CDOFeatureDelta> listChanges = delta.getListChanges(); + int size = listChanges.size(); + if (size == 0) + { + // nothing to do. + return; + } + + if (table == null) + { + initTable(accessor); + } + IRepository repo = accessor.getStore().getRepository(); InternalCDORevision originalRevision = (InternalCDORevision)repo.getRevisionManager().getRevision(id, repo.getBranchManager().getMainBranch().getHead(), /* chunksize = */0, CDORevision.DEPTH_NONE, true); @@ -841,7 +905,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi TRACER.format("Processing deltas..."); //$NON-NLS-1$ } - for (CDOFeatureDelta listDelta : delta.getListChanges()) + for (CDOFeatureDelta listDelta : listChanges) { listDelta.accept(visitor); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java index 51709f7939..7189656930 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMapping.java @@ -47,11 +47,13 @@ public class BranchingListTableMapping extends AbstractListTableMapping public BranchingListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initSQLStrings(); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + IDBTable table = getTable(); // ----------- clear list ------------------------- @@ -92,6 +94,11 @@ public class BranchingListTableMapping extends AbstractListTableMapping @Override public void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version) { + if (getTable() == null) + { + initTable(accessor); + } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java index aac4f79ff2..f64306e4cd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java @@ -33,6 +33,7 @@ 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.ITransaction; +import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.IDBStore; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; @@ -51,7 +52,9 @@ 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.IDBSchemaTransaction; import org.eclipse.net4j.db.ddl.IDBIndex.Type; +import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.collection.MoveableList; @@ -120,11 +123,17 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public BranchingListTableMappingWithRanges(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initTable(); - initSQLStrings(); + + IDBStoreAccessor accessor = null; + if (AbstractHorizontalMappingStrategy.isEagerTableCreation(mappingStrategy)) + { + accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + } + + initTable(accessor); } - private void initTable() + private void initTable(IDBStoreAccessor accessor) { String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); typeMapping = getMappingStrategy().createValueMapping(getFeature()); @@ -137,29 +146,43 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM table = database.getSchema().getTable(tableName); if (table == null) { - table = database.getSchemaTransaction().getWorkingCopy().addTable(tableName); - table.addField(LIST_REVISION_ID, idType, idLength, true); - table.addField(LIST_REVISION_BRANCH, DBType.INTEGER, true); - table.addField(LIST_REVISION_VERSION_ADDED, DBType.INTEGER); - table.addField(LIST_REVISION_VERSION_REMOVED, DBType.INTEGER); - table.addField(LIST_IDX, DBType.INTEGER, true); + if (accessor != null) + { + IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction(); - // TODO think about indexes - table.addIndex(Type.NON_UNIQUE, LIST_REVISION_ID, LIST_REVISION_BRANCH, LIST_REVISION_VERSION_ADDED, LIST_REVISION_VERSION_REMOVED, LIST_IDX); + try + { + IDBSchema workingCopy = schemaTransaction.getWorkingCopy(); + IDBTable table = workingCopy.addTable(tableName); + table.addField(LIST_REVISION_ID, idType, idLength, true); + table.addField(LIST_REVISION_BRANCH, DBType.INTEGER, true); + table.addField(LIST_REVISION_VERSION_ADDED, DBType.INTEGER); + table.addField(LIST_REVISION_VERSION_REMOVED, DBType.INTEGER); + table.addField(LIST_IDX, DBType.INTEGER, true); + + // TODO think about indexes + table.addIndex(Type.NON_UNIQUE, LIST_REVISION_ID, LIST_REVISION_BRANCH, LIST_REVISION_VERSION_ADDED, LIST_REVISION_VERSION_REMOVED, LIST_IDX); + + typeMapping.createDBField(table, LIST_VALUE); + + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } - typeMapping.createDBField(table, LIST_VALUE); + initTable(null); + accessor.tableCreated(table); + } } else { typeMapping.setDBField(table, LIST_VALUE); + initSQLStrings(); } } - public Collection<IDBTable> getDBTables() - { - return Collections.singleton(table); - } - private void initSQLStrings() { String tableName = getTable().getName(); @@ -284,6 +307,11 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM sqlClearList = builder.toString(); } + public Collection<IDBTable> getDBTables() + { + return Collections.singleton(table); + } + protected final IDBTable getTable() { return table; @@ -296,6 +324,12 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, final int listChunk) { + if (table == null) + { + // Nothing to read. Take shortcut. + return; + } + MoveableList<Object> list = revision.getListOrNull(getFeature()); if (list == null) { @@ -617,8 +651,13 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { CDOList values = revision.getListOrNull(getFeature()); - if (values != null) + if (values != null && !values.isEmpty()) { + if (table == null) + { + initTable(accessor); + } + int idx = 0; for (Object element : values) { @@ -699,6 +738,11 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM return; } + if (table == null) + { + initTable(accessor); + } + if (TRACER.isEnabled()) { TRACER.format("objectDetached {1}", revision); //$NON-NLS-1$ @@ -721,12 +765,18 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM CDOListFeatureDelta delta) { List<CDOFeatureDelta> listChanges = delta.getListChanges(); - if (listChanges.size() == 0) + int size = listChanges.size(); + if (size == 0) { // nothing to do. return; } + if (table == null) + { + initTable(accessor); + } + InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id); int oldListSize = originalRevision.size(getFeature()); @@ -747,7 +797,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM // optimization: it's only necessary to process deltas // starting with the last feature delta which clears the list // (any operation before the clear is cascaded by it anyway) - int index = listChanges.size() - 1; + int index = size - 1; while (index > 0) { CDOFeatureDelta listDelta = listChanges.get(index); @@ -755,9 +805,10 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM { break; } + index--; } - while (index < listChanges.size()) + while (index < size) { listChanges.get(index++).accept(visitor); } @@ -1380,6 +1431,11 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, QueryXRefsContext context, String idString) { + if (table == null) + { + // Nothing to read. Take shortcut. + return true; + } String tableName = getTable().getName(); String listJoin = getMappingStrategy().getListJoin("a_t", "l_t"); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java index 6feb25ebd9..e4ff0cd3e3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java @@ -102,7 +102,6 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping public HorizontalAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { super(mappingStrategy, eClass); - initSQLStrings(); } @Override @@ -361,6 +360,11 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, boolean exactMatch, CDOBranchPoint branchPoint) { + if (getTable() == null) + { + return null; + } + EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); long timeStamp = branchPoint.getTimeStamp(); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java index e393717ea9..303a75a8fd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java @@ -92,7 +92,6 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { super(mappingStrategy, eClass); - initSQLStrings(); } @Override @@ -311,6 +310,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, boolean exactMatch, CDOBranchPoint branchPoint) { + if (getTable() == null) + { + return null; + } + EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); ITypeMapping nameValueMapping = getValueMapping(nameFeature); @@ -576,6 +580,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp @Override public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor) { + if (getTable() == null) + { + initTable(accessor); + } + CDOID id = revision.getID(); int version = revision.getVersion(); InternalCDOBranch branch = revision.getBranch(); @@ -691,6 +700,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp @Override public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, CDORevisionHandler handler) { + if (getTable() == null) + { + return; + } + StringBuilder builder = new StringBuilder(getSQLSelectForHandle()); boolean whereAppend = false; @@ -805,6 +819,12 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp @Override public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments) { + Set<CDOID> result = new HashSet<CDOID>(); + if (getTable() == null) + { + return result; + } + StringBuilder builder = new StringBuilder(getSQLSelectForChangeSet()); boolean isFirst = true; @@ -836,7 +856,6 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.LOW); ResultSet resultSet = null; - Set<CDOID> result = new HashSet<CDOID>(); try { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java index b0946c36e4..49db7d7db0 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java @@ -85,13 +85,13 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi public HorizontalNonAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { super(mappingStrategy, eClass); - initSQLStrings(); - hasLists = !getListMappings().isEmpty(); } @Override protected void initSQLStrings() { + hasLists = !getListMappings().isEmpty(); + super.initSQLStrings(); // ----------- Select Revision --------------------------- @@ -274,6 +274,11 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, boolean exactMatch, CDOBranchPoint branchPoint) { + if (getTable() == null) + { + return null; + } + long timeStamp = branchPoint.getTimeStamp(); if (timeStamp != CDORevision.UNSPECIFIED_DATE) { diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java index bc791c94ac..ea04a417cd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java @@ -69,11 +69,13 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement public NonAuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) { super(mappingStrategy, eClass, feature); - initSQLStrings(); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + IDBTable table = getTable(); // ----------- clear list ------------------------- @@ -205,6 +207,11 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, long created, CDOListFeatureDelta delta) { + if (getTable() == null) + { + initTable(accessor); + } + List<CDOFeatureDelta> listChanges = delta.getListChanges(); int oldListSize = delta.getOriginSize(); @@ -228,6 +235,11 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement */ private void clearList(IDBStoreAccessor accessor, CDOID id) { + if (getTable() == null) + { + return; + } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlClear, ReuseProbability.HIGH); @@ -248,6 +260,12 @@ public class NonAuditListTableMapping extends AbstractListTableMapping implement private int getCurrentIndexOffset(IDBStoreAccessor accessor, CDOID id) { + if (getTable() == null) + { + // List is empty. Return the default offset of 0. + return 0; + } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReadCurrentIndexOffset, ReuseProbability.HIGH); ResultSet rset = null; |