diff options
author | Eike Stepper | 2015-08-15 08:27:55 +0000 |
---|---|---|
committer | Eike Stepper | 2015-08-15 08:27:55 +0000 |
commit | aff55d74f59fc7915dae22175c73e2960206b0db (patch) | |
tree | 7590bc4b89ae309bcf03fc38b6f315feabf071ff | |
parent | 23ba5dd08145f170273ba6f4f19e8f31b102e25d (diff) | |
download | cdo-aff55d74f59fc7915dae22175c73e2960206b0db.tar.gz cdo-aff55d74f59fc7915dae22175c73e2960206b0db.tar.xz cdo-aff55d74f59fc7915dae22175c73e2960206b0db.zip |
[474681] Add mapping strategy option to support index creation on all cross references
https://bugs.eclipse.org/bugs/show_bug.cgi?id=474681
27 files changed, 556 insertions, 54 deletions
diff --git a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml index d1c195260e..5e23707118 100644 --- a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml +++ b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.emf.cdo.server.db" label="%featureName" - version="4.3.100.qualifier" + version="4.4.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.emf.cdo.license" license-feature-version="0.0.0"> diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOFeatureType.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOFeatureType.java new file mode 100644 index 0000000000..4e733a45fd --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOFeatureType.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2004-2015 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.common.model; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Eike Stepper + * @since 4.5 + */ +public enum CDOFeatureType +{ + NONE + { + @Override + public boolean matches(EStructuralFeature feature) + { + return false; + } + }, + + ALL + { + @Override + public boolean matches(EStructuralFeature feature) + { + return true; + } + }, + + ATTRIBUTE + { + @Override + public boolean matches(EStructuralFeature feature) + { + return feature instanceof EAttribute; + } + }, + + REFERENCE + { + @Override + public boolean matches(EStructuralFeature feature) + { + return feature instanceof EReference; + } + }, + + CONTAINER + { + @Override + public boolean matches(EStructuralFeature feature) + { + if (feature instanceof EReference) + { + EReference reference = (EReference)feature; + return reference.isContainer(); + } + + return false; + } + }, + + CONTAINMENT + { + @Override + public boolean matches(EStructuralFeature feature) + { + if (feature instanceof EReference) + { + EReference reference = (EReference)feature; + return reference.isContainment(); + } + + return false; + } + }, + + XREF + { + @Override + public boolean matches(EStructuralFeature feature) + { + if (feature instanceof EReference) + { + EReference reference = (EReference)feature; + return !reference.isContainer() && !reference.isContainment(); + } + + return false; + } + }; + + public abstract boolean matches(EStructuralFeature feature); + + public static boolean matchesCombination(EStructuralFeature feature, Collection<CDOFeatureType> featureTypes) + { + if (featureTypes != null) + { + for (CDOFeatureType featureType : featureTypes) + { + if (featureType.matches(feature)) + { + return true; + } + } + } + + return false; + } + + public static CDOFeatureType read(String str) + { + if (str != null) + { + str = str.trim().toUpperCase(); + + try + { + return valueOf(str); + } + catch (Exception ex) + { + //$FALL-THROUGH$ + } + } + + return NONE; + } + + public static Set<CDOFeatureType> readCombination(String str) + { + if (str != null) + { + str = str.replace(' ', '|').replace(',', '|').replace(';', '|'); + + Set<CDOFeatureType> result = new HashSet<CDOFeatureType>(); + + for (String token : str.split("\\|")) + { + CDOFeatureType featureType = read(token); + if (featureType != NONE) + { + result.add(featureType); + } + } + + return result; + } + + return Collections.emptySet(); + } + + public static String writeCombination(Collection<CDOFeatureType> featureTypes) + { + if (featureTypes != null) + { + if (!(featureTypes instanceof Set)) + { + featureTypes = new HashSet<CDOFeatureType>(featureTypes); + } + + if (featureTypes.contains(ALL)) + { + return ALL.toString(); + } + + if (featureTypes.contains(REFERENCE)) + { + featureTypes.remove(CONTAINER); + featureTypes.remove(CONTAINMENT); + featureTypes.remove(XREF); + } + + featureTypes.remove(NONE); + + List<CDOFeatureType> list = new ArrayList<CDOFeatureType>(featureTypes); + Collections.sort(list); + + StringBuilder result = new StringBuilder(); + for (CDOFeatureType featureType : list) + { + if (result.length() != 0) + { + result.append("|"); + } + + result.append(featureType); + } + + return result.toString(); + } + + return ""; + } +} diff --git a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/checkouts/OfflineCDOCheckout.java b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/checkouts/OfflineCDOCheckout.java index b01a1b018e..98fa3387ff 100644 --- a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/checkouts/OfflineCDOCheckout.java +++ b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/checkouts/OfflineCDOCheckout.java @@ -230,7 +230,7 @@ public class OfflineCDOCheckout extends CDOCheckoutImpl dataSource.setURL("jdbc:h2:" + dbPrefix); Map<String, String> props = new HashMap<String, String>(); - props.put(IMappingStrategy.PROP_QUALIFIED_NAMES, "true"); + props.put(IMappingStrategy.Props.QUALIFIED_NAMES, "true"); IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(true, true, false); mappingStrategy.setProperties(props); diff --git a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/LocalCDORepository.java b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/LocalCDORepository.java index 977535c7d9..6f7ba1404d 100644 --- a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/LocalCDORepository.java +++ b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/LocalCDORepository.java @@ -161,7 +161,7 @@ public class LocalCDORepository extends CDORepositoryImpl protected Map<String, String> getMappingStrategyProperties() { Map<String, String> props = new HashMap<String, String>(); - props.put(IMappingStrategy.PROP_QUALIFIED_NAMES, "true"); + props.put(IMappingStrategy.Props.QUALIFIED_NAMES, "true"); props.put(CDODBUtil.PROP_COPY_ON_BRANCH, "true"); return props; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.server.db/.settings/.api_filters index 16058e23d1..6c803d9d9c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/.settings/.api_filters +++ b/plugins/org.eclipse.emf.cdo.server.db/.settings/.api_filters @@ -10,6 +10,12 @@ <filter id="403767336"> <message_arguments> <message_argument value="org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy"/> + <message_argument value="PROP_FORCE_INDEXES"/> + </message_arguments> + </filter> + <filter id="403767336"> + <message_arguments> + <message_argument value="org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy"/> <message_argument value="PROP_TYPE_MAPPING_MODIFIER"/> </message_arguments> </filter> diff --git a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF index 6f660850cf..5cef5f9c30 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.server.db;singleton:=true -Bundle-Version: 4.3.100.qualifier +Bundle-Version: 4.4.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -12,10 +12,10 @@ Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.net4j.db;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.emf.cdo.server;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.server.db;version="4.3.100", - org.eclipse.emf.cdo.server.db.mapping;version="4.3.100", - org.eclipse.emf.cdo.server.internal.db;version="4.3.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui", - org.eclipse.emf.cdo.server.internal.db.bundle;version="4.3.100";x-internal:=true, - org.eclipse.emf.cdo.server.internal.db.mapping;version="4.3.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", - org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.3.100";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", - org.eclipse.emf.cdo.server.internal.db.messages;version="4.3.100";x-internal:=true +Export-Package: org.eclipse.emf.cdo.server.db;version="4.4.0", + org.eclipse.emf.cdo.server.db.mapping;version="4.4.0", + org.eclipse.emf.cdo.server.internal.db;version="4.4.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui", + org.eclipse.emf.cdo.server.internal.db.bundle;version="4.4.0";x-internal:=true, + org.eclipse.emf.cdo.server.internal.db.mapping;version="4.4.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", + org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.4.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", + org.eclipse.emf.cdo.server.internal.db.messages;version="4.4.0";x-internal:=true 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 a2b946ea1a..a2c9d9bc41 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 @@ -56,31 +56,46 @@ public interface IMappingStrategy /** * Name of the integer property that configures the maximum length for table names. A value of zero indicates the * value of the {@link IDBAdapter#getMaxTableNameLength() db adapter} to be used. + * + * @deprecated As of 4.4 use {@link Props#MAX_TABLE_NAME_LENGTH}. */ - public static final String PROP_MAX_TABLE_NAME_LENGTH = "maxTableNameLength"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_MAX_TABLE_NAME_LENGTH = Props.MAX_TABLE_NAME_LENGTH; /** * Name of the integer property that configures the maximum length for column names. A value of zero indicates the * value of the {@link IDBAdapter#getMaxFieldNameLength() db adapter} to be used. + * + * @deprecated As of 4.4 use {@link Props#MAX_FIELD_NAME_LENGTH}. */ - public static final String PROP_MAX_FIELD_NAME_LENGTH = "maxFieldNameLength"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_MAX_FIELD_NAME_LENGTH = Props.MAX_FIELD_NAME_LENGTH; /** * Name of the String property that specifies a common prefix for table names. + * + * @deprecated As of 4.4 use {@link Props#TABLE_NAME_PREFIX}. */ - public static final String PROP_TABLE_NAME_PREFIX = "tableNamePrefix"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_TABLE_NAME_PREFIX = Props.TABLE_NAME_PREFIX; /** * Name of the boolean property that configures whether the table names are made of simple class names or of qualified * class names. + * + * @deprecated As of 4.4 use {@link Props#QUALIFIED_NAMES}. */ - public static final String PROP_QUALIFIED_NAMES = "qualifiedNames"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_QUALIFIED_NAMES = Props.QUALIFIED_NAMES; /** * Name of the boolean property that configures whether table names and column names are always suffixed with the * internal DBID or only in cases where generated names violate the naming constraints of the underlying backend. + * + * @deprecated As of 4.4 use {@link Props#FORCE_NAMES_WITH_ID}. */ - public static final String PROP_FORCE_NAMES_WITH_ID = "forceNamesWithID"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_FORCE_NAMES_WITH_ID = Props.FORCE_NAMES_WITH_ID; /** * Name of the integer property that configures the size of the object type in-memory cache. Possible configuration @@ -93,15 +108,19 @@ public interface IMappingStrategy * <p> * * @since 4.0 + * @deprecated As of 4.4 use {@link Props#OBJECT_TYPE_CACHE_SIZE}. */ - public static final String PROP_OBJECT_TYPE_CACHE_SIZE = "objectTypeCacheSize"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_OBJECT_TYPE_CACHE_SIZE = Props.OBJECT_TYPE_CACHE_SIZE; /** * Name of a String property that specifies the name of a {@link ColumnTypeModifier column type modifier}. * * @since 4.2 + * @deprecated As of 4.4 use {@link Props#COLUMN_TYPE_MODIFIER}. */ - public static final String PROP_COLUMN_TYPE_MODIFIER = "columnTypeModifier"; //$NON-NLS-1$ + @Deprecated + public static final String PROP_COLUMN_TYPE_MODIFIER = Props.COLUMN_TYPE_MODIFIER; /** * @return the store, this MappingStrategy instance belongs to. @@ -352,4 +371,67 @@ public interface IMappingStrategy * @since 4.0 */ public String getListJoin(String attrTable, String listTable); + + /** + * Contains symbolic constants that specifiy valid keys of {@link IMappingStrategy#getProperties() mapping strategy properties}. + * + * @author Eike Stepper + * @since 4.4 + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + * @apiviz.exclude + */ + public interface Props + { + /** + * Name of the integer property that configures the maximum length for table names. A value of zero indicates the + * value of the {@link IDBAdapter#getMaxTableNameLength() db adapter} to be used. + */ + public static final String MAX_TABLE_NAME_LENGTH = "maxTableNameLength"; //$NON-NLS-1$ + + /** + * Name of the integer property that configures the maximum length for column names. A value of zero indicates the + * value of the {@link IDBAdapter#getMaxFieldNameLength() db adapter} to be used. + */ + public static final String MAX_FIELD_NAME_LENGTH = "maxFieldNameLength"; //$NON-NLS-1$ + + /** + * Name of the String property that specifies a common prefix for table names. + */ + public static final String TABLE_NAME_PREFIX = "tableNamePrefix"; //$NON-NLS-1$ + + /** + * Name of the boolean property that configures whether the table names are made of simple class names or of qualified + * class names. + */ + public static final String QUALIFIED_NAMES = "qualifiedNames"; //$NON-NLS-1$ + + /** + * Name of the boolean property that configures whether table names and column names are always suffixed with the + * internal DBID or only in cases where generated names violate the naming constraints of the underlying backend. + */ + public static final String FORCE_NAMES_WITH_ID = "forceNamesWithID"; //$NON-NLS-1$ + + /** + * Name of the String property that configures on what types of {@link EStructuralFeature structural features} additional + * indexes are to be created. + */ + public static final String FORCE_INDEXES = "forceIndexes"; //$NON-NLS-1$ + + /** + * Name of the integer property that configures the size of the object type in-memory cache. Possible configuration + * values are: + * <ul> + * <li>0 (zero). Don't use memory caching. + * <li>>0. Use memory caching with the cache size given. + * </ul> + * Default is a memory cache size of 10,000,000. + */ + public static final String OBJECT_TYPE_CACHE_SIZE = "objectTypeCacheSize"; //$NON-NLS-1$ + + /** + * 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$ + } } 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 68e9d746d3..3cc751bc9c 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 @@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.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; @@ -120,6 +121,8 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp private SystemPackageMappingInfo systemPackageMappingInfo; + private Set<CDOFeatureType> forceIndexes; + public AbstractMappingStrategy() { classMappings = new ConcurrentHashMap<EClass, IClassMapping>(); @@ -144,34 +147,44 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp private int getMaxTableNameLength() { - String value = getProperties().get(PROP_MAX_TABLE_NAME_LENGTH); + String value = getProperties().get(Props.MAX_TABLE_NAME_LENGTH); return value == null ? store.getDBAdapter().getMaxTableNameLength() : Integer.valueOf(value); } private int getMaxFieldNameLength() { - String value = getProperties().get(PROP_MAX_FIELD_NAME_LENGTH); + String value = getProperties().get(Props.MAX_FIELD_NAME_LENGTH); return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value); } private boolean isQualifiedNames() { - String value = getProperties().get(PROP_QUALIFIED_NAMES); + String value = getProperties().get(Props.QUALIFIED_NAMES); return value == null ? false : Boolean.valueOf(value); } private boolean isForceNamesWithID() { - String value = getProperties().get(PROP_FORCE_NAMES_WITH_ID); + String value = getProperties().get(Props.FORCE_NAMES_WITH_ID); return value == null ? false : Boolean.valueOf(value); } private String getTableNamePrefix() { - String value = getProperties().get(PROP_TABLE_NAME_PREFIX); + String value = getProperties().get(Props.TABLE_NAME_PREFIX); return StringUtil.safe(value); } + public Set<CDOFeatureType> getForceIndexes() + { + if (forceIndexes == null) + { + forceIndexes = doGetForceIndexes(this); + } + + return forceIndexes; + } + // -- getters and setters ---------------------------------------------- public final IDBStore getStore() @@ -791,10 +804,25 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp public abstract IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature); + private static Set<CDOFeatureType> doGetForceIndexes(IMappingStrategy mappingStrategy) + { + return CDOFeatureType.readCombination(mappingStrategy.getProperties().get(Props.FORCE_INDEXES)); + } + + public static Set<CDOFeatureType> getForceIndexes(IMappingStrategy mappingStrategy) + { + if (mappingStrategy instanceof AbstractMappingStrategy) + { + return ((AbstractMappingStrategy)mappingStrategy).getForceIndexes(); + } + + return doGetForceIndexes(mappingStrategy); + } + /** * @author Eike Stepper */ - private final class SystemPackageMappingInfo + private static final class SystemPackageMappingInfo { public boolean ecoreMapped; 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 ca297bf593..1116d42499 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 @@ -381,7 +381,7 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. private ColumnTypeModifier getColumnTypeModifier(IMappingStrategy mappingStrategy) { - String factoryType = mappingStrategy.getProperties().get(IMappingStrategy.PROP_COLUMN_TYPE_MODIFIER); + String factoryType = mappingStrategy.getProperties().get(IMappingStrategy.Props.COLUMN_TYPE_MODIFIER); if (factoryType == null) { factoryType = mappingStrategy.getStore().getDBAdapter().getName(); @@ -515,7 +515,7 @@ public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping. registerFactoryType(factoryType); } else - // delta.getKind() == Kind.REMOVED + // delta.getKind() == Kind.REMOVED { // XXX Runtime removal of typeMappingFactories removal of type mappings is currently not supported. OM.LOG.warn(Messages.getString("TypeMappingRegistry.3")); 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 8ebaa5c4c1..b83a8e41fb 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 @@ -18,6 +18,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchManager; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.CDOFeatureType; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; @@ -33,6 +34,7 @@ import org.eclipse.emf.cdo.server.db.mapping.IListMapping; 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.commit.CDOChangeSetSegment; import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; @@ -48,6 +50,7 @@ import org.eclipse.net4j.db.ddl.IDBField; import org.eclipse.net4j.db.ddl.IDBIndex; import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.spi.db.ddl.InternalDBIndex; import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -203,6 +206,21 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I valueMappings.add(mapping); + Set<CDOFeatureType> forceIndexes = AbstractMappingStrategy.getForceIndexes(mappingStrategy); + if (CDOFeatureType.matchesCombination(feature, forceIndexes)) + { + if (field == null) + { + field = table.getField(fieldName); + } + + if (!table.hasIndexFor(field)) + { + InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field); + index.setOptional(true); // Creation might fail for unsupported column type! + } + } + if (feature.isUnsettable()) { hasUnsettableFeatures = true; 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 a524387c29..8e3d98a136 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 @@ -409,7 +409,7 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS { int objectTypeCacheSize = ObjectTypeCache.DEFAULT_CACHE_CAPACITY; - Object value = getProperties().get(PROP_OBJECT_TYPE_CACHE_SIZE); + Object value = getProperties().get(Props.OBJECT_TYPE_CACHE_SIZE); if (value != 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 a364263f7c..b65bf0b709 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,6 +14,7 @@ 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; @@ -25,6 +26,7 @@ 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; @@ -37,6 +39,7 @@ 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.spi.db.ddl.InternalDBIndex; import org.eclipse.net4j.util.collection.MoveableList; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -51,6 +54,7 @@ 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. @@ -90,10 +94,13 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap private void initTable() { - String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); - typeMapping = getMappingStrategy().createValueMapping(getFeature()); + IMappingStrategy mappingStrategy = getMappingStrategy(); + EStructuralFeature feature = getFeature(); - IDBDatabase database = getMappingStrategy().getStore().getDatabase(); + String tableName = mappingStrategy.getTableName(getContainingClass(), feature); + typeMapping = mappingStrategy.createValueMapping(feature); + + IDBDatabase database = mappingStrategy.getStore().getDatabase(); table = database.getSchema().getTable(tableName); if (table == null) { @@ -117,6 +124,18 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap { 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)) + { + InternalDBIndex index = (InternalDBIndex)table.addIndex(IDBIndex.Type.NON_UNIQUE, field); + index.setOptional(true); // Creation might fail for unsupported column type! + } + } } private void initSQLStrings() diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalMappingStrategy.java index 5068ba8661..62c99da3e4 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalMappingStrategy.java @@ -16,7 +16,7 @@ import org.eclipse.emf.cdo.common.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; -import org.eclipse.emf.cdo.server.IRepository.Props; +import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext; import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; import org.eclipse.emf.cdo.server.db.CDODBUtil; @@ -237,8 +237,8 @@ public class HorizontalMappingStrategy extends Lifecycle implements IMappingStra { super.doActivate(); - boolean auditing = getBooleanProperty(Props.SUPPORTING_AUDITS); - boolean branching = getBooleanProperty(Props.SUPPORTING_BRANCHES); + boolean auditing = getBooleanProperty(IRepository.Props.SUPPORTING_AUDITS); + boolean branching = getBooleanProperty(IRepository.Props.SUPPORTING_BRANCHES); boolean withRanges = false; if (auditing || branching) diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java index 7f78ac3bde..90c0bf2880 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java @@ -136,7 +136,8 @@ public abstract class DBConfig extends RepositoryConfig protected Map<String, String> createMappingStrategyProperties() { Map<String, String> props = new HashMap<String, String>(); - props.put(IMappingStrategy.PROP_QUALIFIED_NAMES, "true"); + props.put(IMappingStrategy.Props.QUALIFIED_NAMES, "true"); + props.put(IMappingStrategy.Props.FORCE_INDEXES, "XREF"); props.put(CDODBUtil.PROP_COPY_ON_BRANCH, Boolean.toString(copyOnBranch)); return props; } diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/offline/DBOfflineConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/offline/DBOfflineConfig.java index 7c367c1dbd..19c6a784d4 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/offline/DBOfflineConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/offline/DBOfflineConfig.java @@ -102,7 +102,7 @@ public abstract class DBOfflineConfig extends OfflineConfig protected Map<String, String> createMappingStrategyProperties() { Map<String, String> props = new HashMap<String, String>(); - props.put(IMappingStrategy.PROP_QUALIFIED_NAMES, "true"); + props.put(IMappingStrategy.Props.QUALIFIED_NAMES, "true"); props.put(CDODBUtil.PROP_COPY_ON_BRANCH, Boolean.toString(copyOnBranch)); return props; } diff --git a/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF index 01089f321b..85f44d8a3c 100644 --- a/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.net4j.db;singleton:=true -Bundle-Version: 4.4.100.qualifier +Bundle-Version: 4.5.0.qualifier Bundle-Activator: org.eclipse.net4j.internal.db.bundle.OM$Activator Bundle-Vendor: %providerName Bundle-ClassPath: . @@ -11,16 +11,16 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.db.jdbc;bundle-version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.net4j.db;version="4.4.100", - org.eclipse.net4j.db.ddl;version="4.4.100", - org.eclipse.net4j.db.ddl.delta;version="4.4.100", - org.eclipse.net4j.db.dml;version="4.4.100", - org.eclipse.net4j.internal.db;version="4.4.100";x-internal:=true, - org.eclipse.net4j.internal.db.bundle;version="4.4.100";x-internal:=true, - org.eclipse.net4j.internal.db.ddl;version="4.4.100";x-friends:="org.eclipse.emf.cdo.server.db", - org.eclipse.net4j.internal.db.ddl.delta;version="4.4.100";x-internal:=true, - org.eclipse.net4j.internal.db.dml;version="4.4.100";x-internal:=true, - org.eclipse.net4j.spi.db;version="4.4.100", - org.eclipse.net4j.spi.db.ddl;version="4.4.100" +Export-Package: org.eclipse.net4j.db;version="4.5.0", + org.eclipse.net4j.db.ddl;version="4.5.0", + org.eclipse.net4j.db.ddl.delta;version="4.5.0", + org.eclipse.net4j.db.dml;version="4.5.0", + org.eclipse.net4j.internal.db;version="4.5.0";x-internal:=true, + org.eclipse.net4j.internal.db.bundle;version="4.5.0";x-internal:=true, + org.eclipse.net4j.internal.db.ddl;version="4.5.0";x-friends:="org.eclipse.emf.cdo.server.db", + org.eclipse.net4j.internal.db.ddl.delta;version="4.5.0";x-internal:=true, + org.eclipse.net4j.internal.db.dml;version="4.5.0";x-internal:=true, + org.eclipse.net4j.spi.db;version="4.5.0", + org.eclipse.net4j.spi.db.ddl;version="4.5.0" Bundle-ActivationPolicy: lazy Eclipse-BuddyPolicy: registered diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java index f029f12a2e..af5cfc8845 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java @@ -57,6 +57,11 @@ public interface IDBTable extends IDBSchemaElement public IDBField[] getFields(String... fieldNames) throws SchemaElementNotFoundException; /** + * @since 4.5 + */ + public boolean hasIndexFor(IDBField... fields); + + /** * @since 4.2 */ public IDBIndex addIndex(String name, IDBIndex.Type type, IDBField... fields); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java index 4e51feab0e..9162f65078 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java @@ -25,6 +25,11 @@ public interface IDBIndexDelta extends IDBDeltaWithProperties { public static final String TYPE_PROPERTY = "type"; + /** + * @since 4.5 + */ + public static final String OPTIONAL_PROPERTY = "optional"; + public IDBTableDelta getParent(); public int getIndexFieldDeltaCount(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java index 0e76c53c39..3258cabbe0 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java @@ -54,6 +54,8 @@ public class DBIndex extends DBSchemaElement implements InternalDBIndex private List<IDBIndexField> indexFields = new ArrayList<IDBIndexField>(); + private boolean optional; + public DBIndex(IDBTable table, String name, Type type, IDBField[] fields) { super(name); @@ -111,6 +113,16 @@ public class DBIndex extends DBSchemaElement implements InternalDBIndex this.type = type; } + public boolean isOptional() + { + return optional; + } + + public void setOptional(boolean optional) + { + this.optional = optional; + } + @Deprecated public int getPosition() { diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java index 4bb34c2778..b4349c0398 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java @@ -25,6 +25,7 @@ import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.db.ddl.SchemaElementNotFoundException; import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta; import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta; +import org.eclipse.net4j.spi.db.ddl.InternalDBIndex; import org.eclipse.net4j.spi.db.ddl.InternalDBSchema; import javax.sql.DataSource; @@ -75,6 +76,8 @@ public class DBSchema extends DBSchemaElement implements InternalDBSchema for (IDBIndex sourceIndex : sourceTable.getIndices()) { IDBIndex index = table.addIndexEmpty(sourceIndex.getName(), sourceIndex.getType()); + ((InternalDBIndex)index).setOptional(((InternalDBIndex)sourceIndex).isOptional()); + for (IDBField sourceField : sourceIndex.getFields()) { IDBField field = table.getField(sourceField.getPosition()); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java index 8b602d1e39..2502e88641 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java @@ -180,6 +180,20 @@ public class DBTable extends DBSchemaElement implements InternalDBTable return result.toArray(new IDBField[result.size()]); } + public boolean hasIndexFor(IDBField... fields) + { + for (IDBIndex index : indices) + { + IDBField[] indexFields = index.getFields(); + if (startsWith(indexFields, fields)) + { + return true; + } + } + + return false; + } + public IDBIndex addIndex(String name, IDBIndex.Type type, IDBField... fields) { assertUnlocked(); @@ -339,4 +353,24 @@ public class DBTable extends DBSchemaElement implements InternalDBTable { ((InternalDBSchema)schema).assertUnlocked(); } + + private static boolean startsWith(IDBField[] indexFields, IDBField[] fields) + { + int length = fields.length; + if (length <= indexFields.length) + { + for (int i = 0; i < length; i++) + { + IDBField field = fields[i]; + if (field != indexFields[i]) + { + return false; + } + } + + return true; + } + + return false; + } } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBIndex.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBIndex.java index 4fb261f9de..65df3641fc 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBIndex.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBIndex.java @@ -80,6 +80,16 @@ public final class DelegatingDBIndex extends DelegatingDBSchemaElement implement getDelegate().removeIndexField(unwrap(indexFieldToRemove)); } + public boolean isOptional() + { + return getDelegate().isOptional(); + } + + public void setOptional(boolean optional) + { + getDelegate().setOptional(optional); + } + @Deprecated public int getPosition() { diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBTable.java index 8b4575bba5..b3dffb2583 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBTable.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBTable.java @@ -139,6 +139,11 @@ public final class DelegatingDBTable extends DelegatingDBSchemaElement implement return wrap(getDelegate().getFields(fieldNames), IDBField.class); } + public boolean hasIndexFor(IDBField... fields) + { + return getDelegate().hasIndexFor(unwrap(fields, IDBField.class)); + } + public IDBIndex addIndex(String name, Type type, IDBField... fields) { return wrap(getDelegate().addIndex(name, type, unwrap(fields, IDBField.class))); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java index ec8c902e01..fcd559ec79 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java @@ -55,6 +55,14 @@ public final class DBIndexDelta extends DBDeltaWithProperties implements IDBInde new DBPropertyDelta<IDBIndex.Type>(this, TYPE_PROPERTY, IDBPropertyDelta.Type.STRING, type, oldType)); } + Boolean optional = index == null ? null : ((InternalDBIndex)index).isOptional(); + Boolean oldOptional = oldIndex == null ? null : ((InternalDBIndex)oldIndex).isOptional(); + if (!ObjectUtil.equals(optional, oldOptional)) + { + addPropertyDelta( + new DBPropertyDelta<Boolean>(this, OPTIONAL_PROPERTY, IDBPropertyDelta.Type.BOOLEAN, optional, oldOptional)); + } + IDBIndexField[] indexFields = index == null ? InternalDBIndex.NO_INDEX_FIELDS : index.getIndexFields(); IDBIndexField[] oldIndexFields = oldIndex == null ? InternalDBIndex.NO_INDEX_FIELDS : oldIndex.getIndexFields(); compare(indexFields, oldIndexFields, new SchemaElementComparator<IDBIndexField>() diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java index 8975ed4620..8a5b1357f3 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java @@ -23,6 +23,7 @@ import org.eclipse.net4j.db.ddl.delta.IDBIndexDelta; import org.eclipse.net4j.db.ddl.delta.IDBIndexFieldDelta; import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta; import org.eclipse.net4j.db.ddl.delta.IDBTableDelta; +import org.eclipse.net4j.spi.db.ddl.InternalDBIndex; import org.eclipse.net4j.spi.db.ddl.InternalDBSchema; import java.text.MessageFormat; @@ -201,9 +202,11 @@ public final class DBSchemaDelta extends DBDelta implements IDBSchemaDelta { String name = delta.getName(); IDBIndex.Type type = delta.getPropertyValue(IDBIndexDelta.TYPE_PROPERTY); + Boolean optional = delta.getPropertyValue(IDBIndexDelta.OPTIONAL_PROPERTY); IDBTable table = delta.getParent().getSchemaElement(schema); - table.addIndexEmpty(name, type); + InternalDBIndex index = (InternalDBIndex)table.addIndexEmpty(name, type); + index.setOptional(optional == Boolean.TRUE); } @Override diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java index 030fa78a1d..fbd52b6c73 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java @@ -27,6 +27,7 @@ import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta; import org.eclipse.net4j.db.ddl.delta.IDBTableDelta; import org.eclipse.net4j.internal.db.bundle.OM; import org.eclipse.net4j.internal.db.ddl.DBField; +import org.eclipse.net4j.spi.db.ddl.InternalDBIndex; import org.eclipse.net4j.util.CheckUtil; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -395,21 +396,41 @@ public abstract class DBAdapter implements IDBAdapter @Override public void visit(IDBIndexDelta delta) { - IDBIndex element = delta.getSchemaElement(schema); + InternalDBIndex index = (InternalDBIndex)delta.getSchemaElement(schema); ChangeKind changeKind = delta.getChangeKind(); switch (changeKind) { case ADD: - createIndex(connection, element, delta); + try + { + createIndex(connection, index, delta); + } + catch (RuntimeException ex) + { + if (!index.isOptional()) + { + throw ex; + } + } break; case REMOVE: - dropIndex(connection, element, delta); + dropIndex(connection, index, delta); break; case CHANGE: - dropIndex(connection, element, delta); - createIndex(connection, element, delta); + dropIndex(connection, index, delta); + try + { + createIndex(connection, index, delta); + } + catch (RuntimeException ex) + { + if (!index.isOptional()) + { + throw ex; + } + } break; default: @@ -769,7 +790,26 @@ public abstract class DBAdapter implements IDBAdapter IDBIndex[] indices = table.getIndices(); for (int i = 0; i < indices.length; i++) { - createIndex(indices[i], statement, i); + InternalDBIndex index = (InternalDBIndex)indices[i]; + + try + { + createIndex(index, statement, i); + } + catch (SQLException ex) + { + if (!index.isOptional()) + { + throw ex; + } + } + catch (RuntimeException ex) + { + if (!index.isOptional()) + { + throw ex; + } + } } } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/ddl/InternalDBIndex.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/ddl/InternalDBIndex.java index 2494661b20..ff3dfafe73 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/ddl/InternalDBIndex.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/ddl/InternalDBIndex.java @@ -26,4 +26,14 @@ public interface InternalDBIndex extends IDBIndex, InternalDBSchemaElement public IDBIndex getWrapper(); public void removeIndexField(IDBIndexField indexFieldToRemove); + + /** + * @since 4.5 + */ + public boolean isOptional(); + + /** + * @since 4.5 + */ + public void setOptional(boolean optional); } |