Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2015-08-15 04:27:55 -0400
committerEike Stepper2015-08-15 04:27:55 -0400
commitaff55d74f59fc7915dae22175c73e2960206b0db (patch)
tree7590bc4b89ae309bcf03fc38b6f315feabf071ff /plugins
parent23ba5dd08145f170273ba6f4f19e8f31b102e25d (diff)
downloadcdo-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
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOFeatureType.java213
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/checkouts/OfflineCDOCheckout.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/LocalCDORepository.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/.settings/.api_filters6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java96
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java40
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java18
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java25
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalMappingStrategy.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfig.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/offline/DBOfflineConfig.java2
-rw-r--r--plugins/org.eclipse.net4j.db/META-INF/MANIFEST.MF24
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java12
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java3
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java34
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBIndex.java10
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DelegatingDBTable.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java8
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java52
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/ddl/InternalDBIndex.java10
26 files changed, 555 insertions, 53 deletions
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>&gt;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);
}

Back to the top