diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.db/src/org')
50 files changed, 10221 insertions, 10221 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java index 032ff9be09..08e3f68fe2 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java @@ -1,287 +1,287 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - bug 271444: [DB] Multiple refactorings
- * Stefan Winkler - bug 275303: [DB] DBStore does not handle BIG_INTEGER and BIG_DECIMAL
- * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations
- * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations
- * Stefan Winkler - bug 285270: [DB] Support XSD based models
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.server.internal.db.DBAnnotation;
-import org.eclipse.emf.cdo.server.internal.db.MetaDataManager;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingRegistry;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.container.IManagedContainer;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common
- * types. Implementors should provide a constructor which the factory (see below) can use and implement
- * {@link #getResultSetValue(ResultSet)}. If needed, {@link #doSetValue(PreparedStatement, int, Object)} can also be
- * overridden as a counterpart to {@link #getResultSetValue(ResultSet)}. Finally, an implementor should also implement a
- * suitable factory for the {@link TypeMappingRegistry} and register it either manually using
- * {@link IManagedContainer#registerFactory(org.eclipse.net4j.util.factory.IFactory)} or using the Net4j Extension Point
- * <code>factories</code>.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 4.0
- */
-public abstract class AbstractTypeMapping implements ITypeMapping
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractTypeMapping.class);
-
- private IMappingStrategy mappingStrategy;
-
- private EStructuralFeature feature;
-
- private IDBField field;
-
- private DBType dbType;
-
- /**
- * Create a new type mapping
- */
- public AbstractTypeMapping()
- {
- super();
- }
-
- public final void setMappingStrategy(IMappingStrategy mappingStrategy)
- {
- this.mappingStrategy = mappingStrategy;
- }
-
- public final IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public final void setFeature(EStructuralFeature feature)
- {
- this.feature = feature;
- }
-
- public final EStructuralFeature getFeature()
- {
- return feature;
- }
-
- public final void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision revision)
- throws SQLException
- {
- setValue(stmt, index, getRevisionValue(revision));
- }
-
- public final void setDefaultValue(PreparedStatement stmt, int index) throws SQLException
- {
- setValue(stmt, index, getDefaultValue());
- }
-
- public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- if (value == CDORevisionData.NIL)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: converting Revision.NIL to DB-null", feature.getName()); //$NON-NLS-1$
- }
-
- stmt.setNull(index, getSqlType());
- }
- else if (value == null)
- {
- if (feature.isMany() || getDefaultValue() == null)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: writing Revision.null as DB.null", feature.getName()); //$NON-NLS-1$
- }
-
- stmt.setNull(index, getSqlType());
- }
- else
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: converting Revision.null to default value", feature.getName()); //$NON-NLS-1$
- }
-
- setDefaultValue(stmt, index);
- }
- }
- else
- {
- doSetValue(stmt, index, value);
- }
- }
-
- public final void createDBField(IDBTable table)
- {
- createDBField(table, mappingStrategy.getFieldName(feature));
- }
-
- public final void createDBField(IDBTable table, String fieldName)
- {
- DBType fieldType = getDBType();
- int fieldLength = getDBLength(fieldType);
- field = table.addField(fieldName, fieldType, fieldLength);
- }
-
- public final void setDBField(IDBTable table, String fieldName)
- {
- field = table.getField(fieldName);
- }
-
- public final IDBField getField()
- {
- return field;
- }
-
- public final void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException
- {
- Object value = readValue(resultSet);
- revision.setValue(getFeature(), value);
- }
-
- public final Object readValue(ResultSet resultSet) throws SQLException
- {
- Object value = getResultSetValue(resultSet);
- if (resultSet.wasNull())
- {
- if (feature.isMany())
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: read db.null - setting Revision.null", feature.getName()); //$NON-NLS-1$
- }
-
- value = null;
- }
- else
- {
- if (getDefaultValue() == null)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(
- "TypeMapping for {0}: read db.null - setting Revision.null, because of default", feature.getName()); //$NON-NLS-1$
- }
-
- value = null;
- }
- else
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: read db.null - setting Revision.NIL", feature.getName()); //$NON-NLS-1$
- }
-
- value = CDORevisionData.NIL;
- }
- }
- }
-
- return value;
- }
-
- protected Object getDefaultValue()
- {
- return feature.getDefaultValue();
- }
-
- protected final Object getRevisionValue(InternalCDORevision revision)
- {
- return revision.getValue(getFeature());
- }
-
- /**
- * Implementors could override this method to convert a given value to the database representation and set it to the
- * prepared statement.
- *
- * @param stmt
- * the {@link PreparedStatement} which is used for DB access
- * @param index
- * the parameter index in the statement which should be set
- * @param value
- * the value of the feature which should be written into the DB
- */
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setObject(index, value, getSqlType());
- }
-
- /**
- * Returns the SQL type of this TypeMapping. The default implementation considers the type map held by the
- * {@link MetaDataManager meta-data manager}. Subclasses may override.
- *
- * @return The sql type of this TypeMapping.
- */
- protected int getSqlType()
- {
- return getDBType().getCode();
- }
-
- public final void setDBType(DBType dbType)
- {
- this.dbType = dbType;
- }
-
- public DBType getDBType()
- {
- return dbType;
- }
-
- protected int getDBLength(DBType type)
- {
- String value = DBAnnotation.COLUMN_LENGTH.getValue(feature);
- if (value != null)
- {
- try
- {
- return Integer.parseInt(value);
- }
- catch (NumberFormatException e)
- {
- OM.LOG.error("Illegal columnLength annotation of feature " + feature.getName());
- }
- }
-
- // TODO: implement DBAdapter.getDBLength
- // mappingStrategy.getStore().getDBAdapter().getDBLength(type);
- // which should then return the correct default field length for the db type
- return type == DBType.VARCHAR ? 32672 : IDBField.DEFAULT;
- }
-
- /**
- * Subclasses should implement this method to read the value from the result set. Typical implementations should look
- * similar to this one: <code>resultSet.getString(getField().getName())</code>
- *
- * @param resultSet
- * the result set to read from
- * @return the result value read (this has to be compatible with the {@link #feature}.
- */
- protected abstract Object getResultSetValue(ResultSet resultSet) throws SQLException;
-
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - bug 271444: [DB] Multiple refactorings + * Stefan Winkler - bug 275303: [DB] DBStore does not handle BIG_INTEGER and BIG_DECIMAL + * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations + * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations + * Stefan Winkler - bug 285270: [DB] Support XSD based models + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.common.revision.CDORevisionData; +import org.eclipse.emf.cdo.server.internal.db.DBAnnotation; +import org.eclipse.emf.cdo.server.internal.db.MetaDataManager; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingRegistry; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common + * types. Implementors should provide a constructor which the factory (see below) can use and implement + * {@link #getResultSetValue(ResultSet)}. If needed, {@link #doSetValue(PreparedStatement, int, Object)} can also be + * overridden as a counterpart to {@link #getResultSetValue(ResultSet)}. Finally, an implementor should also implement a + * suitable factory for the {@link TypeMappingRegistry} and register it either manually using + * {@link IManagedContainer#registerFactory(org.eclipse.net4j.util.factory.IFactory)} or using the Net4j Extension Point + * <code>factories</code>. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 4.0 + */ +public abstract class AbstractTypeMapping implements ITypeMapping +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractTypeMapping.class); + + private IMappingStrategy mappingStrategy; + + private EStructuralFeature feature; + + private IDBField field; + + private DBType dbType; + + /** + * Create a new type mapping + */ + public AbstractTypeMapping() + { + super(); + } + + public final void setMappingStrategy(IMappingStrategy mappingStrategy) + { + this.mappingStrategy = mappingStrategy; + } + + public final IMappingStrategy getMappingStrategy() + { + return mappingStrategy; + } + + public final void setFeature(EStructuralFeature feature) + { + this.feature = feature; + } + + public final EStructuralFeature getFeature() + { + return feature; + } + + public final void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision revision) + throws SQLException + { + setValue(stmt, index, getRevisionValue(revision)); + } + + public final void setDefaultValue(PreparedStatement stmt, int index) throws SQLException + { + setValue(stmt, index, getDefaultValue()); + } + + public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + if (value == CDORevisionData.NIL) + { + if (TRACER.isEnabled()) + { + TRACER.format("TypeMapping for {0}: converting Revision.NIL to DB-null", feature.getName()); //$NON-NLS-1$ + } + + stmt.setNull(index, getSqlType()); + } + else if (value == null) + { + if (feature.isMany() || getDefaultValue() == null) + { + if (TRACER.isEnabled()) + { + TRACER.format("TypeMapping for {0}: writing Revision.null as DB.null", feature.getName()); //$NON-NLS-1$ + } + + stmt.setNull(index, getSqlType()); + } + else + { + if (TRACER.isEnabled()) + { + TRACER.format("TypeMapping for {0}: converting Revision.null to default value", feature.getName()); //$NON-NLS-1$ + } + + setDefaultValue(stmt, index); + } + } + else + { + doSetValue(stmt, index, value); + } + } + + public final void createDBField(IDBTable table) + { + createDBField(table, mappingStrategy.getFieldName(feature)); + } + + public final void createDBField(IDBTable table, String fieldName) + { + DBType fieldType = getDBType(); + int fieldLength = getDBLength(fieldType); + field = table.addField(fieldName, fieldType, fieldLength); + } + + public final void setDBField(IDBTable table, String fieldName) + { + field = table.getField(fieldName); + } + + public final IDBField getField() + { + return field; + } + + public final void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException + { + Object value = readValue(resultSet); + revision.setValue(getFeature(), value); + } + + public final Object readValue(ResultSet resultSet) throws SQLException + { + Object value = getResultSetValue(resultSet); + if (resultSet.wasNull()) + { + if (feature.isMany()) + { + if (TRACER.isEnabled()) + { + TRACER.format("TypeMapping for {0}: read db.null - setting Revision.null", feature.getName()); //$NON-NLS-1$ + } + + value = null; + } + else + { + if (getDefaultValue() == null) + { + if (TRACER.isEnabled()) + { + TRACER.format( + "TypeMapping for {0}: read db.null - setting Revision.null, because of default", feature.getName()); //$NON-NLS-1$ + } + + value = null; + } + else + { + if (TRACER.isEnabled()) + { + TRACER.format("TypeMapping for {0}: read db.null - setting Revision.NIL", feature.getName()); //$NON-NLS-1$ + } + + value = CDORevisionData.NIL; + } + } + } + + return value; + } + + protected Object getDefaultValue() + { + return feature.getDefaultValue(); + } + + protected final Object getRevisionValue(InternalCDORevision revision) + { + return revision.getValue(getFeature()); + } + + /** + * Implementors could override this method to convert a given value to the database representation and set it to the + * prepared statement. + * + * @param stmt + * the {@link PreparedStatement} which is used for DB access + * @param index + * the parameter index in the statement which should be set + * @param value + * the value of the feature which should be written into the DB + */ + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + stmt.setObject(index, value, getSqlType()); + } + + /** + * Returns the SQL type of this TypeMapping. The default implementation considers the type map held by the + * {@link MetaDataManager meta-data manager}. Subclasses may override. + * + * @return The sql type of this TypeMapping. + */ + protected int getSqlType() + { + return getDBType().getCode(); + } + + public final void setDBType(DBType dbType) + { + this.dbType = dbType; + } + + public DBType getDBType() + { + return dbType; + } + + protected int getDBLength(DBType type) + { + String value = DBAnnotation.COLUMN_LENGTH.getValue(feature); + if (value != null) + { + try + { + return Integer.parseInt(value); + } + catch (NumberFormatException e) + { + OM.LOG.error("Illegal columnLength annotation of feature " + feature.getName()); + } + } + + // TODO: implement DBAdapter.getDBLength + // mappingStrategy.getStore().getDBAdapter().getDBLength(type); + // which should then return the correct default field length for the db type + return type == DBType.VARCHAR ? 32672 : IDBField.DEFAULT; + } + + /** + * Subclasses should implement this method to read the value from the result set. Typical implementations should look + * similar to this one: <code>resultSet.getString(getField().getName())</code> + * + * @param resultSet + * the result set to read from + * @return the result value read (this has to be compatible with the {@link #feature}. + */ + protected abstract Object getResultSetValue(ResultSet resultSet) throws SQLException; + +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMappingFactory.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMappingFactory.java index 1fa92510f6..0f0e345cfe 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMappingFactory.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMappingFactory.java @@ -1,43 +1,43 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.db.mapping;
-
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping.Descriptor;
-
-import org.eclipse.net4j.util.factory.Factory;
-import org.eclipse.net4j.util.factory.ProductCreationException;
-
-/**
- * Abstract implementation for {@link ITypeMapping.Factory}. Implementors should implement their custom
- * {@link #create(String)} method and construct the factory using their custom descriptor. Subclasses must have a
- * default constructor!
- *
- * @author Stefan Winkler
- * @since 4.0
- */
-public abstract class AbstractTypeMappingFactory extends Factory implements
- org.eclipse.emf.cdo.server.db.mapping.ITypeMapping.Factory
-{
- private ITypeMapping.Descriptor descriptor;
-
- public AbstractTypeMappingFactory(Descriptor descriptor)
- {
- super(PRODUCT_GROUP, descriptor.getFactoryType());
- this.descriptor = descriptor;
- }
-
- public abstract ITypeMapping create(String description) throws ProductCreationException;
-
- public final Descriptor getDescriptor()
- {
- return descriptor;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.db.mapping; + +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping.Descriptor; + +import org.eclipse.net4j.util.factory.Factory; +import org.eclipse.net4j.util.factory.ProductCreationException; + +/** + * Abstract implementation for {@link ITypeMapping.Factory}. Implementors should implement their custom + * {@link #create(String)} method and construct the factory using their custom descriptor. Subclasses must have a + * default constructor! + * + * @author Stefan Winkler + * @since 4.0 + */ +public abstract class AbstractTypeMappingFactory extends Factory implements + org.eclipse.emf.cdo.server.db.mapping.ITypeMapping.Factory +{ + private ITypeMapping.Descriptor descriptor; + + public AbstractTypeMappingFactory(Descriptor descriptor) + { + super(PRODUCT_GROUP, descriptor.getFactoryType()); + this.descriptor = descriptor; + } + + public abstract ITypeMapping create(String description) throws ProductCreationException; + + public final Descriptor getDescriptor() + { + return descriptor; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java index 58468451a3..68dad77fe2 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java @@ -1,201 +1,201 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-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.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.PreparedStatement;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Basic interface for class mappings.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IClassMapping
-{
- /**
- * @since 3.0
- */
- public EClass getEClass();
-
- /**
- * Returns all DB tables which are used by this class and all its contained features.
- *
- * @return a collection of all tables of this class and all its contained features.
- * @since 3.0
- */
- public List<IDBTable> getDBTables();
-
- /**
- * Get the mapping of the many-valued feature.
- *
- * @param feature
- * the feature for which the mapping should be returned. <code>feature.isMany()</code> has to be
- * <code>true</code>.
- * @return the list mapping corresponding to the feature.
- */
- public IListMapping getListMapping(EStructuralFeature feature);
-
- /**
- * @since 3.0
- */
- public List<IListMapping> getListMappings();
-
- /**
- * @since 4.0
- */
- public List<ITypeMapping> getValueMappings();
-
- /**
- * Read a revision. The branch and timestamp to be read are derived from the branchPoint which is set to the Revision.
- * Note that non-audit stores only support {@link CDOBranchPoint#UNSPECIFIED_DATE} and non-branching stores only
- * support the main branch.
- *
- * @param accessor
- * the accessor to use.
- * @param revision
- * the revision object into which the data should be read. The revision has to be have its ID set to the
- * requested object's ID. The version is ignored, as the version parameter is used to determine the version
- * to be read.
- * @param listChunk
- * the chunk size to read attribute lists.
- * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision
- * could not be found. In this case, the content of <code>revision</code> is undefined.
- */
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk);
-
- /**
- * Write the revision data to the database.
- *
- * @param accessor
- * the accessor to use.
- * @param revision
- * the revision to write.
- * @param mapType
- * <code>true</code> if the type of the object is supposed to be mapped, <code>false</code> otherwise.
- * @param revise
- * <code>true</code> if the previous revision is supposed to be revised, <code>false</code> otherwise.
- * @param monitor
- * the monitor to indicate progress.
- * @since 4.0
- */
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise,
- OMMonitor monitor);
-
- /**
- * Detaches (deletes) a CDO object leaving a "ghost" revision behind.
- *
- * @param accessor
- * the accessor to use.
- * @param id
- * the id to revise.
- * @param version
- * the last valid version.
- * @param timeStamp
- * the timestamp of detach.
- * @param monitor
- * the monitor to indicate progress.
- * @since 3.0
- */
- public void detachObject(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp,
- OMMonitor monitor);
-
- /**
- * Create a prepared statement which returns all IDs of instances of the corresponding class.
- *
- * @param accessor
- * the accessor to use to create the statement
- * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>.
- * @since 3.0
- */
- public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor);
-
- /**
- * Create a prepared statement which returns all IDs of instances of the corresponding class.
- *
- * @param accessor
- * the accessor to use to create the statement
- * @param folderId
- * the ID of the containing folder. <code>0</code> means none.
- * @param name
- * the name of the resource node to look up
- * @param exactMatch
- * if <code>true</code>, <code>name</code> must match exactly, otherwise all resource nodes starting with
- * <code>name</code> are returned.
- * @param branchPoint
- * a branchPoint (branch and timestamp). A timestamp in the past if past versions should be looked up. In
- * case of no audit support, this must be {@link CDORevision#UNSPECIFIED_DATE}. In case of non branching
- * support the branch id must be equal to {@link CDOBranch#MAIN_BRANCH_ID}.
- * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>.
- * @throws ImplementationError
- * if called on a mapping which does not map an <code>EClass instanceof CDOResourceNode</code>.
- * @since 3.0
- */
- public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, CDOBranchPoint branchPoint);
-
- /**
- * Passes all revisions of the store to the {@link CDORevisionHandler handler} if <b>all</b> of the following
- * conditions are met:
- * <ul>
- * <li>The <code>branch</code> parameter is <code>null</code> or equal to <code>revision.getBranch()</code>.
- * <li>The <code>timeStamp</code> parameter is {@link CDOBranchPoint#UNSPECIFIED_DATE} or equal to
- * <code>revision.getTimeStamp()</code>.
- * </ul>
- *
- * @see IMappingStrategy#handleRevisions(IDBStoreAccessor, org.eclipse.emf.ecore.EClass, CDOBranch, long, boolean,
- * CDORevisionHandler)
- * @since 4.0
- */
- public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime,
- CDORevisionHandler handler);
-
- /**
- * Returns a set of CDOIDs that have at least one revision in any of the passed branches and time ranges.
- * DetachedCDORevisions must also be considered!
- *
- * @see IStoreAccessor#readChangeSet(OMMonitor, CDOChangeSetSegment...)
- * @since 3.0
- */
- public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments);
-
- /**
- * Retrieve cross-references from DB
- *
- * @param idString
- * a string of the form "(id1, id2, id3, ...)" which can be used directly in SQL to form the where-part
- * "SELECT * FROM foobar WHERE foobar.target IN [idString]".
- * @see IStoreAccessor#queryXRefs(QueryXRefsContext)
- * @since 4.0
- */
- public boolean queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context, String idString);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.db.mapping; + +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.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; +import org.eclipse.emf.cdo.server.IStoreAccessor; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.sql.PreparedStatement; +import java.util.List; +import java.util.Set; + +/** + * Basic interface for class mappings. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface IClassMapping +{ + /** + * @since 3.0 + */ + public EClass getEClass(); + + /** + * Returns all DB tables which are used by this class and all its contained features. + * + * @return a collection of all tables of this class and all its contained features. + * @since 3.0 + */ + public List<IDBTable> getDBTables(); + + /** + * Get the mapping of the many-valued feature. + * + * @param feature + * the feature for which the mapping should be returned. <code>feature.isMany()</code> has to be + * <code>true</code>. + * @return the list mapping corresponding to the feature. + */ + public IListMapping getListMapping(EStructuralFeature feature); + + /** + * @since 3.0 + */ + public List<IListMapping> getListMappings(); + + /** + * @since 4.0 + */ + public List<ITypeMapping> getValueMappings(); + + /** + * Read a revision. The branch and timestamp to be read are derived from the branchPoint which is set to the Revision. + * Note that non-audit stores only support {@link CDOBranchPoint#UNSPECIFIED_DATE} and non-branching stores only + * support the main branch. + * + * @param accessor + * the accessor to use. + * @param revision + * the revision object into which the data should be read. The revision has to be have its ID set to the + * requested object's ID. The version is ignored, as the version parameter is used to determine the version + * to be read. + * @param listChunk + * the chunk size to read attribute lists. + * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision + * could not be found. In this case, the content of <code>revision</code> is undefined. + */ + public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk); + + /** + * Write the revision data to the database. + * + * @param accessor + * the accessor to use. + * @param revision + * the revision to write. + * @param mapType + * <code>true</code> if the type of the object is supposed to be mapped, <code>false</code> otherwise. + * @param revise + * <code>true</code> if the previous revision is supposed to be revised, <code>false</code> otherwise. + * @param monitor + * the monitor to indicate progress. + * @since 4.0 + */ + public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, + OMMonitor monitor); + + /** + * Detaches (deletes) a CDO object leaving a "ghost" revision behind. + * + * @param accessor + * the accessor to use. + * @param id + * the id to revise. + * @param version + * the last valid version. + * @param timeStamp + * the timestamp of detach. + * @param monitor + * the monitor to indicate progress. + * @since 3.0 + */ + public void detachObject(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, + OMMonitor monitor); + + /** + * Create a prepared statement which returns all IDs of instances of the corresponding class. + * + * @param accessor + * the accessor to use to create the statement + * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>. + * @since 3.0 + */ + public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor); + + /** + * Create a prepared statement which returns all IDs of instances of the corresponding class. + * + * @param accessor + * the accessor to use to create the statement + * @param folderId + * the ID of the containing folder. <code>0</code> means none. + * @param name + * the name of the resource node to look up + * @param exactMatch + * if <code>true</code>, <code>name</code> must match exactly, otherwise all resource nodes starting with + * <code>name</code> are returned. + * @param branchPoint + * a branchPoint (branch and timestamp). A timestamp in the past if past versions should be looked up. In + * case of no audit support, this must be {@link CDORevision#UNSPECIFIED_DATE}. In case of non branching + * support the branch id must be equal to {@link CDOBranch#MAIN_BRANCH_ID}. + * @return the prepared statement ready to be executed using <code>result.executeQuery()</code>. + * @throws ImplementationError + * if called on a mapping which does not map an <code>EClass instanceof CDOResourceNode</code>. + * @since 3.0 + */ + public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, + boolean exactMatch, CDOBranchPoint branchPoint); + + /** + * Passes all revisions of the store to the {@link CDORevisionHandler handler} if <b>all</b> of the following + * conditions are met: + * <ul> + * <li>The <code>branch</code> parameter is <code>null</code> or equal to <code>revision.getBranch()</code>. + * <li>The <code>timeStamp</code> parameter is {@link CDOBranchPoint#UNSPECIFIED_DATE} or equal to + * <code>revision.getTimeStamp()</code>. + * </ul> + * + * @see IMappingStrategy#handleRevisions(IDBStoreAccessor, org.eclipse.emf.ecore.EClass, CDOBranch, long, boolean, + * CDORevisionHandler) + * @since 4.0 + */ + public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, + CDORevisionHandler handler); + + /** + * Returns a set of CDOIDs that have at least one revision in any of the passed branches and time ranges. + * DetachedCDORevisions must also be considered! + * + * @see IStoreAccessor#readChangeSet(OMMonitor, CDOChangeSetSegment...) + * @since 3.0 + */ + public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments); + + /** + * Retrieve cross-references from DB + * + * @param idString + * a string of the form "(id1, id2, id3, ...)" which can be used directly in SQL to form the where-part + * "SELECT * FROM foobar WHERE foobar.target IN [idString]". + * @see IStoreAccessor#queryXRefs(QueryXRefsContext) + * @since 4.0 + */ + public boolean queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context, String idString); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java index 0980409cba..5e4d317ab7 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingAuditSupport.java @@ -1,44 +1,44 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-/**
- * Interface which complements {@link IClassMapping} with methods to facilitate audit support.
- *
- * @see IMappingStrategy#hasAuditSupport()
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IClassMappingAuditSupport
-{
- /**
- * Read a specific version of a revision. If this method returns <code>true</code> it is guaranteed that
- * <code>revision.getVersion() == version</code>
- *
- * @param storeAccessor
- * the accessor to use.
- * @param revision
- * the revision object into which the data should be read. The revision has to be have its ID set to the
- * requested object's ID. The version is ignored, as the version parameter is used to determine the version
- * to be read.
- * @param listChunk
- * the chunk size to read attribute lists.
- * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision
- * could not be found. In this case, the content of <code>revision</code> is undefined.
- * @since 3.0
- */
- public boolean readRevisionByVersion(IDBStoreAccessor storeAccessor, InternalCDORevision revision, int listChunk);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +/** + * Interface which complements {@link IClassMapping} with methods to facilitate audit support. + * + * @see IMappingStrategy#hasAuditSupport() + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface IClassMappingAuditSupport +{ + /** + * Read a specific version of a revision. If this method returns <code>true</code> it is guaranteed that + * <code>revision.getVersion() == version</code> + * + * @param storeAccessor + * the accessor to use. + * @param revision + * the revision object into which the data should be read. The revision has to be have its ID set to the + * requested object's ID. The version is ignored, as the version parameter is used to determine the version + * to be read. + * @param listChunk + * the chunk size to read attribute lists. + * @return <code>true</code>, if the revision has been found and read correctly. <code>false</code> if the revision + * could not be found. In this case, the content of <code>revision</code> is undefined. + * @since 3.0 + */ + public boolean readRevisionByVersion(IDBStoreAccessor storeAccessor, InternalCDORevision revision, int listChunk); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java index ec23910917..e0ec0b2757 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingDeltaSupport.java @@ -1,43 +1,43 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-/**
- * Interface which complements {@link IClassMapping} with methods to facilitate revision delta support.
- *
- * @see IMappingStrategy#hasDeltaSupport()
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IClassMappingDeltaSupport
-{
- /**
- * Write a revision delta.
- *
- * @param accessor
- * the accessor to use.
- * @param delta
- * the delta to write.
- * @param created
- * the creation timestamp of the new version
- * @param monitor
- * the monitor to report progress.
- */
- public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
- OMMonitor monitor);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; + +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +/** + * Interface which complements {@link IClassMapping} with methods to facilitate revision delta support. + * + * @see IMappingStrategy#hasDeltaSupport() + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface IClassMappingDeltaSupport +{ + /** + * Write a revision delta. + * + * @param accessor + * the accessor to use. + * @param delta + * the delta to write. + * @param created + * the creation timestamp of the new version + * @param monitor + * the monitor to report progress. + */ + public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, + OMMonitor monitor); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java index 5e9bceb7da..d4e168a737 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java @@ -1,113 +1,113 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.ddl.IDBTable;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Interface for mapping features with <code>isMany() == true</code>.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IListMapping
-{
- /**
- * Return the mapped feature.
- *
- * @return the mapped feature.
- */
- public EStructuralFeature getFeature();
-
- /**
- * Returns all DB tables which are used by this feature.
- *
- * @return a collection of all tables of this feature.
- */
- public Collection<IDBTable> getDBTables();
-
- /**
- * Write a complete list of values to the database.
- *
- * @param accessor
- * the accessor to use.
- * @param revision
- * the revision containing the list to be written.
- */
- public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision);
-
- /**
- * Read the list size and the complete list or the first part of it.
- *
- * @param accessor
- * the accessor to use.
- * @param revision
- * the revision into which the list values should be read.
- * @param listChunk
- * indicating the lazy loading behavior: {@link CDORevision#UNCHUNKED} means that the whole list should be
- * read. Else, if <code>listChunk >= 0</code>, the list is filled with {@link InternalCDOList#UNINITIALIZED}
- * and only the first <code>listChunk</code> values are read.
- */
- public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk);
-
- /**
- * Used to load-on-demand chunks of a list.
- *
- * @param dbStoreChunkReader
- * the chunkReader to use
- * @param chunks
- * the chunks to read
- * @param where
- * the where-clause to use in order to read the chunks.
- */
- public void readChunks(IDBStoreChunkReader dbStoreChunkReader, List<Chunk> chunks, String where);
-
- /**
- * Hook with which a list mapping is notified that a containing object has been revised. Can be implemented in order
- * to clean up lists of revised objects.
- *
- * @param accessor
- * the accessor to use.
- * @param id
- * the ID of the object which has been revised.
- * @param revised
- * the timestamp at which the object was revised.
- * @since 3.0
- */
- public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised);
-
- /**
- * Retrieve cross-references from DB.
- *
- * @see IClassMapping#queryXRefs(IDBStoreAccessor, IStoreAccessor.QueryXRefsContext, String)
- * @see IStoreAccessor#queryXRefs(IStoreAccessor.QueryXRefsContext)
- * @since 4.0
- */
- public boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere,
- QueryXRefsContext context, String idString);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.IStoreAccessor; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +import org.eclipse.net4j.db.ddl.IDBTable; + +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.util.Collection; +import java.util.List; + +/** + * Interface for mapping features with <code>isMany() == true</code>. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface IListMapping +{ + /** + * Return the mapped feature. + * + * @return the mapped feature. + */ + public EStructuralFeature getFeature(); + + /** + * Returns all DB tables which are used by this feature. + * + * @return a collection of all tables of this feature. + */ + public Collection<IDBTable> getDBTables(); + + /** + * Write a complete list of values to the database. + * + * @param accessor + * the accessor to use. + * @param revision + * the revision containing the list to be written. + */ + public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision); + + /** + * Read the list size and the complete list or the first part of it. + * + * @param accessor + * the accessor to use. + * @param revision + * the revision into which the list values should be read. + * @param listChunk + * indicating the lazy loading behavior: {@link CDORevision#UNCHUNKED} means that the whole list should be + * read. Else, if <code>listChunk >= 0</code>, the list is filled with {@link InternalCDOList#UNINITIALIZED} + * and only the first <code>listChunk</code> values are read. + */ + public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk); + + /** + * Used to load-on-demand chunks of a list. + * + * @param dbStoreChunkReader + * the chunkReader to use + * @param chunks + * the chunks to read + * @param where + * the where-clause to use in order to read the chunks. + */ + public void readChunks(IDBStoreChunkReader dbStoreChunkReader, List<Chunk> chunks, String where); + + /** + * Hook with which a list mapping is notified that a containing object has been revised. Can be implemented in order + * to clean up lists of revised objects. + * + * @param accessor + * the accessor to use. + * @param id + * the ID of the object which has been revised. + * @param revised + * the timestamp at which the object was revised. + * @since 3.0 + */ + public void objectDetached(IDBStoreAccessor accessor, CDOID id, long revised); + + /** + * Retrieve cross-references from DB. + * + * @see IClassMapping#queryXRefs(IDBStoreAccessor, IStoreAccessor.QueryXRefsContext, String) + * @see IStoreAccessor#queryXRefs(IStoreAccessor.QueryXRefsContext) + * @since 4.0 + */ + public boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, + QueryXRefsContext context, String idString); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping2.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping2.java index 3cf0f5452d..f38dc3d119 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping2.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping2.java @@ -1,28 +1,28 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-
-/**
- * Extension interface to {@link IListMapping}.
- *
- * @author Eike Stepper
- * @since 4.1
- */
-public interface IListMapping2 extends IListMapping
-{
- public void addSimpleChunkWhere(IDBStoreAccessor accessor, CDOID cdoid, StringBuilder builder, int index);
-
- public void addRangedChunkWhere(IDBStoreAccessor accessor, CDOID cdoid, StringBuilder builder, int fromIndex,
- int toIndex);
-}
+/* + * Copyright (c) 2004 - 2012 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.server.db.mapping; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; + +/** + * Extension interface to {@link IListMapping}. + * + * @author Eike Stepper + * @since 4.1 + */ +public interface IListMapping2 extends IListMapping +{ + public void addSimpleChunkWhere(IDBStoreAccessor accessor, CDOID cdoid, StringBuilder builder, int index); + + public void addRangedChunkWhere(IDBStoreAccessor accessor, CDOID cdoid, StringBuilder builder, int fromIndex, + int toIndex); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java index 86a8805d16..8bc8690a7d 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java @@ -1,47 +1,47 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-
-/**
- * Interface to complement {@link IListMapping} in order to provide list delta processing support.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface IListMappingDeltaSupport
-{
- /**
- * Process a set of CDOFeatureDeltas for a many-valued feature.
- *
- * @param accessor
- * the accessor to use
- * @param id
- * the ID of the revision affected
- * @param oldVersion
- * the original version of the revision
- * @param newVersion
- * the new revision of the revision (after the change)
- * @param created
- * the creation date for the new revision
- * @param delta
- * the {@link CDOListFeatureDelta} which contains the list deltas.
- * @since 4.0
- */
- public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion,
- long created, CDOListFeatureDelta delta);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; + +/** + * Interface to complement {@link IListMapping} in order to provide list delta processing support. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface IListMappingDeltaSupport +{ + /** + * Process a set of CDOFeatureDeltas for a many-valued feature. + * + * @param accessor + * the accessor to use + * @param id + * the ID of the revision affected + * @param oldVersion + * the original version of the revision + * @param newVersion + * the new revision of the revision (after the change) + * @param created + * the creation date for the new revision + * @param delta + * the {@link CDOListFeatureDelta} which contains the list deltas. + * @since 4.0 + */ + public void processDelta(IDBStoreAccessor accessor, CDOID id, int branchId, int oldVersion, int newVersion, + long created, CDOListFeatureDelta delta); +} 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 7dbb8b060a..0f34a85e96 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 @@ -1,348 +1,348 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-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.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.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.internal.db.DBStore;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.util.collection.CloseableIterator;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.ENamedElement;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * The mapping strategy acts as a connection between the DBStore and the database management (and OR-mapping) classes.
- * The {@link DBStore} uses methods of this interface to create and lookup mappings (or mappers, as they could also be
- * named as such) and to get properties and informations about the mappings used. The mapping classes (e.g., instances
- * of IClassMapping and IListMapping) also use this class as a central point of information and as a resource of common
- * functionalities.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-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.
- */
- public static final String PROP_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 PROP_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 PROP_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 PROP_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 PROP_FORCE_NAMES_WITH_ID = "forceNamesWithID"; //$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.
- * <p>
- *
- * @since 4.0
- */
- public static final String PROP_OBJECT_TYPE_CACHE_SIZE = "objectTypeCacheSize"; //$NON-NLS-1$
-
- /**
- * @return the store, this MappingStrategy instance belongs to.
- */
- public IDBStore getStore();
-
- /**
- * Set the store to which this MappingStrategy instance belongs. Should only be called by the {@link DBStore}, and
- * only once to initialize the connection between {@link DBStore} and mapping strategy.
- *
- * @param dbStore
- * the DBStore instance to which this MappingStrategy instance belongs.
- */
- public void setStore(IDBStore dbStore);
-
- /**
- * Factory for value mappings of single-valued attributes.
- *
- * @param feature
- * the feature for which a mapping should be created. It must hold <code>feature.isMany() == false</code>.
- * @return the mapping created.
- */
- public ITypeMapping createValueMapping(EStructuralFeature feature);
-
- /**
- * Factory for value mappings of multi-valued-attributes.
- *
- * @param containingClass
- * the class containing the feature.
- * @param feature
- * the feature for which a mapping should be created. It must hold <code>feature.isMany() == true</code>.
- */
- public IListMapping createListMapping(EClass containingClass, EStructuralFeature feature);
-
- /**
- * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes.
- *
- * @param element
- * the element for which the name should be created. It must hold:
- * <code>element instanceof EClass || element instanceof EPackage</code>.
- * @return the created table name. It is guaranteed that the table name is compatible with the chosen database.
- */
- public String getTableName(ENamedElement element);
-
- /**
- * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes.
- * Should only be called by mapping classes.
- *
- * @param containingClass
- * the class containeng the feature.
- * @param feature
- * the feature for which the table name should be created.
- * @return the created table name. It is guaranteed that the table name is compatible with the chosen database.
- */
- public String getTableName(EClass containingClass, EStructuralFeature feature);
-
- /**
- * Create a suitable column name which can be used to map the given element. Should only be called by mapping classes.
- *
- * @param feature
- * the feature for which the column name should be created.
- * @return the created column name. It is guaranteed that the name is compatible with the chosen database.
- */
- public String getFieldName(EStructuralFeature feature);
-
- /**
- * Create and initialize the mapping infrastructure for the given packages. Should be called from the DBStore or the
- * DBStoreAccessor.
- *
- * @param connection
- * the connection to use.
- * @param packageUnits
- * the packages whose elements should be mapped.
- * @param monitor
- * the monitor to report progress.
- */
- public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor);
-
- /**
- * Remove the mapping infrastructure for the given packages. Should be called from the DBStore or the DBStoreAccessor.
- *
- * @param connection
- * the connection to use.
- * @param packageUnits
- * the packages for which the mappings should be removed
- * @since 4.0
- */
- // Bugzilla 298632
- public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits);
-
- /**
- * Look up an existing class mapping for the given class. Before this method is called, the class mapping must have
- * been initialized by calling {@link #createMapping(Connection, InternalCDOPackageUnit[], OMMonitor)} on its
- * containing package.
- *
- * @param eClass
- * the class to look up.
- * @return the class mapping.
- */
- public IClassMapping getClassMapping(EClass eClass);
-
- /**
- * Returns all class mappings of this strategy.
- *
- * @since 4.0
- */
- public Map<EClass, IClassMapping> getClassMappings();
-
- /**
- * Returns all class mappings of this strategy.
- *
- * @since 4.0
- */
- public Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand);
-
- /**
- * Query if this mapping supports revision deltas. <br>
- * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by
- * {@link #getClassMapping(EClass)} implement {@link IClassMappingDeltaSupport}.
- *
- * @return <code>true</code> if revision deltas are supported, <code>false</code> else.
- */
- public boolean hasDeltaSupport();
-
- /**
- * Query if this mapping supports audits. <br>
- * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by
- * {@link #getClassMapping(EClass)} implement {@link IClassMappingAuditSupport}.
- *
- * @return <code>true</code> if audits are supported, <code>false</code> else.
- */
- public boolean hasAuditSupport();
-
- /**
- * Query if this mapping supports branches. <br>
- *
- * @return <code>true</code> if branches are supported, <code>false</code> else.
- * @since 3.0
- */
- public boolean hasBranchingSupport();
-
- /**
- * Executes a resource query.
- *
- * @param accessor
- * the accessor to use.
- * @param context
- * the context from which the query parameters are read and to which the result is written.
- */
- public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context);
-
- /**
- * Executes a cross reference query.
- *
- * @param accessor
- * the accessor to use.
- * @param context
- * the context from which the query parameters are read and to which the result is written.
- * @since 3.0
- */
- public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context);
-
- /**
- * Read the type (i.e. class) of the object referred to by a given ID.
- *
- * @param accessor
- * the accessor to use to look up the type.
- * @param id
- * the ID of the object for which the type is to be determined.
- * @return the type of the object.
- */
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id);
-
- /**
- * Get an iterator over all instances of objects in the store.
- *
- * @param accessor
- * the accessor to use.
- * @return the iterator.
- */
- public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor);
-
- /**
- * Return the maximum object id used in the store. This is used by the DBStore if a previous crash is discovered
- * during the startup process. Should only be called by the DBStore and only during startup.
- *
- * @param dbAdapter
- * the dbAdapter to use to access the database
- * @param connection
- * the connection to use to access the database
- * @since 4.0
- */
- public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection);
-
- /**
- * Returns the configuration properties of this mapping strategy.
- *
- * @since 4.0
- */
- public Map<String, String> getProperties();
-
- /**
- * Set configuration properties for this mapping strategy. Should only be called by the factory creating the mapping
- * strategy instance.
- *
- * @param properties
- * the configuration properties to set.
- */
- public void setProperties(Map<String, String> properties);
-
- /**
- * Passes all revisions of the store to the {@link CDORevisionHandler handler} if <b>all</b> of the following
- * conditions are met:
- * <ul>
- * <li>The <code>eClass</code> parameter is <code>null</code> or equal to <code>revision.getEClass()</code>.
- * <li>The <code>branch</code> parameter is <code>null</code> or equal to <code>revision.getBranch()</code>.
- * <li>The <code>timeStamp</code> parameter is {@link CDOBranchPoint#UNSPECIFIED_DATE} or equal to
- * <code>revision.getTimeStamp()</code>.
- * </ul>
- *
- * @since 4.0
- */
- public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp,
- boolean exactTime, CDORevisionHandler handler);
-
- /**
- * Returns a set of CDOIDs that have at least one revision in any of the passed branches and time ranges.
- * DetachedCDORevisions must also be considered!
- *
- * @see IStoreAccessor#readChangeSet(OMMonitor, CDOChangeSetSegment...)
- * @since 4.0
- */
- public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments);
-
- /**
- * @since 3.0
- */
- public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int lastReplicatedBranchID, int lastBranchID,
- long lastReplicatedCommitTime, long lastCommitTime) throws IOException;
-
- /**
- * @since 4.0
- */
- public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException;
-
- /**
- * @since 4.0
- */
- public String getListJoin(String attrTable, String listTable);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.db.mapping; + +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.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.IStoreAccessor; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.internal.db.DBStore; +import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; + +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.util.collection.CloseableIterator; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.io.IOException; +import java.sql.Connection; +import java.util.Map; +import java.util.Set; + +/** + * The mapping strategy acts as a connection between the DBStore and the database management (and OR-mapping) classes. + * The {@link DBStore} uses methods of this interface to create and lookup mappings (or mappers, as they could also be + * named as such) and to get properties and informations about the mappings used. The mapping classes (e.g., instances + * of IClassMapping and IListMapping) also use this class as a central point of information and as a resource of common + * functionalities. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +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. + */ + public static final String PROP_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 PROP_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 PROP_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 PROP_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 PROP_FORCE_NAMES_WITH_ID = "forceNamesWithID"; //$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. + * <p> + * + * @since 4.0 + */ + public static final String PROP_OBJECT_TYPE_CACHE_SIZE = "objectTypeCacheSize"; //$NON-NLS-1$ + + /** + * @return the store, this MappingStrategy instance belongs to. + */ + public IDBStore getStore(); + + /** + * Set the store to which this MappingStrategy instance belongs. Should only be called by the {@link DBStore}, and + * only once to initialize the connection between {@link DBStore} and mapping strategy. + * + * @param dbStore + * the DBStore instance to which this MappingStrategy instance belongs. + */ + public void setStore(IDBStore dbStore); + + /** + * Factory for value mappings of single-valued attributes. + * + * @param feature + * the feature for which a mapping should be created. It must hold <code>feature.isMany() == false</code>. + * @return the mapping created. + */ + public ITypeMapping createValueMapping(EStructuralFeature feature); + + /** + * Factory for value mappings of multi-valued-attributes. + * + * @param containingClass + * the class containing the feature. + * @param feature + * the feature for which a mapping should be created. It must hold <code>feature.isMany() == true</code>. + */ + public IListMapping createListMapping(EClass containingClass, EStructuralFeature feature); + + /** + * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes. + * + * @param element + * the element for which the name should be created. It must hold: + * <code>element instanceof EClass || element instanceof EPackage</code>. + * @return the created table name. It is guaranteed that the table name is compatible with the chosen database. + */ + public String getTableName(ENamedElement element); + + /** + * Create a suitable table name which can be used to map the given element. Should only be called by mapping classes. + * Should only be called by mapping classes. + * + * @param containingClass + * the class containeng the feature. + * @param feature + * the feature for which the table name should be created. + * @return the created table name. It is guaranteed that the table name is compatible with the chosen database. + */ + public String getTableName(EClass containingClass, EStructuralFeature feature); + + /** + * Create a suitable column name which can be used to map the given element. Should only be called by mapping classes. + * + * @param feature + * the feature for which the column name should be created. + * @return the created column name. It is guaranteed that the name is compatible with the chosen database. + */ + public String getFieldName(EStructuralFeature feature); + + /** + * Create and initialize the mapping infrastructure for the given packages. Should be called from the DBStore or the + * DBStoreAccessor. + * + * @param connection + * the connection to use. + * @param packageUnits + * the packages whose elements should be mapped. + * @param monitor + * the monitor to report progress. + */ + public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor); + + /** + * Remove the mapping infrastructure for the given packages. Should be called from the DBStore or the DBStoreAccessor. + * + * @param connection + * the connection to use. + * @param packageUnits + * the packages for which the mappings should be removed + * @since 4.0 + */ + // Bugzilla 298632 + public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits); + + /** + * Look up an existing class mapping for the given class. Before this method is called, the class mapping must have + * been initialized by calling {@link #createMapping(Connection, InternalCDOPackageUnit[], OMMonitor)} on its + * containing package. + * + * @param eClass + * the class to look up. + * @return the class mapping. + */ + public IClassMapping getClassMapping(EClass eClass); + + /** + * Returns all class mappings of this strategy. + * + * @since 4.0 + */ + public Map<EClass, IClassMapping> getClassMappings(); + + /** + * Returns all class mappings of this strategy. + * + * @since 4.0 + */ + public Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand); + + /** + * Query if this mapping supports revision deltas. <br> + * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by + * {@link #getClassMapping(EClass)} implement {@link IClassMappingDeltaSupport}. + * + * @return <code>true</code> if revision deltas are supported, <code>false</code> else. + */ + public boolean hasDeltaSupport(); + + /** + * Query if this mapping supports audits. <br> + * If this method returns <code>true</code>, it is guaranteed that all class mappings returned by + * {@link #getClassMapping(EClass)} implement {@link IClassMappingAuditSupport}. + * + * @return <code>true</code> if audits are supported, <code>false</code> else. + */ + public boolean hasAuditSupport(); + + /** + * Query if this mapping supports branches. <br> + * + * @return <code>true</code> if branches are supported, <code>false</code> else. + * @since 3.0 + */ + public boolean hasBranchingSupport(); + + /** + * Executes a resource query. + * + * @param accessor + * the accessor to use. + * @param context + * the context from which the query parameters are read and to which the result is written. + */ + public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context); + + /** + * Executes a cross reference query. + * + * @param accessor + * the accessor to use. + * @param context + * the context from which the query parameters are read and to which the result is written. + * @since 3.0 + */ + public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context); + + /** + * Read the type (i.e. class) of the object referred to by a given ID. + * + * @param accessor + * the accessor to use to look up the type. + * @param id + * the ID of the object for which the type is to be determined. + * @return the type of the object. + */ + public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id); + + /** + * Get an iterator over all instances of objects in the store. + * + * @param accessor + * the accessor to use. + * @return the iterator. + */ + public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor); + + /** + * Return the maximum object id used in the store. This is used by the DBStore if a previous crash is discovered + * during the startup process. Should only be called by the DBStore and only during startup. + * + * @param dbAdapter + * the dbAdapter to use to access the database + * @param connection + * the connection to use to access the database + * @since 4.0 + */ + public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection); + + /** + * Returns the configuration properties of this mapping strategy. + * + * @since 4.0 + */ + public Map<String, String> getProperties(); + + /** + * Set configuration properties for this mapping strategy. Should only be called by the factory creating the mapping + * strategy instance. + * + * @param properties + * the configuration properties to set. + */ + public void setProperties(Map<String, String> properties); + + /** + * Passes all revisions of the store to the {@link CDORevisionHandler handler} if <b>all</b> of the following + * conditions are met: + * <ul> + * <li>The <code>eClass</code> parameter is <code>null</code> or equal to <code>revision.getEClass()</code>. + * <li>The <code>branch</code> parameter is <code>null</code> or equal to <code>revision.getBranch()</code>. + * <li>The <code>timeStamp</code> parameter is {@link CDOBranchPoint#UNSPECIFIED_DATE} or equal to + * <code>revision.getTimeStamp()</code>. + * </ul> + * + * @since 4.0 + */ + public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp, + boolean exactTime, CDORevisionHandler handler); + + /** + * Returns a set of CDOIDs that have at least one revision in any of the passed branches and time ranges. + * DetachedCDORevisions must also be considered! + * + * @see IStoreAccessor#readChangeSet(OMMonitor, CDOChangeSetSegment...) + * @since 4.0 + */ + public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments); + + /** + * @since 3.0 + */ + public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int lastReplicatedBranchID, int lastBranchID, + long lastReplicatedCommitTime, long lastCommitTime) throws IOException; + + /** + * @since 4.0 + */ + public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException; + + /** + * @since 4.0 + */ + public String getListJoin(String attrTable, String listTable); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java index 4fe43bfd7a..8a7bca2835 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java @@ -1,278 +1,278 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455
- */
-package org.eclipse.emf.cdo.server.db.mapping;
-
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingRegistry;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingUtil;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.factory.IFactory;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-
-/**
- * Mapping of single values to and from the database.
- *
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 2.0
- */
-public interface ITypeMapping
-{
- /**
- * @return The feature which is associated with this mapping.
- */
- public EStructuralFeature getFeature();
-
- /**
- * @return The db field which is associated with this mapping.
- */
- public IDBField getField();
-
- /**
- * @return The db type which is associated with this mapping.
- * @since 3.0
- */
- public DBType getDBType();
-
- /**
- * @since 4.0
- */
- public void setMappingStrategy(IMappingStrategy mappingStrategy);
-
- /**
- * @since 4.0
- */
- public void setFeature(EStructuralFeature feature);
-
- /**
- * @since 4.0
- */
- public void setDBType(DBType dbType);
-
- /**
- * Creates the DBField and adds it to the given table. The name of the DBField is derived from the feature.
- *
- * @param table
- * the table to add this field to.
- */
- public void createDBField(IDBTable table);
-
- /**
- * Creates the DBField and adds it to the given table. The name of the DBField is explicitly determined by the
- * corresponding parameter.
- *
- * @param table
- * the table to add this field to.
- * @param fieldName
- * the name for the DBField.
- */
- public void createDBField(IDBTable table, String fieldName);
-
- /**
- * Sets the DBField. The name of the DBField is explicitly determined by the corresponding parameter.
- *
- * @param table
- * the table to add this field to.
- * @param fieldName
- * the name for the DBField.
- * @since 3.0
- */
- public void setDBField(IDBTable table, String fieldName);
-
- /**
- * Set the given value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> method.
- *
- * @param stmt
- * the prepared statement to set the value
- * @param index
- * the index to use for the <code>setXxx</code> method.
- * @param value
- * the value to set.
- * @throws SQLException
- * if the <code>setXxx</code> throws it.
- */
- public void setValue(PreparedStatement stmt, int index, Object value) throws SQLException;
-
- /**
- * Set the feature's default value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code>
- * method.
- *
- * @param stmt
- * the prepared statement to set the value
- * @param index
- * the index to use for the <code>setXxx</code> method.
- * @throws SQLException
- * if the <code>setXxx</code> throws it.
- * @since 3.0
- */
- public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException;
-
- /**
- * Set a value of the given revision to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code>
- * method. The feature from which the value is taken is determined by {@link #getFeature()}.
- *
- * @param stmt
- * the prepared statement to set the value
- * @param index
- * the index to use for the <code>setXxx</code> method.
- * @param value
- * the revision to get the value to set from.
- * @throws SQLException
- * if the <code>setXxx</code> throws it.
- */
- public void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision value) throws SQLException;
-
- /**
- * Read the value from a {@link ResultSet} and convert it from the DB to the CDO representation. The resultSet field
- * to read from is determined automatically by the internal {@link #getField()} name.
- *
- * @param resultSet
- * the result set to read from
- * @return the read value
- * @throws SQLException
- * if reading the value throws an SQLException
- * @since 3.0
- */
- public Object readValue(ResultSet resultSet) throws SQLException;
-
- /**
- * Read a value from a {@link ResultSet}, convert it from the DB to the CDO representation and set it to the feature
- * of the revision. The feature is determined by getFeature() The resultSet field to read from is determined
- * automatically by the internal {@link #getField()} name.
- *
- * @param resultSet
- * the result set to read from
- * @param revision
- * the revision to which the value should be set.
- * @throws SQLException
- * if reading the value throws an SQLException
- * @since 3.0
- */
- public void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException;
-
- /**
- * A descriptor which describes one type mapping class. The descriptor is encoded in the factoryType which is used as
- * a string description for the extension point mechanism. Translations and instantiations can be done using the
- * methods in {@link TypeMappingUtil}.
- *
- * @author Stefan Winkler
- * @since 4.0
- */
- public interface Descriptor
- {
- /**
- * The factoryType of the factory which can create the type mapping
- */
- public String getFactoryType();
-
- /**
- * The ID of the described type mapping.
- */
- public String getID();
-
- /**
- * The source (i.e., model) type that can be mapped by the type mapping.
- */
- public EClassifier getEClassifier();
-
- /**
- * The target (i.e., db) type that can be mapped by the type mapping.
- */
- public DBType getDBType();
-
- }
-
- /**
- * A global (singleton) registry which collects all available type mappings which are either available in the CDO
- * core, as declared extensions, or registered manually.
- *
- * @author Stefan Winkler
- * @since 4.0
- */
- public interface Registry
- {
- /**
- * The one global (singleton) registry instance.
- */
- public static Registry INSTANCE = new TypeMappingRegistry();
-
- /**
- * Register a type mapping by descriptor.
- */
- public void registerTypeMapping(ITypeMapping.Descriptor descriptor);
-
- /**
- * Provides a list of all DBTypes for which type mappings exist in the registry. This is used in feature map tables
- * to create columns for all of these types.
- */
- public Collection<DBType> getDefaultFeatureMapDBTypes();
- }
-
- /**
- * A provider for type mapping information. This provider is used by the {@link TypeMappingRegistry} to create an
- * {@link ITypeMapping} instance suitable for a given feature and DB field. Usually, one factory is responsible for
- * one type mapping.
- *
- * @author Stefan Winkler
- * @since 4.0
- */
- public interface Provider
- {
- /**
- * The one global (singleton) provider instance.
- */
- public static Provider INSTANCE = (Provider)Registry.INSTANCE;
-
- /**
- * Create an {@link ITypeMapping} implementation.
- *
- * @param mappingStrategy
- * the mapping strategy
- * @param feature
- * the feature the new type mapping shall be responsible for
- * @return the newly created {@link ITypeMapping} instance
- */
- public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature);
- }
-
- /**
- * A factory for typeMappings. This is a regular Net4j factory registered by the respective extension point. It
- * enhances the regular factory using a descriptor which is translated from and to the factoryType by the methods in
- * {@link TypeMappingUtil}.
- *
- * @author Stefan Winkler
- * @since 4.0
- */
- public interface Factory extends IFactory
- {
- /**
- * The Net4j factory product group for type mappings
- */
- public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.db.typeMappings";
-
- /**
- * Return the descriptor of the kind of type mapping created by this factory.
- */
- public ITypeMapping.Descriptor getDescriptor();
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455 + */ +package org.eclipse.emf.cdo.server.db.mapping; + +import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingRegistry; +import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingUtil; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.factory.IFactory; + +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +/** + * Mapping of single values to and from the database. + * + * @author Eike Stepper + * @author Stefan Winkler + * @since 2.0 + */ +public interface ITypeMapping +{ + /** + * @return The feature which is associated with this mapping. + */ + public EStructuralFeature getFeature(); + + /** + * @return The db field which is associated with this mapping. + */ + public IDBField getField(); + + /** + * @return The db type which is associated with this mapping. + * @since 3.0 + */ + public DBType getDBType(); + + /** + * @since 4.0 + */ + public void setMappingStrategy(IMappingStrategy mappingStrategy); + + /** + * @since 4.0 + */ + public void setFeature(EStructuralFeature feature); + + /** + * @since 4.0 + */ + public void setDBType(DBType dbType); + + /** + * Creates the DBField and adds it to the given table. The name of the DBField is derived from the feature. + * + * @param table + * the table to add this field to. + */ + public void createDBField(IDBTable table); + + /** + * Creates the DBField and adds it to the given table. The name of the DBField is explicitly determined by the + * corresponding parameter. + * + * @param table + * the table to add this field to. + * @param fieldName + * the name for the DBField. + */ + public void createDBField(IDBTable table, String fieldName); + + /** + * Sets the DBField. The name of the DBField is explicitly determined by the corresponding parameter. + * + * @param table + * the table to add this field to. + * @param fieldName + * the name for the DBField. + * @since 3.0 + */ + public void setDBField(IDBTable table, String fieldName); + + /** + * Set the given value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> method. + * + * @param stmt + * the prepared statement to set the value + * @param index + * the index to use for the <code>setXxx</code> method. + * @param value + * the value to set. + * @throws SQLException + * if the <code>setXxx</code> throws it. + */ + public void setValue(PreparedStatement stmt, int index, Object value) throws SQLException; + + /** + * Set the feature's default value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> + * method. + * + * @param stmt + * the prepared statement to set the value + * @param index + * the index to use for the <code>setXxx</code> method. + * @throws SQLException + * if the <code>setXxx</code> throws it. + * @since 3.0 + */ + public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException; + + /** + * Set a value of the given revision to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> + * method. The feature from which the value is taken is determined by {@link #getFeature()}. + * + * @param stmt + * the prepared statement to set the value + * @param index + * the index to use for the <code>setXxx</code> method. + * @param value + * the revision to get the value to set from. + * @throws SQLException + * if the <code>setXxx</code> throws it. + */ + public void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision value) throws SQLException; + + /** + * Read the value from a {@link ResultSet} and convert it from the DB to the CDO representation. The resultSet field + * to read from is determined automatically by the internal {@link #getField()} name. + * + * @param resultSet + * the result set to read from + * @return the read value + * @throws SQLException + * if reading the value throws an SQLException + * @since 3.0 + */ + public Object readValue(ResultSet resultSet) throws SQLException; + + /** + * Read a value from a {@link ResultSet}, convert it from the DB to the CDO representation and set it to the feature + * of the revision. The feature is determined by getFeature() The resultSet field to read from is determined + * automatically by the internal {@link #getField()} name. + * + * @param resultSet + * the result set to read from + * @param revision + * the revision to which the value should be set. + * @throws SQLException + * if reading the value throws an SQLException + * @since 3.0 + */ + public void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException; + + /** + * A descriptor which describes one type mapping class. The descriptor is encoded in the factoryType which is used as + * a string description for the extension point mechanism. Translations and instantiations can be done using the + * methods in {@link TypeMappingUtil}. + * + * @author Stefan Winkler + * @since 4.0 + */ + public interface Descriptor + { + /** + * The factoryType of the factory which can create the type mapping + */ + public String getFactoryType(); + + /** + * The ID of the described type mapping. + */ + public String getID(); + + /** + * The source (i.e., model) type that can be mapped by the type mapping. + */ + public EClassifier getEClassifier(); + + /** + * The target (i.e., db) type that can be mapped by the type mapping. + */ + public DBType getDBType(); + + } + + /** + * A global (singleton) registry which collects all available type mappings which are either available in the CDO + * core, as declared extensions, or registered manually. + * + * @author Stefan Winkler + * @since 4.0 + */ + public interface Registry + { + /** + * The one global (singleton) registry instance. + */ + public static Registry INSTANCE = new TypeMappingRegistry(); + + /** + * Register a type mapping by descriptor. + */ + public void registerTypeMapping(ITypeMapping.Descriptor descriptor); + + /** + * Provides a list of all DBTypes for which type mappings exist in the registry. This is used in feature map tables + * to create columns for all of these types. + */ + public Collection<DBType> getDefaultFeatureMapDBTypes(); + } + + /** + * A provider for type mapping information. This provider is used by the {@link TypeMappingRegistry} to create an + * {@link ITypeMapping} instance suitable for a given feature and DB field. Usually, one factory is responsible for + * one type mapping. + * + * @author Stefan Winkler + * @since 4.0 + */ + public interface Provider + { + /** + * The one global (singleton) provider instance. + */ + public static Provider INSTANCE = (Provider)Registry.INSTANCE; + + /** + * Create an {@link ITypeMapping} implementation. + * + * @param mappingStrategy + * the mapping strategy + * @param feature + * the feature the new type mapping shall be responsible for + * @return the newly created {@link ITypeMapping} instance + */ + public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature); + } + + /** + * A factory for typeMappings. This is a regular Net4j factory registered by the respective extension point. It + * enhances the regular factory using a descriptor which is translated from and to the factoryType by the methods in + * {@link TypeMappingUtil}. + * + * @author Stefan Winkler + * @since 4.0 + */ + public interface Factory extends IFactory + { + /** + * The Net4j factory product group for type mappings + */ + public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.db.typeMappings"; + + /** + * Return the descriptor of the kind of type mapping created by this factory. + */ + public ITypeMapping.Descriptor getDescriptor(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/package-info.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/package-info.java index 4b4c63905a..e1b3d052c5 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/package-info.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/package-info.java @@ -1,15 +1,15 @@ -/*
- * Copyright (c) 2004 - 2012 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
- */
-
-/**
- * Server concepts for dealing with mapping strategies and mappings for classes, lists and types.
- */
-package org.eclipse.emf.cdo.server.db.mapping;
+/* + * Copyright (c) 2004 - 2012 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 + */ + +/** + * Server concepts for dealing with mapping strategies and mappings for classes, lists and types. + */ +package org.eclipse.emf.cdo.server.db.mapping; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/package-info.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/package-info.java index 9d59198382..7ef9ed90d4 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/package-info.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/package-info.java @@ -1,15 +1,15 @@ -/*
- * Copyright (c) 2004 - 2012 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
- */
-
-/**
- * Server concepts for dealing with DB stores and accessors.
- */
-package org.eclipse.emf.cdo.server.db;
+/* + * Copyright (c) 2004 - 2012 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 + */ + +/** + * Server concepts for dealing with DB stores and accessors. + */ +package org.eclipse.emf.cdo.server.db; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java index aabfbefbc5..40ee479ff6 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/AbstractPreparedStatementCache.java @@ -1,47 +1,47 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Stefan Winkler - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-
-import java.sql.Connection;
-
-/**
- * @author Stefan Winkler
- * @since 2.0
- */
-public abstract class AbstractPreparedStatementCache extends Lifecycle implements IPreparedStatementCache
-{
- private Connection connection;
-
- public AbstractPreparedStatementCache()
- {
- }
-
- public final Connection getConnection()
- {
- return connection;
- }
-
- public final void setConnection(Connection connection)
- {
- checkInactive();
- this.connection = connection;
- }
-
- @Override
- protected void doBeforeActivate()
- {
- checkState(connection, "Must have valid connection to start"); //$NON-NLS-1$
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Stefan Winkler - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache; + +import org.eclipse.net4j.util.lifecycle.Lifecycle; + +import java.sql.Connection; + +/** + * @author Stefan Winkler + * @since 2.0 + */ +public abstract class AbstractPreparedStatementCache extends Lifecycle implements IPreparedStatementCache +{ + private Connection connection; + + public AbstractPreparedStatementCache() + { + } + + public final Connection getConnection() + { + return connection; + } + + public final void setConnection(Connection connection) + { + checkInactive(); + this.connection = connection; + } + + @Override + protected void doBeforeActivate() + { + checkState(connection, "Must have valid connection to start"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java index 0c6c8bf7b4..c7f8d205b2 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java @@ -1,267 +1,267 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- * Stefan Winkler - 249610: [DB] Support external references (Implementation)
- * Andre Dietisheim - bug 256649
- *
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBIndex;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.spi.db.DBSchema;
-
-/**
- * @author Eike Stepper
- */
-public class CDODBSchema extends DBSchema
-{
- public static final CDODBSchema INSTANCE = new CDODBSchema();
-
- /**
- * DBTable cdo_properties
- */
- public static final IDBTable PROPERTIES = INSTANCE.addTable("cdo_properties"); //$NON-NLS-1$
-
- public static final IDBField PROPERTIES_NAME = //
- PROPERTIES.addField("name", DBType.VARCHAR, 255); //$NON-NLS-1$
-
- public static final IDBField PROPERTIES_VALUE = //
- PROPERTIES.addField("value", DBType.LONGVARCHAR); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_PROPERTIES_PK = //
- PROPERTIES.addIndex(IDBIndex.Type.PRIMARY_KEY, PROPERTIES_NAME);
-
- public static final String SQL_DELETE_PROPERTIES = "DELETE FROM " + PROPERTIES + " WHERE " + PROPERTIES_NAME + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- public static final String SQL_INSERT_PROPERTIES = "INSERT INTO " + PROPERTIES + " (" + PROPERTIES_NAME + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + PROPERTIES_VALUE + ") VALUES (?, ?)"; //$NON-NLS-1$
-
- public static final String SQL_SELECT_PROPERTIES = "SELECT " + PROPERTIES_VALUE + " FROM " + PROPERTIES + " WHERE " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + PROPERTIES_NAME + "=?"; //$NON-NLS-1$
-
- public static final String SQL_SELECT_ALL_PROPERTIES = "SELECT " + PROPERTIES_NAME + ", " + PROPERTIES_VALUE //$NON-NLS-1$ //$NON-NLS-2$
- + " FROM " + PROPERTIES; //$NON-NLS-1$
-
- /**
- * DBTable cdo_package_units
- */
- public static final IDBTable PACKAGE_UNITS = INSTANCE.addTable("cdo_package_units"); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_UNITS_ID = //
- PACKAGE_UNITS.addField("id", DBType.VARCHAR, 255); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_UNITS_ORIGINAL_TYPE = //
- PACKAGE_UNITS.addField("original_type", DBType.INTEGER); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_UNITS_TIME_STAMP = //
- PACKAGE_UNITS.addField("time_stamp", DBType.BIGINT); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_UNITS_PACKAGE_DATA = //
- PACKAGE_UNITS.addField("package_data", DBType.BLOB); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_PACKAGE_UNITS_PK = //
- PACKAGE_UNITS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_UNITS_ID);
-
- /**
- * DBTable cdo_packages
- */
- public static final IDBTable PACKAGE_INFOS = INSTANCE.addTable("cdo_package_infos"); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_INFOS_URI = //
- PACKAGE_INFOS.addField("uri", DBType.VARCHAR, 255); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_INFOS_PARENT = //
- PACKAGE_INFOS.addField("parent", DBType.VARCHAR, 255); //$NON-NLS-1$
-
- public static final IDBField PACKAGE_INFOS_UNIT = //
- PACKAGE_INFOS.addField("unit", DBType.VARCHAR, 255); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_PACKAGE_INFOS_PK = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_INFOS_URI);
-
- public static final IDBIndex INDEX_PACKAGE_INFOS_PARENT = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_PARENT);
-
- public static final IDBIndex INDEX_PACKAGE_INFOS_UNIT = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_UNIT);
-
- /**
- * DBTable cdo_branches
- */
- public static final IDBTable BRANCHES = INSTANCE.addTable("cdo_branches"); //$NON-NLS-1$
-
- public static final IDBField BRANCHES_ID = //
- BRANCHES.addField("id", DBType.INTEGER); //$NON-NLS-1$
-
- public static final IDBField BRANCHES_NAME = //
- BRANCHES.addField("name", DBType.VARCHAR); //$NON-NLS-1$
-
- public static final IDBField BRANCHES_BASE_BRANCH_ID = //
- BRANCHES.addField("base_id", DBType.INTEGER); //$NON-NLS-1$
-
- public static final IDBField BRANCHES_BASE_TIMESTAMP = //
- BRANCHES.addField("base_time", DBType.BIGINT); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_BRANCHES_ID = //
- BRANCHES.addIndex(IDBIndex.Type.PRIMARY_KEY, BRANCHES_ID);
-
- public static final String SQL_CREATE_BRANCH = "INSERT INTO " + BRANCHES + " (" + BRANCHES_ID + ", " + BRANCHES_NAME //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + ", " + BRANCHES_BASE_BRANCH_ID + ", " + BRANCHES_BASE_TIMESTAMP + ") VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- public static final String SQL_LOAD_BRANCH = "SELECT " + BRANCHES_NAME + ", " + BRANCHES_BASE_BRANCH_ID + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + BRANCHES_BASE_TIMESTAMP + " FROM " + BRANCHES + " WHERE " + BRANCHES_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- public static final String SQL_LOAD_SUB_BRANCHES = "SELECT " + BRANCHES_ID + ", " + BRANCHES_NAME + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + BRANCHES_BASE_TIMESTAMP + " FROM " + BRANCHES + " WHERE " + BRANCHES_BASE_BRANCH_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- public static final String SQL_LOAD_BRANCHES = "SELECT " + BRANCHES_ID + ", " + BRANCHES_NAME + ", " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- BRANCHES_BASE_BRANCH_ID + ", " + BRANCHES_BASE_TIMESTAMP //$NON-NLS-1$
- + " FROM " + BRANCHES + " WHERE " + BRANCHES_ID + " BETWEEN ? AND ? ORDER BY " + BRANCHES_ID; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- /**
- * DBTable cdo_commit_infos
- */
- public static final IDBTable COMMIT_INFOS = INSTANCE.addTable("cdo_commit_infos"); //$NON-NLS-1$
-
- public static final IDBField COMMIT_INFOS_TIMESTAMP = //
- COMMIT_INFOS.addField("commit_time", DBType.BIGINT); //$NON-NLS-1$
-
- public static final IDBField COMMIT_INFOS_PREVIOUS_TIMESTAMP = //
- COMMIT_INFOS.addField("previous_time", DBType.BIGINT); //$NON-NLS-1$
-
- public static final IDBField COMMIT_INFOS_BRANCH = //
- COMMIT_INFOS.addField("branch_id", DBType.INTEGER); //$NON-NLS-1$
-
- public static final IDBField COMMIT_INFOS_USER = //
- COMMIT_INFOS.addField("user_id", DBType.VARCHAR); //$NON-NLS-1$
-
- public static final IDBField COMMIT_INFOS_COMMENT = //
- COMMIT_INFOS.addField("commit_comment", DBType.VARCHAR); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_COMMIT_INFOS_PK = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, COMMIT_INFOS_TIMESTAMP);
-
- public static final IDBIndex INDEX_COMMIT_INFOS_BRANCH = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_BRANCH);
-
- public static final IDBIndex INDEX_COMMIT_INFOS_USER = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_USER);
-
- public static final String SQL_CREATE_COMMIT_INFO = "INSERT INTO " + COMMIT_INFOS + "(" + COMMIT_INFOS_TIMESTAMP //$NON-NLS-1$ //$NON-NLS-2$
- + ", " + COMMIT_INFOS_PREVIOUS_TIMESTAMP + ", " + COMMIT_INFOS_BRANCH + ", " + COMMIT_INFOS_USER + ", " + COMMIT_INFOS_COMMENT + ") " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- + "VALUES (?, ?, ?, ?, ?)"; //$NON-NLS-1$
-
- /**
- * DBTable cdo_lobs
- */
- public static final IDBTable LOBS = INSTANCE.addTable("cdo_lobs"); //$NON-NLS-1$
-
- public static final IDBField LOBS_ID = //
- LOBS.addField("id", DBType.VARCHAR, 64); //$NON-NLS-1$
-
- public static final IDBField LOBS_SIZE = //
- LOBS.addField("size", DBType.BIGINT); //$NON-NLS-1$
-
- public static final IDBField LOBS_BDATA = //
- LOBS.addField("bdata", DBType.BLOB); //$NON-NLS-1$
-
- public static final IDBField LOBS_CDATA = //
- LOBS.addField("cdata", DBType.CLOB); //$NON-NLS-1$
-
- public static final IDBIndex INDEX_LOBS_ID = //
- LOBS.addIndex(IDBIndex.Type.PRIMARY_KEY, LOBS_ID);
-
- public static final String SQL_QUERY_LOBS = "SELECT 1 FROM " + CDODBSchema.LOBS + " WHERE " + CDODBSchema.LOBS_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- public static final String SQL_HANDLE_LOBS = "SELECT " + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ", " + CDODBSchema.LOBS_CDATA + " FROM " + CDODBSchema.LOBS; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-
- public static final String SQL_LOAD_LOB = "SELECT " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ", " + CDODBSchema.LOBS_CDATA + " FROM " + CDODBSchema.LOBS + " WHERE " + CDODBSchema.LOBS_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
-
- public static final String SQL_WRITE_BLOB = "INSERT INTO " + CDODBSchema.LOBS + "(" + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ") VALUES(?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-
- public static final String SQL_WRITE_CLOB = "INSERT INTO " + CDODBSchema.LOBS + "(" + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_CDATA + ") VALUES(?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-
- /**
- * Name of object table
- */
- public static final String CDO_OBJECTS = "cdo_objects"; //$NON-NLS-1$
-
- /**
- * Field names of attribute tables
- */
- public static final String ATTRIBUTES_ID = "cdo_id"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_BRANCH = "cdo_branch"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_VERSION = "cdo_version"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_CLASS = "cdo_class"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_CREATED = "cdo_created"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_REVISED = "cdo_revised"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_RESOURCE = "cdo_resource"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_CONTAINER = "cdo_container"; //$NON-NLS-1$
-
- public static final String ATTRIBUTES_FEATURE = "cdo_feature"; //$NON-NLS-1$
-
- /**
- * Field names of list tables
- */
- public static final String LIST_FEATURE = "cdo_feature"; //$NON-NLS-1$
-
- public static final String LIST_REVISION_ID = "cdo_source"; //$NON-NLS-1$
-
- public static final String LIST_REVISION_VERSION = "cdo_version"; //$NON-NLS-1$
-
- public static final String LIST_REVISION_VERSION_ADDED = "cdo_version_added"; //$NON-NLS-1$
-
- public static final String LIST_REVISION_VERSION_REMOVED = "cdo_version_removed"; //$NON-NLS-1$
-
- public static final String LIST_REVISION_BRANCH = "cdo_branch"; //$NON-NLS-1$
-
- public static final String LIST_IDX = "cdo_idx"; //$NON-NLS-1$
-
- public static final String LIST_VALUE = "cdo_value"; //$NON-NLS-1$
-
- /**
- * Field names of featuremap tables
- */
- public static final String FEATUREMAP_REVISION_ID = LIST_REVISION_ID;
-
- public static final String FEATUREMAP_VERSION = LIST_REVISION_VERSION;
-
- public static final String FEATUREMAP_VERSION_ADDED = LIST_REVISION_VERSION_ADDED;
-
- public static final String FEATUREMAP_VERSION_REMOVED = LIST_REVISION_VERSION_REMOVED;
-
- public static final String FEATUREMAP_BRANCH = LIST_REVISION_BRANCH;
-
- public static final String FEATUREMAP_IDX = LIST_IDX;
-
- public static final String FEATUREMAP_TAG = LIST_FEATURE;
-
- public static final String FEATUREMAP_VALUE = LIST_VALUE;
-
- private CDODBSchema()
- {
- super("CDO"); //$NON-NLS-1$
- }
-
- static
- {
- INSTANCE.lock();
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + * Stefan Winkler - 249610: [DB] Support external references (Implementation) + * Andre Dietisheim - bug 256649 + * + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBIndex; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.spi.db.DBSchema; + +/** + * @author Eike Stepper + */ +public class CDODBSchema extends DBSchema +{ + public static final CDODBSchema INSTANCE = new CDODBSchema(); + + /** + * DBTable cdo_properties + */ + public static final IDBTable PROPERTIES = INSTANCE.addTable("cdo_properties"); //$NON-NLS-1$ + + public static final IDBField PROPERTIES_NAME = // + PROPERTIES.addField("name", DBType.VARCHAR, 255); //$NON-NLS-1$ + + public static final IDBField PROPERTIES_VALUE = // + PROPERTIES.addField("value", DBType.LONGVARCHAR); //$NON-NLS-1$ + + public static final IDBIndex INDEX_PROPERTIES_PK = // + PROPERTIES.addIndex(IDBIndex.Type.PRIMARY_KEY, PROPERTIES_NAME); + + public static final String SQL_DELETE_PROPERTIES = "DELETE FROM " + PROPERTIES + " WHERE " + PROPERTIES_NAME + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String SQL_INSERT_PROPERTIES = "INSERT INTO " + PROPERTIES + " (" + PROPERTIES_NAME + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + PROPERTIES_VALUE + ") VALUES (?, ?)"; //$NON-NLS-1$ + + public static final String SQL_SELECT_PROPERTIES = "SELECT " + PROPERTIES_VALUE + " FROM " + PROPERTIES + " WHERE " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + PROPERTIES_NAME + "=?"; //$NON-NLS-1$ + + public static final String SQL_SELECT_ALL_PROPERTIES = "SELECT " + PROPERTIES_NAME + ", " + PROPERTIES_VALUE //$NON-NLS-1$ //$NON-NLS-2$ + + " FROM " + PROPERTIES; //$NON-NLS-1$ + + /** + * DBTable cdo_package_units + */ + public static final IDBTable PACKAGE_UNITS = INSTANCE.addTable("cdo_package_units"); //$NON-NLS-1$ + + public static final IDBField PACKAGE_UNITS_ID = // + PACKAGE_UNITS.addField("id", DBType.VARCHAR, 255); //$NON-NLS-1$ + + public static final IDBField PACKAGE_UNITS_ORIGINAL_TYPE = // + PACKAGE_UNITS.addField("original_type", DBType.INTEGER); //$NON-NLS-1$ + + public static final IDBField PACKAGE_UNITS_TIME_STAMP = // + PACKAGE_UNITS.addField("time_stamp", DBType.BIGINT); //$NON-NLS-1$ + + public static final IDBField PACKAGE_UNITS_PACKAGE_DATA = // + PACKAGE_UNITS.addField("package_data", DBType.BLOB); //$NON-NLS-1$ + + public static final IDBIndex INDEX_PACKAGE_UNITS_PK = // + PACKAGE_UNITS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_UNITS_ID); + + /** + * DBTable cdo_packages + */ + public static final IDBTable PACKAGE_INFOS = INSTANCE.addTable("cdo_package_infos"); //$NON-NLS-1$ + + public static final IDBField PACKAGE_INFOS_URI = // + PACKAGE_INFOS.addField("uri", DBType.VARCHAR, 255); //$NON-NLS-1$ + + public static final IDBField PACKAGE_INFOS_PARENT = // + PACKAGE_INFOS.addField("parent", DBType.VARCHAR, 255); //$NON-NLS-1$ + + public static final IDBField PACKAGE_INFOS_UNIT = // + PACKAGE_INFOS.addField("unit", DBType.VARCHAR, 255); //$NON-NLS-1$ + + public static final IDBIndex INDEX_PACKAGE_INFOS_PK = // + PACKAGE_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_INFOS_URI); + + public static final IDBIndex INDEX_PACKAGE_INFOS_PARENT = // + PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_PARENT); + + public static final IDBIndex INDEX_PACKAGE_INFOS_UNIT = // + PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_UNIT); + + /** + * DBTable cdo_branches + */ + public static final IDBTable BRANCHES = INSTANCE.addTable("cdo_branches"); //$NON-NLS-1$ + + public static final IDBField BRANCHES_ID = // + BRANCHES.addField("id", DBType.INTEGER); //$NON-NLS-1$ + + public static final IDBField BRANCHES_NAME = // + BRANCHES.addField("name", DBType.VARCHAR); //$NON-NLS-1$ + + public static final IDBField BRANCHES_BASE_BRANCH_ID = // + BRANCHES.addField("base_id", DBType.INTEGER); //$NON-NLS-1$ + + public static final IDBField BRANCHES_BASE_TIMESTAMP = // + BRANCHES.addField("base_time", DBType.BIGINT); //$NON-NLS-1$ + + public static final IDBIndex INDEX_BRANCHES_ID = // + BRANCHES.addIndex(IDBIndex.Type.PRIMARY_KEY, BRANCHES_ID); + + public static final String SQL_CREATE_BRANCH = "INSERT INTO " + BRANCHES + " (" + BRANCHES_ID + ", " + BRANCHES_NAME //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + ", " + BRANCHES_BASE_BRANCH_ID + ", " + BRANCHES_BASE_TIMESTAMP + ") VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String SQL_LOAD_BRANCH = "SELECT " + BRANCHES_NAME + ", " + BRANCHES_BASE_BRANCH_ID + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + BRANCHES_BASE_TIMESTAMP + " FROM " + BRANCHES + " WHERE " + BRANCHES_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String SQL_LOAD_SUB_BRANCHES = "SELECT " + BRANCHES_ID + ", " + BRANCHES_NAME + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + BRANCHES_BASE_TIMESTAMP + " FROM " + BRANCHES + " WHERE " + BRANCHES_BASE_BRANCH_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String SQL_LOAD_BRANCHES = "SELECT " + BRANCHES_ID + ", " + BRANCHES_NAME + ", " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + BRANCHES_BASE_BRANCH_ID + ", " + BRANCHES_BASE_TIMESTAMP //$NON-NLS-1$ + + " FROM " + BRANCHES + " WHERE " + BRANCHES_ID + " BETWEEN ? AND ? ORDER BY " + BRANCHES_ID; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + /** + * DBTable cdo_commit_infos + */ + public static final IDBTable COMMIT_INFOS = INSTANCE.addTable("cdo_commit_infos"); //$NON-NLS-1$ + + public static final IDBField COMMIT_INFOS_TIMESTAMP = // + COMMIT_INFOS.addField("commit_time", DBType.BIGINT); //$NON-NLS-1$ + + public static final IDBField COMMIT_INFOS_PREVIOUS_TIMESTAMP = // + COMMIT_INFOS.addField("previous_time", DBType.BIGINT); //$NON-NLS-1$ + + public static final IDBField COMMIT_INFOS_BRANCH = // + COMMIT_INFOS.addField("branch_id", DBType.INTEGER); //$NON-NLS-1$ + + public static final IDBField COMMIT_INFOS_USER = // + COMMIT_INFOS.addField("user_id", DBType.VARCHAR); //$NON-NLS-1$ + + public static final IDBField COMMIT_INFOS_COMMENT = // + COMMIT_INFOS.addField("commit_comment", DBType.VARCHAR); //$NON-NLS-1$ + + public static final IDBIndex INDEX_COMMIT_INFOS_PK = // + COMMIT_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, COMMIT_INFOS_TIMESTAMP); + + public static final IDBIndex INDEX_COMMIT_INFOS_BRANCH = // + COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_BRANCH); + + public static final IDBIndex INDEX_COMMIT_INFOS_USER = // + COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_USER); + + public static final String SQL_CREATE_COMMIT_INFO = "INSERT INTO " + COMMIT_INFOS + "(" + COMMIT_INFOS_TIMESTAMP //$NON-NLS-1$ //$NON-NLS-2$ + + ", " + COMMIT_INFOS_PREVIOUS_TIMESTAMP + ", " + COMMIT_INFOS_BRANCH + ", " + COMMIT_INFOS_USER + ", " + COMMIT_INFOS_COMMENT + ") " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + "VALUES (?, ?, ?, ?, ?)"; //$NON-NLS-1$ + + /** + * DBTable cdo_lobs + */ + public static final IDBTable LOBS = INSTANCE.addTable("cdo_lobs"); //$NON-NLS-1$ + + public static final IDBField LOBS_ID = // + LOBS.addField("id", DBType.VARCHAR, 64); //$NON-NLS-1$ + + public static final IDBField LOBS_SIZE = // + LOBS.addField("size", DBType.BIGINT); //$NON-NLS-1$ + + public static final IDBField LOBS_BDATA = // + LOBS.addField("bdata", DBType.BLOB); //$NON-NLS-1$ + + public static final IDBField LOBS_CDATA = // + LOBS.addField("cdata", DBType.CLOB); //$NON-NLS-1$ + + public static final IDBIndex INDEX_LOBS_ID = // + LOBS.addIndex(IDBIndex.Type.PRIMARY_KEY, LOBS_ID); + + public static final String SQL_QUERY_LOBS = "SELECT 1 FROM " + CDODBSchema.LOBS + " WHERE " + CDODBSchema.LOBS_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String SQL_HANDLE_LOBS = "SELECT " + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ", " + CDODBSchema.LOBS_CDATA + " FROM " + CDODBSchema.LOBS; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + + public static final String SQL_LOAD_LOB = "SELECT " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ", " + CDODBSchema.LOBS_CDATA + " FROM " + CDODBSchema.LOBS + " WHERE " + CDODBSchema.LOBS_ID + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + + public static final String SQL_WRITE_BLOB = "INSERT INTO " + CDODBSchema.LOBS + "(" + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_BDATA + ") VALUES(?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + + public static final String SQL_WRITE_CLOB = "INSERT INTO " + CDODBSchema.LOBS + "(" + CDODBSchema.LOBS_ID + ", " + CDODBSchema.LOBS_SIZE + ", " + CDODBSchema.LOBS_CDATA + ") VALUES(?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + + /** + * Name of object table + */ + public static final String CDO_OBJECTS = "cdo_objects"; //$NON-NLS-1$ + + /** + * Field names of attribute tables + */ + public static final String ATTRIBUTES_ID = "cdo_id"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_BRANCH = "cdo_branch"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_VERSION = "cdo_version"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_CLASS = "cdo_class"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_CREATED = "cdo_created"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_REVISED = "cdo_revised"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_RESOURCE = "cdo_resource"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_CONTAINER = "cdo_container"; //$NON-NLS-1$ + + public static final String ATTRIBUTES_FEATURE = "cdo_feature"; //$NON-NLS-1$ + + /** + * Field names of list tables + */ + public static final String LIST_FEATURE = "cdo_feature"; //$NON-NLS-1$ + + public static final String LIST_REVISION_ID = "cdo_source"; //$NON-NLS-1$ + + public static final String LIST_REVISION_VERSION = "cdo_version"; //$NON-NLS-1$ + + public static final String LIST_REVISION_VERSION_ADDED = "cdo_version_added"; //$NON-NLS-1$ + + public static final String LIST_REVISION_VERSION_REMOVED = "cdo_version_removed"; //$NON-NLS-1$ + + public static final String LIST_REVISION_BRANCH = "cdo_branch"; //$NON-NLS-1$ + + public static final String LIST_IDX = "cdo_idx"; //$NON-NLS-1$ + + public static final String LIST_VALUE = "cdo_value"; //$NON-NLS-1$ + + /** + * Field names of featuremap tables + */ + public static final String FEATUREMAP_REVISION_ID = LIST_REVISION_ID; + + public static final String FEATUREMAP_VERSION = LIST_REVISION_VERSION; + + public static final String FEATUREMAP_VERSION_ADDED = LIST_REVISION_VERSION_ADDED; + + public static final String FEATUREMAP_VERSION_REMOVED = LIST_REVISION_VERSION_REMOVED; + + public static final String FEATUREMAP_BRANCH = LIST_REVISION_BRANCH; + + public static final String FEATUREMAP_IDX = LIST_IDX; + + public static final String FEATUREMAP_TAG = LIST_FEATURE; + + public static final String FEATUREMAP_VALUE = LIST_VALUE; + + private CDODBSchema() + { + super("CDO"); //$NON-NLS-1$ + } + + static + { + INSTANCE.lock(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java index ce430b25dd..6106f7c258 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java @@ -1,67 +1,67 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Kai Schlamp - initial API and implementation
- * Eike Stepper - maintenance
- * Kai Schlamp - Bug 284680 - [DB] Provide annotation to bypass ClassMapping
- * Stefan Winkler - maintenance
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.ecore.EModelElement;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-
-/**
- * @author Kai Schlamp
- */
-public enum DBAnnotation
-{
- TABLE_MAPPING("tableMapping"), //
- TABLE_NAME("tableName"), //
- COLUMN_NAME("columnName"), //
- COLUMN_TYPE("columnType"), //
- COLUMN_LENGTH("columnLength"), //
- TYPE_MAPPING("typeMapping");
-
- public final static String SOURCE_URI = "http://www.eclipse.org/CDO/DBStore";
-
- public final static String TABLE_MAPPING_NONE = "NONE";
-
- private String keyword;
-
- private DBAnnotation(String keyword)
- {
- this.keyword = keyword;
- }
-
- public String getKeyword()
- {
- return keyword == null ? super.toString() : keyword;
- }
-
- /**
- * @return A non-empty string or <code>null</code>.
- */
- public String getValue(EModelElement element)
- {
- String value = EcoreUtil.getAnnotation(element, SOURCE_URI, keyword);
- if (value != null && value.length() == 0)
- {
- return null;
- }
-
- return value;
- }
-
- @Override
- public String toString()
- {
- return getKeyword();
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Kai Schlamp - initial API and implementation + * Eike Stepper - maintenance + * Kai Schlamp - Bug 284680 - [DB] Provide annotation to bypass ClassMapping + * Stefan Winkler - maintenance + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.util.EcoreUtil; + +/** + * @author Kai Schlamp + */ +public enum DBAnnotation +{ + TABLE_MAPPING("tableMapping"), // + TABLE_NAME("tableName"), // + COLUMN_NAME("columnName"), // + COLUMN_TYPE("columnType"), // + COLUMN_LENGTH("columnLength"), // + TYPE_MAPPING("typeMapping"); + + public final static String SOURCE_URI = "http://www.eclipse.org/CDO/DBStore"; + + public final static String TABLE_MAPPING_NONE = "NONE"; + + private String keyword; + + private DBAnnotation(String keyword) + { + this.keyword = keyword; + } + + public String getKeyword() + { + return keyword == null ? super.toString() : keyword; + } + + /** + * @return A non-empty string or <code>null</code>. + */ + public String getValue(EModelElement element) + { + String value = EcoreUtil.getAnnotation(element, SOURCE_URI, keyword); + if (value != null && value.length() == 0) + { + return null; + } + + return value; + } + + @Override + public String toString() + { + return getKeyword(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java index 16c53b623b..af35dc73fe 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBBrowserPage.java @@ -1,208 +1,208 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db;
-
-import org.eclipse.emf.cdo.server.CDOServerBrowser;
-import org.eclipse.emf.cdo.server.CDOServerBrowser.AbstractPage;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBConnectionProvider;
-import org.eclipse.net4j.util.factory.ProductCreationException;
-
-import java.io.PrintStream;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public class DBBrowserPage extends AbstractPage
-{
- public DBBrowserPage()
- {
- super("tables", "Database Tables");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return repository.getStore() instanceof IDBConnectionProvider;
- }
-
- public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out)
- {
- IDBConnectionProvider connectionProvider = (IDBConnectionProvider)repository.getStore();
- Connection connection = null;
-
- try
- {
- connection = connectionProvider.getConnection();
-
- out.print("<table border=\"0\">\r\n");
- out.print("<tr>\r\n");
-
- out.print("<td valign=\"top\">\r\n");
- String table = showTables(browser, out, connection, repository.getName());
- out.print("</td>\r\n");
-
- if (table != null)
- {
- out.print("<td valign=\"top\">\r\n");
- showTable(browser, out, connection, table);
- out.print("</td>\r\n");
- }
-
- out.print("</tr>\r\n");
- out.print("</table>\r\n");
- }
- catch (DBException ex)
- {
- ex.printStackTrace();
- }
- finally
- {
- DBUtil.close(connection);
- }
- }
-
- /**
- * @since 4.0
- */
- protected String showTables(CDOServerBrowser browser, PrintStream pout, Connection connection, String repo)
- {
- String table = browser.getParam("table");
-
- List<String> allTableNames = DBUtil.getAllTableNames(connection, repo);
- for (String tableName : allTableNames)
- {
- if (table == null)
- {
- table = tableName;
- }
-
- String label = browser.escape(tableName)/* .toLowerCase() */;
- if (tableName.equals(table))
- {
- pout.print("<b>" + label + "</b><br>\r\n");
- }
- else
- {
- pout.print(browser.href(label, getName(), "table", tableName, "order", null, "direction", null) + "<br>\r\n");
- }
- }
-
- return table;
- }
-
- /**
- * @since 4.0
- */
- protected void showTable(CDOServerBrowser browser, PrintStream pout, Connection connection, String table)
- {
- try
- {
- String order = browser.getParam("order");
- executeQuery(browser, pout, connection, "SELECT * FROM " + table
- + (order == null ? "" : " ORDER BY " + order + " " + browser.getParam("direction")));
- }
- catch (Exception ex)
- {
- browser.removeParam("order");
- browser.removeParam("direction");
- executeQuery(browser, pout, connection, "SELECT * FROM " + table);
- }
- }
-
- protected void executeQuery(CDOServerBrowser browser, PrintStream pout, Connection connection, String sql)
- {
- String order = browser.getParam("order");
- String direction = browser.getParam("direction");
- String highlight = browser.getParam("highlight");
-
- Statement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = connection.createStatement();
- resultSet = stmt.executeQuery(sql);
-
- ResultSetMetaData metaData = resultSet.getMetaData();
- int columns = metaData.getColumnCount();
-
- pout.print("<table border=\"1\" cellpadding=\"2\">\r\n");
- pout.print("<tr>\r\n");
- pout.print("<td> </td>\r\n");
- for (int i = 0; i < columns; i++)
- {
- String column = metaData.getColumnLabel(1 + i);
- String type = metaData.getColumnTypeName(1 + i).toLowerCase();
-
- String dir = column.equals(order) && "ASC".equals(direction) ? "DESC" : "ASC";
- pout.print("<td align=\"center\"><b>" + browser.href(column, getName(), "order", column, "direction", dir));
- pout.print("</b><br>" + type + "</td>\r\n");
- }
-
- pout.print("</tr>\r\n");
-
- int row = 0;
- while (resultSet.next())
- {
- ++row;
- pout.print("<tr>\r\n");
- pout.print("<td><b>" + row + "</b></td>\r\n");
- for (int i = 0; i < columns; i++)
- {
- String value = resultSet.getString(1 + i);
- String bgcolor = highlight != null && highlight.equals(value) ? " bgcolor=\"#fffca6\"" : "";
- pout.print("<td" + bgcolor + ">" + browser.href(value, getName(), "highlight", value) + "</td>\r\n");
- }
-
- pout.print("</tr>\r\n");
- }
-
- pout.print("</table>\r\n");
- }
- catch (SQLException ex)
- {
- ex.printStackTrace();
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmt);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends org.eclipse.net4j.util.factory.Factory
- {
- public static final String TYPE = "default";
-
- public Factory()
- {
- super(PRODUCT_GROUP, TYPE);
- }
-
- public DBBrowserPage create(String description) throws ProductCreationException
- {
- return new DBBrowserPage();
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db; + +import org.eclipse.emf.cdo.server.CDOServerBrowser; +import org.eclipse.emf.cdo.server.CDOServerBrowser.AbstractPage; +import org.eclipse.emf.cdo.spi.server.InternalRepository; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBConnectionProvider; +import org.eclipse.net4j.util.factory.ProductCreationException; + +import java.io.PrintStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public class DBBrowserPage extends AbstractPage +{ + public DBBrowserPage() + { + super("tables", "Database Tables"); + } + + public boolean canDisplay(InternalRepository repository) + { + return repository.getStore() instanceof IDBConnectionProvider; + } + + public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out) + { + IDBConnectionProvider connectionProvider = (IDBConnectionProvider)repository.getStore(); + Connection connection = null; + + try + { + connection = connectionProvider.getConnection(); + + out.print("<table border=\"0\">\r\n"); + out.print("<tr>\r\n"); + + out.print("<td valign=\"top\">\r\n"); + String table = showTables(browser, out, connection, repository.getName()); + out.print("</td>\r\n"); + + if (table != null) + { + out.print("<td valign=\"top\">\r\n"); + showTable(browser, out, connection, table); + out.print("</td>\r\n"); + } + + out.print("</tr>\r\n"); + out.print("</table>\r\n"); + } + catch (DBException ex) + { + ex.printStackTrace(); + } + finally + { + DBUtil.close(connection); + } + } + + /** + * @since 4.0 + */ + protected String showTables(CDOServerBrowser browser, PrintStream pout, Connection connection, String repo) + { + String table = browser.getParam("table"); + + List<String> allTableNames = DBUtil.getAllTableNames(connection, repo); + for (String tableName : allTableNames) + { + if (table == null) + { + table = tableName; + } + + String label = browser.escape(tableName)/* .toLowerCase() */; + if (tableName.equals(table)) + { + pout.print("<b>" + label + "</b><br>\r\n"); + } + else + { + pout.print(browser.href(label, getName(), "table", tableName, "order", null, "direction", null) + "<br>\r\n"); + } + } + + return table; + } + + /** + * @since 4.0 + */ + protected void showTable(CDOServerBrowser browser, PrintStream pout, Connection connection, String table) + { + try + { + String order = browser.getParam("order"); + executeQuery(browser, pout, connection, "SELECT * FROM " + table + + (order == null ? "" : " ORDER BY " + order + " " + browser.getParam("direction"))); + } + catch (Exception ex) + { + browser.removeParam("order"); + browser.removeParam("direction"); + executeQuery(browser, pout, connection, "SELECT * FROM " + table); + } + } + + protected void executeQuery(CDOServerBrowser browser, PrintStream pout, Connection connection, String sql) + { + String order = browser.getParam("order"); + String direction = browser.getParam("direction"); + String highlight = browser.getParam("highlight"); + + Statement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = connection.createStatement(); + resultSet = stmt.executeQuery(sql); + + ResultSetMetaData metaData = resultSet.getMetaData(); + int columns = metaData.getColumnCount(); + + pout.print("<table border=\"1\" cellpadding=\"2\">\r\n"); + pout.print("<tr>\r\n"); + pout.print("<td> </td>\r\n"); + for (int i = 0; i < columns; i++) + { + String column = metaData.getColumnLabel(1 + i); + String type = metaData.getColumnTypeName(1 + i).toLowerCase(); + + String dir = column.equals(order) && "ASC".equals(direction) ? "DESC" : "ASC"; + pout.print("<td align=\"center\"><b>" + browser.href(column, getName(), "order", column, "direction", dir)); + pout.print("</b><br>" + type + "</td>\r\n"); + } + + pout.print("</tr>\r\n"); + + int row = 0; + while (resultSet.next()) + { + ++row; + pout.print("<tr>\r\n"); + pout.print("<td><b>" + row + "</b></td>\r\n"); + for (int i = 0; i < columns; i++) + { + String value = resultSet.getString(1 + i); + String bgcolor = highlight != null && highlight.equals(value) ? " bgcolor=\"#fffca6\"" : ""; + pout.print("<td" + bgcolor + ">" + browser.href(value, getName(), "highlight", value) + "</td>\r\n"); + } + + pout.print("</tr>\r\n"); + } + + pout.print("</table>\r\n"); + } + catch (SQLException ex) + { + ex.printStackTrace(); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmt); + } + } + + /** + * @author Eike Stepper + */ + public static class Factory extends org.eclipse.net4j.util.factory.Factory + { + public static final String TYPE = "default"; + + public Factory() + { + super(PRODUCT_GROUP, TYPE); + } + + public DBBrowserPage create(String description) throws ProductCreationException + { + return new DBBrowserPage(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBRevisionHandler.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBRevisionHandler.java index 09edbe7752..38ad8fd5b7 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBRevisionHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBRevisionHandler.java @@ -1,40 +1,40 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-
-/**
- * @author Eike Stepper
- */
-public class DBRevisionHandler implements CDORevisionHandler
-{
- private CDORevisionHandler delegate;
-
- public DBRevisionHandler(CDORevisionHandler delegate)
- {
- this.delegate = delegate;
- }
-
- public boolean handleRevision(CDORevision revision)
- {
- if (revision.getVersion() < CDOBranchVersion.FIRST_VERSION - 1)
- {
- revision = new DetachedCDORevision(revision.getEClass(), revision.getID(), revision.getBranch(),
- -revision.getVersion(), revision.getTimeStamp(), revision.getRevised());
- }
-
- return delegate.handleRevision(revision);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db; + +import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; +import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision; + +/** + * @author Eike Stepper + */ +public class DBRevisionHandler implements CDORevisionHandler +{ + private CDORevisionHandler delegate; + + public DBRevisionHandler(CDORevisionHandler delegate) + { + this.delegate = delegate; + } + + public boolean handleRevision(CDORevision revision) + { + if (revision.getVersion() < CDOBranchVersion.FIRST_VERSION - 1) + { + revision = new DetachedCDORevision(revision.getEClass(), revision.getID(), revision.getBranch(), + -revision.getVersion(), revision.getTimeStamp(), revision.getRevised()); + } + + return delegate.handleRevision(revision); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java index 6bf3a35c23..cfdda9a298 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java @@ -1,727 +1,727 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - Bug 259402
- * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444
- * Stefan Winkler - Bug 249610: [DB] Support external references (Implementation)
- * Stefan Winkler - Bug 289056: [DB] Exception "ERROR: relation "cdo_external_refs" does not exist" while executing test-suite for PostgreSQL
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation;
-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.revision.CDOAllRevisionsProvider;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.server.ISession;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.server.IView;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IMetaDataManager;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.messages.Messages;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.LongIDStoreAccessor;
-import org.eclipse.emf.cdo.spi.server.Store;
-import org.eclipse.emf.cdo.spi.server.StoreAccessorPool;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.IDBConnectionProvider;
-import org.eclipse.net4j.db.ddl.IDBSchema;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.spi.db.DBSchema;
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.ProgressDistributor;
-
-import javax.sql.DataSource;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.Timer;
-
-/**
- * @author Eike Stepper
- */
-public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
-{
- public static final String TYPE = "db"; //$NON-NLS-1$
-
- private static final String PROP_REPOSITORY_CREATED = "org.eclipse.emf.cdo.server.db.repositoryCreated"; //$NON-NLS-1$
-
- private static final String PROP_REPOSITORY_STOPPED = "org.eclipse.emf.cdo.server.db.repositoryStopped"; //$NON-NLS-1$
-
- private static final String PROP_NEXT_LOCAL_CDOID = "org.eclipse.emf.cdo.server.db.nextLocalCDOID"; //$NON-NLS-1$
-
- private static final String PROP_LAST_CDOID = "org.eclipse.emf.cdo.server.db.lastCDOID"; //$NON-NLS-1$
-
- private static final String PROP_LAST_BRANCHID = "org.eclipse.emf.cdo.server.db.lastBranchID"; //$NON-NLS-1$
-
- private static final String PROP_LAST_LOCAL_BRANCHID = "org.eclipse.emf.cdo.server.db.lastLocalBranchID"; //$NON-NLS-1$
-
- private static final String PROP_LAST_COMMITTIME = "org.eclipse.emf.cdo.server.db.lastCommitTime"; //$NON-NLS-1$
-
- private static final String PROP_LAST_NONLOCAL_COMMITTIME = "org.eclipse.emf.cdo.server.db.lastNonLocalCommitTime"; //$NON-NLS-1$
-
- private static final String PROP_GRACEFULLY_SHUT_DOWN = "org.eclipse.emf.cdo.server.db.gracefullyShutDown"; //$NON-NLS-1$
-
- private long creationTime;
-
- private boolean firstTime;
-
- private Map<String, String> properties;
-
- private IIDHandler idHandler;
-
- private IMetaDataManager metaDataManager = new MetaDataManager(this);
-
- private DurableLockingManager durableLockingManager = new DurableLockingManager(this);
-
- private IMappingStrategy mappingStrategy;
-
- private IDBSchema dbSchema;
-
- private IDBAdapter dbAdapter;
-
- private IDBConnectionProvider dbConnectionProvider;
-
- @ExcludeFromDump
- private transient ProgressDistributor accessorWriteDistributor = new ProgressDistributor.Geometric()
- {
- @Override
- public String toString()
- {
- String result = "accessorWriteDistributor"; //$NON-NLS-1$
- if (getRepository() != null)
- {
- result += ": " + getRepository().getName(); //$NON-NLS-1$
- }
-
- return result;
- }
- };
-
- @ExcludeFromDump
- private transient StoreAccessorPool readerPool = new StoreAccessorPool(this, null);
-
- @ExcludeFromDump
- private transient StoreAccessorPool writerPool = new StoreAccessorPool(this, null);
-
- @ExcludeFromDump
- private transient Timer connectionKeepAliveTimer;
-
- public DBStore()
- {
- super(TYPE, null, set(ChangeFormat.REVISION, ChangeFormat.DELTA), //
- set(RevisionTemporality.AUDITING, RevisionTemporality.NONE), //
- set(RevisionParallelism.NONE, RevisionParallelism.BRANCHING));
- }
-
- public IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public void setMappingStrategy(IMappingStrategy mappingStrategy)
- {
- this.mappingStrategy = mappingStrategy;
- mappingStrategy.setStore(this);
- }
-
- public IDBAdapter getDBAdapter()
- {
- return dbAdapter;
- }
-
- public void setDBAdapter(IDBAdapter dbAdapter)
- {
- this.dbAdapter = dbAdapter;
- }
-
- public void setProperties(Map<String, String> properties)
- {
- this.properties = properties;
- }
-
- public Map<String, String> getProperties()
- {
- return properties;
- }
-
- public IIDHandler getIDHandler()
- {
- return idHandler;
- }
-
- public Connection getConnection()
- {
- Connection connection = dbConnectionProvider.getConnection();
- if (connection == null)
- {
- throw new DBException("No connection from connection provider: " + dbConnectionProvider); //$NON-NLS-1$
- }
-
- try
- {
- connection.setAutoCommit(false);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex, "SET AUTO COMMIT = false");
- }
-
- return connection;
- }
-
- public void setDbConnectionProvider(IDBConnectionProvider dbConnectionProvider)
- {
- this.dbConnectionProvider = dbConnectionProvider;
- }
-
- public void setDataSource(DataSource dataSource)
- {
- dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
- }
-
- public IMetaDataManager getMetaDataManager()
- {
- return metaDataManager;
- }
-
- public DurableLockingManager getDurableLockingManager()
- {
- return durableLockingManager;
- }
-
- public Timer getConnectionKeepAliveTimer()
- {
- return connectionKeepAliveTimer;
- }
-
- @Override
- public Set<ChangeFormat> getSupportedChangeFormats()
- {
- if (mappingStrategy.hasDeltaSupport())
- {
- return set(ChangeFormat.DELTA);
- }
-
- return set(ChangeFormat.REVISION);
- }
-
- public ProgressDistributor getAccessorWriteDistributor()
- {
- return accessorWriteDistributor;
- }
-
- public IDBSchema getDBSchema()
- {
- return dbSchema;
- }
-
- public Map<String, String> getPersistentProperties(Set<String> names)
- {
- Connection connection = null;
- PreparedStatement selectStmt = null;
- String sql = null;
-
- try
- {
- connection = getConnection();
- Map<String, String> result = new HashMap<String, String>();
- boolean allProperties = names == null || names.isEmpty();
- if (allProperties)
- {
- sql = CDODBSchema.SQL_SELECT_ALL_PROPERTIES;
- selectStmt = connection.prepareStatement(sql);
- ResultSet resultSet = null;
-
- try
- {
- resultSet = selectStmt.executeQuery();
- while (resultSet.next())
- {
- String key = resultSet.getString(1);
- String value = resultSet.getString(2);
- result.put(key, value);
- }
- }
- finally
- {
- DBUtil.close(resultSet);
- }
- }
- else
- {
- sql = CDODBSchema.SQL_SELECT_PROPERTIES;
- selectStmt = connection.prepareStatement(sql);
- for (String name : names)
- {
- selectStmt.setString(1, name);
- ResultSet resultSet = null;
-
- try
- {
- resultSet = selectStmt.executeQuery();
- if (resultSet.next())
- {
- String value = resultSet.getString(1);
- result.put(name, value);
- }
- }
- finally
- {
- DBUtil.close(resultSet);
- }
- }
- }
-
- return result;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex, sql);
- }
- finally
- {
- DBUtil.close(selectStmt);
- DBUtil.close(connection);
- }
- }
-
- public void setPersistentProperties(Map<String, String> properties)
- {
- Connection connection = null;
- PreparedStatement deleteStmt = null;
- PreparedStatement insertStmt = null;
- String sql = null;
-
- try
- {
- connection = getConnection();
- deleteStmt = connection.prepareStatement(CDODBSchema.SQL_DELETE_PROPERTIES);
- insertStmt = connection.prepareStatement(CDODBSchema.SQL_INSERT_PROPERTIES);
-
- for (Entry<String, String> entry : properties.entrySet())
- {
- String name = entry.getKey();
- String value = entry.getValue();
-
- sql = CDODBSchema.SQL_DELETE_PROPERTIES;
- deleteStmt.setString(1, name);
- deleteStmt.executeUpdate();
-
- sql = CDODBSchema.SQL_INSERT_PROPERTIES;
- insertStmt.setString(1, name);
- insertStmt.setString(2, value);
- insertStmt.executeUpdate();
- }
-
- sql = null;
- connection.commit();
- }
- catch (SQLException ex)
- {
- throw new DBException(ex, sql);
- }
- finally
- {
- DBUtil.close(insertStmt);
- DBUtil.close(deleteStmt);
- DBUtil.close(connection);
- }
- }
-
- public void removePersistentProperties(Set<String> names)
- {
- Connection connection = null;
- PreparedStatement deleteStmt = null;
-
- try
- {
- connection = getConnection();
- deleteStmt = connection.prepareStatement(CDODBSchema.SQL_DELETE_PROPERTIES);
-
- for (String name : names)
- {
- deleteStmt.setString(1, name);
- deleteStmt.executeUpdate();
- }
-
- connection.commit();
- }
- catch (SQLException ex)
- {
- throw new DBException(ex, CDODBSchema.SQL_DELETE_PROPERTIES);
- }
- finally
- {
- DBUtil.close(deleteStmt);
- DBUtil.close(connection);
- }
- }
-
- @Override
- public DBStoreAccessor getReader(ISession session)
- {
- return (DBStoreAccessor)super.getReader(session);
- }
-
- @Override
- public DBStoreAccessor getWriter(ITransaction transaction)
- {
- return (DBStoreAccessor)super.getWriter(transaction);
- }
-
- @Override
- protected StoreAccessorPool getReaderPool(ISession session, boolean forReleasing)
- {
- return readerPool;
- }
-
- @Override
- protected StoreAccessorPool getWriterPool(IView view, boolean forReleasing)
- {
- return writerPool;
- }
-
- @Override
- protected DBStoreAccessor createReader(ISession session) throws DBException
- {
- return new DBStoreAccessor(this, session);
- }
-
- @Override
- protected DBStoreAccessor createWriter(ITransaction transaction) throws DBException
- {
- return new DBStoreAccessor(this, transaction);
- }
-
- public Map<CDOBranch, List<CDORevision>> getAllRevisions()
- {
- final Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>();
- IDBStoreAccessor accessor = getReader(null);
- StoreThreadLocal.setAccessor(accessor);
-
- try
- {
- accessor.handleRevisions(null, null, CDOBranchPoint.UNSPECIFIED_DATE, true,
- new CDORevisionHandler.Filtered.Undetached(new CDORevisionHandler()
- {
- public boolean handleRevision(CDORevision revision)
- {
- CDOBranch branch = revision.getBranch();
- List<CDORevision> list = result.get(branch);
- if (list == null)
- {
- list = new ArrayList<CDORevision>();
- result.put(branch, list);
- }
-
- list.add(revision);
- return true;
- }
- }));
- }
- finally
- {
- StoreThreadLocal.release();
- }
-
- return result;
- }
-
- public CDOID createObjectID(String val)
- {
- return idHandler.createCDOID(val);
- }
-
- public boolean isLocal(CDOID id)
- {
- return idHandler.isLocalCDOID(id);
- }
-
- public CDOID getNextCDOID(LongIDStoreAccessor accessor, CDORevision revision)
- {
- return idHandler.getNextCDOID(revision);
- }
-
- public long getCreationTime()
- {
- return creationTime;
- }
-
- public void setCreationTime(long creationTime)
- {
- this.creationTime = creationTime;
-
- Map<String, String> map = new HashMap<String, String>();
- map.put(PROP_REPOSITORY_CREATED, Long.toString(creationTime));
- setPersistentProperties(map);
- }
-
- public boolean isFirstStart()
- {
- return firstTime;
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkNull(mappingStrategy, Messages.getString("DBStore.2")); //$NON-NLS-1$
- checkNull(dbAdapter, Messages.getString("DBStore.1")); //$NON-NLS-1$
- checkNull(dbConnectionProvider, Messages.getString("DBStore.0")); //$NON-NLS-1$
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- if (getRepository().getIDGenerationLocation() == IDGenerationLocation.CLIENT)
- {
- idHandler = new UUIDHandler(this);
- }
- else
- {
- idHandler = new LongIDHandler(this);
- }
-
- setObjectIDTypes(idHandler.getObjectIDTypes());
- connectionKeepAliveTimer = new Timer("Connection-Keep-Alive-" + this); //$NON-NLS-1$
-
- Set<IDBTable> createdTables = null;
- Connection connection = getConnection();
-
- try
- {
- if (isDropAllDataOnActivate())
- {
- OM.LOG.info("Dropping all tables from repository " + getRepository().getName() + "...");
- DBUtil.dropAllTables(connection, null);
- connection.commit();
- }
-
- createdTables = CDODBSchema.INSTANCE.create(dbAdapter, connection);
- connection.commit();
- }
- finally
- {
- DBUtil.close(connection);
- }
-
- dbSchema = createSchema();
-
- LifecycleUtil.activate(idHandler);
- LifecycleUtil.activate(metaDataManager);
- LifecycleUtil.activate(durableLockingManager);
- LifecycleUtil.activate(mappingStrategy);
-
- setRevisionTemporality(mappingStrategy.hasAuditSupport() ? RevisionTemporality.AUDITING : RevisionTemporality.NONE);
- setRevisionParallelism(mappingStrategy.hasBranchingSupport() ? RevisionParallelism.BRANCHING
- : RevisionParallelism.NONE);
-
- if (isFirstStart(createdTables))
- {
- firstStart();
- }
- else
- {
- reStart();
- }
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(mappingStrategy);
- LifecycleUtil.deactivate(durableLockingManager);
- LifecycleUtil.deactivate(metaDataManager);
- LifecycleUtil.deactivate(idHandler);
-
- Map<String, String> map = new HashMap<String, String>();
- map.put(PROP_GRACEFULLY_SHUT_DOWN, Boolean.TRUE.toString());
- map.put(PROP_REPOSITORY_STOPPED, Long.toString(getRepository().getTimeStamp()));
-
- if (getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE)
- {
- map.put(PROP_NEXT_LOCAL_CDOID, Store.idToString(idHandler.getNextLocalObjectID()));
- map.put(PROP_LAST_CDOID, Store.idToString(idHandler.getLastObjectID()));
- }
-
- map.put(PROP_LAST_BRANCHID, Integer.toString(getLastBranchID()));
- map.put(PROP_LAST_LOCAL_BRANCHID, Integer.toString(getLastLocalBranchID()));
- map.put(PROP_LAST_COMMITTIME, Long.toString(getLastCommitTime()));
- map.put(PROP_LAST_NONLOCAL_COMMITTIME, Long.toString(getLastNonLocalCommitTime()));
- setPersistentProperties(map);
-
- if (readerPool != null)
- {
- readerPool.dispose();
- }
-
- if (writerPool != null)
- {
- writerPool.dispose();
- }
-
- connectionKeepAliveTimer.cancel();
- connectionKeepAliveTimer = null;
-
- super.doDeactivate();
- }
-
- protected boolean isFirstStart(Set<IDBTable> createdTables)
- {
- if (createdTables.contains(CDODBSchema.PROPERTIES))
- {
- return true;
- }
-
- Set<String> names = new HashSet<String>();
- names.add(PROP_REPOSITORY_CREATED);
-
- Map<String, String> map = getPersistentProperties(names);
- return map.get(PROP_REPOSITORY_CREATED) == null;
- }
-
- protected void firstStart()
- {
- InternalRepository repository = getRepository();
- setCreationTime(repository.getTimeStamp());
- firstTime = true;
- }
-
- protected void reStart()
- {
- Set<String> names = new HashSet<String>();
- names.add(PROP_REPOSITORY_CREATED);
- names.add(PROP_GRACEFULLY_SHUT_DOWN);
-
- Map<String, String> map = getPersistentProperties(names);
- creationTime = Long.valueOf(map.get(PROP_REPOSITORY_CREATED));
-
- if (map.containsKey(PROP_GRACEFULLY_SHUT_DOWN))
- {
- names.clear();
-
- InternalRepository repository = getRepository();
- boolean generatingIDs = repository.getIDGenerationLocation() == IDGenerationLocation.STORE;
- if (generatingIDs)
- {
- names.add(PROP_NEXT_LOCAL_CDOID);
- names.add(PROP_LAST_CDOID);
- }
-
- names.add(PROP_LAST_BRANCHID);
- names.add(PROP_LAST_LOCAL_BRANCHID);
- names.add(PROP_LAST_COMMITTIME);
- names.add(PROP_LAST_NONLOCAL_COMMITTIME);
- map = getPersistentProperties(names);
-
- if (generatingIDs)
- {
- idHandler.setNextLocalObjectID(Store.stringToID(map.get(PROP_NEXT_LOCAL_CDOID)));
- idHandler.setLastObjectID(Store.stringToID(map.get(PROP_LAST_CDOID)));
- }
-
- setLastBranchID(Integer.valueOf(map.get(PROP_LAST_BRANCHID)));
- setLastLocalBranchID(Integer.valueOf(map.get(PROP_LAST_LOCAL_BRANCHID)));
- setLastCommitTime(Long.valueOf(map.get(PROP_LAST_COMMITTIME)));
- setLastNonLocalCommitTime(Long.valueOf(map.get(PROP_LAST_NONLOCAL_COMMITTIME)));
- }
- else
- {
- repairAfterCrash();
- }
-
- removePersistentProperties(Collections.singleton(PROP_GRACEFULLY_SHUT_DOWN));
- }
-
- protected void repairAfterCrash()
- {
- String name = getRepository().getName();
- OM.LOG.warn(MessageFormat.format(Messages.getString("DBStore.9"), name)); //$NON-NLS-1$
-
- Connection connection = getConnection();
-
- try
- {
- connection.setAutoCommit(false);
- connection.setReadOnly(true);
-
- mappingStrategy.repairAfterCrash(dbAdapter, connection); // Must update the idHandler
-
- boolean storeIDs = getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE;
- CDOID lastObjectID = storeIDs ? idHandler.getLastObjectID() : CDOID.NULL;
- CDOID nextLocalObjectID = storeIDs ? idHandler.getNextLocalObjectID() : CDOID.NULL;
-
- int branchID = DBUtil.selectMaximumInt(connection, CDODBSchema.BRANCHES_ID);
- setLastBranchID(branchID > 0 ? branchID : 0);
-
- int localBranchID = DBUtil.selectMinimumInt(connection, CDODBSchema.BRANCHES_ID);
- setLastLocalBranchID(localBranchID < 0 ? localBranchID : 0);
-
- long lastCommitTime = DBUtil.selectMaximumLong(connection, CDODBSchema.COMMIT_INFOS_TIMESTAMP);
- setLastCommitTime(lastCommitTime);
-
- long lastNonLocalCommitTime = DBUtil.selectMaximumLong(connection, CDODBSchema.COMMIT_INFOS_TIMESTAMP,
- CDOBranch.MAIN_BRANCH_ID + "<=" + CDODBSchema.COMMIT_INFOS_BRANCH);
- setLastNonLocalCommitTime(lastNonLocalCommitTime);
-
- if (storeIDs)
- {
- OM.LOG
- .info(MessageFormat.format(
- Messages.getString("DBStore.10"), name, lastObjectID, nextLocalObjectID, getLastBranchID(), getLastCommitTime(), getLastNonLocalCommitTime())); //$NON-NLS-1$
- }
- else
- {
- OM.LOG
- .info(MessageFormat.format(
- Messages.getString("DBStore.10b"), name, getLastBranchID(), getLastCommitTime(), getLastNonLocalCommitTime())); //$NON-NLS-1$
- }
- }
- catch (SQLException e)
- {
- OM.LOG.error(MessageFormat.format(Messages.getString("DBStore.11"), name), e); //$NON-NLS-1$
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(connection);
- }
- }
-
- protected IDBSchema createSchema()
- {
- String name = getRepository().getName();
- return new DBSchema(name);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - Bug 259402 + * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444 + * Stefan Winkler - Bug 249610: [DB] Support external references (Implementation) + * Stefan Winkler - Bug 289056: [DB] Exception "ERROR: relation "cdo_external_refs" does not exist" while executing test-suite for PostgreSQL + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation; +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.revision.CDOAllRevisionsProvider; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; +import org.eclipse.emf.cdo.server.ISession; +import org.eclipse.emf.cdo.server.ITransaction; +import org.eclipse.emf.cdo.server.IView; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.IMetaDataManager; +import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.server.internal.db.messages.Messages; +import org.eclipse.emf.cdo.spi.server.InternalRepository; +import org.eclipse.emf.cdo.spi.server.LongIDStoreAccessor; +import org.eclipse.emf.cdo.spi.server.Store; +import org.eclipse.emf.cdo.spi.server.StoreAccessorPool; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.db.IDBConnectionProvider; +import org.eclipse.net4j.db.ddl.IDBSchema; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.spi.db.DBSchema; +import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.om.monitor.ProgressDistributor; + +import javax.sql.DataSource; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.Timer; + +/** + * @author Eike Stepper + */ +public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider +{ + public static final String TYPE = "db"; //$NON-NLS-1$ + + private static final String PROP_REPOSITORY_CREATED = "org.eclipse.emf.cdo.server.db.repositoryCreated"; //$NON-NLS-1$ + + private static final String PROP_REPOSITORY_STOPPED = "org.eclipse.emf.cdo.server.db.repositoryStopped"; //$NON-NLS-1$ + + private static final String PROP_NEXT_LOCAL_CDOID = "org.eclipse.emf.cdo.server.db.nextLocalCDOID"; //$NON-NLS-1$ + + private static final String PROP_LAST_CDOID = "org.eclipse.emf.cdo.server.db.lastCDOID"; //$NON-NLS-1$ + + private static final String PROP_LAST_BRANCHID = "org.eclipse.emf.cdo.server.db.lastBranchID"; //$NON-NLS-1$ + + private static final String PROP_LAST_LOCAL_BRANCHID = "org.eclipse.emf.cdo.server.db.lastLocalBranchID"; //$NON-NLS-1$ + + private static final String PROP_LAST_COMMITTIME = "org.eclipse.emf.cdo.server.db.lastCommitTime"; //$NON-NLS-1$ + + private static final String PROP_LAST_NONLOCAL_COMMITTIME = "org.eclipse.emf.cdo.server.db.lastNonLocalCommitTime"; //$NON-NLS-1$ + + private static final String PROP_GRACEFULLY_SHUT_DOWN = "org.eclipse.emf.cdo.server.db.gracefullyShutDown"; //$NON-NLS-1$ + + private long creationTime; + + private boolean firstTime; + + private Map<String, String> properties; + + private IIDHandler idHandler; + + private IMetaDataManager metaDataManager = new MetaDataManager(this); + + private DurableLockingManager durableLockingManager = new DurableLockingManager(this); + + private IMappingStrategy mappingStrategy; + + private IDBSchema dbSchema; + + private IDBAdapter dbAdapter; + + private IDBConnectionProvider dbConnectionProvider; + + @ExcludeFromDump + private transient ProgressDistributor accessorWriteDistributor = new ProgressDistributor.Geometric() + { + @Override + public String toString() + { + String result = "accessorWriteDistributor"; //$NON-NLS-1$ + if (getRepository() != null) + { + result += ": " + getRepository().getName(); //$NON-NLS-1$ + } + + return result; + } + }; + + @ExcludeFromDump + private transient StoreAccessorPool readerPool = new StoreAccessorPool(this, null); + + @ExcludeFromDump + private transient StoreAccessorPool writerPool = new StoreAccessorPool(this, null); + + @ExcludeFromDump + private transient Timer connectionKeepAliveTimer; + + public DBStore() + { + super(TYPE, null, set(ChangeFormat.REVISION, ChangeFormat.DELTA), // + set(RevisionTemporality.AUDITING, RevisionTemporality.NONE), // + set(RevisionParallelism.NONE, RevisionParallelism.BRANCHING)); + } + + public IMappingStrategy getMappingStrategy() + { + return mappingStrategy; + } + + public void setMappingStrategy(IMappingStrategy mappingStrategy) + { + this.mappingStrategy = mappingStrategy; + mappingStrategy.setStore(this); + } + + public IDBAdapter getDBAdapter() + { + return dbAdapter; + } + + public void setDBAdapter(IDBAdapter dbAdapter) + { + this.dbAdapter = dbAdapter; + } + + public void setProperties(Map<String, String> properties) + { + this.properties = properties; + } + + public Map<String, String> getProperties() + { + return properties; + } + + public IIDHandler getIDHandler() + { + return idHandler; + } + + public Connection getConnection() + { + Connection connection = dbConnectionProvider.getConnection(); + if (connection == null) + { + throw new DBException("No connection from connection provider: " + dbConnectionProvider); //$NON-NLS-1$ + } + + try + { + connection.setAutoCommit(false); + } + catch (SQLException ex) + { + throw new DBException(ex, "SET AUTO COMMIT = false"); + } + + return connection; + } + + public void setDbConnectionProvider(IDBConnectionProvider dbConnectionProvider) + { + this.dbConnectionProvider = dbConnectionProvider; + } + + public void setDataSource(DataSource dataSource) + { + dbConnectionProvider = DBUtil.createConnectionProvider(dataSource); + } + + public IMetaDataManager getMetaDataManager() + { + return metaDataManager; + } + + public DurableLockingManager getDurableLockingManager() + { + return durableLockingManager; + } + + public Timer getConnectionKeepAliveTimer() + { + return connectionKeepAliveTimer; + } + + @Override + public Set<ChangeFormat> getSupportedChangeFormats() + { + if (mappingStrategy.hasDeltaSupport()) + { + return set(ChangeFormat.DELTA); + } + + return set(ChangeFormat.REVISION); + } + + public ProgressDistributor getAccessorWriteDistributor() + { + return accessorWriteDistributor; + } + + public IDBSchema getDBSchema() + { + return dbSchema; + } + + public Map<String, String> getPersistentProperties(Set<String> names) + { + Connection connection = null; + PreparedStatement selectStmt = null; + String sql = null; + + try + { + connection = getConnection(); + Map<String, String> result = new HashMap<String, String>(); + boolean allProperties = names == null || names.isEmpty(); + if (allProperties) + { + sql = CDODBSchema.SQL_SELECT_ALL_PROPERTIES; + selectStmt = connection.prepareStatement(sql); + ResultSet resultSet = null; + + try + { + resultSet = selectStmt.executeQuery(); + while (resultSet.next()) + { + String key = resultSet.getString(1); + String value = resultSet.getString(2); + result.put(key, value); + } + } + finally + { + DBUtil.close(resultSet); + } + } + else + { + sql = CDODBSchema.SQL_SELECT_PROPERTIES; + selectStmt = connection.prepareStatement(sql); + for (String name : names) + { + selectStmt.setString(1, name); + ResultSet resultSet = null; + + try + { + resultSet = selectStmt.executeQuery(); + if (resultSet.next()) + { + String value = resultSet.getString(1); + result.put(name, value); + } + } + finally + { + DBUtil.close(resultSet); + } + } + } + + return result; + } + catch (SQLException ex) + { + throw new DBException(ex, sql); + } + finally + { + DBUtil.close(selectStmt); + DBUtil.close(connection); + } + } + + public void setPersistentProperties(Map<String, String> properties) + { + Connection connection = null; + PreparedStatement deleteStmt = null; + PreparedStatement insertStmt = null; + String sql = null; + + try + { + connection = getConnection(); + deleteStmt = connection.prepareStatement(CDODBSchema.SQL_DELETE_PROPERTIES); + insertStmt = connection.prepareStatement(CDODBSchema.SQL_INSERT_PROPERTIES); + + for (Entry<String, String> entry : properties.entrySet()) + { + String name = entry.getKey(); + String value = entry.getValue(); + + sql = CDODBSchema.SQL_DELETE_PROPERTIES; + deleteStmt.setString(1, name); + deleteStmt.executeUpdate(); + + sql = CDODBSchema.SQL_INSERT_PROPERTIES; + insertStmt.setString(1, name); + insertStmt.setString(2, value); + insertStmt.executeUpdate(); + } + + sql = null; + connection.commit(); + } + catch (SQLException ex) + { + throw new DBException(ex, sql); + } + finally + { + DBUtil.close(insertStmt); + DBUtil.close(deleteStmt); + DBUtil.close(connection); + } + } + + public void removePersistentProperties(Set<String> names) + { + Connection connection = null; + PreparedStatement deleteStmt = null; + + try + { + connection = getConnection(); + deleteStmt = connection.prepareStatement(CDODBSchema.SQL_DELETE_PROPERTIES); + + for (String name : names) + { + deleteStmt.setString(1, name); + deleteStmt.executeUpdate(); + } + + connection.commit(); + } + catch (SQLException ex) + { + throw new DBException(ex, CDODBSchema.SQL_DELETE_PROPERTIES); + } + finally + { + DBUtil.close(deleteStmt); + DBUtil.close(connection); + } + } + + @Override + public DBStoreAccessor getReader(ISession session) + { + return (DBStoreAccessor)super.getReader(session); + } + + @Override + public DBStoreAccessor getWriter(ITransaction transaction) + { + return (DBStoreAccessor)super.getWriter(transaction); + } + + @Override + protected StoreAccessorPool getReaderPool(ISession session, boolean forReleasing) + { + return readerPool; + } + + @Override + protected StoreAccessorPool getWriterPool(IView view, boolean forReleasing) + { + return writerPool; + } + + @Override + protected DBStoreAccessor createReader(ISession session) throws DBException + { + return new DBStoreAccessor(this, session); + } + + @Override + protected DBStoreAccessor createWriter(ITransaction transaction) throws DBException + { + return new DBStoreAccessor(this, transaction); + } + + public Map<CDOBranch, List<CDORevision>> getAllRevisions() + { + final Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>(); + IDBStoreAccessor accessor = getReader(null); + StoreThreadLocal.setAccessor(accessor); + + try + { + accessor.handleRevisions(null, null, CDOBranchPoint.UNSPECIFIED_DATE, true, + new CDORevisionHandler.Filtered.Undetached(new CDORevisionHandler() + { + public boolean handleRevision(CDORevision revision) + { + CDOBranch branch = revision.getBranch(); + List<CDORevision> list = result.get(branch); + if (list == null) + { + list = new ArrayList<CDORevision>(); + result.put(branch, list); + } + + list.add(revision); + return true; + } + })); + } + finally + { + StoreThreadLocal.release(); + } + + return result; + } + + public CDOID createObjectID(String val) + { + return idHandler.createCDOID(val); + } + + public boolean isLocal(CDOID id) + { + return idHandler.isLocalCDOID(id); + } + + public CDOID getNextCDOID(LongIDStoreAccessor accessor, CDORevision revision) + { + return idHandler.getNextCDOID(revision); + } + + public long getCreationTime() + { + return creationTime; + } + + public void setCreationTime(long creationTime) + { + this.creationTime = creationTime; + + Map<String, String> map = new HashMap<String, String>(); + map.put(PROP_REPOSITORY_CREATED, Long.toString(creationTime)); + setPersistentProperties(map); + } + + public boolean isFirstStart() + { + return firstTime; + } + + @Override + protected void doBeforeActivate() throws Exception + { + super.doBeforeActivate(); + checkNull(mappingStrategy, Messages.getString("DBStore.2")); //$NON-NLS-1$ + checkNull(dbAdapter, Messages.getString("DBStore.1")); //$NON-NLS-1$ + checkNull(dbConnectionProvider, Messages.getString("DBStore.0")); //$NON-NLS-1$ + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + + if (getRepository().getIDGenerationLocation() == IDGenerationLocation.CLIENT) + { + idHandler = new UUIDHandler(this); + } + else + { + idHandler = new LongIDHandler(this); + } + + setObjectIDTypes(idHandler.getObjectIDTypes()); + connectionKeepAliveTimer = new Timer("Connection-Keep-Alive-" + this); //$NON-NLS-1$ + + Set<IDBTable> createdTables = null; + Connection connection = getConnection(); + + try + { + if (isDropAllDataOnActivate()) + { + OM.LOG.info("Dropping all tables from repository " + getRepository().getName() + "..."); + DBUtil.dropAllTables(connection, null); + connection.commit(); + } + + createdTables = CDODBSchema.INSTANCE.create(dbAdapter, connection); + connection.commit(); + } + finally + { + DBUtil.close(connection); + } + + dbSchema = createSchema(); + + LifecycleUtil.activate(idHandler); + LifecycleUtil.activate(metaDataManager); + LifecycleUtil.activate(durableLockingManager); + LifecycleUtil.activate(mappingStrategy); + + setRevisionTemporality(mappingStrategy.hasAuditSupport() ? RevisionTemporality.AUDITING : RevisionTemporality.NONE); + setRevisionParallelism(mappingStrategy.hasBranchingSupport() ? RevisionParallelism.BRANCHING + : RevisionParallelism.NONE); + + if (isFirstStart(createdTables)) + { + firstStart(); + } + else + { + reStart(); + } + } + + @Override + protected void doDeactivate() throws Exception + { + LifecycleUtil.deactivate(mappingStrategy); + LifecycleUtil.deactivate(durableLockingManager); + LifecycleUtil.deactivate(metaDataManager); + LifecycleUtil.deactivate(idHandler); + + Map<String, String> map = new HashMap<String, String>(); + map.put(PROP_GRACEFULLY_SHUT_DOWN, Boolean.TRUE.toString()); + map.put(PROP_REPOSITORY_STOPPED, Long.toString(getRepository().getTimeStamp())); + + if (getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE) + { + map.put(PROP_NEXT_LOCAL_CDOID, Store.idToString(idHandler.getNextLocalObjectID())); + map.put(PROP_LAST_CDOID, Store.idToString(idHandler.getLastObjectID())); + } + + map.put(PROP_LAST_BRANCHID, Integer.toString(getLastBranchID())); + map.put(PROP_LAST_LOCAL_BRANCHID, Integer.toString(getLastLocalBranchID())); + map.put(PROP_LAST_COMMITTIME, Long.toString(getLastCommitTime())); + map.put(PROP_LAST_NONLOCAL_COMMITTIME, Long.toString(getLastNonLocalCommitTime())); + setPersistentProperties(map); + + if (readerPool != null) + { + readerPool.dispose(); + } + + if (writerPool != null) + { + writerPool.dispose(); + } + + connectionKeepAliveTimer.cancel(); + connectionKeepAliveTimer = null; + + super.doDeactivate(); + } + + protected boolean isFirstStart(Set<IDBTable> createdTables) + { + if (createdTables.contains(CDODBSchema.PROPERTIES)) + { + return true; + } + + Set<String> names = new HashSet<String>(); + names.add(PROP_REPOSITORY_CREATED); + + Map<String, String> map = getPersistentProperties(names); + return map.get(PROP_REPOSITORY_CREATED) == null; + } + + protected void firstStart() + { + InternalRepository repository = getRepository(); + setCreationTime(repository.getTimeStamp()); + firstTime = true; + } + + protected void reStart() + { + Set<String> names = new HashSet<String>(); + names.add(PROP_REPOSITORY_CREATED); + names.add(PROP_GRACEFULLY_SHUT_DOWN); + + Map<String, String> map = getPersistentProperties(names); + creationTime = Long.valueOf(map.get(PROP_REPOSITORY_CREATED)); + + if (map.containsKey(PROP_GRACEFULLY_SHUT_DOWN)) + { + names.clear(); + + InternalRepository repository = getRepository(); + boolean generatingIDs = repository.getIDGenerationLocation() == IDGenerationLocation.STORE; + if (generatingIDs) + { + names.add(PROP_NEXT_LOCAL_CDOID); + names.add(PROP_LAST_CDOID); + } + + names.add(PROP_LAST_BRANCHID); + names.add(PROP_LAST_LOCAL_BRANCHID); + names.add(PROP_LAST_COMMITTIME); + names.add(PROP_LAST_NONLOCAL_COMMITTIME); + map = getPersistentProperties(names); + + if (generatingIDs) + { + idHandler.setNextLocalObjectID(Store.stringToID(map.get(PROP_NEXT_LOCAL_CDOID))); + idHandler.setLastObjectID(Store.stringToID(map.get(PROP_LAST_CDOID))); + } + + setLastBranchID(Integer.valueOf(map.get(PROP_LAST_BRANCHID))); + setLastLocalBranchID(Integer.valueOf(map.get(PROP_LAST_LOCAL_BRANCHID))); + setLastCommitTime(Long.valueOf(map.get(PROP_LAST_COMMITTIME))); + setLastNonLocalCommitTime(Long.valueOf(map.get(PROP_LAST_NONLOCAL_COMMITTIME))); + } + else + { + repairAfterCrash(); + } + + removePersistentProperties(Collections.singleton(PROP_GRACEFULLY_SHUT_DOWN)); + } + + protected void repairAfterCrash() + { + String name = getRepository().getName(); + OM.LOG.warn(MessageFormat.format(Messages.getString("DBStore.9"), name)); //$NON-NLS-1$ + + Connection connection = getConnection(); + + try + { + connection.setAutoCommit(false); + connection.setReadOnly(true); + + mappingStrategy.repairAfterCrash(dbAdapter, connection); // Must update the idHandler + + boolean storeIDs = getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE; + CDOID lastObjectID = storeIDs ? idHandler.getLastObjectID() : CDOID.NULL; + CDOID nextLocalObjectID = storeIDs ? idHandler.getNextLocalObjectID() : CDOID.NULL; + + int branchID = DBUtil.selectMaximumInt(connection, CDODBSchema.BRANCHES_ID); + setLastBranchID(branchID > 0 ? branchID : 0); + + int localBranchID = DBUtil.selectMinimumInt(connection, CDODBSchema.BRANCHES_ID); + setLastLocalBranchID(localBranchID < 0 ? localBranchID : 0); + + long lastCommitTime = DBUtil.selectMaximumLong(connection, CDODBSchema.COMMIT_INFOS_TIMESTAMP); + setLastCommitTime(lastCommitTime); + + long lastNonLocalCommitTime = DBUtil.selectMaximumLong(connection, CDODBSchema.COMMIT_INFOS_TIMESTAMP, + CDOBranch.MAIN_BRANCH_ID + "<=" + CDODBSchema.COMMIT_INFOS_BRANCH); + setLastNonLocalCommitTime(lastNonLocalCommitTime); + + if (storeIDs) + { + OM.LOG + .info(MessageFormat.format( + Messages.getString("DBStore.10"), name, lastObjectID, nextLocalObjectID, getLastBranchID(), getLastCommitTime(), getLastNonLocalCommitTime())); //$NON-NLS-1$ + } + else + { + OM.LOG + .info(MessageFormat.format( + Messages.getString("DBStore.10b"), name, getLastBranchID(), getLastCommitTime(), getLastNonLocalCommitTime())); //$NON-NLS-1$ + } + } + catch (SQLException e) + { + OM.LOG.error(MessageFormat.format(Messages.getString("DBStore.11"), name), e); //$NON-NLS-1$ + throw new DBException(e); + } + finally + { + DBUtil.close(connection); + } + } + + protected IDBSchema createSchema() + { + String name = getRepository().getName(); + return new DBSchema(name); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java index c342c44d7b..4f9b61d18b 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java @@ -1,110 +1,110 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - Bug 283998: [DB] Chunk reading for multiple chunks fails
- * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping2;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.spi.server.StoreChunkReader;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChunkReader
-{
- private IListMapping referenceMapping;
-
- private StringBuilder builder = new StringBuilder();
-
- public DBStoreChunkReader(DBStoreAccessor accessor, CDORevision revision, EStructuralFeature feature)
- {
- super(accessor, revision, feature);
- IMappingStrategy mappingStrategy = accessor.getStore().getMappingStrategy();
- IClassMapping mapping = mappingStrategy.getClassMapping(revision.getEClass());
- referenceMapping = mapping.getListMapping(feature);
- }
-
- @Override
- public DBStoreAccessor getAccessor()
- {
- return (DBStoreAccessor)super.getAccessor();
- }
-
- @Override
- public void addSimpleChunk(int index)
- {
- super.addSimpleChunk(index);
- prepareAddition();
-
- if (referenceMapping instanceof IListMapping2)
- {
- ((IListMapping2)referenceMapping).addSimpleChunkWhere(getAccessor(), getRevision().getID(), builder, index);
- }
- else
- {
- builder.append(CDODBSchema.LIST_IDX);
- builder.append('=');
- builder.append(index);
- }
- }
-
- @Override
- public void addRangedChunk(int fromIndex, int toIndex)
- {
- super.addRangedChunk(fromIndex, toIndex);
- prepareAddition();
-
- if (referenceMapping instanceof IListMapping2)
- {
- ((IListMapping2)referenceMapping).addRangedChunkWhere(getAccessor(), getRevision().getID(), builder, fromIndex,
- toIndex);
- }
- else
- {
- builder.append(CDODBSchema.LIST_IDX);
- builder.append(" BETWEEN "); //$NON-NLS-1$
- builder.append(fromIndex);
- builder.append(" AND "); //$NON-NLS-1$
- builder.append(toIndex - 1);
- }
- }
-
- public List<Chunk> executeRead()
- {
- List<Chunk> chunks = getChunks();
- if (chunks.size() > 1)
- {
- builder.insert(0, '(');
- builder.append(')');
- }
-
- referenceMapping.readChunks(this, chunks, builder.toString());
- return chunks;
- }
-
- private void prepareAddition()
- {
- // If not empty, a chunk has been already added, and the next condition needs to be OR-ed
- if (builder.length() > 0)
- {
- builder.append(" OR "); //$NON-NLS-1$
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - Bug 283998: [DB] Chunk reading for multiple chunks fails + * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping2; +import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; +import org.eclipse.emf.cdo.spi.server.StoreChunkReader; + +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.util.List; + +/** + * @author Eike Stepper + */ +public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChunkReader +{ + private IListMapping referenceMapping; + + private StringBuilder builder = new StringBuilder(); + + public DBStoreChunkReader(DBStoreAccessor accessor, CDORevision revision, EStructuralFeature feature) + { + super(accessor, revision, feature); + IMappingStrategy mappingStrategy = accessor.getStore().getMappingStrategy(); + IClassMapping mapping = mappingStrategy.getClassMapping(revision.getEClass()); + referenceMapping = mapping.getListMapping(feature); + } + + @Override + public DBStoreAccessor getAccessor() + { + return (DBStoreAccessor)super.getAccessor(); + } + + @Override + public void addSimpleChunk(int index) + { + super.addSimpleChunk(index); + prepareAddition(); + + if (referenceMapping instanceof IListMapping2) + { + ((IListMapping2)referenceMapping).addSimpleChunkWhere(getAccessor(), getRevision().getID(), builder, index); + } + else + { + builder.append(CDODBSchema.LIST_IDX); + builder.append('='); + builder.append(index); + } + } + + @Override + public void addRangedChunk(int fromIndex, int toIndex) + { + super.addRangedChunk(fromIndex, toIndex); + prepareAddition(); + + if (referenceMapping instanceof IListMapping2) + { + ((IListMapping2)referenceMapping).addRangedChunkWhere(getAccessor(), getRevision().getID(), builder, fromIndex, + toIndex); + } + else + { + builder.append(CDODBSchema.LIST_IDX); + builder.append(" BETWEEN "); //$NON-NLS-1$ + builder.append(fromIndex); + builder.append(" AND "); //$NON-NLS-1$ + builder.append(toIndex - 1); + } + } + + public List<Chunk> executeRead() + { + List<Chunk> chunks = getChunks(); + if (chunks.size() > 1) + { + builder.insert(0, '('); + builder.append(')'); + } + + referenceMapping.readChunks(this, chunks, builder.toString()); + return chunks; + } + + private void prepareAddition() + { + // If not empty, a chunk has been already added, and the next condition needs to be OR-ed + if (builder.length() > 0) + { + builder.append(" OR "); //$NON-NLS-1$ + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java index 7c0903e393..f4a98ab18c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreFactory.java @@ -1,130 +1,130 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- * Caspar De Groot - maintenance
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.IStoreFactory;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.spi.server.RepositoryConfigurator;
-
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.IDBConnectionProvider;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.NodeList;
-
-import javax.sql.DataSource;
-
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * @author Eike Stepper
- */
-public class DBStoreFactory implements IStoreFactory
-{
- public DBStoreFactory()
- {
- }
-
- public String getStoreType()
- {
- return DBStore.TYPE;
- }
-
- public IStore createStore(String repositoryName, Map<String, String> repositoryProperties, Element storeConfig)
- {
- IMappingStrategy mappingStrategy = getMappingStrategy(repositoryName, repositoryProperties, storeConfig);
- IDBAdapter dbAdapter = getDBAdapter(storeConfig);
- DataSource dataSource = getDataSource(storeConfig);
- IDBConnectionProvider connectionProvider = DBUtil.createConnectionProvider(dataSource);
-
- DBStore store = new DBStore();
- store.setMappingStrategy(mappingStrategy);
- store.setDBAdapter(dbAdapter);
- store.setDbConnectionProvider(connectionProvider);
-
- Map<String, String> storeProperties = RepositoryConfigurator.getProperties(storeConfig, 1);
- store.setProperties(storeProperties);
-
- return store;
- }
-
- private IMappingStrategy getMappingStrategy(String repositoryName, Map<String, String> repositoryProperties,
- Element storeConfig)
- {
- NodeList mappingStrategyConfigs = storeConfig.getElementsByTagName("mappingStrategy"); //$NON-NLS-1$
- if (mappingStrategyConfigs.getLength() != 1)
- {
- throw new IllegalStateException("Exactly one mapping strategy must be configured for DB store"); //$NON-NLS-1$
- }
-
- Element mappingStrategyConfig = (Element)mappingStrategyConfigs.item(0);
- String mappingStrategyType = mappingStrategyConfig.getAttribute("type"); //$NON-NLS-1$
- IMappingStrategy mappingStrategy = CDODBUtil.createMappingStrategy(mappingStrategyType);
- if (mappingStrategy == null)
- {
- throw new IllegalArgumentException("Unknown mapping strategy: " + mappingStrategyType); //$NON-NLS-1$
- }
-
- Map<String, String> properties = RepositoryConfigurator.getProperties(mappingStrategyConfig, 1);
- properties.put("repositoryName", repositoryName);
- properties.putAll(repositoryProperties);
- mappingStrategy.setProperties(properties);
-
- return mappingStrategy;
- }
-
- private IDBAdapter getDBAdapter(Element storeConfig)
- {
- NodeList dbAdapterConfigs = storeConfig.getElementsByTagName("dbAdapter"); //$NON-NLS-1$
- if (dbAdapterConfigs.getLength() != 1)
- {
- throw new IllegalStateException("Exactly one dbAdapter must be configured for DB store"); //$NON-NLS-1$
- }
-
- Element dbAdapterConfig = (Element)dbAdapterConfigs.item(0);
- String dbAdapterName = dbAdapterConfig.getAttribute("name"); //$NON-NLS-1$
- IDBAdapter dbAdapter = DBUtil.getDBAdapter(dbAdapterName);
- if (dbAdapter == null)
- {
- throw new IllegalArgumentException("Unknown DB adapter: " + dbAdapterName); //$NON-NLS-1$
- }
-
- return dbAdapter;
- }
-
- private DataSource getDataSource(Element storeConfig)
- {
- NodeList dataSourceConfigs = storeConfig.getElementsByTagName("dataSource"); //$NON-NLS-1$
- if (dataSourceConfigs.getLength() != 1)
- {
- throw new IllegalStateException("Exactly one dataSource must be configured for DB store"); //$NON-NLS-1$
- }
-
- Properties properties = new Properties();
- Element dataSourceConfig = (Element)dataSourceConfigs.item(0);
- NamedNodeMap attributes = dataSourceConfig.getAttributes();
- for (int i = 0; i < attributes.getLength(); i++)
- {
- Attr attribute = (Attr)attributes.item(i);
- properties.put(attribute.getName(), attribute.getValue());
- }
-
- return DBUtil.createDataSource(properties);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + * Caspar De Groot - maintenance + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.server.IStore; +import org.eclipse.emf.cdo.server.IStoreFactory; +import org.eclipse.emf.cdo.server.db.CDODBUtil; +import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; +import org.eclipse.emf.cdo.spi.server.RepositoryConfigurator; + +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.db.IDBConnectionProvider; + +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.NodeList; + +import javax.sql.DataSource; + +import java.util.Map; +import java.util.Properties; + +/** + * @author Eike Stepper + */ +public class DBStoreFactory implements IStoreFactory +{ + public DBStoreFactory() + { + } + + public String getStoreType() + { + return DBStore.TYPE; + } + + public IStore createStore(String repositoryName, Map<String, String> repositoryProperties, Element storeConfig) + { + IMappingStrategy mappingStrategy = getMappingStrategy(repositoryName, repositoryProperties, storeConfig); + IDBAdapter dbAdapter = getDBAdapter(storeConfig); + DataSource dataSource = getDataSource(storeConfig); + IDBConnectionProvider connectionProvider = DBUtil.createConnectionProvider(dataSource); + + DBStore store = new DBStore(); + store.setMappingStrategy(mappingStrategy); + store.setDBAdapter(dbAdapter); + store.setDbConnectionProvider(connectionProvider); + + Map<String, String> storeProperties = RepositoryConfigurator.getProperties(storeConfig, 1); + store.setProperties(storeProperties); + + return store; + } + + private IMappingStrategy getMappingStrategy(String repositoryName, Map<String, String> repositoryProperties, + Element storeConfig) + { + NodeList mappingStrategyConfigs = storeConfig.getElementsByTagName("mappingStrategy"); //$NON-NLS-1$ + if (mappingStrategyConfigs.getLength() != 1) + { + throw new IllegalStateException("Exactly one mapping strategy must be configured for DB store"); //$NON-NLS-1$ + } + + Element mappingStrategyConfig = (Element)mappingStrategyConfigs.item(0); + String mappingStrategyType = mappingStrategyConfig.getAttribute("type"); //$NON-NLS-1$ + IMappingStrategy mappingStrategy = CDODBUtil.createMappingStrategy(mappingStrategyType); + if (mappingStrategy == null) + { + throw new IllegalArgumentException("Unknown mapping strategy: " + mappingStrategyType); //$NON-NLS-1$ + } + + Map<String, String> properties = RepositoryConfigurator.getProperties(mappingStrategyConfig, 1); + properties.put("repositoryName", repositoryName); + properties.putAll(repositoryProperties); + mappingStrategy.setProperties(properties); + + return mappingStrategy; + } + + private IDBAdapter getDBAdapter(Element storeConfig) + { + NodeList dbAdapterConfigs = storeConfig.getElementsByTagName("dbAdapter"); //$NON-NLS-1$ + if (dbAdapterConfigs.getLength() != 1) + { + throw new IllegalStateException("Exactly one dbAdapter must be configured for DB store"); //$NON-NLS-1$ + } + + Element dbAdapterConfig = (Element)dbAdapterConfigs.item(0); + String dbAdapterName = dbAdapterConfig.getAttribute("name"); //$NON-NLS-1$ + IDBAdapter dbAdapter = DBUtil.getDBAdapter(dbAdapterName); + if (dbAdapter == null) + { + throw new IllegalArgumentException("Unknown DB adapter: " + dbAdapterName); //$NON-NLS-1$ + } + + return dbAdapter; + } + + private DataSource getDataSource(Element storeConfig) + { + NodeList dataSourceConfigs = storeConfig.getElementsByTagName("dataSource"); //$NON-NLS-1$ + if (dataSourceConfigs.getLength() != 1) + { + throw new IllegalStateException("Exactly one dataSource must be configured for DB store"); //$NON-NLS-1$ + } + + Properties properties = new Properties(); + Element dataSourceConfig = (Element)dataSourceConfigs.item(0); + NamedNodeMap attributes = dataSourceConfig.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) + { + Attr attribute = (Attr)attributes.item(i); + properties.put(attribute.getName(), attribute.getValue()); + } + + return DBUtil.createDataSource(properties); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ExternalReferenceManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ExternalReferenceManager.java index 32ae01dca7..a13172dc2f 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ExternalReferenceManager.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ExternalReferenceManager.java @@ -1,302 +1,302 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Stefan Winkler - initial API and implementation
- * Stefan Winkler - bug 249610: [DB] Support external references (Implementation)
- * Eike Stepper - maintenance
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.id.CDOIDExternal;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBIndex;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * @author Stefan Winkler
- */
-public class ExternalReferenceManager extends Lifecycle
-{
- private static final int NULL = 0;
-
- private IDBTable table;
-
- private IDBField idField;
-
- private IDBField uriField;
-
- private IDBField timestampField;
-
- private final IIDHandler idHandler;
-
- private AtomicLong lastMappedID = new AtomicLong(NULL);
-
- @ExcludeFromDump
- private transient String sqlSelectByLongID;
-
- @ExcludeFromDump
- private transient String sqlSelectByURI;
-
- @ExcludeFromDump
- private transient String sqlInsert;
-
- public ExternalReferenceManager(IIDHandler idHandler)
- {
- this.idHandler = idHandler;
- }
-
- public IIDHandler getIDHandler()
- {
- return idHandler;
- }
-
- public long mapExternalReference(CDOIDExternal id, long commitTime)
- {
- IDBStoreAccessor accessor = getAccessor();
- return mapURI(accessor, id.getURI(), commitTime);
- }
-
- public CDOIDExternal unmapExternalReference(long mappedId)
- {
- IDBStoreAccessor accessor = getAccessor();
- return CDOIDUtil.createExternal(unmapURI(accessor, mappedId));
- }
-
- public long mapURI(IDBStoreAccessor accessor, String uri, long commitTime)
- {
- long result = lookupByURI(accessor, uri);
- if (result < NULL)
- {
- // mapping found
- return result;
- }
-
- return insertNew(accessor, uri, commitTime);
- }
-
- public String unmapURI(IDBStoreAccessor accessor, long mappedId)
- {
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlSelectByLongID, ReuseProbability.HIGH);
- stmt.setLong(1, mappedId);
- resultSet = stmt.executeQuery();
-
- if (!resultSet.next())
- {
- OM.LOG.error("External ID " + mappedId + " not found. Database inconsistent!");
- throw new IllegalStateException("External ID " + mappedId + " not found. Database inconsistent!");
- }
-
- return resultSet.getString(1);
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- String where = " WHERE " + timestampField + " BETWEEN " + fromCommitTime + " AND " + toCommitTime;
- DBUtil.serializeTable(out, connection, table, null, where);
- }
-
- public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- DBUtil.deserializeTable(in, connection, table, monitor);
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- IDBStore store = idHandler.getStore();
- table = store.getDBSchema().addTable("cdo_external_refs"); //$NON-NLS-1$
- idField = table.addField("id", idHandler.getDBType()); //$NON-NLS-1$
- uriField = table.addField("uri", DBType.VARCHAR, 1024); //$NON-NLS-1$
- timestampField = table.addField("committime", DBType.BIGINT); //$NON-NLS-1$
-
- table.addIndex(IDBIndex.Type.PRIMARY_KEY, idField);
- table.addIndex(IDBIndex.Type.NON_UNIQUE, uriField);
-
- IDBStoreAccessor writer = store.getWriter(null);
- Connection connection = writer.getConnection();
- Statement statement = null;
- ResultSet resultSet = null;
-
- try
- {
- statement = connection.createStatement();
- store.getDBAdapter().createTable(table, statement);
- connection.commit();
-
- String sql = "SELECT MIN(" + idField + ") FROM " + table;
- resultSet = statement.executeQuery(sql);
-
- if (resultSet.next())
- {
- lastMappedID.set(resultSet.getLong(1));
- }
-
- // else: resultSet is empty => table is empty
- // and lastMappedId stays 0 - as initialized.
- }
- catch (SQLException ex)
- {
- connection.rollback();
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(statement);
- writer.release();
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("INSERT INTO ");
- builder.append(table);
- builder.append("(");
- builder.append(idField);
- builder.append(",");
- builder.append(uriField);
- builder.append(",");
- builder.append(timestampField);
- builder.append(") VALUES (?, ?, ?)");
- sqlInsert = builder.toString();
-
- builder = new StringBuilder();
- builder.append("SELECT "); //$NON-NLS-1$
- builder.append(idField);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(table);
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(uriField);
- builder.append("=?"); //$NON-NLS-1$
- sqlSelectByURI = builder.toString();
-
- builder = new StringBuilder();
- builder.append("SELECT "); //$NON-NLS-1$
- builder.append(uriField);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(table);
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(idField);
- builder.append("=?"); //$NON-NLS-1$
- sqlSelectByLongID = builder.toString();
- }
-
- private long insertNew(IDBStoreAccessor accessor, String uri, long commitTime)
- {
- long newMappedID = lastMappedID.decrementAndGet();
-
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.MEDIUM);
- stmt.setLong(1, newMappedID);
- stmt.setString(2, uri);
- stmt.setLong(3, commitTime);
-
- DBUtil.update(stmt, true);
- return newMappedID;
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- private long lookupByURI(IDBStoreAccessor accessor, String uri)
- {
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlSelectByURI, ReuseProbability.HIGH);
- stmt.setString(1, uri);
-
- resultSet = stmt.executeQuery();
-
- if (resultSet.next())
- {
- return resultSet.getLong(1);
- }
-
- // Not found ...
- return NULL;
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- private static IDBStoreAccessor getAccessor()
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- if (accessor == null)
- {
- throw new IllegalStateException("Can only be called from within a valid IDBStoreAccessor context");
- }
-
- return (IDBStoreAccessor)accessor;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Stefan Winkler - initial API and implementation + * Stefan Winkler - bug 249610: [DB] Support external references (Implementation) + * Eike Stepper - maintenance + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.id.CDOIDExternal; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.server.IStoreAccessor; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBIndex; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author Stefan Winkler + */ +public class ExternalReferenceManager extends Lifecycle +{ + private static final int NULL = 0; + + private IDBTable table; + + private IDBField idField; + + private IDBField uriField; + + private IDBField timestampField; + + private final IIDHandler idHandler; + + private AtomicLong lastMappedID = new AtomicLong(NULL); + + @ExcludeFromDump + private transient String sqlSelectByLongID; + + @ExcludeFromDump + private transient String sqlSelectByURI; + + @ExcludeFromDump + private transient String sqlInsert; + + public ExternalReferenceManager(IIDHandler idHandler) + { + this.idHandler = idHandler; + } + + public IIDHandler getIDHandler() + { + return idHandler; + } + + public long mapExternalReference(CDOIDExternal id, long commitTime) + { + IDBStoreAccessor accessor = getAccessor(); + return mapURI(accessor, id.getURI(), commitTime); + } + + public CDOIDExternal unmapExternalReference(long mappedId) + { + IDBStoreAccessor accessor = getAccessor(); + return CDOIDUtil.createExternal(unmapURI(accessor, mappedId)); + } + + public long mapURI(IDBStoreAccessor accessor, String uri, long commitTime) + { + long result = lookupByURI(accessor, uri); + if (result < NULL) + { + // mapping found + return result; + } + + return insertNew(accessor, uri, commitTime); + } + + public String unmapURI(IDBStoreAccessor accessor, long mappedId) + { + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlSelectByLongID, ReuseProbability.HIGH); + stmt.setLong(1, mappedId); + resultSet = stmt.executeQuery(); + + if (!resultSet.next()) + { + OM.LOG.error("External ID " + mappedId + " not found. Database inconsistent!"); + throw new IllegalStateException("External ID " + mappedId + " not found. Database inconsistent!"); + } + + return resultSet.getString(1); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(resultSet); + statementCache.releasePreparedStatement(stmt); + } + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + String where = " WHERE " + timestampField + " BETWEEN " + fromCommitTime + " AND " + toCommitTime; + DBUtil.serializeTable(out, connection, table, null, where); + } + + public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + DBUtil.deserializeTable(in, connection, table, monitor); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + + IDBStore store = idHandler.getStore(); + table = store.getDBSchema().addTable("cdo_external_refs"); //$NON-NLS-1$ + idField = table.addField("id", idHandler.getDBType()); //$NON-NLS-1$ + uriField = table.addField("uri", DBType.VARCHAR, 1024); //$NON-NLS-1$ + timestampField = table.addField("committime", DBType.BIGINT); //$NON-NLS-1$ + + table.addIndex(IDBIndex.Type.PRIMARY_KEY, idField); + table.addIndex(IDBIndex.Type.NON_UNIQUE, uriField); + + IDBStoreAccessor writer = store.getWriter(null); + Connection connection = writer.getConnection(); + Statement statement = null; + ResultSet resultSet = null; + + try + { + statement = connection.createStatement(); + store.getDBAdapter().createTable(table, statement); + connection.commit(); + + String sql = "SELECT MIN(" + idField + ") FROM " + table; + resultSet = statement.executeQuery(sql); + + if (resultSet.next()) + { + lastMappedID.set(resultSet.getLong(1)); + } + + // else: resultSet is empty => table is empty + // and lastMappedId stays 0 - as initialized. + } + catch (SQLException ex) + { + connection.rollback(); + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(statement); + writer.release(); + } + + StringBuilder builder = new StringBuilder(); + builder.append("INSERT INTO "); + builder.append(table); + builder.append("("); + builder.append(idField); + builder.append(","); + builder.append(uriField); + builder.append(","); + builder.append(timestampField); + builder.append(") VALUES (?, ?, ?)"); + sqlInsert = builder.toString(); + + builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(idField); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(table); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(uriField); + builder.append("=?"); //$NON-NLS-1$ + sqlSelectByURI = builder.toString(); + + builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(uriField); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(table); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(idField); + builder.append("=?"); //$NON-NLS-1$ + sqlSelectByLongID = builder.toString(); + } + + private long insertNew(IDBStoreAccessor accessor, String uri, long commitTime) + { + long newMappedID = lastMappedID.decrementAndGet(); + + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.MEDIUM); + stmt.setLong(1, newMappedID); + stmt.setString(2, uri); + stmt.setLong(3, commitTime); + + DBUtil.update(stmt, true); + return newMappedID; + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + statementCache.releasePreparedStatement(stmt); + } + } + + private long lookupByURI(IDBStoreAccessor accessor, String uri) + { + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlSelectByURI, ReuseProbability.HIGH); + stmt.setString(1, uri); + + resultSet = stmt.executeQuery(); + + if (resultSet.next()) + { + return resultSet.getLong(1); + } + + // Not found ... + return NULL; + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(resultSet); + statementCache.releasePreparedStatement(stmt); + } + } + + private static IDBStoreAccessor getAccessor() + { + IStoreAccessor accessor = StoreThreadLocal.getAccessor(); + if (accessor == null) + { + throw new IllegalStateException("Can only be called from within a valid IDBStoreAccessor context"); + } + + return (IDBStoreAccessor)accessor; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/IObjectTypeMapper.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/IObjectTypeMapper.java index 79976213de..c12caa8a69 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/IObjectTypeMapper.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/IObjectTypeMapper.java @@ -1,53 +1,53 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-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.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.io.IOException;
-import java.sql.Connection;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public interface IObjectTypeMapper
-{
- public CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id);
-
- public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type);
-
- public void removeObjectType(IDBStoreAccessor accessor, CDOID id);
-
- /**
- * Return the maximum object id managed by this cache.
- *
- * @param connection
- * the DB connection to use.
- * @return the maximum object ID.
- */
- public CDOID getMaxID(Connection connection, IIDHandler idHandler);
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException;
-
- public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException;
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.id.CDOID; +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.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; + +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; + +import java.io.IOException; +import java.sql.Connection; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public interface IObjectTypeMapper +{ + public CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id); + + public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type); + + public void removeObjectType(IDBStoreAccessor accessor, CDOID id); + + /** + * Return the maximum object id managed by this cache. + * + * @param connection + * the DB connection to use. + * @return the maximum object ID. + */ + public CDOID getMaxID(Connection connection, IIDHandler idHandler); + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException; + + public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException; +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/LongIDHandler.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/LongIDHandler.java index d6f5adb99d..63a68b3a25 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/LongIDHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/LongIDHandler.java @@ -1,270 +1,270 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
-import org.eclipse.emf.cdo.common.id.CDOIDExternal;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings;
-import org.eclipse.emf.cdo.spi.server.LongIDStore;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class LongIDHandler extends Lifecycle implements IIDHandler
-{
- public static final CDOID MIN = CDOID.NULL;
-
- public static final CDOID MAX = create(Long.MAX_VALUE);
-
- private DBStore store;
-
- private ExternalReferenceManager externalReferenceManager;
-
- private CDOID lastObjectID = MIN;
-
- private CDOID nextLocalObjectID = MAX;
-
- public LongIDHandler(DBStore store)
- {
- this.store = store;
- externalReferenceManager = new ExternalReferenceManager(this);
- }
-
- public DBStore getStore()
- {
- return store;
- }
-
- public Set<ObjectType> getObjectIDTypes()
- {
- return LongIDStore.OBJECT_ID_TYPES;
- }
-
- public CDOID getMinCDOID()
- {
- return MIN;
- }
-
- public CDOID getMaxCDOID()
- {
- return MAX;
- }
-
- public int compare(CDOID id1, CDOID id2)
- {
- return id1.compareTo(id2);
- }
-
- public CDOID createCDOID(String val)
- {
- Long id = Long.valueOf(val);
- return create(id);
- }
-
- public synchronized CDOID getLastObjectID()
- {
- return lastObjectID;
- }
-
- public synchronized void setLastObjectID(CDOID lastObjectID)
- {
- this.lastObjectID = lastObjectID;
- }
-
- public synchronized void adjustLastObjectID(CDOID maxID)
- {
- if (compare(maxID, lastObjectID) > 0)
- {
- lastObjectID = maxID;
- }
- }
-
- public synchronized CDOID getNextLocalObjectID()
- {
- return nextLocalObjectID;
- }
-
- public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID)
- {
- this.nextLocalObjectID = nextLocalObjectID;
- }
-
- public synchronized CDOID getNextCDOID(CDORevision revision)
- {
- if (revision.getBranch().isLocal())
- {
- CDOID result = nextLocalObjectID;
- nextLocalObjectID = create(value(result) - 1);
- return result;
- }
-
- lastObjectID = create(value(lastObjectID) + 1);
- return lastObjectID;
- }
-
- public boolean isLocalCDOID(CDOID id)
- {
- return compare(id, nextLocalObjectID) > 0;
- }
-
- public DBType getDBType()
- {
- return DBType.BIGINT;
- }
-
- public ITypeMapping getObjectTypeMapping()
- {
- return new CoreTypeMappings.TMObject();
- }
-
- public void appendCDOID(StringBuilder builder, CDOID id)
- {
- long value = value(id);
- builder.append(value);
- }
-
- public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException
- {
- stmt.setLong(column, (Long)rawID);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException
- {
- setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException
- {
- long value;
- if (id.getType() == CDOID.Type.EXTERNAL_OBJECT)
- {
- if (commitTime == CDOBranchPoint.INVALID_DATE)
- {
- CommitContext commitContext = StoreThreadLocal.getCommitContext();
- commitTime = commitContext != null ? commitContext.getBranchPoint().getTimeStamp()
- : CDOBranchPoint.UNSPECIFIED_DATE; // Happens on rawStore for workspace checkouts
- }
-
- value = externalReferenceManager.mapExternalReference((CDOIDExternal)id, commitTime);
- }
- else
- {
- value = value(id);
- }
-
- stmt.setLong(column, value);
- }
-
- public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException
- {
- long id = resultSet.getLong(column);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return unmapExternalReference(id);
- }
-
- public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException
- {
- long id = resultSet.getLong(name);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return unmapExternalReference(id);
- }
-
- private CDOID unmapExternalReference(long id)
- {
- if (id < 0)
- {
- return externalReferenceManager.unmapExternalReference(id);
- }
-
- return create(id);
- }
-
- public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime)
- {
- return create(externalReferenceManager.mapURI(accessor, uri, commitTime));
- }
-
- public String unmapURI(IDBStoreAccessor accessor, CDOID id)
- {
- if (id.getType() == CDOID.Type.EXTERNAL_OBJECT)
- {
- return ((CDOIDExternal)id).getURI();
- }
-
- return externalReferenceManager.unmapURI(accessor, value(id));
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- externalReferenceManager.rawExport(connection, out, fromCommitTime, toCommitTime);
- }
-
- public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- externalReferenceManager.rawImport(connection, in, fromCommitTime, toCommitTime, monitor);
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- externalReferenceManager.activate();
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- externalReferenceManager.deactivate();
- super.doDeactivate();
- }
-
- private static CDOID create(long id)
- {
- return CDOIDUtil.createLong(id);
- }
-
- private static long value(CDOID id)
- {
- return CDOIDUtil.getLong(id);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db; + +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOID.ObjectType; +import org.eclipse.emf.cdo.common.id.CDOIDExternal; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; +import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings; +import org.eclipse.emf.cdo.spi.server.LongIDStore; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public class LongIDHandler extends Lifecycle implements IIDHandler +{ + public static final CDOID MIN = CDOID.NULL; + + public static final CDOID MAX = create(Long.MAX_VALUE); + + private DBStore store; + + private ExternalReferenceManager externalReferenceManager; + + private CDOID lastObjectID = MIN; + + private CDOID nextLocalObjectID = MAX; + + public LongIDHandler(DBStore store) + { + this.store = store; + externalReferenceManager = new ExternalReferenceManager(this); + } + + public DBStore getStore() + { + return store; + } + + public Set<ObjectType> getObjectIDTypes() + { + return LongIDStore.OBJECT_ID_TYPES; + } + + public CDOID getMinCDOID() + { + return MIN; + } + + public CDOID getMaxCDOID() + { + return MAX; + } + + public int compare(CDOID id1, CDOID id2) + { + return id1.compareTo(id2); + } + + public CDOID createCDOID(String val) + { + Long id = Long.valueOf(val); + return create(id); + } + + public synchronized CDOID getLastObjectID() + { + return lastObjectID; + } + + public synchronized void setLastObjectID(CDOID lastObjectID) + { + this.lastObjectID = lastObjectID; + } + + public synchronized void adjustLastObjectID(CDOID maxID) + { + if (compare(maxID, lastObjectID) > 0) + { + lastObjectID = maxID; + } + } + + public synchronized CDOID getNextLocalObjectID() + { + return nextLocalObjectID; + } + + public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID) + { + this.nextLocalObjectID = nextLocalObjectID; + } + + public synchronized CDOID getNextCDOID(CDORevision revision) + { + if (revision.getBranch().isLocal()) + { + CDOID result = nextLocalObjectID; + nextLocalObjectID = create(value(result) - 1); + return result; + } + + lastObjectID = create(value(lastObjectID) + 1); + return lastObjectID; + } + + public boolean isLocalCDOID(CDOID id) + { + return compare(id, nextLocalObjectID) > 0; + } + + public DBType getDBType() + { + return DBType.BIGINT; + } + + public ITypeMapping getObjectTypeMapping() + { + return new CoreTypeMappings.TMObject(); + } + + public void appendCDOID(StringBuilder builder, CDOID id) + { + long value = value(id); + builder.append(value); + } + + public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException + { + stmt.setLong(column, (Long)rawID); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException + { + setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException + { + long value; + if (id.getType() == CDOID.Type.EXTERNAL_OBJECT) + { + if (commitTime == CDOBranchPoint.INVALID_DATE) + { + CommitContext commitContext = StoreThreadLocal.getCommitContext(); + commitTime = commitContext != null ? commitContext.getBranchPoint().getTimeStamp() + : CDOBranchPoint.UNSPECIFIED_DATE; // Happens on rawStore for workspace checkouts + } + + value = externalReferenceManager.mapExternalReference((CDOIDExternal)id, commitTime); + } + else + { + value = value(id); + } + + stmt.setLong(column, value); + } + + public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException + { + long id = resultSet.getLong(column); + if (resultSet.wasNull()) + { + return null; + } + + return unmapExternalReference(id); + } + + public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException + { + long id = resultSet.getLong(name); + if (resultSet.wasNull()) + { + return null; + } + + return unmapExternalReference(id); + } + + private CDOID unmapExternalReference(long id) + { + if (id < 0) + { + return externalReferenceManager.unmapExternalReference(id); + } + + return create(id); + } + + public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime) + { + return create(externalReferenceManager.mapURI(accessor, uri, commitTime)); + } + + public String unmapURI(IDBStoreAccessor accessor, CDOID id) + { + if (id.getType() == CDOID.Type.EXTERNAL_OBJECT) + { + return ((CDOIDExternal)id).getURI(); + } + + return externalReferenceManager.unmapURI(accessor, value(id)); + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + externalReferenceManager.rawExport(connection, out, fromCommitTime, toCommitTime); + } + + public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + externalReferenceManager.rawImport(connection, in, fromCommitTime, toCommitTime, monitor); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + externalReferenceManager.activate(); + } + + @Override + protected void doDeactivate() throws Exception + { + externalReferenceManager.deactivate(); + super.doDeactivate(); + } + + private static CDOID create(long id) + { + return CDOIDUtil.createLong(id); + } + + private static long value(CDOID id) + { + return CDOIDUtil.getLong(id); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java index 923ee93651..d54993c9fd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java @@ -1,429 +1,429 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - bug 271444: [DB] Multiple refactorings
- * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations
- * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelConstants;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IMetaDataManager;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBRowHandler;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.Monitor;
-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;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EModelElement;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * @author Eike Stepper
- */
-public class MetaDataManager extends Lifecycle implements IMetaDataManager
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, MetaDataManager.class);
-
- private static final boolean ZIP_PACKAGE_BYTES = true;
-
- private IDBStore store;
-
- private Map<EModelElement, CDOID> modelElementToMetaID = new HashMap<EModelElement, CDOID>();
-
- private Map<CDOID, EModelElement> metaIDToModelElement = new HashMap<CDOID, EModelElement>();
-
- public MetaDataManager(IDBStore store)
- {
- this.store = store;
- }
-
- public synchronized CDOID getMetaID(EModelElement modelElement, long commitTime)
- {
- CDOID metaID = modelElementToMetaID.get(modelElement);
- if (metaID != null)
- {
- return metaID;
- }
-
- IDBStoreAccessor accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor();
- String uri = EcoreUtil.getURI(modelElement).toString();
- metaID = store.getIDHandler().mapURI(accessor, uri, commitTime);
- cacheMetaIDMapping(modelElement, metaID);
-
- return metaID;
- }
-
- public synchronized EModelElement getMetaInstance(CDOID id)
- {
- EModelElement modelElement = metaIDToModelElement.get(id);
- if (modelElement != null)
- {
- return modelElement;
- }
-
- IDBStoreAccessor accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor();
- String uri = store.getIDHandler().unmapURI(accessor, id);
-
- ResourceSet resourceSet = new ResourceSetImpl();
- resourceSet.setPackageRegistry(getStore().getRepository().getPackageRegistry());
-
- return (EModelElement)resourceSet.getEObject(URI.createURI(uri), true);
- }
-
- public synchronized void clearMetaIDMappings()
- {
- modelElementToMetaID.clear();
- metaIDToModelElement.clear();
- }
-
- public final EPackage[] loadPackageUnit(Connection connection, InternalCDOPackageUnit packageUnit)
- {
- String where = CDODBSchema.PACKAGE_UNITS_ID.getName() + "='" + packageUnit.getID() + "'"; //$NON-NLS-1$ //$NON-NLS-2$
- Object[] values = DBUtil.select(connection, where, CDODBSchema.PACKAGE_UNITS_PACKAGE_DATA);
- byte[] bytes = (byte[])values[0];
- EPackage ePackage = createEPackage(packageUnit, bytes);
- return EMFUtil.getAllPackages(ePackage);
- }
-
- public Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection)
- {
- return readPackageUnits(connection, CDOBranchPoint.UNSPECIFIED_DATE, CDOBranchPoint.UNSPECIFIED_DATE, new Monitor());
- }
-
- public final void writePackageUnits(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- try
- {
- monitor.begin(2);
- fillSystemTables(connection, packageUnits, monitor.fork());
- }
- finally
- {
- monitor.done();
- }
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- // Export package units
- String where = " WHERE p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.CORE_PACKAGE_URI + //
- "' AND p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.RESOURCE_PACKAGE_URI + //
- "' AND p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.TYPES_PACKAGE_URI + //
- "' AND p_u." + CDODBSchema.PACKAGE_UNITS_TIME_STAMP + " BETWEEN " + fromCommitTime + " AND " + toCommitTime;
- DBUtil.serializeTable(out, connection, CDODBSchema.PACKAGE_UNITS, "p_u", where);
-
- // Export package infos
- String join = ", " + CDODBSchema.PACKAGE_UNITS + " p_u" + where + " AND p_i." + CDODBSchema.PACKAGE_INFOS_UNIT
- + "=p_u." + CDODBSchema.PACKAGE_UNITS_ID;
- DBUtil.serializeTable(out, connection, CDODBSchema.PACKAGE_INFOS, "p_i", join);
- }
-
- public Collection<InternalCDOPackageUnit> rawImport(Connection connection, CDODataInput in, long fromCommitTime,
- long toCommitTime, OMMonitor monitor) throws IOException
- {
- monitor.begin(3);
-
- try
- {
- DBUtil.deserializeTable(in, connection, CDODBSchema.PACKAGE_UNITS, monitor.fork());
- DBUtil.deserializeTable(in, connection, CDODBSchema.PACKAGE_INFOS, monitor.fork());
- return readPackageUnits(connection, fromCommitTime, toCommitTime, monitor.fork());
- }
- finally
- {
- monitor.done();
- }
- }
-
- protected IDBStore getStore()
- {
- return store;
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- checkState(store, "Store is not set"); //$NON-NLS-1$
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- clearMetaIDMappings();
- super.doDeactivate();
- }
-
- protected InternalCDOPackageInfo createPackageInfo()
- {
- return (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo();
- }
-
- protected InternalCDOPackageUnit createPackageUnit()
- {
- return (InternalCDOPackageUnit)CDOModelUtil.createPackageUnit();
- }
-
- private InternalCDOPackageRegistry getPackageRegistry()
- {
- return (InternalCDOPackageRegistry)store.getRepository().getPackageRegistry();
- }
-
- private EPackage createEPackage(InternalCDOPackageUnit packageUnit, byte[] bytes)
- {
- ResourceSet resourceSet = EMFUtil.newEcoreResourceSet(getPackageRegistry());
- return EMFUtil.createEPackage(packageUnit.getID(), bytes, ZIP_PACKAGE_BYTES, resourceSet, false);
- }
-
- private byte[] getEPackageBytes(InternalCDOPackageUnit packageUnit)
- {
- EPackage ePackage = packageUnit.getTopLevelPackageInfo().getEPackage();
- return EMFUtil.getEPackageBytes(ePackage, ZIP_PACKAGE_BYTES, getPackageRegistry());
- }
-
- private void fillSystemTables(Connection connection, InternalCDOPackageUnit packageUnit, OMMonitor monitor)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Writing package unit: {0}", packageUnit); //$NON-NLS-1$
- }
-
- InternalCDOPackageInfo[] packageInfos = packageUnit.getPackageInfos();
- Async async = null;
- monitor.begin(1 + packageInfos.length);
-
- try
- {
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$
- DBUtil.trace(sql);
- PreparedStatement stmt = null;
-
- try
- {
- async = monitor.forkAsync();
- stmt = connection.prepareStatement(sql);
- stmt.setString(1, packageUnit.getID());
- stmt.setInt(2, packageUnit.getOriginalType().ordinal());
- stmt.setLong(3, packageUnit.getTimeStamp());
- stmt.setBytes(4, getEPackageBytes(packageUnit));
-
- if (stmt.execute())
- {
- throw new DBException("No result set expected"); //$NON-NLS-1$
- }
-
- if (stmt.getUpdateCount() == 0)
- {
- throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_UNITS); //$NON-NLS-1$
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(stmt);
- if (async != null)
- {
- async.stop();
- }
- }
-
- for (InternalCDOPackageInfo packageInfo : packageInfos)
- {
- fillSystemTables(connection, packageInfo, monitor); // Don't fork monitor
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void fillSystemTables(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- try
- {
- monitor.begin(packageUnits.length);
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- fillSystemTables(connection, packageUnit, monitor.fork());
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void fillSystemTables(Connection connection, InternalCDOPackageInfo packageInfo, OMMonitor monitor)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Writing package info: {0}", packageInfo); //$NON-NLS-1$
- }
-
- String packageURI = packageInfo.getPackageURI();
- String parentURI = packageInfo.getParentURI();
- String unitID = packageInfo.getPackageUnit().getID();
-
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " VALUES (?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$
- DBUtil.trace(sql);
- PreparedStatement stmt = null;
- Async async = monitor.forkAsync();
-
- try
- {
- stmt = connection.prepareStatement(sql);
- stmt.setString(1, packageURI);
- stmt.setString(2, parentURI);
- stmt.setString(3, unitID);
-
- if (stmt.execute())
- {
- throw new DBException("No result set expected"); //$NON-NLS-1$
- }
-
- if (stmt.getUpdateCount() == 0)
- {
- throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_INFOS); //$NON-NLS-1$
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(stmt);
- if (async != null)
- {
- async.stop();
- }
- }
- }
-
- private Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection, long fromCommitTime,
- long toCommitTime, OMMonitor monitor)
- {
- final Map<String, InternalCDOPackageUnit> packageUnits = new HashMap<String, InternalCDOPackageUnit>();
- IDBRowHandler unitRowHandler = new IDBRowHandler()
- {
- public boolean handle(int row, final Object... values)
- {
- InternalCDOPackageUnit packageUnit = createPackageUnit();
- packageUnit.setOriginalType(CDOPackageUnit.Type.values()[(Integer)values[1]]);
- packageUnit.setTimeStamp((Long)values[2]);
- packageUnits.put((String)values[0], packageUnit);
- return true;
- }
- };
-
- String where = null;
- if (fromCommitTime != CDOBranchPoint.UNSPECIFIED_DATE)
- {
- where = CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.CORE_PACKAGE_URI + "' AND "
- + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.RESOURCE_PACKAGE_URI + "' AND "
- + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.TYPES_PACKAGE_URI + "' AND "
- + CDODBSchema.PACKAGE_UNITS_TIME_STAMP + " BETWEEN " + fromCommitTime + " AND " + toCommitTime;
- }
-
- DBUtil.select(connection, unitRowHandler, where, CDODBSchema.PACKAGE_UNITS_ID,
- CDODBSchema.PACKAGE_UNITS_ORIGINAL_TYPE, CDODBSchema.PACKAGE_UNITS_TIME_STAMP);
-
- final Map<String, List<InternalCDOPackageInfo>> packageInfos = new HashMap<String, List<InternalCDOPackageInfo>>();
- IDBRowHandler infoRowHandler = new IDBRowHandler()
- {
- public boolean handle(int row, final Object... values)
- {
- InternalCDOPackageInfo packageInfo = createPackageInfo();
- packageInfo.setPackageURI((String)values[1]);
- packageInfo.setParentURI((String)values[2]);
-
- String unit = (String)values[0];
- List<InternalCDOPackageInfo> list = packageInfos.get(unit);
- if (list == null)
- {
- list = new ArrayList<InternalCDOPackageInfo>();
- packageInfos.put(unit, list);
- }
-
- list.add(packageInfo);
- return true;
- }
- };
-
- monitor.begin();
- Async async = monitor.forkAsync();
-
- try
- {
- DBUtil.select(connection, infoRowHandler, CDODBSchema.PACKAGE_INFOS_UNIT, CDODBSchema.PACKAGE_INFOS_URI,
- CDODBSchema.PACKAGE_INFOS_PARENT);
- }
- finally
- {
- async.stop();
- monitor.done();
- }
-
- for (Entry<String, InternalCDOPackageUnit> entry : packageUnits.entrySet())
- {
- String id = entry.getKey();
- InternalCDOPackageUnit packageUnit = entry.getValue();
-
- List<InternalCDOPackageInfo> list = packageInfos.get(id);
- InternalCDOPackageInfo[] array = list.toArray(new InternalCDOPackageInfo[list.size()]);
- packageUnit.setPackageInfos(array);
- }
-
- return packageUnits.values();
- }
-
- private void cacheMetaIDMapping(EModelElement modelElement, CDOID metaID)
- {
- modelElementToMetaID.put(modelElement, metaID);
- metaIDToModelElement.put(metaID, modelElement);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - bug 271444: [DB] Multiple refactorings + * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations + * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.CDOModelConstants; +import org.eclipse.emf.cdo.common.model.CDOModelUtil; +import org.eclipse.emf.cdo.common.model.CDOPackageUnit; +import org.eclipse.emf.cdo.common.model.EMFUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IMetaDataManager; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBRowHandler; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.Monitor; +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; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * @author Eike Stepper + */ +public class MetaDataManager extends Lifecycle implements IMetaDataManager +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, MetaDataManager.class); + + private static final boolean ZIP_PACKAGE_BYTES = true; + + private IDBStore store; + + private Map<EModelElement, CDOID> modelElementToMetaID = new HashMap<EModelElement, CDOID>(); + + private Map<CDOID, EModelElement> metaIDToModelElement = new HashMap<CDOID, EModelElement>(); + + public MetaDataManager(IDBStore store) + { + this.store = store; + } + + public synchronized CDOID getMetaID(EModelElement modelElement, long commitTime) + { + CDOID metaID = modelElementToMetaID.get(modelElement); + if (metaID != null) + { + return metaID; + } + + IDBStoreAccessor accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + String uri = EcoreUtil.getURI(modelElement).toString(); + metaID = store.getIDHandler().mapURI(accessor, uri, commitTime); + cacheMetaIDMapping(modelElement, metaID); + + return metaID; + } + + public synchronized EModelElement getMetaInstance(CDOID id) + { + EModelElement modelElement = metaIDToModelElement.get(id); + if (modelElement != null) + { + return modelElement; + } + + IDBStoreAccessor accessor = (IDBStoreAccessor)StoreThreadLocal.getAccessor(); + String uri = store.getIDHandler().unmapURI(accessor, id); + + ResourceSet resourceSet = new ResourceSetImpl(); + resourceSet.setPackageRegistry(getStore().getRepository().getPackageRegistry()); + + return (EModelElement)resourceSet.getEObject(URI.createURI(uri), true); + } + + public synchronized void clearMetaIDMappings() + { + modelElementToMetaID.clear(); + metaIDToModelElement.clear(); + } + + public final EPackage[] loadPackageUnit(Connection connection, InternalCDOPackageUnit packageUnit) + { + String where = CDODBSchema.PACKAGE_UNITS_ID.getName() + "='" + packageUnit.getID() + "'"; //$NON-NLS-1$ //$NON-NLS-2$ + Object[] values = DBUtil.select(connection, where, CDODBSchema.PACKAGE_UNITS_PACKAGE_DATA); + byte[] bytes = (byte[])values[0]; + EPackage ePackage = createEPackage(packageUnit, bytes); + return EMFUtil.getAllPackages(ePackage); + } + + public Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection) + { + return readPackageUnits(connection, CDOBranchPoint.UNSPECIFIED_DATE, CDOBranchPoint.UNSPECIFIED_DATE, new Monitor()); + } + + public final void writePackageUnits(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) + { + try + { + monitor.begin(2); + fillSystemTables(connection, packageUnits, monitor.fork()); + } + finally + { + monitor.done(); + } + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + // Export package units + String where = " WHERE p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.CORE_PACKAGE_URI + // + "' AND p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.RESOURCE_PACKAGE_URI + // + "' AND p_u." + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.TYPES_PACKAGE_URI + // + "' AND p_u." + CDODBSchema.PACKAGE_UNITS_TIME_STAMP + " BETWEEN " + fromCommitTime + " AND " + toCommitTime; + DBUtil.serializeTable(out, connection, CDODBSchema.PACKAGE_UNITS, "p_u", where); + + // Export package infos + String join = ", " + CDODBSchema.PACKAGE_UNITS + " p_u" + where + " AND p_i." + CDODBSchema.PACKAGE_INFOS_UNIT + + "=p_u." + CDODBSchema.PACKAGE_UNITS_ID; + DBUtil.serializeTable(out, connection, CDODBSchema.PACKAGE_INFOS, "p_i", join); + } + + public Collection<InternalCDOPackageUnit> rawImport(Connection connection, CDODataInput in, long fromCommitTime, + long toCommitTime, OMMonitor monitor) throws IOException + { + monitor.begin(3); + + try + { + DBUtil.deserializeTable(in, connection, CDODBSchema.PACKAGE_UNITS, monitor.fork()); + DBUtil.deserializeTable(in, connection, CDODBSchema.PACKAGE_INFOS, monitor.fork()); + return readPackageUnits(connection, fromCommitTime, toCommitTime, monitor.fork()); + } + finally + { + monitor.done(); + } + } + + protected IDBStore getStore() + { + return store; + } + + @Override + protected void doBeforeActivate() throws Exception + { + checkState(store, "Store is not set"); //$NON-NLS-1$ + } + + @Override + protected void doDeactivate() throws Exception + { + clearMetaIDMappings(); + super.doDeactivate(); + } + + protected InternalCDOPackageInfo createPackageInfo() + { + return (InternalCDOPackageInfo)CDOModelUtil.createPackageInfo(); + } + + protected InternalCDOPackageUnit createPackageUnit() + { + return (InternalCDOPackageUnit)CDOModelUtil.createPackageUnit(); + } + + private InternalCDOPackageRegistry getPackageRegistry() + { + return (InternalCDOPackageRegistry)store.getRepository().getPackageRegistry(); + } + + private EPackage createEPackage(InternalCDOPackageUnit packageUnit, byte[] bytes) + { + ResourceSet resourceSet = EMFUtil.newEcoreResourceSet(getPackageRegistry()); + return EMFUtil.createEPackage(packageUnit.getID(), bytes, ZIP_PACKAGE_BYTES, resourceSet, false); + } + + private byte[] getEPackageBytes(InternalCDOPackageUnit packageUnit) + { + EPackage ePackage = packageUnit.getTopLevelPackageInfo().getEPackage(); + return EMFUtil.getEPackageBytes(ePackage, ZIP_PACKAGE_BYTES, getPackageRegistry()); + } + + private void fillSystemTables(Connection connection, InternalCDOPackageUnit packageUnit, OMMonitor monitor) + { + if (TRACER.isEnabled()) + { + TRACER.format("Writing package unit: {0}", packageUnit); //$NON-NLS-1$ + } + + InternalCDOPackageInfo[] packageInfos = packageUnit.getPackageInfos(); + Async async = null; + monitor.begin(1 + packageInfos.length); + + try + { + String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ + DBUtil.trace(sql); + PreparedStatement stmt = null; + + try + { + async = monitor.forkAsync(); + stmt = connection.prepareStatement(sql); + stmt.setString(1, packageUnit.getID()); + stmt.setInt(2, packageUnit.getOriginalType().ordinal()); + stmt.setLong(3, packageUnit.getTimeStamp()); + stmt.setBytes(4, getEPackageBytes(packageUnit)); + + if (stmt.execute()) + { + throw new DBException("No result set expected"); //$NON-NLS-1$ + } + + if (stmt.getUpdateCount() == 0) + { + throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_UNITS); //$NON-NLS-1$ + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + if (async != null) + { + async.stop(); + } + } + + for (InternalCDOPackageInfo packageInfo : packageInfos) + { + fillSystemTables(connection, packageInfo, monitor); // Don't fork monitor + } + } + finally + { + monitor.done(); + } + } + + private void fillSystemTables(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) + { + try + { + monitor.begin(packageUnits.length); + for (InternalCDOPackageUnit packageUnit : packageUnits) + { + fillSystemTables(connection, packageUnit, monitor.fork()); + } + } + finally + { + monitor.done(); + } + } + + private void fillSystemTables(Connection connection, InternalCDOPackageInfo packageInfo, OMMonitor monitor) + { + if (TRACER.isEnabled()) + { + TRACER.format("Writing package info: {0}", packageInfo); //$NON-NLS-1$ + } + + String packageURI = packageInfo.getPackageURI(); + String parentURI = packageInfo.getParentURI(); + String unitID = packageInfo.getPackageUnit().getID(); + + String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " VALUES (?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ + DBUtil.trace(sql); + PreparedStatement stmt = null; + Async async = monitor.forkAsync(); + + try + { + stmt = connection.prepareStatement(sql); + stmt.setString(1, packageURI); + stmt.setString(2, parentURI); + stmt.setString(3, unitID); + + if (stmt.execute()) + { + throw new DBException("No result set expected"); //$NON-NLS-1$ + } + + if (stmt.getUpdateCount() == 0) + { + throw new DBException("No row inserted into table " + CDODBSchema.PACKAGE_INFOS); //$NON-NLS-1$ + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + if (async != null) + { + async.stop(); + } + } + } + + private Collection<InternalCDOPackageUnit> readPackageUnits(Connection connection, long fromCommitTime, + long toCommitTime, OMMonitor monitor) + { + final Map<String, InternalCDOPackageUnit> packageUnits = new HashMap<String, InternalCDOPackageUnit>(); + IDBRowHandler unitRowHandler = new IDBRowHandler() + { + public boolean handle(int row, final Object... values) + { + InternalCDOPackageUnit packageUnit = createPackageUnit(); + packageUnit.setOriginalType(CDOPackageUnit.Type.values()[(Integer)values[1]]); + packageUnit.setTimeStamp((Long)values[2]); + packageUnits.put((String)values[0], packageUnit); + return true; + } + }; + + String where = null; + if (fromCommitTime != CDOBranchPoint.UNSPECIFIED_DATE) + { + where = CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.CORE_PACKAGE_URI + "' AND " + + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.RESOURCE_PACKAGE_URI + "' AND " + + CDODBSchema.PACKAGE_UNITS_ID + "<>'" + CDOModelConstants.TYPES_PACKAGE_URI + "' AND " + + CDODBSchema.PACKAGE_UNITS_TIME_STAMP + " BETWEEN " + fromCommitTime + " AND " + toCommitTime; + } + + DBUtil.select(connection, unitRowHandler, where, CDODBSchema.PACKAGE_UNITS_ID, + CDODBSchema.PACKAGE_UNITS_ORIGINAL_TYPE, CDODBSchema.PACKAGE_UNITS_TIME_STAMP); + + final Map<String, List<InternalCDOPackageInfo>> packageInfos = new HashMap<String, List<InternalCDOPackageInfo>>(); + IDBRowHandler infoRowHandler = new IDBRowHandler() + { + public boolean handle(int row, final Object... values) + { + InternalCDOPackageInfo packageInfo = createPackageInfo(); + packageInfo.setPackageURI((String)values[1]); + packageInfo.setParentURI((String)values[2]); + + String unit = (String)values[0]; + List<InternalCDOPackageInfo> list = packageInfos.get(unit); + if (list == null) + { + list = new ArrayList<InternalCDOPackageInfo>(); + packageInfos.put(unit, list); + } + + list.add(packageInfo); + return true; + } + }; + + monitor.begin(); + Async async = monitor.forkAsync(); + + try + { + DBUtil.select(connection, infoRowHandler, CDODBSchema.PACKAGE_INFOS_UNIT, CDODBSchema.PACKAGE_INFOS_URI, + CDODBSchema.PACKAGE_INFOS_PARENT); + } + finally + { + async.stop(); + monitor.done(); + } + + for (Entry<String, InternalCDOPackageUnit> entry : packageUnits.entrySet()) + { + String id = entry.getKey(); + InternalCDOPackageUnit packageUnit = entry.getValue(); + + List<InternalCDOPackageInfo> list = packageInfos.get(id); + InternalCDOPackageInfo[] array = list.toArray(new InternalCDOPackageInfo[list.size()]); + packageUnit.setPackageInfos(array); + } + + return packageUnits.values(); + } + + private void cacheMetaIDMapping(EModelElement modelElement, CDOID metaID) + { + modelElementToMetaID.put(modelElement, metaID); + metaIDToModelElement.put(metaID, modelElement); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java index d45512b2d5..6db0e11782 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NullPreparedStatementCache.java @@ -1,69 +1,69 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.HashSet;
-
-/**
- * @author Stefan Winkler
- * @since 2.0
- */
-public class NullPreparedStatementCache extends AbstractPreparedStatementCache
-{
- private HashSet<PreparedStatement> allocatedStatements = new HashSet<PreparedStatement>();
-
- public NullPreparedStatementCache()
- {
- }
-
- public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability)
- {
- try
- {
- PreparedStatement result = getConnection().prepareStatement(sql);
- allocatedStatements.add(result);
- return result;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- public void releasePreparedStatement(PreparedStatement ps)
- {
- allocatedStatements.remove(ps);
- DBUtil.close(ps);
- }
-
- @Override
- protected void doBeforeDeactivate() throws Exception
- {
- if (!allocatedStatements.isEmpty())
- {
- OM.LOG.warn("Possible Leak Detected:"); //$NON-NLS-1$
- for (PreparedStatement ps : allocatedStatements)
- {
- OM.LOG.warn("- " + ps.toString()); //$NON-NLS-1$
- }
-
- assert false;
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.HashSet; + +/** + * @author Stefan Winkler + * @since 2.0 + */ +public class NullPreparedStatementCache extends AbstractPreparedStatementCache +{ + private HashSet<PreparedStatement> allocatedStatements = new HashSet<PreparedStatement>(); + + public NullPreparedStatementCache() + { + } + + public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability) + { + try + { + PreparedStatement result = getConnection().prepareStatement(sql); + allocatedStatements.add(result); + return result; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + + public void releasePreparedStatement(PreparedStatement ps) + { + allocatedStatements.remove(ps); + DBUtil.close(ps); + } + + @Override + protected void doBeforeDeactivate() throws Exception + { + if (!allocatedStatements.isEmpty()) + { + OM.LOG.warn("Possible Leak Detected:"); //$NON-NLS-1$ + for (PreparedStatement ps : allocatedStatements) + { + OM.LOG.warn("- " + ps.toString()); //$NON-NLS-1$ + } + + assert false; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java index 26e41d33e2..610af45a85 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectIDIterator.java @@ -1,138 +1,138 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Victor Roldan Betancort - bug 208689
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.util.collection.CloseableIterator;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.NoSuchElementException;
-
-/**
- * @author Eike Stepper
- */
-public abstract class ObjectIDIterator implements CloseableIterator<CDOID>
-{
- private IMappingStrategy mappingStrategy;
-
- private IIDHandler idHandler;
-
- private IDBStoreAccessor accessor;
-
- private ResultSet currentResultSet;
-
- private CDOID nextID;
-
- private boolean closed;
-
- /**
- * Creates an iterator over all objects in a store. It is important to {@link #close()} of this iterator after usage
- * to properly close internal result sets.
- */
- public ObjectIDIterator(IMappingStrategy mappingStrategy, IDBStoreAccessor accessor)
- {
- this.mappingStrategy = mappingStrategy;
- this.accessor = accessor;
- idHandler = getMappingStrategy().getStore().getIDHandler();
-
- }
-
- public void close()
- {
- closeCurrentResultSet();
- nextID = null;
- closed = true;
- }
-
- public boolean isClosed()
- {
- return closed;
- }
-
- public IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public IDBStoreAccessor getAccessor()
- {
- return accessor;
- }
-
- public boolean hasNext()
- {
- if (closed)
- {
- return false;
- }
-
- nextID = null;
- for (;;)
- {
- if (currentResultSet == null)
- {
- currentResultSet = getNextResultSet();
- if (currentResultSet == null)
- {
- return false;
- }
- }
-
- try
- {
- if (currentResultSet.next())
- {
- nextID = idHandler.getCDOID(currentResultSet, 1);
- return true;
- }
-
- closeCurrentResultSet();
-
- currentResultSet = null;
- return false;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
- }
-
- protected void closeCurrentResultSet()
- {
- DBUtil.close(currentResultSet);
- }
-
- public CDOID next()
- {
- if (nextID == null)
- {
- throw new NoSuchElementException();
- }
-
- return nextID;
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
- protected abstract ResultSet getNextResultSet();
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Victor Roldan Betancort - bug 208689 + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.util.collection.CloseableIterator; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.NoSuchElementException; + +/** + * @author Eike Stepper + */ +public abstract class ObjectIDIterator implements CloseableIterator<CDOID> +{ + private IMappingStrategy mappingStrategy; + + private IIDHandler idHandler; + + private IDBStoreAccessor accessor; + + private ResultSet currentResultSet; + + private CDOID nextID; + + private boolean closed; + + /** + * Creates an iterator over all objects in a store. It is important to {@link #close()} of this iterator after usage + * to properly close internal result sets. + */ + public ObjectIDIterator(IMappingStrategy mappingStrategy, IDBStoreAccessor accessor) + { + this.mappingStrategy = mappingStrategy; + this.accessor = accessor; + idHandler = getMappingStrategy().getStore().getIDHandler(); + + } + + public void close() + { + closeCurrentResultSet(); + nextID = null; + closed = true; + } + + public boolean isClosed() + { + return closed; + } + + public IMappingStrategy getMappingStrategy() + { + return mappingStrategy; + } + + public IDBStoreAccessor getAccessor() + { + return accessor; + } + + public boolean hasNext() + { + if (closed) + { + return false; + } + + nextID = null; + for (;;) + { + if (currentResultSet == null) + { + currentResultSet = getNextResultSet(); + if (currentResultSet == null) + { + return false; + } + } + + try + { + if (currentResultSet.next()) + { + nextID = idHandler.getCDOID(currentResultSet, 1); + return true; + } + + closeCurrentResultSet(); + + currentResultSet = null; + return false; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + } + + protected void closeCurrentResultSet() + { + DBUtil.close(currentResultSet); + } + + public CDOID next() + { + if (nextID == null) + { + throw new NoSuchElementException(); + } + + return nextID; + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + + protected abstract ResultSet getNextResultSet(); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java index 6018a33077..74574a2f00 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/SmartPreparedStatementCache.java @@ -1,291 +1,291 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Stefan Winkler - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db;
-
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.util.ImplementationError;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.HashMap;
-
-/**
- * @author Stefan Winkler
- * @since 2.0
- */
-public class SmartPreparedStatementCache extends AbstractPreparedStatementCache
-{
- private Cache cache;
-
- private HashMap<PreparedStatement, CachedPreparedStatement> checkedOut = new HashMap<PreparedStatement, CachedPreparedStatement>();
-
- public SmartPreparedStatementCache(int capacity)
- {
- cache = new Cache(capacity);
- }
-
- public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability)
- {
- CachedPreparedStatement cachedStatement = cache.remove(sql);
- if (cachedStatement == null)
- {
- cachedStatement = createCachedPreparedStatement(sql, reuseProbability);
- }
-
- PreparedStatement result = cachedStatement.getPreparedStatement();
- checkedOut.put(result, cachedStatement);
-
- return result;
- }
-
- /**
- * @param ps
- * the prepared statement to be released to the cache, or <code>null</code>.
- */
- public void releasePreparedStatement(PreparedStatement ps)
- {
- if (ps != null) // Bug 276926: Silently accept ps == null and do nothing.
- {
- CachedPreparedStatement cachedStatement = checkedOut.remove(ps);
- cache.put(cachedStatement);
- }
- }
-
- @Override
- protected void doBeforeDeactivate() throws Exception
- {
- if (!checkedOut.isEmpty())
- {
- OM.LOG.warn("Statement leak detected"); //$NON-NLS-1$
- }
- }
-
- private CachedPreparedStatement createCachedPreparedStatement(String sql, ReuseProbability reuseProbability)
- {
- try
- {
- Connection connection = getConnection();
- PreparedStatement stmt = connection.prepareStatement(sql);
- return new CachedPreparedStatement(sql, reuseProbability, stmt);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- }
-
- /**
- * @author Stefan Winkler
- */
- private static final class Cache
- {
- private CacheList lists[];
-
- private HashMap<String, CachedPreparedStatement> lookup;
-
- private int capacity;
-
- public Cache(int capacity)
- {
- this.capacity = capacity;
-
- lookup = new HashMap<String, CachedPreparedStatement>(capacity);
-
- lists = new CacheList[ReuseProbability.values().length];
- for (ReuseProbability prob : ReuseProbability.values())
- {
- lists[prob.ordinal()] = new CacheList();
- }
- }
-
- public void put(CachedPreparedStatement cachedStatement)
- {
- // refresh age
- cachedStatement.touch();
-
- // put into appripriate list
- lists[cachedStatement.getProbability().ordinal()].add(cachedStatement);
-
- // put into lookup table
- if (lookup.put(cachedStatement.getSQL(), cachedStatement) != null)
- {
- throw new ImplementationError(cachedStatement.getSQL() + " already in cache"); //$NON-NLS-1$
- }
-
- // handle capacity overflow
- if (lookup.size() > capacity)
- {
- evictOne();
- }
- }
-
- private void evictOne()
- {
- long maxAge = -1;
- int ordinal = -1;
-
- for (ReuseProbability prob : ReuseProbability.values())
- {
- if (!lists[prob.ordinal()].isEmpty())
- {
- long age = lists[prob.ordinal()].tail().getAge();
- if (maxAge < age)
- {
- maxAge = age;
- ordinal = prob.ordinal();
- }
- }
- }
-
- remove(lists[ordinal].tail().getSQL());
- }
-
- public CachedPreparedStatement remove(String sql)
- {
- CachedPreparedStatement result = lookup.remove(sql);
- if (result == null)
- {
- return null;
- }
-
- lists[result.getProbability().ordinal()].remove(result);
- return result;
- }
-
- /**
- * @author Stefan Winkler
- */
- private class CacheList
- {
- private CachedPreparedStatement first;
-
- private CachedPreparedStatement last;
-
- public CacheList()
- {
- }
-
- public void add(CachedPreparedStatement s)
- {
- if (first == null)
- {
- first = s;
- last = s;
- s.previous = null;
- s.next = null;
- }
- else
- {
- first.previous = s;
- s.next = first;
- first = s;
- }
- }
-
- public void remove(CachedPreparedStatement s)
- {
- if (s == first)
- {
- first = s.next;
- }
-
- if (s.next != null)
- {
- s.next.previous = s.previous;
- }
-
- if (s == last)
- {
- last = s.previous;
- }
-
- if (s.previous != null)
- {
- s.previous.next = s.next;
- }
-
- s.previous = null;
- s.next = null;
- }
-
- public CachedPreparedStatement tail()
- {
- return last;
- }
-
- public boolean isEmpty()
- {
- return first == null;
- }
- }
- }
-
- /**
- * @author Stefan Winkler
- */
- private static final class CachedPreparedStatement
- {
- private long timeStamp;
-
- private String sql;
-
- private ReuseProbability probability;
-
- private PreparedStatement statement;
-
- /**
- * DL field
- */
- private CachedPreparedStatement previous;
-
- /**
- * DL field
- */
- private CachedPreparedStatement next;
-
- public CachedPreparedStatement(String sql, ReuseProbability prob, PreparedStatement stmt)
- {
- this.sql = sql;
- probability = prob;
- statement = stmt;
- timeStamp = System.currentTimeMillis();
- }
-
- public PreparedStatement getPreparedStatement()
- {
- return statement;
- }
-
- public long getAge()
- {
- long currentTime = System.currentTimeMillis();
- return (currentTime - timeStamp) * probability.ordinal();
- }
-
- public void touch()
- {
- timeStamp = System.currentTimeMillis();
- }
-
- public String getSQL()
- {
- return sql;
- }
-
- public ReuseProbability getProbability()
- {
- return probability;
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Stefan Winkler - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.db; + +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.util.ImplementationError; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.HashMap; + +/** + * @author Stefan Winkler + * @since 2.0 + */ +public class SmartPreparedStatementCache extends AbstractPreparedStatementCache +{ + private Cache cache; + + private HashMap<PreparedStatement, CachedPreparedStatement> checkedOut = new HashMap<PreparedStatement, CachedPreparedStatement>(); + + public SmartPreparedStatementCache(int capacity) + { + cache = new Cache(capacity); + } + + public PreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability) + { + CachedPreparedStatement cachedStatement = cache.remove(sql); + if (cachedStatement == null) + { + cachedStatement = createCachedPreparedStatement(sql, reuseProbability); + } + + PreparedStatement result = cachedStatement.getPreparedStatement(); + checkedOut.put(result, cachedStatement); + + return result; + } + + /** + * @param ps + * the prepared statement to be released to the cache, or <code>null</code>. + */ + public void releasePreparedStatement(PreparedStatement ps) + { + if (ps != null) // Bug 276926: Silently accept ps == null and do nothing. + { + CachedPreparedStatement cachedStatement = checkedOut.remove(ps); + cache.put(cachedStatement); + } + } + + @Override + protected void doBeforeDeactivate() throws Exception + { + if (!checkedOut.isEmpty()) + { + OM.LOG.warn("Statement leak detected"); //$NON-NLS-1$ + } + } + + private CachedPreparedStatement createCachedPreparedStatement(String sql, ReuseProbability reuseProbability) + { + try + { + Connection connection = getConnection(); + PreparedStatement stmt = connection.prepareStatement(sql); + return new CachedPreparedStatement(sql, reuseProbability, stmt); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + + /** + * @author Stefan Winkler + */ + private static final class Cache + { + private CacheList lists[]; + + private HashMap<String, CachedPreparedStatement> lookup; + + private int capacity; + + public Cache(int capacity) + { + this.capacity = capacity; + + lookup = new HashMap<String, CachedPreparedStatement>(capacity); + + lists = new CacheList[ReuseProbability.values().length]; + for (ReuseProbability prob : ReuseProbability.values()) + { + lists[prob.ordinal()] = new CacheList(); + } + } + + public void put(CachedPreparedStatement cachedStatement) + { + // refresh age + cachedStatement.touch(); + + // put into appripriate list + lists[cachedStatement.getProbability().ordinal()].add(cachedStatement); + + // put into lookup table + if (lookup.put(cachedStatement.getSQL(), cachedStatement) != null) + { + throw new ImplementationError(cachedStatement.getSQL() + " already in cache"); //$NON-NLS-1$ + } + + // handle capacity overflow + if (lookup.size() > capacity) + { + evictOne(); + } + } + + private void evictOne() + { + long maxAge = -1; + int ordinal = -1; + + for (ReuseProbability prob : ReuseProbability.values()) + { + if (!lists[prob.ordinal()].isEmpty()) + { + long age = lists[prob.ordinal()].tail().getAge(); + if (maxAge < age) + { + maxAge = age; + ordinal = prob.ordinal(); + } + } + } + + remove(lists[ordinal].tail().getSQL()); + } + + public CachedPreparedStatement remove(String sql) + { + CachedPreparedStatement result = lookup.remove(sql); + if (result == null) + { + return null; + } + + lists[result.getProbability().ordinal()].remove(result); + return result; + } + + /** + * @author Stefan Winkler + */ + private class CacheList + { + private CachedPreparedStatement first; + + private CachedPreparedStatement last; + + public CacheList() + { + } + + public void add(CachedPreparedStatement s) + { + if (first == null) + { + first = s; + last = s; + s.previous = null; + s.next = null; + } + else + { + first.previous = s; + s.next = first; + first = s; + } + } + + public void remove(CachedPreparedStatement s) + { + if (s == first) + { + first = s.next; + } + + if (s.next != null) + { + s.next.previous = s.previous; + } + + if (s == last) + { + last = s.previous; + } + + if (s.previous != null) + { + s.previous.next = s.next; + } + + s.previous = null; + s.next = null; + } + + public CachedPreparedStatement tail() + { + return last; + } + + public boolean isEmpty() + { + return first == null; + } + } + } + + /** + * @author Stefan Winkler + */ + private static final class CachedPreparedStatement + { + private long timeStamp; + + private String sql; + + private ReuseProbability probability; + + private PreparedStatement statement; + + /** + * DL field + */ + private CachedPreparedStatement previous; + + /** + * DL field + */ + private CachedPreparedStatement next; + + public CachedPreparedStatement(String sql, ReuseProbability prob, PreparedStatement stmt) + { + this.sql = sql; + probability = prob; + statement = stmt; + timeStamp = System.currentTimeMillis(); + } + + public PreparedStatement getPreparedStatement() + { + return statement; + } + + public long getAge() + { + long currentTime = System.currentTimeMillis(); + return (currentTime - timeStamp) * probability.ordinal(); + } + + public void touch() + { + timeStamp = System.currentTimeMillis(); + } + + public String getSQL() + { + return sql; + } + + public ReuseProbability getProbability() + { + return probability; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/StringIDHandler.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/StringIDHandler.java index 1f5ee29c78..256dc5282f 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/StringIDHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/StringIDHandler.java @@ -1,254 +1,254 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class StringIDHandler extends Lifecycle implements IIDHandler
-{
- public static final Set<ObjectType> OBJECT_ID_TYPES = Collections.singleton(CDOID.ObjectType.STRING);
-
- public static final CDOID MIN = CDOID.NULL;
-
- public static final CDOID MAX = create(Long.toString(Long.MAX_VALUE));
-
- private DBStore store;
-
- private long lastObjectID = 0;
-
- private long nextLocalObjectID = Long.MAX_VALUE;
-
- public StringIDHandler(DBStore store)
- {
- this.store = store;
- }
-
- public DBStore getStore()
- {
- return store;
- }
-
- public int compare(CDOID id1, CDOID id2)
- {
- if (id1.getType() == CDOID.Type.OBJECT && id2.getType() == CDOID.Type.OBJECT)
- {
- return Long.valueOf(value(id1)).compareTo(Long.valueOf(value(id2)));
- }
-
- return id1.compareTo(id2);
- }
-
- public DBType getDBType()
- {
- return DBType.VARCHAR;
- }
-
- public Set<ObjectType> getObjectIDTypes()
- {
- return OBJECT_ID_TYPES;
- }
-
- public CDOID createCDOID(String val)
- {
- return create(val);
- }
-
- public synchronized CDOID getLastObjectID()
- {
- return CDOIDUtil.createString("" + lastObjectID);
- }
-
- public synchronized void setLastObjectID(CDOID lastObjectID)
- {
- this.lastObjectID = Long.parseLong(value(lastObjectID));
- }
-
- public void adjustLastObjectID(CDOID maxID)
- {
- // TODO: implement StringIDHandler.adjustLastObjectID(maxID)
- throw new UnsupportedOperationException();
- }
-
- public synchronized CDOID getNextLocalObjectID()
- {
- return CDOIDUtil.createString("" + nextLocalObjectID);
- }
-
- public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID)
- {
- this.nextLocalObjectID = Long.parseLong(value(nextLocalObjectID));
- }
-
- public synchronized CDOID getNextCDOID(CDORevision revision)
- {
- if (revision.getBranch().isLocal())
- {
- return CDOIDUtil.createString("" + nextLocalObjectID--);
- }
-
- return CDOIDUtil.createString("" + ++lastObjectID);
- }
-
- public boolean isLocalCDOID(CDOID id)
- {
- if (id.getType() == CDOID.Type.OBJECT)
- {
- return Long.parseLong(value(id)) > nextLocalObjectID;
- }
-
- return false;
- }
-
- public ITypeMapping getObjectTypeMapping()
- {
- return new CoreTypeMappings.TMObject();
- }
-
- public void appendCDOID(StringBuilder builder, CDOID id)
- {
- builder.append("'");
- builder.append(value(id));
- builder.append("'");
- }
-
- public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException
- {
- stmt.setString(column, (String)rawID);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException
- {
- setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException
- {
- String value = value(id);
- stmt.setString(column, value == null || value.length() == 0 ? "0" : value);
- }
-
- public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException
- {
- String id = resultSet.getString(column);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return create(id);
- }
-
- public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException
- {
- String id = resultSet.getString(name);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return create(id);
- }
-
- public CDOID getMinCDOID()
- {
- return MIN;
- }
-
- public CDOID getMaxCDOID()
- {
- return MAX;
- }
-
- public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime)
- {
- return create(uri);
- }
-
- public String unmapURI(IDBStoreAccessor accessor, CDOID id)
- {
- return value(id);
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- // Do nothing
- }
-
- public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- // Do nothing
- }
-
- private static CDOID create(String id)
- {
- if (id == null)
- {
- return null;
- }
-
- int length = id.length();
- if (length == 0)
- {
- return null;
- }
-
- char firstChar = id.charAt(0);
- if (length == 1 && firstChar == '0')
- {
- return null;
- }
-
- if (Character.isDigit(firstChar))
- {
- long value = Long.parseLong(id);
- if (value < 0)
- {
- throw new IllegalArgumentException("Illegal ID value: " + id);
- }
-
- return CDOIDUtil.createString(id);
- }
-
- return CDOIDUtil.createExternal(id);
- }
-
- private static String value(CDOID id)
- {
- return CDOIDUtil.getString(id);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db; + +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOID.ObjectType; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; +import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public class StringIDHandler extends Lifecycle implements IIDHandler +{ + public static final Set<ObjectType> OBJECT_ID_TYPES = Collections.singleton(CDOID.ObjectType.STRING); + + public static final CDOID MIN = CDOID.NULL; + + public static final CDOID MAX = create(Long.toString(Long.MAX_VALUE)); + + private DBStore store; + + private long lastObjectID = 0; + + private long nextLocalObjectID = Long.MAX_VALUE; + + public StringIDHandler(DBStore store) + { + this.store = store; + } + + public DBStore getStore() + { + return store; + } + + public int compare(CDOID id1, CDOID id2) + { + if (id1.getType() == CDOID.Type.OBJECT && id2.getType() == CDOID.Type.OBJECT) + { + return Long.valueOf(value(id1)).compareTo(Long.valueOf(value(id2))); + } + + return id1.compareTo(id2); + } + + public DBType getDBType() + { + return DBType.VARCHAR; + } + + public Set<ObjectType> getObjectIDTypes() + { + return OBJECT_ID_TYPES; + } + + public CDOID createCDOID(String val) + { + return create(val); + } + + public synchronized CDOID getLastObjectID() + { + return CDOIDUtil.createString("" + lastObjectID); + } + + public synchronized void setLastObjectID(CDOID lastObjectID) + { + this.lastObjectID = Long.parseLong(value(lastObjectID)); + } + + public void adjustLastObjectID(CDOID maxID) + { + // TODO: implement StringIDHandler.adjustLastObjectID(maxID) + throw new UnsupportedOperationException(); + } + + public synchronized CDOID getNextLocalObjectID() + { + return CDOIDUtil.createString("" + nextLocalObjectID); + } + + public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID) + { + this.nextLocalObjectID = Long.parseLong(value(nextLocalObjectID)); + } + + public synchronized CDOID getNextCDOID(CDORevision revision) + { + if (revision.getBranch().isLocal()) + { + return CDOIDUtil.createString("" + nextLocalObjectID--); + } + + return CDOIDUtil.createString("" + ++lastObjectID); + } + + public boolean isLocalCDOID(CDOID id) + { + if (id.getType() == CDOID.Type.OBJECT) + { + return Long.parseLong(value(id)) > nextLocalObjectID; + } + + return false; + } + + public ITypeMapping getObjectTypeMapping() + { + return new CoreTypeMappings.TMObject(); + } + + public void appendCDOID(StringBuilder builder, CDOID id) + { + builder.append("'"); + builder.append(value(id)); + builder.append("'"); + } + + public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException + { + stmt.setString(column, (String)rawID); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException + { + setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException + { + String value = value(id); + stmt.setString(column, value == null || value.length() == 0 ? "0" : value); + } + + public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException + { + String id = resultSet.getString(column); + if (resultSet.wasNull()) + { + return null; + } + + return create(id); + } + + public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException + { + String id = resultSet.getString(name); + if (resultSet.wasNull()) + { + return null; + } + + return create(id); + } + + public CDOID getMinCDOID() + { + return MIN; + } + + public CDOID getMaxCDOID() + { + return MAX; + } + + public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime) + { + return create(uri); + } + + public String unmapURI(IDBStoreAccessor accessor, CDOID id) + { + return value(id); + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + // Do nothing + } + + public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + // Do nothing + } + + private static CDOID create(String id) + { + if (id == null) + { + return null; + } + + int length = id.length(); + if (length == 0) + { + return null; + } + + char firstChar = id.charAt(0); + if (length == 1 && firstChar == '0') + { + return null; + } + + if (Character.isDigit(firstChar)) + { + long value = Long.parseLong(id); + if (value < 0) + { + throw new IllegalArgumentException("Illegal ID value: " + id); + } + + return CDOIDUtil.createString(id); + } + + return CDOIDUtil.createExternal(id); + } + + private static String value(CDOID id) + { + return CDOIDUtil.getString(id); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java index f86309b00b..513a34db80 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java @@ -1,242 +1,242 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class UUIDHandler extends Lifecycle implements IIDHandler
-{
- public static final Set<ObjectType> OBJECT_ID_TYPES = Collections.singleton(ObjectType.UUID);
-
- private static final char NULL_CHAR = '0';
-
- private static final String NULL_STRING = Character.toString(NULL_CHAR);
-
- private static final char INTERNAL_CHAR = '@';
-
- private static final String INTERNAL_STRING = Character.toString(INTERNAL_CHAR);
-
- private DBStore store;
-
- public UUIDHandler(DBStore store)
- {
- this.store = store;
- }
-
- public DBStore getStore()
- {
- return store;
- }
-
- public int compare(CDOID id1, CDOID id2)
- {
- throw new UnsupportedOperationException();
- }
-
- public DBType getDBType()
- {
- return DBType.VARCHAR;
- }
-
- public Set<ObjectType> getObjectIDTypes()
- {
- return OBJECT_ID_TYPES;
- }
-
- public CDOID createCDOID(String val)
- {
- return create(INTERNAL_STRING + val);
- }
-
- public synchronized CDOID getLastObjectID()
- {
- throw new UnsupportedOperationException();
- }
-
- public synchronized void setLastObjectID(CDOID lastObjectID)
- {
- // Do nothing
- }
-
- public void adjustLastObjectID(CDOID maxID)
- {
- // Do nothing
- }
-
- public synchronized CDOID getNextLocalObjectID()
- {
- throw new UnsupportedOperationException();
- }
-
- public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID)
- {
- // Do nothing
- }
-
- public synchronized CDOID getNextCDOID(CDORevision revision)
- {
- throw new UnsupportedOperationException();
- }
-
- public boolean isLocalCDOID(CDOID id)
- {
- return false;
- }
-
- public ITypeMapping getObjectTypeMapping()
- {
- return new CoreTypeMappings.TMObject();
- }
-
- public void appendCDOID(StringBuilder builder, CDOID id)
- {
- builder.append("'");
- builder.append(value(id));
- builder.append("'");
- }
-
- public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException
- {
- stmt.setString(column, (String)rawID);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException
- {
- setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE);
- }
-
- public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException
- {
- stmt.setString(column, value(id));
- }
-
- public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException
- {
- String id = resultSet.getString(column);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return create(id);
- }
-
- public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException
- {
- String id = resultSet.getString(name);
- if (resultSet.wasNull())
- {
- return null;
- }
-
- return create(id);
- }
-
- public CDOID getMinCDOID()
- {
- throw new UnsupportedOperationException();
- }
-
- public CDOID getMaxCDOID()
- {
- throw new UnsupportedOperationException();
- }
-
- public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime)
- {
- return CDOIDUtil.createExternal(uri);
- }
-
- public String unmapURI(IDBStoreAccessor accessor, CDOID id)
- {
- return CDOIDUtil.getString(id);
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- // Do nothing
- }
-
- public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- // Do nothing
- }
-
- private static CDOID create(String id)
- {
- if (id == null)
- {
- return null;
- }
-
- int length = id.length();
- if (length == 0)
- {
- return null;
- }
-
- char firstChar = id.charAt(0);
- if (length == 1 && firstChar == NULL_CHAR)
- {
- return null;
- }
-
- if (firstChar == INTERNAL_CHAR)
- {
- byte[] bytes = CDOIDUtil.decodeUUID(id.substring(1));
- return CDOIDUtil.createUUID(bytes);
- }
-
- return CDOIDUtil.createExternal(id);
- }
-
- private static String value(CDOID id)
- {
- if (CDOIDUtil.isNull(id))
- {
- return NULL_STRING;
- }
-
- if (id.isExternal())
- {
- return CDOIDUtil.getString(id);
- }
-
- return INTERNAL_STRING + id.toURIFragment();
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db; + +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOID.ObjectType; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; +import org.eclipse.emf.cdo.server.internal.db.mapping.CoreTypeMappings; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public class UUIDHandler extends Lifecycle implements IIDHandler +{ + public static final Set<ObjectType> OBJECT_ID_TYPES = Collections.singleton(ObjectType.UUID); + + private static final char NULL_CHAR = '0'; + + private static final String NULL_STRING = Character.toString(NULL_CHAR); + + private static final char INTERNAL_CHAR = '@'; + + private static final String INTERNAL_STRING = Character.toString(INTERNAL_CHAR); + + private DBStore store; + + public UUIDHandler(DBStore store) + { + this.store = store; + } + + public DBStore getStore() + { + return store; + } + + public int compare(CDOID id1, CDOID id2) + { + throw new UnsupportedOperationException(); + } + + public DBType getDBType() + { + return DBType.VARCHAR; + } + + public Set<ObjectType> getObjectIDTypes() + { + return OBJECT_ID_TYPES; + } + + public CDOID createCDOID(String val) + { + return create(INTERNAL_STRING + val); + } + + public synchronized CDOID getLastObjectID() + { + throw new UnsupportedOperationException(); + } + + public synchronized void setLastObjectID(CDOID lastObjectID) + { + // Do nothing + } + + public void adjustLastObjectID(CDOID maxID) + { + // Do nothing + } + + public synchronized CDOID getNextLocalObjectID() + { + throw new UnsupportedOperationException(); + } + + public synchronized void setNextLocalObjectID(CDOID nextLocalObjectID) + { + // Do nothing + } + + public synchronized CDOID getNextCDOID(CDORevision revision) + { + throw new UnsupportedOperationException(); + } + + public boolean isLocalCDOID(CDOID id) + { + return false; + } + + public ITypeMapping getObjectTypeMapping() + { + return new CoreTypeMappings.TMObject(); + } + + public void appendCDOID(StringBuilder builder, CDOID id) + { + builder.append("'"); + builder.append(value(id)); + builder.append("'"); + } + + public void setCDOIDRaw(PreparedStatement stmt, int column, Object rawID) throws SQLException + { + stmt.setString(column, (String)rawID); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id) throws SQLException + { + setCDOID(stmt, column, id, CDOBranchPoint.INVALID_DATE); + } + + public void setCDOID(PreparedStatement stmt, int column, CDOID id, long commitTime) throws SQLException + { + stmt.setString(column, value(id)); + } + + public CDOID getCDOID(ResultSet resultSet, int column) throws SQLException + { + String id = resultSet.getString(column); + if (resultSet.wasNull()) + { + return null; + } + + return create(id); + } + + public CDOID getCDOID(ResultSet resultSet, String name) throws SQLException + { + String id = resultSet.getString(name); + if (resultSet.wasNull()) + { + return null; + } + + return create(id); + } + + public CDOID getMinCDOID() + { + throw new UnsupportedOperationException(); + } + + public CDOID getMaxCDOID() + { + throw new UnsupportedOperationException(); + } + + public CDOID mapURI(IDBStoreAccessor accessor, String uri, long commitTime) + { + return CDOIDUtil.createExternal(uri); + } + + public String unmapURI(IDBStoreAccessor accessor, CDOID id) + { + return CDOIDUtil.getString(id); + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + // Do nothing + } + + public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + // Do nothing + } + + private static CDOID create(String id) + { + if (id == null) + { + return null; + } + + int length = id.length(); + if (length == 0) + { + return null; + } + + char firstChar = id.charAt(0); + if (length == 1 && firstChar == NULL_CHAR) + { + return null; + } + + if (firstChar == INTERNAL_CHAR) + { + byte[] bytes = CDOIDUtil.decodeUUID(id.substring(1)); + return CDOIDUtil.createUUID(bytes); + } + + return CDOIDUtil.createExternal(id); + } + + private static String value(CDOID id) + { + if (CDOIDUtil.isNull(id)) + { + return NULL_STRING; + } + + if (id.isExternal()) + { + return CDOIDUtil.getString(id); + } + + return INTERNAL_STRING + id.toURIFragment(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/bundle/OM.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/bundle/OM.java index b4fd4238cf..946849a1dd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/bundle/OM.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/bundle/OM.java @@ -1,45 +1,45 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.internal.db.bundle;
-
-import org.eclipse.net4j.util.om.OMBundle;
-import org.eclipse.net4j.util.om.OMPlatform;
-import org.eclipse.net4j.util.om.OSGiActivator;
-import org.eclipse.net4j.util.om.log.OMLogger;
-import org.eclipse.net4j.util.om.trace.OMTracer;
-
-/**
- * The <em>Operations & Maintenance</em> class of this bundle.
- *
- * @author Eike Stepper
- */
-public abstract class OM
-{
- public static final String BUNDLE_ID = "org.eclipse.emf.cdo.server.db"; //$NON-NLS-1$
-
- public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, OM.class);
-
- public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$
-
- public static final OMLogger LOG = BUNDLE.logger();
-
- /**
- * @author Eike Stepper
- */
- public static final class Activator extends OSGiActivator
- {
- public Activator()
- {
- super(BUNDLE);
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.internal.db.bundle; + +import org.eclipse.net4j.util.om.OMBundle; +import org.eclipse.net4j.util.om.OMPlatform; +import org.eclipse.net4j.util.om.OSGiActivator; +import org.eclipse.net4j.util.om.log.OMLogger; +import org.eclipse.net4j.util.om.trace.OMTracer; + +/** + * The <em>Operations & Maintenance</em> class of this bundle. + * + * @author Eike Stepper + */ +public abstract class OM +{ + public static final String BUNDLE_ID = "org.eclipse.emf.cdo.server.db"; //$NON-NLS-1$ + + public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, OM.class); + + public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$ + + public static final OMLogger LOG = BUNDLE.logger(); + + /** + * @author Eike Stepper + */ + public static final class Activator extends OSGiActivator + { + public Activator() + { + super(BUNDLE); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/WrappedPreparedStatement.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/WrappedPreparedStatement.java index d4e29cbbc3..fec0e3797c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/WrappedPreparedStatement.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/WrappedPreparedStatement.java @@ -1,81 +1,81 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db.jdbc;
-
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import java.sql.PreparedStatement;
-import java.text.MessageFormat;
-
-/**
- * Wrapper for a prepared statement that is cleaned up when it is cached in a WeakReferenceCache and gc'd. Note that
- * this is just a wrapper with access to its wrapped object. There's no interface delegation, because the interface
- * delegation would also put the necessity to wrap resultSets and maybe even more, which seems to much overkill for a
- * simple internal implementation.
- *
- * @author Stefan Winkler
- */
-public class WrappedPreparedStatement
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, WrappedPreparedStatement.class);
-
- private PreparedStatement wrappedStatement;
-
- public WrappedPreparedStatement(PreparedStatement ps)
- {
- wrappedStatement = ps;
- if (TRACER.isEnabled())
- {
- TRACER.format("Wrapping Statement: {0}", wrappedStatement); //$NON-NLS-1$
- }
- }
-
- public PreparedStatement getWrappedStatement()
- {
- return wrappedStatement;
- }
-
- public PreparedStatement unwrapStatement()
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("UnWrapping Statement: {0}", wrappedStatement); //$NON-NLS-1$
- }
-
- PreparedStatement result = wrappedStatement;
- wrappedStatement = null;
- return result;
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("Wrapped[{0}]", wrappedStatement); //$NON-NLS-1$
- }
-
- @Override
- protected void finalize() throws Throwable
- {
- if (wrappedStatement != null)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Closing statement: {0}", wrappedStatement); //$NON-NLS-1$
- }
-
- DBUtil.close(wrappedStatement);
- wrappedStatement = null;
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db.jdbc; + +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; + +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import java.sql.PreparedStatement; +import java.text.MessageFormat; + +/** + * Wrapper for a prepared statement that is cleaned up when it is cached in a WeakReferenceCache and gc'd. Note that + * this is just a wrapper with access to its wrapped object. There's no interface delegation, because the interface + * delegation would also put the necessity to wrap resultSets and maybe even more, which seems to much overkill for a + * simple internal implementation. + * + * @author Stefan Winkler + */ +public class WrappedPreparedStatement +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, WrappedPreparedStatement.class); + + private PreparedStatement wrappedStatement; + + public WrappedPreparedStatement(PreparedStatement ps) + { + wrappedStatement = ps; + if (TRACER.isEnabled()) + { + TRACER.format("Wrapping Statement: {0}", wrappedStatement); //$NON-NLS-1$ + } + } + + public PreparedStatement getWrappedStatement() + { + return wrappedStatement; + } + + public PreparedStatement unwrapStatement() + { + if (TRACER.isEnabled()) + { + TRACER.format("UnWrapping Statement: {0}", wrappedStatement); //$NON-NLS-1$ + } + + PreparedStatement result = wrappedStatement; + wrappedStatement = null; + return result; + } + + @Override + public String toString() + { + return MessageFormat.format("Wrapped[{0}]", wrappedStatement); //$NON-NLS-1$ + } + + @Override + protected void finalize() throws Throwable + { + if (wrappedStatement != null) + { + if (TRACER.isEnabled()) + { + TRACER.format("Closing statement: {0}", wrappedStatement); //$NON-NLS-1$ + } + + DBUtil.close(wrappedStatement); + wrappedStatement = null; + } + } +} 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 1f6538733a..725b2ffada 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 @@ -1,641 +1,641 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444
- * Stefan Winkler - Bug 282976: [DB] Influence Mappings through EAnnotations
- * Kai Schlamp - Bug 284680 - [DB] Provide annotation to bypass ClassMapping
- * Stefan Winkler - maintenance
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-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.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IMetaDataManager;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-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.DBAnnotation;
-import org.eclipse.emf.cdo.server.internal.db.ObjectIDIterator;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBSchema;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.StringUtil;
-import org.eclipse.net4j.util.collection.CloseableIterator;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.ENamedElement;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.util.FeatureMapUtil;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * This abstract base class implements those methods which are most likely common to most mapping strategies. It can be
- * used to derive custom mapping strategy implementation.
- *
- * @author Eike Stepper
- * @since 2.0
- */
-public abstract class AbstractMappingStrategy extends Lifecycle implements IMappingStrategy
-{
- // --------- database name generation strings --------------
- protected static final String NAME_SEPARATOR = "_"; //$NON-NLS-1$
-
- protected static final String TYPE_PREFIX_FEATURE = "F"; //$NON-NLS-1$
-
- protected static final String TYPE_PREFIX_CLASS = "C"; //$NON-NLS-1$
-
- protected static final String TYPE_PREFIX_PACKAGE = "P"; //$NON-NLS-1$
-
- protected static final String GENERAL_PREFIX = "X"; //$NON-NLS-1$
-
- protected static final String GENERAL_SUFFIX = "0"; //$NON-NLS-1$
-
- /**
- * Prefix for unsettable feature helper columns
- */
- protected static final String CDO_SET_PREFIX = "cdo_set_"; //$NON-NLS-1$
-
- protected static final String FEATURE_TABLE_SUFFIX = "_list"; //$NON-NLS-1$
-
- private IDBStore store;
-
- private Map<String, String> properties;
-
- private ConcurrentMap<EClass, IClassMapping> classMappings;
-
- private boolean allClassMappingsCreated;
-
- public AbstractMappingStrategy()
- {
- classMappings = new ConcurrentHashMap<EClass, IClassMapping>();
- }
-
- // -- property related methods -----------------------------------------
-
- public synchronized Map<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new HashMap<String, String>();
- }
-
- return properties;
- }
-
- public synchronized void setProperties(Map<String, String> properties)
- {
- this.properties = properties;
- }
-
- private int getMaxTableNameLength()
- {
- String value = getProperties().get(PROP_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);
- return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value);
- }
-
- private boolean isQualifiedNames()
- {
- String value = getProperties().get(PROP_QUALIFIED_NAMES);
- return value == null ? false : Boolean.valueOf(value);
- }
-
- private boolean isForceNamesWithID()
- {
- String value = getProperties().get(PROP_FORCE_NAMES_WITH_ID);
- return value == null ? false : Boolean.valueOf(value);
- }
-
- private String getTableNamePrefix()
- {
- String value = getProperties().get(PROP_TABLE_NAME_PREFIX);
- return StringUtil.safe(value);
- }
-
- // -- getters and setters ----------------------------------------------
-
- public final IDBStore getStore()
- {
- return store;
- }
-
- public final void setStore(IDBStore dbStore)
- {
- checkInactive();
- store = dbStore;
- }
-
- protected final IMetaDataManager getMetaDataManager()
- {
- return getStore().getMetaDataManager();
- }
-
- // -- object id related methods ----------------------------------------
-
- public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp,
- boolean exactTime, CDORevisionHandler handler)
- {
- if (eClass == null)
- {
- Collection<IClassMapping> values = getClassMappings().values();
- for (IClassMapping mapping : values)
- {
- mapping.handleRevisions(accessor, branch, timeStamp, exactTime, handler);
- }
- }
- else
- {
- IClassMapping classMapping = getClassMapping(eClass);
- classMapping.handleRevisions(accessor, branch, timeStamp, exactTime, handler);
- }
- }
-
- public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments)
- {
- Set<CDOID> result = new HashSet<CDOID>();
- Collection<IClassMapping> classMappings = getClassMappings().values();
-
- monitor.begin(classMappings.size());
-
- try
- {
- for (IClassMapping mapping : classMappings)
- {
- Async async = monitor.forkAsync();
-
- try
- {
- Set<CDOID> ids = mapping.readChangeSet(accessor, segments);
- result.addAll(ids);
- }
- finally
- {
- async.stop();
- }
- }
-
- return result;
- }
- finally
- {
- monitor.done();
- }
- }
-
- public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor)
- {
- Collection<EClass> classes = getClassesWithObjectInfo();
- final Iterator<EClass> classIt = classes.iterator();
-
- return new ObjectIDIterator(this, accessor)
- {
- private PreparedStatement currentStatement;
-
- @Override
- protected ResultSet getNextResultSet()
- {
- while (classIt.hasNext())
- {
- EClass eClass = classIt.next();
- IClassMapping mapping = getClassMapping(eClass);
- currentStatement = mapping.createObjectIDStatement(getAccessor());
-
- ResultSet resultSet = null;
-
- try
- {
- resultSet = currentStatement.executeQuery();
- return resultSet;
- }
- catch (Exception ex)
- {
- DBUtil.close(resultSet); // only on error
- releaseCurrentStatement();
- throw new DBException(ex);
- }
- }
-
- return null;
- }
-
- @Override
- protected void closeCurrentResultSet()
- {
- super.closeCurrentResultSet();
- releaseCurrentStatement();
- }
-
- private void releaseCurrentStatement()
- {
- IPreparedStatementCache statementCache = getAccessor().getStatementCache();
- statementCache.releasePreparedStatement(currentStatement);
- currentStatement = null;
- }
- };
- }
-
- protected abstract Collection<EClass> getClassesWithObjectInfo();
-
- // -- database name demangling methods ---------------------------------
-
- public String getTableName(ENamedElement element)
- {
- String name = null;
- String typePrefix = null;
-
- if (element instanceof EClass)
- {
- typePrefix = TYPE_PREFIX_CLASS;
- name = DBAnnotation.TABLE_NAME.getValue(element);
- if (name == null)
- {
- name = isQualifiedNames() ? EMFUtil.getQualifiedName((EClass)element, NAME_SEPARATOR) : element.getName();
- }
- }
- else if (element instanceof EPackage)
- {
- typePrefix = TYPE_PREFIX_PACKAGE;
- name = DBAnnotation.TABLE_NAME.getValue(element);
- if (name == null)
- {
- name = isQualifiedNames() ? EMFUtil.getQualifiedName((EPackage)element, NAME_SEPARATOR) : element.getName();
- }
- }
- else
- {
- throw new ImplementationError("Unknown element: " + element); //$NON-NLS-1$
- }
-
- String prefix = getTableNamePrefix();
- if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR))
- {
- prefix += NAME_SEPARATOR;
- }
-
- return getName(prefix + name, typePrefix + getUniqueID(element), getMaxTableNameLength());
- }
-
- public String getTableName(EClass eClass, EStructuralFeature feature)
- {
- String name = DBAnnotation.TABLE_NAME.getValue(eClass);
- if (name == null)
- {
- name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName();
- }
-
- name += NAME_SEPARATOR;
- name += feature.getName();
- name += FEATURE_TABLE_SUFFIX;
-
- String prefix = getTableNamePrefix();
- if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR))
- {
- prefix += NAME_SEPARATOR;
- }
-
- return getName(prefix + name, TYPE_PREFIX_FEATURE + getUniqueID(feature), getMaxTableNameLength());
- }
-
- public String getFieldName(EStructuralFeature feature)
- {
- String name = DBAnnotation.COLUMN_NAME.getValue(feature);
- if (name == null)
- {
- name = getName(feature.getName(), TYPE_PREFIX_FEATURE + getUniqueID(feature), getMaxFieldNameLength());
- }
-
- return name;
- }
-
- public String getUnsettableFieldName(EStructuralFeature feature)
- {
- String name = DBAnnotation.COLUMN_NAME.getValue(feature);
- if (name != null)
- {
- return CDO_SET_PREFIX + name;
- }
-
- return getName(CDO_SET_PREFIX + feature.getName(), TYPE_PREFIX_FEATURE + getUniqueID(feature),
- getMaxFieldNameLength());
- }
-
- private String getName(String name, String suffix, int maxLength)
- {
- if (!store.getDBAdapter().isValidFirstChar(name.charAt(0)))
- {
- name = GENERAL_PREFIX + name;
- }
-
- boolean forceNamesWithID = isForceNamesWithID();
- if (!forceNamesWithID && store.getDBAdapter().isReservedWord(name))
- {
- name = name + GENERAL_SUFFIX;
- }
-
- if (name.length() > maxLength || forceNamesWithID)
- {
- suffix = NAME_SEPARATOR + suffix.replace('-', 'S');
- int length = Math.min(name.length(), maxLength - suffix.length());
- name = name.substring(0, length) + suffix;
- }
-
- return name;
- }
-
- private String getUniqueID(ENamedElement element)
- {
- long timeStamp;
- CommitContext commitContext = StoreThreadLocal.getCommitContext();
- if (commitContext != null)
- {
- timeStamp = commitContext.getBranchPoint().getTimeStamp();
- }
- else
- {
- // This happens outside a commit, i.e. at system init time.
- // Ensure that resulting ext refs are not replicated!
- timeStamp = CDOBranchPoint.INVALID_DATE;
-
- // timeStamp = getStore().getRepository().getTimeStamp();
- }
-
- CDOID result = getMetaDataManager().getMetaID(element, timeStamp);
-
- StringBuilder builder = new StringBuilder();
- CDOIDUtil.write(builder, result);
- return builder.toString();
- }
-
- // -- factories for mapping of classes, values, lists ------------------
-
- public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- Async async = null;
- monitor.begin();
-
- try
- {
- async = monitor.forkAsync();
-
- try
- {
- mapPackageUnits(packageUnits, connection, false);
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits)
- {
- mapPackageUnits(packageUnits, connection, true);
- }
-
- private void mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap)
- {
- if (packageUnits != null && packageUnits.length != 0)
- {
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- mapPackageInfos(packageUnit.getPackageInfos(), connection, unmap);
- }
- }
- }
-
- private void mapPackageInfos(InternalCDOPackageInfo[] packageInfos, Connection connection, boolean unmap)
- {
- boolean supportingEcore = getStore().getRepository().isSupportingEcore();
- for (InternalCDOPackageInfo packageInfo : packageInfos)
- {
- EPackage ePackage = packageInfo.getEPackage();
- if (!CDOModelUtil.isCorePackage(ePackage) || supportingEcore)
- {
- mapClasses(connection, unmap, EMFUtil.getPersistentClasses(ePackage));
- }
- }
- }
-
- private void mapClasses(Connection connection, boolean unmap, EClass... eClasses)
- {
- for (EClass eClass : eClasses)
- {
- if (!(eClass.isInterface() || eClass.isAbstract()))
- {
- String mappingAnnotation = DBAnnotation.TABLE_MAPPING.getValue(eClass);
-
- // TODO Maybe we should explicitly report unknown values of the annotation
- if (mappingAnnotation != null && mappingAnnotation.equalsIgnoreCase(DBAnnotation.TABLE_MAPPING_NONE))
- {
- continue;
- }
-
- if (!unmap)
- {
- // TODO Bugzilla 296087: Before we go ahead with creation, we should check if it's already there
- IClassMapping mapping = createClassMapping(eClass);
- getStore().getDBAdapter().createTables(mapping.getDBTables(), connection);
- }
- else
- {
- IClassMapping mapping = removeClassMapping(eClass);
- getStore().getDBAdapter().dropTables(mapping.getDBTables(), connection);
- }
- }
- }
- }
-
- private IClassMapping createClassMapping(EClass eClass)
- {
- IClassMapping mapping = doCreateClassMapping(eClass);
- if (mapping != null)
- {
- classMappings.put(eClass, mapping);
- }
-
- return mapping;
- }
-
- private IClassMapping removeClassMapping(EClass eClass)
- {
- IClassMapping mapping = classMappings.get(eClass);
- if (mapping != null)
- {
- IDBSchema schema = getStore().getDBSchema();
- for (IDBTable table : mapping.getDBTables())
- {
- schema.removeTable(table.getName());
- }
- classMappings.remove(eClass);
- }
- return mapping;
- }
-
- protected abstract IClassMapping doCreateClassMapping(EClass eClass);
-
- public final IClassMapping getClassMapping(EClass eClass)
- {
- if (!isMapped(eClass))
- {
- throw new IllegalArgumentException("Class is not mapped: " + eClass);
- }
-
- // Try without synchronization first; this will almost always succeed, so it avoids the
- // performance penalty of syncing in the majority of cases
- IClassMapping result = classMappings.get(eClass);
- if (result == null)
- {
- // Synchronize on the classMappings to prevent concurrent invocations of createClassMapping
- // (Synchronizing on the eClass allows for more concurrency, but is risky because application
- // code may be syncing on the eClass also.)
- synchronized (classMappings)
- {
- // Check again, because other thread may have just added the mapping
- result = classMappings.get(eClass);
- if (result == null)
- {
- result = createClassMapping(eClass);
- }
- }
- }
-
- return result;
- }
-
- public final Map<EClass, IClassMapping> getClassMappings()
- {
- return getClassMappings(true);
- }
-
- public final Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand)
- {
- return doGetClassMappings(createOnDemand);
- }
-
- public final Map<EClass, IClassMapping> doGetClassMappings(boolean createOnDemand)
- {
- if (createOnDemand)
- {
- synchronized (classMappings)
- {
- if (!allClassMappingsCreated)
- {
- createAllClassMappings();
- allClassMappingsCreated = true;
- }
- }
- }
-
- return classMappings;
- }
-
- private void createAllClassMappings()
- {
- InternalRepository repository = (InternalRepository)getStore().getRepository();
- InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false);
- for (InternalCDOPackageInfo packageInfo : packageRegistry.getPackageInfos())
- {
- if (!packageInfo.isSystemPackage())
- {
- for (EClassifier eClassifier : packageInfo.getEPackage().getEClassifiers())
- {
- if (eClassifier instanceof EClass)
- {
- EClass eClass = (EClass)eClassifier;
- if (isMapped(eClass))
- {
- getClassMapping(eClass); // Get or create it
- }
- }
- }
- }
- }
- }
-
- protected abstract boolean isMapped(EClass eClass);
-
- public ITypeMapping createValueMapping(EStructuralFeature feature)
- {
- ITypeMapping.Provider provider = getTypeMappingProvider();
- return provider.createTypeMapping(this, feature);
- }
-
- protected ITypeMapping.Provider getTypeMappingProvider()
- {
- return ITypeMapping.Provider.INSTANCE;
- }
-
- public final IListMapping createListMapping(EClass containingClass, EStructuralFeature feature)
- {
- checkArg(feature.isMany(), "Only many-valued features allowed"); //$NON-NLS-1$
- IListMapping mapping = doCreateListMapping(containingClass, feature);
- return mapping;
- }
-
- public final IListMapping createFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- checkArg(FeatureMapUtil.isFeatureMap(feature), "Only FeatureMaps allowed"); //$NON-NLS-1$
- IListMapping mapping = doCreateFeatureMapMapping(containingClass, feature);
- return mapping;
- }
-
- public abstract IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature);
-
- public abstract IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature);
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + * Stefan Winkler - Bug 271444: [DB] Multiple refactorings bug 271444 + * Stefan Winkler - Bug 282976: [DB] Influence Mappings through EAnnotations + * Kai Schlamp - Bug 284680 - [DB] Provide annotation to bypass ClassMapping + * Stefan Winkler - maintenance + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.internal.db.mapping; + +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.CDOModelUtil; +import org.eclipse.emf.cdo.common.model.EMFUtil; +import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; +import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IMetaDataManager; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +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.DBAnnotation; +import org.eclipse.emf.cdo.server.internal.db.ObjectIDIterator; +import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; +import org.eclipse.emf.cdo.spi.server.InternalRepository; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.ddl.IDBSchema; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.collection.CloseableIterator; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.FeatureMapUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * This abstract base class implements those methods which are most likely common to most mapping strategies. It can be + * used to derive custom mapping strategy implementation. + * + * @author Eike Stepper + * @since 2.0 + */ +public abstract class AbstractMappingStrategy extends Lifecycle implements IMappingStrategy +{ + // --------- database name generation strings -------------- + protected static final String NAME_SEPARATOR = "_"; //$NON-NLS-1$ + + protected static final String TYPE_PREFIX_FEATURE = "F"; //$NON-NLS-1$ + + protected static final String TYPE_PREFIX_CLASS = "C"; //$NON-NLS-1$ + + protected static final String TYPE_PREFIX_PACKAGE = "P"; //$NON-NLS-1$ + + protected static final String GENERAL_PREFIX = "X"; //$NON-NLS-1$ + + protected static final String GENERAL_SUFFIX = "0"; //$NON-NLS-1$ + + /** + * Prefix for unsettable feature helper columns + */ + protected static final String CDO_SET_PREFIX = "cdo_set_"; //$NON-NLS-1$ + + protected static final String FEATURE_TABLE_SUFFIX = "_list"; //$NON-NLS-1$ + + private IDBStore store; + + private Map<String, String> properties; + + private ConcurrentMap<EClass, IClassMapping> classMappings; + + private boolean allClassMappingsCreated; + + public AbstractMappingStrategy() + { + classMappings = new ConcurrentHashMap<EClass, IClassMapping>(); + } + + // -- property related methods ----------------------------------------- + + public synchronized Map<String, String> getProperties() + { + if (properties == null) + { + properties = new HashMap<String, String>(); + } + + return properties; + } + + public synchronized void setProperties(Map<String, String> properties) + { + this.properties = properties; + } + + private int getMaxTableNameLength() + { + String value = getProperties().get(PROP_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); + return value == null ? store.getDBAdapter().getMaxFieldNameLength() : Integer.valueOf(value); + } + + private boolean isQualifiedNames() + { + String value = getProperties().get(PROP_QUALIFIED_NAMES); + return value == null ? false : Boolean.valueOf(value); + } + + private boolean isForceNamesWithID() + { + String value = getProperties().get(PROP_FORCE_NAMES_WITH_ID); + return value == null ? false : Boolean.valueOf(value); + } + + private String getTableNamePrefix() + { + String value = getProperties().get(PROP_TABLE_NAME_PREFIX); + return StringUtil.safe(value); + } + + // -- getters and setters ---------------------------------------------- + + public final IDBStore getStore() + { + return store; + } + + public final void setStore(IDBStore dbStore) + { + checkInactive(); + store = dbStore; + } + + protected final IMetaDataManager getMetaDataManager() + { + return getStore().getMetaDataManager(); + } + + // -- object id related methods ---------------------------------------- + + public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp, + boolean exactTime, CDORevisionHandler handler) + { + if (eClass == null) + { + Collection<IClassMapping> values = getClassMappings().values(); + for (IClassMapping mapping : values) + { + mapping.handleRevisions(accessor, branch, timeStamp, exactTime, handler); + } + } + else + { + IClassMapping classMapping = getClassMapping(eClass); + classMapping.handleRevisions(accessor, branch, timeStamp, exactTime, handler); + } + } + + public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments) + { + Set<CDOID> result = new HashSet<CDOID>(); + Collection<IClassMapping> classMappings = getClassMappings().values(); + + monitor.begin(classMappings.size()); + + try + { + for (IClassMapping mapping : classMappings) + { + Async async = monitor.forkAsync(); + + try + { + Set<CDOID> ids = mapping.readChangeSet(accessor, segments); + result.addAll(ids); + } + finally + { + async.stop(); + } + } + + return result; + } + finally + { + monitor.done(); + } + } + + public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor) + { + Collection<EClass> classes = getClassesWithObjectInfo(); + final Iterator<EClass> classIt = classes.iterator(); + + return new ObjectIDIterator(this, accessor) + { + private PreparedStatement currentStatement; + + @Override + protected ResultSet getNextResultSet() + { + while (classIt.hasNext()) + { + EClass eClass = classIt.next(); + IClassMapping mapping = getClassMapping(eClass); + currentStatement = mapping.createObjectIDStatement(getAccessor()); + + ResultSet resultSet = null; + + try + { + resultSet = currentStatement.executeQuery(); + return resultSet; + } + catch (Exception ex) + { + DBUtil.close(resultSet); // only on error + releaseCurrentStatement(); + throw new DBException(ex); + } + } + + return null; + } + + @Override + protected void closeCurrentResultSet() + { + super.closeCurrentResultSet(); + releaseCurrentStatement(); + } + + private void releaseCurrentStatement() + { + IPreparedStatementCache statementCache = getAccessor().getStatementCache(); + statementCache.releasePreparedStatement(currentStatement); + currentStatement = null; + } + }; + } + + protected abstract Collection<EClass> getClassesWithObjectInfo(); + + // -- database name demangling methods --------------------------------- + + public String getTableName(ENamedElement element) + { + String name = null; + String typePrefix = null; + + if (element instanceof EClass) + { + typePrefix = TYPE_PREFIX_CLASS; + name = DBAnnotation.TABLE_NAME.getValue(element); + if (name == null) + { + name = isQualifiedNames() ? EMFUtil.getQualifiedName((EClass)element, NAME_SEPARATOR) : element.getName(); + } + } + else if (element instanceof EPackage) + { + typePrefix = TYPE_PREFIX_PACKAGE; + name = DBAnnotation.TABLE_NAME.getValue(element); + if (name == null) + { + name = isQualifiedNames() ? EMFUtil.getQualifiedName((EPackage)element, NAME_SEPARATOR) : element.getName(); + } + } + else + { + throw new ImplementationError("Unknown element: " + element); //$NON-NLS-1$ + } + + String prefix = getTableNamePrefix(); + if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR)) + { + prefix += NAME_SEPARATOR; + } + + return getName(prefix + name, typePrefix + getUniqueID(element), getMaxTableNameLength()); + } + + public String getTableName(EClass eClass, EStructuralFeature feature) + { + String name = DBAnnotation.TABLE_NAME.getValue(eClass); + if (name == null) + { + name = isQualifiedNames() ? EMFUtil.getQualifiedName(eClass, NAME_SEPARATOR) : eClass.getName(); + } + + name += NAME_SEPARATOR; + name += feature.getName(); + name += FEATURE_TABLE_SUFFIX; + + String prefix = getTableNamePrefix(); + if (prefix.length() != 0 && !prefix.endsWith(NAME_SEPARATOR)) + { + prefix += NAME_SEPARATOR; + } + + return getName(prefix + name, TYPE_PREFIX_FEATURE + getUniqueID(feature), getMaxTableNameLength()); + } + + public String getFieldName(EStructuralFeature feature) + { + String name = DBAnnotation.COLUMN_NAME.getValue(feature); + if (name == null) + { + name = getName(feature.getName(), TYPE_PREFIX_FEATURE + getUniqueID(feature), getMaxFieldNameLength()); + } + + return name; + } + + public String getUnsettableFieldName(EStructuralFeature feature) + { + String name = DBAnnotation.COLUMN_NAME.getValue(feature); + if (name != null) + { + return CDO_SET_PREFIX + name; + } + + return getName(CDO_SET_PREFIX + feature.getName(), TYPE_PREFIX_FEATURE + getUniqueID(feature), + getMaxFieldNameLength()); + } + + private String getName(String name, String suffix, int maxLength) + { + if (!store.getDBAdapter().isValidFirstChar(name.charAt(0))) + { + name = GENERAL_PREFIX + name; + } + + boolean forceNamesWithID = isForceNamesWithID(); + if (!forceNamesWithID && store.getDBAdapter().isReservedWord(name)) + { + name = name + GENERAL_SUFFIX; + } + + if (name.length() > maxLength || forceNamesWithID) + { + suffix = NAME_SEPARATOR + suffix.replace('-', 'S'); + int length = Math.min(name.length(), maxLength - suffix.length()); + name = name.substring(0, length) + suffix; + } + + return name; + } + + private String getUniqueID(ENamedElement element) + { + long timeStamp; + CommitContext commitContext = StoreThreadLocal.getCommitContext(); + if (commitContext != null) + { + timeStamp = commitContext.getBranchPoint().getTimeStamp(); + } + else + { + // This happens outside a commit, i.e. at system init time. + // Ensure that resulting ext refs are not replicated! + timeStamp = CDOBranchPoint.INVALID_DATE; + + // timeStamp = getStore().getRepository().getTimeStamp(); + } + + CDOID result = getMetaDataManager().getMetaID(element, timeStamp); + + StringBuilder builder = new StringBuilder(); + CDOIDUtil.write(builder, result); + return builder.toString(); + } + + // -- factories for mapping of classes, values, lists ------------------ + + public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) + { + Async async = null; + monitor.begin(); + + try + { + async = monitor.forkAsync(); + + try + { + mapPackageUnits(packageUnits, connection, false); + } + finally + { + if (async != null) + { + async.stop(); + } + } + } + finally + { + monitor.done(); + } + } + + public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits) + { + mapPackageUnits(packageUnits, connection, true); + } + + private void mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap) + { + if (packageUnits != null && packageUnits.length != 0) + { + for (InternalCDOPackageUnit packageUnit : packageUnits) + { + mapPackageInfos(packageUnit.getPackageInfos(), connection, unmap); + } + } + } + + private void mapPackageInfos(InternalCDOPackageInfo[] packageInfos, Connection connection, boolean unmap) + { + boolean supportingEcore = getStore().getRepository().isSupportingEcore(); + for (InternalCDOPackageInfo packageInfo : packageInfos) + { + EPackage ePackage = packageInfo.getEPackage(); + if (!CDOModelUtil.isCorePackage(ePackage) || supportingEcore) + { + mapClasses(connection, unmap, EMFUtil.getPersistentClasses(ePackage)); + } + } + } + + private void mapClasses(Connection connection, boolean unmap, EClass... eClasses) + { + for (EClass eClass : eClasses) + { + if (!(eClass.isInterface() || eClass.isAbstract())) + { + String mappingAnnotation = DBAnnotation.TABLE_MAPPING.getValue(eClass); + + // TODO Maybe we should explicitly report unknown values of the annotation + if (mappingAnnotation != null && mappingAnnotation.equalsIgnoreCase(DBAnnotation.TABLE_MAPPING_NONE)) + { + continue; + } + + if (!unmap) + { + // TODO Bugzilla 296087: Before we go ahead with creation, we should check if it's already there + IClassMapping mapping = createClassMapping(eClass); + getStore().getDBAdapter().createTables(mapping.getDBTables(), connection); + } + else + { + IClassMapping mapping = removeClassMapping(eClass); + getStore().getDBAdapter().dropTables(mapping.getDBTables(), connection); + } + } + } + } + + private IClassMapping createClassMapping(EClass eClass) + { + IClassMapping mapping = doCreateClassMapping(eClass); + if (mapping != null) + { + classMappings.put(eClass, mapping); + } + + return mapping; + } + + private IClassMapping removeClassMapping(EClass eClass) + { + IClassMapping mapping = classMappings.get(eClass); + if (mapping != null) + { + IDBSchema schema = getStore().getDBSchema(); + for (IDBTable table : mapping.getDBTables()) + { + schema.removeTable(table.getName()); + } + classMappings.remove(eClass); + } + return mapping; + } + + protected abstract IClassMapping doCreateClassMapping(EClass eClass); + + public final IClassMapping getClassMapping(EClass eClass) + { + if (!isMapped(eClass)) + { + throw new IllegalArgumentException("Class is not mapped: " + eClass); + } + + // Try without synchronization first; this will almost always succeed, so it avoids the + // performance penalty of syncing in the majority of cases + IClassMapping result = classMappings.get(eClass); + if (result == null) + { + // Synchronize on the classMappings to prevent concurrent invocations of createClassMapping + // (Synchronizing on the eClass allows for more concurrency, but is risky because application + // code may be syncing on the eClass also.) + synchronized (classMappings) + { + // Check again, because other thread may have just added the mapping + result = classMappings.get(eClass); + if (result == null) + { + result = createClassMapping(eClass); + } + } + } + + return result; + } + + public final Map<EClass, IClassMapping> getClassMappings() + { + return getClassMappings(true); + } + + public final Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand) + { + return doGetClassMappings(createOnDemand); + } + + public final Map<EClass, IClassMapping> doGetClassMappings(boolean createOnDemand) + { + if (createOnDemand) + { + synchronized (classMappings) + { + if (!allClassMappingsCreated) + { + createAllClassMappings(); + allClassMappingsCreated = true; + } + } + } + + return classMappings; + } + + private void createAllClassMappings() + { + InternalRepository repository = (InternalRepository)getStore().getRepository(); + InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false); + for (InternalCDOPackageInfo packageInfo : packageRegistry.getPackageInfos()) + { + if (!packageInfo.isSystemPackage()) + { + for (EClassifier eClassifier : packageInfo.getEPackage().getEClassifiers()) + { + if (eClassifier instanceof EClass) + { + EClass eClass = (EClass)eClassifier; + if (isMapped(eClass)) + { + getClassMapping(eClass); // Get or create it + } + } + } + } + } + } + + protected abstract boolean isMapped(EClass eClass); + + public ITypeMapping createValueMapping(EStructuralFeature feature) + { + ITypeMapping.Provider provider = getTypeMappingProvider(); + return provider.createTypeMapping(this, feature); + } + + protected ITypeMapping.Provider getTypeMappingProvider() + { + return ITypeMapping.Provider.INSTANCE; + } + + public final IListMapping createListMapping(EClass containingClass, EStructuralFeature feature) + { + checkArg(feature.isMany(), "Only many-valued features allowed"); //$NON-NLS-1$ + IListMapping mapping = doCreateListMapping(containingClass, feature); + return mapping; + } + + public final IListMapping createFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + checkArg(FeatureMapUtil.isFeatureMap(feature), "Only FeatureMaps allowed"); //$NON-NLS-1$ + IListMapping mapping = doCreateFeatureMapMapping(containingClass, feature); + return mapping; + } + + public abstract IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature); + + public abstract IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java index e2ebb06e9d..b88c8b3dba 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java @@ -1,914 +1,914 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - bug 271444: [DB] Multiple refactorings
- * Stefan Winkler - bug 275303: [DB] DBStore does not handle BIG_INTEGER and BIG_DECIMAL
- * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations
- * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations
- * Stefan Winkler - bug 285270: [DB] Support XSD based models
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lob.CDOBlob;
-import org.eclipse.emf.cdo.common.lob.CDOClob;
-import org.eclipse.emf.cdo.common.lob.CDOLobUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMapping;
-import org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMappingFactory;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.util.HexUtil;
-import org.eclipse.net4j.util.factory.ProductCreationException;
-
-import org.eclipse.emf.common.util.Enumerator;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EEnumLiteral;
-import org.eclipse.emf.ecore.EFactory;
-import org.eclipse.emf.ecore.EcorePackage;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Date;
-
-/**
- * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common
- * types.
- *
- * @author Eike Stepper
- */
-public class CoreTypeMappings
-{
- public static final String ID_PREFIX = "org.eclipse.emf.cdo.server.db.CoreTypeMappings";
-
- /**
- * @author Eike Stepper
- */
- public static class TMEnum extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Enum",
- EcorePackage.eINSTANCE.getEEnum(), DBType.INTEGER));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- // see Bug 271941
- return resultSet.getInt(getField().getName());
- // EEnum type = (EEnum)getFeature().getEType();
- // int value = resultSet.getInt(column);
- // return type.getEEnumLiteral(value);
- }
-
- @Override
- protected Object getDefaultValue()
- {
- EEnum eenum = (EEnum)getFeature().getEType();
-
- String defaultValueLiteral = getFeature().getDefaultValueLiteral();
- if (defaultValueLiteral != null)
- {
- EEnumLiteral literal = eenum.getEEnumLiteralByLiteral(defaultValueLiteral);
- return literal.getValue();
- }
-
- Enumerator enumerator = (Enumerator)eenum.getDefaultValue();
- return enumerator.getValue();
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMEnum();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMString extends AbstractTypeMapping
- {
- public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".StringVarchar", EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".StringLongVarchar", EcorePackage.eINSTANCE.getEString(), DBType.LONGVARCHAR));
-
- public static final Factory FACTORY_CLOB = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".StringClob",
- EcorePackage.eINSTANCE.getEString(), DBType.CLOB));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getString(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMString();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMBlob extends AbstractTypeMapping
- {
- public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BlobStream", EtypesPackage.eINSTANCE.getBlob(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BlobStreamLongVarchar", EtypesPackage.eINSTANCE.getBlob(), DBType.LONGVARCHAR));
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- CDOBlob blob = (CDOBlob)value;
- stmt.setString(index, HexUtil.bytesToHex(blob.getID()) + "-" + blob.getSize());
- }
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String str = resultSet.getString(getField().getName());
- if (str == null)
- {
- return null;
- }
-
- int pos = str.indexOf('-');
-
- byte[] id = HexUtil.hexToBytes(str.substring(0, pos));
- long size = Long.parseLong(str.substring(pos + 1));
- return CDOLobUtil.createBlob(id, size);
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBlob();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMClob extends AbstractTypeMapping
- {
- public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".ClobStream", EtypesPackage.eINSTANCE.getClob(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".ClobStreamLongVarchar", EtypesPackage.eINSTANCE.getClob(), DBType.LONGVARCHAR));
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- CDOClob clob = (CDOClob)value;
- stmt.setString(index, HexUtil.bytesToHex(clob.getID()) + "-" + clob.getSize());
- }
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String str = resultSet.getString(getField().getName());
- if (str == null)
- {
- return null;
- }
-
- int pos = str.indexOf('-');
-
- byte[] id = HexUtil.hexToBytes(str.substring(0, pos));
- long size = Long.parseLong(str.substring(pos + 1));
- return CDOLobUtil.createClob(id, size);
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMClob();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMShort extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Short",
- EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".ShortObject", EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getShort(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMShort();
- }
- }
- }
-
- /**
- * @author Eike Stepper <br>
- */
- public static class TMObject extends AbstractTypeMapping
- {
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- CDOID id = idHandler.getCDOID(resultSet, getField().getName());
-
- if (id == null && getFeature().isUnsettable())
- {
- return CDORevisionData.NIL;
- }
-
- return id;
- }
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- idHandler.setCDOID(stmt, index, (CDOID)value);
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMObject();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMLong extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Long",
- EcorePackage.eINSTANCE.getELong(), DBType.BIGINT));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(
- ID_PREFIX + ".LongObject", EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getLong(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMLong();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMInteger extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Integer",
- EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".IntegerObject", EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getInt(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMInteger();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMFloat extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Float",
- EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".FloatObject", EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getFloat(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMFloat();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMDouble extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Double",
- EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".DoubleObject", EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getDouble(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMDouble();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMDate2Timestamp extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Timestamp",
- EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getTimestamp(getField().getName());
- }
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setTimestamp(index, new Timestamp(((Date)value).getTime()));
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMDate2Timestamp();
- }
- }
- }
-
- /**
- * @author Heiko Ahlig
- */
- public static class TMDate2Date extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Date",
- EcorePackage.eINSTANCE.getEDate(), DBType.DATE));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getDate(getField().getName(), Calendar.getInstance());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMDate2Date();
- }
- }
- }
-
- /**
- * @author Heiko Ahlig
- */
- public static class TMDate2Time extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Time",
- EcorePackage.eINSTANCE.getEDate(), DBType.TIME));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getTime(getField().getName(), Calendar.getInstance());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMDate2Time();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMCharacter extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Character",
- EcorePackage.eINSTANCE.getEChar(), DBType.CHAR));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".CharacterObject", EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String str = resultSet.getString(getField().getName());
- if (resultSet.wasNull())
- {
- return getFeature().isUnsettable() ? CDORevisionData.NIL : null;
- }
-
- return str.charAt(0);
- }
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setString(index, ((Character)value).toString());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMCharacter();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMByte extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Byte",
- EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(
- ID_PREFIX + ".ByteObject", EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getByte(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMByte();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMBytes extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".ByteArray",
- EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getBytes(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBytes();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMBytesVarbinary extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".ByteArrayVarbinary", EcorePackage.eINSTANCE.getEByteArray(), DBType.VARBINARY));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getBytes(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBytesVarbinary();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static class TMBoolean extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Boolean",
- EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN));
-
- public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BooleanObject", EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN));
-
- public static final Factory FACTORY_SMALLINT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".Boolean_SMALLINT", EcorePackage.eINSTANCE.getEBoolean(), DBType.SMALLINT));
-
- public static final Factory FACTORY_OBJECT_SMALLINT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BooleanObject_SMALLINT", EcorePackage.eINSTANCE.getEBooleanObject(), DBType.SMALLINT));
-
- @Override
- public Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- return resultSet.getBoolean(getField().getName());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBoolean();
- }
- }
- }
-
- /**
- * @author Stefan Winkler
- */
- public static class TMBigInteger extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".BigInteger",
- EcorePackage.eINSTANCE.getEBigInteger(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BigIntegerLongVarChar", EcorePackage.eINSTANCE.getEBigInteger(), DBType.LONGVARCHAR));
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String val = resultSet.getString(getField().getName());
-
- if (resultSet.wasNull())
- {
- return getFeature().isUnsettable() ? CDORevisionData.NIL : null;
- }
-
- return new BigInteger(val);
- }
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setString(index, ((BigInteger)value).toString());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBigInteger();
- }
- }
- }
-
- /**
- * @author Stefan Winkler
- */
- public static class TMBigDecimal extends AbstractTypeMapping
- {
- public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".BigDecimal",
- EcorePackage.eINSTANCE.getEBigDecimal(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".BigDecimalLongVarchar", EcorePackage.eINSTANCE.getEBigDecimal(), DBType.LONGVARCHAR));
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String val = resultSet.getString(getField().getName());
-
- if (resultSet.wasNull())
- {
- return getFeature().isUnsettable() ? CDORevisionData.NIL : null;
- }
-
- return new BigDecimal(val);
- }
-
- @Override
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setString(index, ((BigDecimal)value).toPlainString());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMBigDecimal();
- }
- }
- }
-
- /**
- * @author Stefan Winkler
- */
- public static class TMCustom extends AbstractTypeMapping
- {
- public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".CustomVarchar", EcorePackage.eINSTANCE.getEDataType(), DBType.VARCHAR));
-
- public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX
- + ".CustomLongVarchar", EcorePackage.eINSTANCE.getEDataType(), DBType.LONGVARCHAR));
-
- public static final Factory FACTORY_CLOB = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".CustomClob",
- EcorePackage.eINSTANCE.getEDataType(), DBType.CLOB));
-
- @Override
- protected Object getResultSetValue(ResultSet resultSet) throws SQLException
- {
- String val = resultSet.getString(getField().getName());
- if (resultSet.wasNull())
- {
- return getFeature().isUnsettable() ? CDORevisionData.NIL : null;
- }
-
- return val;
- }
-
- @Override
- protected Object getDefaultValue()
- {
- Object defaultValue = getFeature().getDefaultValue();
- if (defaultValue == null)
- {
- return null;
- }
-
- EFactory factory = getFeature().getEType().getEPackage().getEFactoryInstance();
- return factory.convertToString((EDataType)getFeature().getEType(), defaultValue);
- }
-
- /**
- * @author Eike Stepper
- */
- public static class Factory extends AbstractTypeMappingFactory
- {
- public Factory(Descriptor descriptor)
- {
- super(descriptor);
- }
-
- @Override
- public ITypeMapping create(String description) throws ProductCreationException
- {
- return new TMCustom();
- }
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - bug 271444: [DB] Multiple refactorings + * Stefan Winkler - bug 275303: [DB] DBStore does not handle BIG_INTEGER and BIG_DECIMAL + * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations + * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations + * Stefan Winkler - bug 285270: [DB] Support XSD based models + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.internal.db.mapping; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.lob.CDOBlob; +import org.eclipse.emf.cdo.common.lob.CDOClob; +import org.eclipse.emf.cdo.common.lob.CDOLobUtil; +import org.eclipse.emf.cdo.common.revision.CDORevisionData; +import org.eclipse.emf.cdo.etypes.EtypesPackage; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMapping; +import org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMappingFactory; +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.util.HexUtil; +import org.eclipse.net4j.util.factory.ProductCreationException; + +import org.eclipse.emf.common.util.Enumerator; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EcorePackage; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; + +/** + * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common + * types. + * + * @author Eike Stepper + */ +public class CoreTypeMappings +{ + public static final String ID_PREFIX = "org.eclipse.emf.cdo.server.db.CoreTypeMappings"; + + /** + * @author Eike Stepper + */ + public static class TMEnum extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Enum", + EcorePackage.eINSTANCE.getEEnum(), DBType.INTEGER)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + // see Bug 271941 + return resultSet.getInt(getField().getName()); + // EEnum type = (EEnum)getFeature().getEType(); + // int value = resultSet.getInt(column); + // return type.getEEnumLiteral(value); + } + + @Override + protected Object getDefaultValue() + { + EEnum eenum = (EEnum)getFeature().getEType(); + + String defaultValueLiteral = getFeature().getDefaultValueLiteral(); + if (defaultValueLiteral != null) + { + EEnumLiteral literal = eenum.getEEnumLiteralByLiteral(defaultValueLiteral); + return literal.getValue(); + } + + Enumerator enumerator = (Enumerator)eenum.getDefaultValue(); + return enumerator.getValue(); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMEnum(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMString extends AbstractTypeMapping + { + public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".StringVarchar", EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".StringLongVarchar", EcorePackage.eINSTANCE.getEString(), DBType.LONGVARCHAR)); + + public static final Factory FACTORY_CLOB = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".StringClob", + EcorePackage.eINSTANCE.getEString(), DBType.CLOB)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getString(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMString(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMBlob extends AbstractTypeMapping + { + public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BlobStream", EtypesPackage.eINSTANCE.getBlob(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BlobStreamLongVarchar", EtypesPackage.eINSTANCE.getBlob(), DBType.LONGVARCHAR)); + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + CDOBlob blob = (CDOBlob)value; + stmt.setString(index, HexUtil.bytesToHex(blob.getID()) + "-" + blob.getSize()); + } + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String str = resultSet.getString(getField().getName()); + if (str == null) + { + return null; + } + + int pos = str.indexOf('-'); + + byte[] id = HexUtil.hexToBytes(str.substring(0, pos)); + long size = Long.parseLong(str.substring(pos + 1)); + return CDOLobUtil.createBlob(id, size); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBlob(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMClob extends AbstractTypeMapping + { + public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".ClobStream", EtypesPackage.eINSTANCE.getClob(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".ClobStreamLongVarchar", EtypesPackage.eINSTANCE.getClob(), DBType.LONGVARCHAR)); + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + CDOClob clob = (CDOClob)value; + stmt.setString(index, HexUtil.bytesToHex(clob.getID()) + "-" + clob.getSize()); + } + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String str = resultSet.getString(getField().getName()); + if (str == null) + { + return null; + } + + int pos = str.indexOf('-'); + + byte[] id = HexUtil.hexToBytes(str.substring(0, pos)); + long size = Long.parseLong(str.substring(pos + 1)); + return CDOLobUtil.createClob(id, size); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMClob(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMShort extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Short", + EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".ShortObject", EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getShort(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMShort(); + } + } + } + + /** + * @author Eike Stepper <br> + */ + public static class TMObject extends AbstractTypeMapping + { + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + CDOID id = idHandler.getCDOID(resultSet, getField().getName()); + + if (id == null && getFeature().isUnsettable()) + { + return CDORevisionData.NIL; + } + + return id; + } + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + idHandler.setCDOID(stmt, index, (CDOID)value); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMObject(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMLong extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Long", + EcorePackage.eINSTANCE.getELong(), DBType.BIGINT)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor( + ID_PREFIX + ".LongObject", EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getLong(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMLong(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMInteger extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Integer", + EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".IntegerObject", EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getInt(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMInteger(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMFloat extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Float", + EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".FloatObject", EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getFloat(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMFloat(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMDouble extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Double", + EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".DoubleObject", EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getDouble(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMDouble(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMDate2Timestamp extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Timestamp", + EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getTimestamp(getField().getName()); + } + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + stmt.setTimestamp(index, new Timestamp(((Date)value).getTime())); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMDate2Timestamp(); + } + } + } + + /** + * @author Heiko Ahlig + */ + public static class TMDate2Date extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Date", + EcorePackage.eINSTANCE.getEDate(), DBType.DATE)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getDate(getField().getName(), Calendar.getInstance()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMDate2Date(); + } + } + } + + /** + * @author Heiko Ahlig + */ + public static class TMDate2Time extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Time", + EcorePackage.eINSTANCE.getEDate(), DBType.TIME)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getTime(getField().getName(), Calendar.getInstance()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMDate2Time(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMCharacter extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Character", + EcorePackage.eINSTANCE.getEChar(), DBType.CHAR)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".CharacterObject", EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String str = resultSet.getString(getField().getName()); + if (resultSet.wasNull()) + { + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; + } + + return str.charAt(0); + } + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + stmt.setString(index, ((Character)value).toString()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMCharacter(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMByte extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Byte", + EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor( + ID_PREFIX + ".ByteObject", EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getByte(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMByte(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMBytes extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".ByteArray", + EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getBytes(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBytes(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMBytesVarbinary extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".ByteArrayVarbinary", EcorePackage.eINSTANCE.getEByteArray(), DBType.VARBINARY)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getBytes(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBytesVarbinary(); + } + } + } + + /** + * @author Eike Stepper + */ + public static class TMBoolean extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".Boolean", + EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN)); + + public static final Factory FACTORY_OBJECT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BooleanObject", EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN)); + + public static final Factory FACTORY_SMALLINT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".Boolean_SMALLINT", EcorePackage.eINSTANCE.getEBoolean(), DBType.SMALLINT)); + + public static final Factory FACTORY_OBJECT_SMALLINT = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BooleanObject_SMALLINT", EcorePackage.eINSTANCE.getEBooleanObject(), DBType.SMALLINT)); + + @Override + public Object getResultSetValue(ResultSet resultSet) throws SQLException + { + return resultSet.getBoolean(getField().getName()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBoolean(); + } + } + } + + /** + * @author Stefan Winkler + */ + public static class TMBigInteger extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".BigInteger", + EcorePackage.eINSTANCE.getEBigInteger(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BigIntegerLongVarChar", EcorePackage.eINSTANCE.getEBigInteger(), DBType.LONGVARCHAR)); + + @Override + protected Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String val = resultSet.getString(getField().getName()); + + if (resultSet.wasNull()) + { + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; + } + + return new BigInteger(val); + } + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + stmt.setString(index, ((BigInteger)value).toString()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBigInteger(); + } + } + } + + /** + * @author Stefan Winkler + */ + public static class TMBigDecimal extends AbstractTypeMapping + { + public static final Factory FACTORY = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".BigDecimal", + EcorePackage.eINSTANCE.getEBigDecimal(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".BigDecimalLongVarchar", EcorePackage.eINSTANCE.getEBigDecimal(), DBType.LONGVARCHAR)); + + @Override + protected Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String val = resultSet.getString(getField().getName()); + + if (resultSet.wasNull()) + { + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; + } + + return new BigDecimal(val); + } + + @Override + protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException + { + stmt.setString(index, ((BigDecimal)value).toPlainString()); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMBigDecimal(); + } + } + } + + /** + * @author Stefan Winkler + */ + public static class TMCustom extends AbstractTypeMapping + { + public static final Factory FACTORY_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".CustomVarchar", EcorePackage.eINSTANCE.getEDataType(), DBType.VARCHAR)); + + public static final Factory FACTORY_LONG_VARCHAR = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + + ".CustomLongVarchar", EcorePackage.eINSTANCE.getEDataType(), DBType.LONGVARCHAR)); + + public static final Factory FACTORY_CLOB = new Factory(TypeMappingUtil.createDescriptor(ID_PREFIX + ".CustomClob", + EcorePackage.eINSTANCE.getEDataType(), DBType.CLOB)); + + @Override + protected Object getResultSetValue(ResultSet resultSet) throws SQLException + { + String val = resultSet.getString(getField().getName()); + if (resultSet.wasNull()) + { + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; + } + + return val; + } + + @Override + protected Object getDefaultValue() + { + Object defaultValue = getFeature().getDefaultValue(); + if (defaultValue == null) + { + return null; + } + + EFactory factory = getFeature().getEType().getEPackage().getEFactoryInstance(); + return factory.convertToString((EDataType)getFeature().getEType(), defaultValue); + } + + /** + * @author Eike Stepper + */ + public static class Factory extends AbstractTypeMappingFactory + { + public Factory(Descriptor descriptor) + { + super(descriptor); + } + + @Override + public ITypeMapping create(String description) throws ProductCreationException + { + return new TMCustom(); + } + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingDescriptor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingDescriptor.java index bae02d5122..74d1fa1a85 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingDescriptor.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingDescriptor.java @@ -1,65 +1,65 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Stefan Winkler - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-
-import org.eclipse.net4j.db.DBType;
-
-import org.eclipse.emf.ecore.EClassifier;
-
-/**
- * @author Stefan Winkler
- */
-public class TypeMappingDescriptor implements ITypeMapping.Descriptor
-{
- private String id;
-
- private String factoryType;
-
- private EClassifier eClassifier;
-
- private DBType dbType;
-
- public TypeMappingDescriptor(String id, String factoryType, EClassifier eClassifier, DBType dbType)
- {
- this.id = id;
- this.factoryType = factoryType;
- this.eClassifier = eClassifier;
- this.dbType = dbType;
- }
-
- public String getID()
- {
- return id;
- }
-
- public String getFactoryType()
- {
- return factoryType;
- }
-
- public EClassifier getEClassifier()
- {
- return eClassifier;
- }
-
- public DBType getDBType()
- {
- return dbType;
- }
-
- @Override
- public String toString()
- {
- return "TypeMappingDescriptor [" + factoryType + "]";
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Stefan Winkler - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.db.mapping; + +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; + +import org.eclipse.net4j.db.DBType; + +import org.eclipse.emf.ecore.EClassifier; + +/** + * @author Stefan Winkler + */ +public class TypeMappingDescriptor implements ITypeMapping.Descriptor +{ + private String id; + + private String factoryType; + + private EClassifier eClassifier; + + private DBType dbType; + + public TypeMappingDescriptor(String id, String factoryType, EClassifier eClassifier, DBType dbType) + { + this.id = id; + this.factoryType = factoryType; + this.eClassifier = eClassifier; + this.dbType = dbType; + } + + public String getID() + { + return id; + } + + public String getFactoryType() + { + return factoryType; + } + + public EClassifier getEClassifier() + { + return eClassifier; + } + + public DBType getDBType() + { + return dbType; + } + + @Override + public String toString() + { + return "TypeMappingDescriptor [" + factoryType + "]"; + } +} 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 5a3f859440..078f051bb6 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 @@ -1,448 +1,448 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Stefan Winkler - initial API and implementation
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-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.DBAnnotation;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingUtil.FactoryTypeParserException;
-import org.eclipse.emf.cdo.server.internal.db.messages.Messages;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.container.ContainerEvent;
-import org.eclipse.net4j.util.container.IContainerDelta;
-import org.eclipse.net4j.util.container.IContainerDelta.Kind;
-import org.eclipse.net4j.util.container.IManagedContainer;
-import org.eclipse.net4j.util.container.IPluginContainer;
-import org.eclipse.net4j.util.event.IEvent;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.factory.IFactory;
-import org.eclipse.net4j.util.factory.IFactoryKey;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-
-import java.text.MessageFormat;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * An implementation of both the Registry and Provider interfaces for type mappings. This class is a singleton which
- * keeps itself in sync with the global factory registry. It reads the available factoryTypes for the type mappings
- * product type and populates indexes which make it easier to determine and look up the correct factories for a needed
- * type mapping.
- *
- * @author Stefan Winkler
- */
-public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping.Provider
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, TypeMappingRegistry.class);
-
- /**
- * Contains a map from model types to db types which represent default mappings. (I.e., if a model element without db
- * type annotation is encountered, this map is consulted to retrieve the default type mapping. This map is populated
- * on a come-first basis. The first mapping for a particular {@link EClassifier} is set as default.
- */
- private Map<EClassifier, DBType> classifierDefaultMapping;
-
- /**
- * The main TypeMapping index. For any known pair of model and db types the {@link ITypeMapping.Descriptor} is
- * registered here.
- */
- private Map<Pair<EClassifier, DBType>, ITypeMapping.Descriptor> typeMappingByTypes;
-
- /**
- * ID-based index. Can be used to lookup an {@link ITypeMapping.Descriptor} for a given ID.
- */
- private Map<String, ITypeMapping.Descriptor> typeMappingsById;
-
- /**
- * A set of all known mapped DBTypes. This is needed for the feature map mappings.
- */
- private Set<DBType> defaultFeatureMapDBTypes;
-
- /**
- * A populator which is used to keep the registry in sync with the registered factories of the
- * {@link IManagedContainer}.
- */
- private RegistryPopulator populator = new RegistryPopulator();
-
- public TypeMappingRegistry()
- {
- init();
- }
-
- public void init()
- {
- populator.disconnect();
-
- defaultFeatureMapDBTypes = new HashSet<DBType>();
- typeMappingsById = new HashMap<String, ITypeMapping.Descriptor>();
- typeMappingByTypes = new HashMap<Pair<EClassifier, DBType>, ITypeMapping.Descriptor>();
- classifierDefaultMapping = new HashMap<EClassifier, DBType>();
-
- registerCoreTypeMappings();
- populator.connect();
- }
-
- /**
- * Register builtin type mapping factories
- */
- private void registerCoreTypeMappings()
- {
- IManagedContainer container = getContainer();
- container.registerFactory(CoreTypeMappings.TMBigDecimal.FACTORY);
- container.registerFactory(CoreTypeMappings.TMBigDecimal.FACTORY_LONG_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMBigInteger.FACTORY);
- container.registerFactory(CoreTypeMappings.TMBigInteger.FACTORY_LONG_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY);
- container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_SMALLINT);
- container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_OBJECT_SMALLINT);
- container.registerFactory(CoreTypeMappings.TMByte.FACTORY);
- container.registerFactory(CoreTypeMappings.TMByte.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMBytes.FACTORY);
- container.registerFactory(CoreTypeMappings.TMBytesVarbinary.FACTORY);
- container.registerFactory(CoreTypeMappings.TMCharacter.FACTORY);
- container.registerFactory(CoreTypeMappings.TMCharacter.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_CLOB);
- container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_LONG_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMDate2Date.FACTORY);
- container.registerFactory(CoreTypeMappings.TMDate2Time.FACTORY);
- container.registerFactory(CoreTypeMappings.TMDate2Timestamp.FACTORY);
- container.registerFactory(CoreTypeMappings.TMDouble.FACTORY);
- container.registerFactory(CoreTypeMappings.TMDouble.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMEnum.FACTORY);
- container.registerFactory(CoreTypeMappings.TMFloat.FACTORY);
- container.registerFactory(CoreTypeMappings.TMFloat.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMInteger.FACTORY);
- container.registerFactory(CoreTypeMappings.TMInteger.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMLong.FACTORY);
- container.registerFactory(CoreTypeMappings.TMLong.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMShort.FACTORY);
- container.registerFactory(CoreTypeMappings.TMShort.FACTORY_OBJECT);
- container.registerFactory(CoreTypeMappings.TMString.FACTORY_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMString.FACTORY_CLOB);
- container.registerFactory(CoreTypeMappings.TMString.FACTORY_LONG_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMBlob.FACTORY_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMBlob.FACTORY_LONG_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMClob.FACTORY_VARCHAR);
- container.registerFactory(CoreTypeMappings.TMClob.FACTORY_LONG_VARCHAR);
-
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDataType(), DBType.VARCHAR);
-
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBigDecimal(), DBType.VARCHAR);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBigInteger(), DBType.VARCHAR);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEChar(), DBType.CHAR);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEEnum(), DBType.INTEGER);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getELong(), DBType.BIGINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT);
- classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR);
-
- classifierDefaultMapping.put(EtypesPackage.eINSTANCE.getBlob(), DBType.VARCHAR); // TODO Should be DBType.BLOB?
- classifierDefaultMapping.put(EtypesPackage.eINSTANCE.getClob(), DBType.VARCHAR); // TODO Should be DBType.CLOB?
- }
-
- protected IManagedContainer getContainer()
- {
- return IPluginContainer.INSTANCE;
- }
-
- public void registerTypeMapping(ITypeMapping.Descriptor descriptor)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Registering {0}", descriptor);
- }
-
- EClassifier eClassifier = descriptor.getEClassifier();
- DBType dbType = descriptor.getDBType();
- Pair<EClassifier, DBType> sourceTargetPair = new Pair<EClassifier, DBType>(eClassifier, dbType);
-
- // currently we do not support more than one typeMapping per source-target type pair
- if (typeMappingByTypes.containsKey(sourceTargetPair))
- {
- OM.LOG.error(Messages.getString("TypeMappingRegistry.4"));
- return;
- }
-
- if (typeMappingsById.containsKey(descriptor.getID()))
- {
- OM.LOG.error(MessageFormat.format(Messages.getString("TypeMappingRegistry.5"), descriptor.getID()));
- return;
- }
-
- typeMappingsById.put(descriptor.getID(), descriptor);
-
- // register first dbType for classifier as default
- if (!classifierDefaultMapping.containsKey(eClassifier))
- {
- classifierDefaultMapping.put(eClassifier, dbType);
- }
-
- defaultFeatureMapDBTypes.add(dbType);
-
- typeMappingByTypes.put(sourceTargetPair, descriptor);
- }
-
- public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature)
- {
- ITypeMapping typeMapping = null;
- if (feature instanceof EReference)
- {
- IIDHandler idHandler = mappingStrategy.getStore().getIDHandler();
- typeMapping = idHandler.getObjectTypeMapping();
- typeMapping.setDBType(idHandler.getDBType());
- }
- else
- {
- IDBAdapter dbAdapter = mappingStrategy.getStore().getDBAdapter();
- DBType dbType = getDBType(feature, dbAdapter);
-
- ITypeMapping.Descriptor descriptor = null;
-
- String typeMappingID = DBAnnotation.TYPE_MAPPING.getValue(feature);
- if (typeMappingID != null)
- {
- // lookup annotated mapping
- descriptor = typeMappingsById.get(typeMappingID);
-
- if (descriptor == null)
- {
- OM.LOG.warn(MessageFormat.format(Messages.getString("TypeMappingRegistry.2"), //
- typeMappingID, feature.toString()));
- }
- }
-
- if (descriptor == null)
- {
- // try to find suitable mapping by type
- descriptor = getMappingByType(feature, dbType);
- }
-
- if (descriptor == null)
- {
- EClassifier type = getEType(feature);
- throw new IllegalStateException(MessageFormat.format(Messages.getString("TypeMappingRegistry.1"), feature
- .getEContainingClass().getName() + "." + feature.getName(),
- type.getEPackage().getName() + "." + type.getName(), dbType.getKeyword()));
- }
-
- IFactory factory = getContainer().getFactory(ITypeMapping.Factory.PRODUCT_GROUP, descriptor.getFactoryType());
- typeMapping = (ITypeMapping)factory.create(null);
- typeMapping.setDBType(dbType);
- }
-
- typeMapping.setMappingStrategy(mappingStrategy);
- typeMapping.setFeature(feature);
- return typeMapping;
- }
-
- private EClassifier getEType(EStructuralFeature feature)
- {
- EClassifier classifier = feature.getEType();
- if (classifier instanceof EEnum)
- {
- return EcorePackage.eINSTANCE.getEEnum();
- }
-
- if (classifier instanceof EClass)
- {
- return EcorePackage.eINSTANCE.getEClass();
- }
-
- EPackage ePackage = classifier.getEPackage();
- if (CDOModelUtil.isCorePackage(ePackage))
- {
- return classifier;
- }
-
- if (CDOModelUtil.isTypesPackage(ePackage))
- {
- return classifier;
- }
-
- return EcorePackage.eINSTANCE.getEDataType();
- }
-
- private DBType getDBType(EStructuralFeature feature, IDBAdapter dbAdapter)
- {
- String typeKeyword = DBAnnotation.COLUMN_TYPE.getValue(feature);
- if (typeKeyword != null)
- {
- DBType dbType = DBType.getTypeByKeyword(typeKeyword);
- if (dbType == null)
- {
- throw new IllegalArgumentException("Unsupported columnType (" + typeKeyword + ") annotation of feature "
- + feature.getName());
- }
-
- return dbType;
- }
-
- // No annotation present - lookup default DB type.
- return getDefaultDBType(getEType(feature), dbAdapter);
- }
-
- private DBType getDefaultDBType(EClassifier type, IDBAdapter dbAdapter)
- {
- DBType result = classifierDefaultMapping.get(type);
-
- if (result == null)
- {
- result = DBType.VARCHAR;
- }
-
- // Give the DBAdapter a chance to override the default type, if it's not supported
- return dbAdapter.adaptType(result);
- }
-
- private ITypeMapping.Descriptor getMappingByType(EStructuralFeature feature, DBType dbType)
- {
- // First try: lookup specific mapping for the immediate type.
- ITypeMapping.Descriptor descriptor = typeMappingByTypes.get(new Pair<EClassifier, DBType>(feature.getEType(),
- dbType));
-
- if (descriptor == null)
- {
- // Second try: lookup general mapping
- descriptor = typeMappingByTypes.get(new Pair<EClassifier, DBType>(getEType(feature), dbType));
- if (descriptor == null)
- {
- // Lookup failed. Give up
- return null;
- }
- }
-
- return descriptor;
- }
-
- public Collection<DBType> getDefaultFeatureMapDBTypes()
- {
- return defaultFeatureMapDBTypes;
- }
-
- /**
- * Keeps the {@link TypeMappingRegistry} in sync with {@link IManagedContainer#getFactoryRegistry()}.
- *
- * @author Stefan Winkler
- */
- private class RegistryPopulator implements IListener
- {
- private IManagedContainer container = getContainer();
-
- public RegistryPopulator()
- {
- }
-
- /**
- * Connect to the factory registry.
- */
- public void connect()
- {
- populateTypeMappingRegistry();
- container.getFactoryRegistry().addListener(this);
- }
-
- public void disconnect()
- {
- container.getFactoryRegistry().removeListener(this);
- }
-
- private void populateTypeMappingRegistry()
- {
- // get available factory types
- Set<String> factoryTypes = container.getFactoryTypes(ITypeMapping.Factory.PRODUCT_GROUP);
-
- // parse the descriptor of each factory type
- for (String factoryType : factoryTypes)
- {
- registerFactoryType(factoryType);
- }
- }
-
- private void registerFactoryType(String factoryType)
- {
- ITypeMapping.Descriptor desc;
-
- try
- {
- desc = TypeMappingUtil.descriptorFromFactoryType(factoryType);
- registerTypeMapping(desc);
- }
- catch (FactoryTypeParserException ex)
- {
- OM.LOG.warn(ex);
- }
- }
-
- public void notifyEvent(IEvent event)
- {
- if (event instanceof ContainerEvent<?>)
- {
- @SuppressWarnings("unchecked")
- ContainerEvent<Map.Entry<IFactoryKey, IFactory>> ev = (ContainerEvent<Entry<IFactoryKey, IFactory>>)event;
-
- for (IContainerDelta<Map.Entry<IFactoryKey, IFactory>> delta : ev.getDeltas())
- {
- IFactoryKey key = delta.getElement().getKey();
- if (key.getProductGroup().equals(ITypeMapping.Factory.PRODUCT_GROUP))
- {
- if (delta.getKind() == Kind.ADDED)
- {
- String factoryType = delta.getElement().getKey().getType();
- registerFactoryType(factoryType);
- }
- else
- // delta.getKind() == Kind.REMOVED
- {
- // XXX Runtime removal of typeMappingFactories removal of type mappings is currently not supported.
- OM.LOG.warn(Messages.getString("TypeMappingRegistry.3"));
- }
- }
- }
- }
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Stefan Winkler - initial API and implementation + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + */ +package org.eclipse.emf.cdo.server.internal.db.mapping; + +import org.eclipse.emf.cdo.common.model.CDOModelUtil; +import org.eclipse.emf.cdo.etypes.EtypesPackage; +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.DBAnnotation; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingUtil.FactoryTypeParserException; +import org.eclipse.emf.cdo.server.internal.db.messages.Messages; + +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.util.collection.Pair; +import org.eclipse.net4j.util.container.ContainerEvent; +import org.eclipse.net4j.util.container.IContainerDelta; +import org.eclipse.net4j.util.container.IContainerDelta.Kind; +import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.util.container.IPluginContainer; +import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.factory.IFactory; +import org.eclipse.net4j.util.factory.IFactoryKey; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcorePackage; + +import java.text.MessageFormat; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * An implementation of both the Registry and Provider interfaces for type mappings. This class is a singleton which + * keeps itself in sync with the global factory registry. It reads the available factoryTypes for the type mappings + * product type and populates indexes which make it easier to determine and look up the correct factories for a needed + * type mapping. + * + * @author Stefan Winkler + */ +public class TypeMappingRegistry implements ITypeMapping.Registry, ITypeMapping.Provider +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, TypeMappingRegistry.class); + + /** + * Contains a map from model types to db types which represent default mappings. (I.e., if a model element without db + * type annotation is encountered, this map is consulted to retrieve the default type mapping. This map is populated + * on a come-first basis. The first mapping for a particular {@link EClassifier} is set as default. + */ + private Map<EClassifier, DBType> classifierDefaultMapping; + + /** + * The main TypeMapping index. For any known pair of model and db types the {@link ITypeMapping.Descriptor} is + * registered here. + */ + private Map<Pair<EClassifier, DBType>, ITypeMapping.Descriptor> typeMappingByTypes; + + /** + * ID-based index. Can be used to lookup an {@link ITypeMapping.Descriptor} for a given ID. + */ + private Map<String, ITypeMapping.Descriptor> typeMappingsById; + + /** + * A set of all known mapped DBTypes. This is needed for the feature map mappings. + */ + private Set<DBType> defaultFeatureMapDBTypes; + + /** + * A populator which is used to keep the registry in sync with the registered factories of the + * {@link IManagedContainer}. + */ + private RegistryPopulator populator = new RegistryPopulator(); + + public TypeMappingRegistry() + { + init(); + } + + public void init() + { + populator.disconnect(); + + defaultFeatureMapDBTypes = new HashSet<DBType>(); + typeMappingsById = new HashMap<String, ITypeMapping.Descriptor>(); + typeMappingByTypes = new HashMap<Pair<EClassifier, DBType>, ITypeMapping.Descriptor>(); + classifierDefaultMapping = new HashMap<EClassifier, DBType>(); + + registerCoreTypeMappings(); + populator.connect(); + } + + /** + * Register builtin type mapping factories + */ + private void registerCoreTypeMappings() + { + IManagedContainer container = getContainer(); + container.registerFactory(CoreTypeMappings.TMBigDecimal.FACTORY); + container.registerFactory(CoreTypeMappings.TMBigDecimal.FACTORY_LONG_VARCHAR); + container.registerFactory(CoreTypeMappings.TMBigInteger.FACTORY); + container.registerFactory(CoreTypeMappings.TMBigInteger.FACTORY_LONG_VARCHAR); + container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY); + container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_SMALLINT); + container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMBoolean.FACTORY_OBJECT_SMALLINT); + container.registerFactory(CoreTypeMappings.TMByte.FACTORY); + container.registerFactory(CoreTypeMappings.TMByte.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMBytes.FACTORY); + container.registerFactory(CoreTypeMappings.TMBytesVarbinary.FACTORY); + container.registerFactory(CoreTypeMappings.TMCharacter.FACTORY); + container.registerFactory(CoreTypeMappings.TMCharacter.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_VARCHAR); + container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_CLOB); + container.registerFactory(CoreTypeMappings.TMCustom.FACTORY_LONG_VARCHAR); + container.registerFactory(CoreTypeMappings.TMDate2Date.FACTORY); + container.registerFactory(CoreTypeMappings.TMDate2Time.FACTORY); + container.registerFactory(CoreTypeMappings.TMDate2Timestamp.FACTORY); + container.registerFactory(CoreTypeMappings.TMDouble.FACTORY); + container.registerFactory(CoreTypeMappings.TMDouble.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMEnum.FACTORY); + container.registerFactory(CoreTypeMappings.TMFloat.FACTORY); + container.registerFactory(CoreTypeMappings.TMFloat.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMInteger.FACTORY); + container.registerFactory(CoreTypeMappings.TMInteger.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMLong.FACTORY); + container.registerFactory(CoreTypeMappings.TMLong.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMShort.FACTORY); + container.registerFactory(CoreTypeMappings.TMShort.FACTORY_OBJECT); + container.registerFactory(CoreTypeMappings.TMString.FACTORY_VARCHAR); + container.registerFactory(CoreTypeMappings.TMString.FACTORY_CLOB); + container.registerFactory(CoreTypeMappings.TMString.FACTORY_LONG_VARCHAR); + container.registerFactory(CoreTypeMappings.TMBlob.FACTORY_VARCHAR); + container.registerFactory(CoreTypeMappings.TMBlob.FACTORY_LONG_VARCHAR); + container.registerFactory(CoreTypeMappings.TMClob.FACTORY_VARCHAR); + container.registerFactory(CoreTypeMappings.TMClob.FACTORY_LONG_VARCHAR); + + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDataType(), DBType.VARCHAR); + + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBigDecimal(), DBType.VARCHAR); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBigInteger(), DBType.VARCHAR); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEChar(), DBType.CHAR); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEEnum(), DBType.INTEGER); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getELong(), DBType.BIGINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT); + classifierDefaultMapping.put(EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR); + + classifierDefaultMapping.put(EtypesPackage.eINSTANCE.getBlob(), DBType.VARCHAR); // TODO Should be DBType.BLOB? + classifierDefaultMapping.put(EtypesPackage.eINSTANCE.getClob(), DBType.VARCHAR); // TODO Should be DBType.CLOB? + } + + protected IManagedContainer getContainer() + { + return IPluginContainer.INSTANCE; + } + + public void registerTypeMapping(ITypeMapping.Descriptor descriptor) + { + if (TRACER.isEnabled()) + { + TRACER.format("Registering {0}", descriptor); + } + + EClassifier eClassifier = descriptor.getEClassifier(); + DBType dbType = descriptor.getDBType(); + Pair<EClassifier, DBType> sourceTargetPair = new Pair<EClassifier, DBType>(eClassifier, dbType); + + // currently we do not support more than one typeMapping per source-target type pair + if (typeMappingByTypes.containsKey(sourceTargetPair)) + { + OM.LOG.error(Messages.getString("TypeMappingRegistry.4")); + return; + } + + if (typeMappingsById.containsKey(descriptor.getID())) + { + OM.LOG.error(MessageFormat.format(Messages.getString("TypeMappingRegistry.5"), descriptor.getID())); + return; + } + + typeMappingsById.put(descriptor.getID(), descriptor); + + // register first dbType for classifier as default + if (!classifierDefaultMapping.containsKey(eClassifier)) + { + classifierDefaultMapping.put(eClassifier, dbType); + } + + defaultFeatureMapDBTypes.add(dbType); + + typeMappingByTypes.put(sourceTargetPair, descriptor); + } + + public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature) + { + ITypeMapping typeMapping = null; + if (feature instanceof EReference) + { + IIDHandler idHandler = mappingStrategy.getStore().getIDHandler(); + typeMapping = idHandler.getObjectTypeMapping(); + typeMapping.setDBType(idHandler.getDBType()); + } + else + { + IDBAdapter dbAdapter = mappingStrategy.getStore().getDBAdapter(); + DBType dbType = getDBType(feature, dbAdapter); + + ITypeMapping.Descriptor descriptor = null; + + String typeMappingID = DBAnnotation.TYPE_MAPPING.getValue(feature); + if (typeMappingID != null) + { + // lookup annotated mapping + descriptor = typeMappingsById.get(typeMappingID); + + if (descriptor == null) + { + OM.LOG.warn(MessageFormat.format(Messages.getString("TypeMappingRegistry.2"), // + typeMappingID, feature.toString())); + } + } + + if (descriptor == null) + { + // try to find suitable mapping by type + descriptor = getMappingByType(feature, dbType); + } + + if (descriptor == null) + { + EClassifier type = getEType(feature); + throw new IllegalStateException(MessageFormat.format(Messages.getString("TypeMappingRegistry.1"), feature + .getEContainingClass().getName() + "." + feature.getName(), + type.getEPackage().getName() + "." + type.getName(), dbType.getKeyword())); + } + + IFactory factory = getContainer().getFactory(ITypeMapping.Factory.PRODUCT_GROUP, descriptor.getFactoryType()); + typeMapping = (ITypeMapping)factory.create(null); + typeMapping.setDBType(dbType); + } + + typeMapping.setMappingStrategy(mappingStrategy); + typeMapping.setFeature(feature); + return typeMapping; + } + + private EClassifier getEType(EStructuralFeature feature) + { + EClassifier classifier = feature.getEType(); + if (classifier instanceof EEnum) + { + return EcorePackage.eINSTANCE.getEEnum(); + } + + if (classifier instanceof EClass) + { + return EcorePackage.eINSTANCE.getEClass(); + } + + EPackage ePackage = classifier.getEPackage(); + if (CDOModelUtil.isCorePackage(ePackage)) + { + return classifier; + } + + if (CDOModelUtil.isTypesPackage(ePackage)) + { + return classifier; + } + + return EcorePackage.eINSTANCE.getEDataType(); + } + + private DBType getDBType(EStructuralFeature feature, IDBAdapter dbAdapter) + { + String typeKeyword = DBAnnotation.COLUMN_TYPE.getValue(feature); + if (typeKeyword != null) + { + DBType dbType = DBType.getTypeByKeyword(typeKeyword); + if (dbType == null) + { + throw new IllegalArgumentException("Unsupported columnType (" + typeKeyword + ") annotation of feature " + + feature.getName()); + } + + return dbType; + } + + // No annotation present - lookup default DB type. + return getDefaultDBType(getEType(feature), dbAdapter); + } + + private DBType getDefaultDBType(EClassifier type, IDBAdapter dbAdapter) + { + DBType result = classifierDefaultMapping.get(type); + + if (result == null) + { + result = DBType.VARCHAR; + } + + // Give the DBAdapter a chance to override the default type, if it's not supported + return dbAdapter.adaptType(result); + } + + private ITypeMapping.Descriptor getMappingByType(EStructuralFeature feature, DBType dbType) + { + // First try: lookup specific mapping for the immediate type. + ITypeMapping.Descriptor descriptor = typeMappingByTypes.get(new Pair<EClassifier, DBType>(feature.getEType(), + dbType)); + + if (descriptor == null) + { + // Second try: lookup general mapping + descriptor = typeMappingByTypes.get(new Pair<EClassifier, DBType>(getEType(feature), dbType)); + if (descriptor == null) + { + // Lookup failed. Give up + return null; + } + } + + return descriptor; + } + + public Collection<DBType> getDefaultFeatureMapDBTypes() + { + return defaultFeatureMapDBTypes; + } + + /** + * Keeps the {@link TypeMappingRegistry} in sync with {@link IManagedContainer#getFactoryRegistry()}. + * + * @author Stefan Winkler + */ + private class RegistryPopulator implements IListener + { + private IManagedContainer container = getContainer(); + + public RegistryPopulator() + { + } + + /** + * Connect to the factory registry. + */ + public void connect() + { + populateTypeMappingRegistry(); + container.getFactoryRegistry().addListener(this); + } + + public void disconnect() + { + container.getFactoryRegistry().removeListener(this); + } + + private void populateTypeMappingRegistry() + { + // get available factory types + Set<String> factoryTypes = container.getFactoryTypes(ITypeMapping.Factory.PRODUCT_GROUP); + + // parse the descriptor of each factory type + for (String factoryType : factoryTypes) + { + registerFactoryType(factoryType); + } + } + + private void registerFactoryType(String factoryType) + { + ITypeMapping.Descriptor desc; + + try + { + desc = TypeMappingUtil.descriptorFromFactoryType(factoryType); + registerTypeMapping(desc); + } + catch (FactoryTypeParserException ex) + { + OM.LOG.warn(ex); + } + } + + public void notifyEvent(IEvent event) + { + if (event instanceof ContainerEvent<?>) + { + @SuppressWarnings("unchecked") + ContainerEvent<Map.Entry<IFactoryKey, IFactory>> ev = (ContainerEvent<Entry<IFactoryKey, IFactory>>)event; + + for (IContainerDelta<Map.Entry<IFactoryKey, IFactory>> delta : ev.getDeltas()) + { + IFactoryKey key = delta.getElement().getKey(); + if (key.getProductGroup().equals(ITypeMapping.Factory.PRODUCT_GROUP)) + { + if (delta.getKind() == Kind.ADDED) + { + String factoryType = delta.getElement().getKey().getType(); + registerFactoryType(factoryType); + } + else + // 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/TypeMappingUtil.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingUtil.java index b297600dd5..084db61463 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingUtil.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingUtil.java @@ -1,113 +1,113 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.messages.Messages;
-
-import org.eclipse.net4j.db.DBType;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EPackage;
-
-import java.text.MessageFormat;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author Stefan Winkler
- */
-public class TypeMappingUtil
-{
- private static final Pattern FACTORY_DESCRIPTOR_PATTERN = Pattern.compile("(.+);(.+)#(.+)->(.+)");
-
- /**
- * Utility class - no instantiation.
- */
- private TypeMappingUtil()
- {
- }
-
- public static ITypeMapping.Descriptor createDescriptor(String id, EClassifier eClassifier, DBType dbType)
- {
- String factoryType = createFactoryType(id, eClassifier, dbType);
- return new TypeMappingDescriptor(id, factoryType, eClassifier, dbType);
- }
-
- public static String createFactoryType(String id, EClassifier eClassifier, DBType dbType)
- {
- StringBuilder builder = new StringBuilder();
-
- // id
- builder.append(id);
- builder.append(";");
-
- // classifier
- builder.append(eClassifier.getEPackage().getNsURI());
- builder.append("#");
- builder.append(eClassifier.getName());
- builder.append("->");
-
- // dbtype
- builder.append(dbType.getKeyword());
-
- return builder.toString();
- }
-
- public static ITypeMapping.Descriptor descriptorFromFactoryType(String factoryType) throws FactoryTypeParserException
- {
- Matcher matcher = FACTORY_DESCRIPTOR_PATTERN.matcher(factoryType);
-
- if (!matcher.matches())
- {
- throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.1"),
- factoryType));
- }
-
- String id = matcher.group(1);
- String packageUri = matcher.group(2);
- String classifierName = matcher.group(3);
- String typeKeyword = matcher.group(4);
-
- EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageUri);
- if (ePackage == null)
- {
- throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.2"),
- packageUri, factoryType));
- }
-
- EClassifier eClassifier = ePackage.getEClassifier(classifierName);
- if (eClassifier == null)
- {
- throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.3"),
- classifierName, factoryType));
- }
-
- DBType dbType = DBType.getTypeByKeyword(typeKeyword);
- if (dbType == null)
- {
- throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.4"),
- dbType, factoryType));
- }
-
- return new TypeMappingDescriptor(id, factoryType, eClassifier, dbType);
- }
-
- public static class FactoryTypeParserException extends Exception
- {
- private static final long serialVersionUID = 1L;
-
- public FactoryTypeParserException(String desc)
- {
- super(desc);
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db.mapping; + +import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping; +import org.eclipse.emf.cdo.server.internal.db.messages.Messages; + +import org.eclipse.net4j.db.DBType; + +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EPackage; + +import java.text.MessageFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Stefan Winkler + */ +public class TypeMappingUtil +{ + private static final Pattern FACTORY_DESCRIPTOR_PATTERN = Pattern.compile("(.+);(.+)#(.+)->(.+)"); + + /** + * Utility class - no instantiation. + */ + private TypeMappingUtil() + { + } + + public static ITypeMapping.Descriptor createDescriptor(String id, EClassifier eClassifier, DBType dbType) + { + String factoryType = createFactoryType(id, eClassifier, dbType); + return new TypeMappingDescriptor(id, factoryType, eClassifier, dbType); + } + + public static String createFactoryType(String id, EClassifier eClassifier, DBType dbType) + { + StringBuilder builder = new StringBuilder(); + + // id + builder.append(id); + builder.append(";"); + + // classifier + builder.append(eClassifier.getEPackage().getNsURI()); + builder.append("#"); + builder.append(eClassifier.getName()); + builder.append("->"); + + // dbtype + builder.append(dbType.getKeyword()); + + return builder.toString(); + } + + public static ITypeMapping.Descriptor descriptorFromFactoryType(String factoryType) throws FactoryTypeParserException + { + Matcher matcher = FACTORY_DESCRIPTOR_PATTERN.matcher(factoryType); + + if (!matcher.matches()) + { + throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.1"), + factoryType)); + } + + String id = matcher.group(1); + String packageUri = matcher.group(2); + String classifierName = matcher.group(3); + String typeKeyword = matcher.group(4); + + EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageUri); + if (ePackage == null) + { + throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.2"), + packageUri, factoryType)); + } + + EClassifier eClassifier = ePackage.getEClassifier(classifierName); + if (eClassifier == null) + { + throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.3"), + classifierName, factoryType)); + } + + DBType dbType = DBType.getTypeByKeyword(typeKeyword); + if (dbType == null) + { + throw new FactoryTypeParserException(MessageFormat.format(Messages.getString("FactoryTypeParserException.4"), + dbType, factoryType)); + } + + return new TypeMappingDescriptor(id, factoryType, eClassifier, dbType); + } + + public static class FactoryTypeParserException extends Exception + { + private static final long serialVersionUID = 1L; + + public FactoryTypeParserException(String desc) + { + super(desc); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java index ede99ae511..d4c1c000d5 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java @@ -1,588 +1,588 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455
- * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails
- * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
- * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
-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.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBIndex.Type;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.collection.MoveableList;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.util.FeatureMap;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This abstract base class provides basic behavior needed for mapping many-valued attributes to tables.
- *
- * @author Eike Stepper
- * @since 3.0
- */
-public abstract class AbstractFeatureMapTableMapping extends BasicAbstractListTableMapping
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractFeatureMapTableMapping.class);
-
- /**
- * The table of this mapping.
- */
- private IDBTable table;
-
- /**
- * The tags mapped to column names
- */
- private HashMap<CDOID, String> tagMap;
-
- /**
- * Column name Set
- */
- private List<String> columnNames;
-
- /**
- * The type mappings for the value fields.
- */
- private Map<CDOID, ITypeMapping> typeMappings;
-
- // --------- SQL strings - see initSQLStrings() -----------------
- private String sqlSelectChunksPrefix;
-
- private String sqlOrderByIndex;
-
- protected String sqlInsert;
-
- private List<DBType> dbTypes;
-
- public AbstractFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
- {
- super(mappingStrategy, eClass, feature);
- initDBTypes();
- initTable();
- initSQLStrings();
- }
-
- private void initDBTypes()
- {
- // TODO add annotation processing here ...
- ITypeMapping.Registry registry = getTypeMappingRegistry();
- dbTypes = new ArrayList<DBType>(registry.getDefaultFeatureMapDBTypes());
- }
-
- protected ITypeMapping.Registry getTypeMappingRegistry()
- {
- return ITypeMapping.Registry.INSTANCE;
- }
-
- private void initTable()
- {
- IDBStore store = getMappingStrategy().getStore();
- String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature());
- table = store.getDBSchema().addTable(tableName);
-
- // add fields for keys (cdo_id, version, feature_id)
- FieldInfo[] fields = getKeyFields();
- IDBField[] dbFields = new IDBField[fields.length];
-
- for (int i = 0; i < fields.length; i++)
- {
- dbFields[i] = table.addField(fields[i].getName(), fields[i].getDbType());
- }
-
- // add field for list index
- IDBField idxField = table.addField(CDODBSchema.FEATUREMAP_IDX, DBType.INTEGER);
-
- // add field for FeatureMap tag (MetaID for Feature in CDO registry)
- IDBField tagField = table.addField(CDODBSchema.FEATUREMAP_TAG, store.getIDHandler().getDBType());
-
- tagMap = new HashMap<CDOID, String>();
- typeMappings = new HashMap<CDOID, ITypeMapping>();
- columnNames = new ArrayList<String>();
-
- // create columns for all DBTypes
- for (DBType type : getDBTypes())
- {
- String column = CDODBSchema.FEATUREMAP_VALUE + "_" + type.name();
- table.addField(column, type);
- columnNames.add(column);
- }
-
- table.addIndex(Type.NON_UNIQUE, dbFields);
- table.addIndex(Type.NON_UNIQUE, idxField);
- table.addIndex(Type.NON_UNIQUE, tagField);
- }
-
- protected abstract FieldInfo[] getKeyFields();
-
- protected abstract void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException;
-
- public Collection<IDBTable> getDBTables()
- {
- return Arrays.asList(table);
- }
-
- private void initSQLStrings()
- {
- String tableName = getTable().getName();
- FieldInfo[] fields = getKeyFields();
-
- // ---------------- SELECT to read chunks ----------------------------
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
-
- builder.append(CDODBSchema.FEATUREMAP_TAG);
- builder.append(", ");
-
- Iterator<String> iter = columnNames.iterator();
- while (iter.hasNext())
- {
- builder.append(iter.next());
- if (iter.hasNext())
- {
- builder.append(", ");
- }
- }
-
- builder.append(" FROM ");
- builder.append(tableName);
- builder.append(" WHERE ");
-
- for (int i = 0; i < fields.length; i++)
- {
- builder.append(fields[i].getName());
- if (i + 1 < fields.length)
- {
- // more to come
- builder.append("=? AND ");
- }
- else
- {
- // last one
- builder.append("=? ");
- }
- }
-
- sqlSelectChunksPrefix = builder.toString();
-
- sqlOrderByIndex = " ORDER BY " + CDODBSchema.FEATUREMAP_IDX; //$NON-NLS-1$
-
- // INSERT with dynamic field name
- // TODO: Better: universal INSERT-Statement, because of stmt caching!
-
- // ----------------- INSERT - prefix -----------------
- builder = new StringBuilder("INSERT INTO ");
- builder.append(tableName);
- builder.append(" ("); //$NON-NLS-1$
- for (int i = 0; i < fields.length; i++)
- {
- builder.append(fields[i].getName());
- builder.append(", "); //$NON-NLS-1$
- }
-
- for (int i = 0; i < columnNames.size(); i++)
- {
- builder.append(columnNames.get(i));
- builder.append(", "); //$NON-NLS-1$
- }
-
- builder.append(CDODBSchema.FEATUREMAP_IDX);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.FEATUREMAP_TAG);
- builder.append(") VALUES ("); //$NON-NLS-1$
- for (int i = 0; i < fields.length + columnNames.size(); i++)
- {
- builder.append("?, ");
- }
-
- builder.append("?, ?)");
- sqlInsert = builder.toString();
- }
-
- protected List<DBType> getDBTypes()
- {
- return dbTypes;
- }
-
- protected final IDBTable getTable()
- {
- return table;
- }
-
- protected final List<String> getColumnNames()
- {
- return columnNames;
- }
-
- protected final Map<CDOID, ITypeMapping> getTypeMappings()
- {
- return typeMappings;
- }
-
- protected final Map<CDOID, String> getTagMap()
- {
- return tagMap;
- }
-
- public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
- {
- MoveableList<Object> list = revision.getList(getFeature());
- if (listChunk == 0 || list.size() == 0)
- {
- // nothing to read take shortcut
- return;
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature()
- .getName(), revision.getID(), revision.getVersion());
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- String sql = sqlSelectChunksPrefix + sqlOrderByIndex;
- stmt = statementCache.getPreparedStatement(sql, ReuseProbability.HIGH);
- setKeyFields(stmt, revision);
-
- if (listChunk != CDORevision.UNCHUNKED)
- {
- stmt.setMaxRows(listChunk); // optimization - don't read unneeded rows.
- }
-
- resultSet = stmt.executeQuery();
- int currentIndex = 0;
-
- while ((listChunk == CDORevision.UNCHUNKED || --listChunk >= 0) && resultSet.next())
- {
- CDOID tag = idHandler.getCDOID(resultSet, 1);
- Object value = getTypeMapping(tag).readValue(resultSet);
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Read value for index {0} from result set: {1}", list.size(), value);
- }
-
- list.set(currentIndex++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value));
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", getContainingClass().getName(),
- getFeature().getName(), revision.getID(), revision.getVersion());
- }
- }
-
- private void addFeature(CDOID tag)
- {
- EStructuralFeature modelFeature = getFeatureByTag(tag);
-
- ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature);
- String column = CDODBSchema.FEATUREMAP_VALUE + "_" + typeMapping.getDBType();
-
- tagMap.put(tag, column);
- typeMapping.setDBField(table, column);
- typeMappings.put(tag, typeMapping);
- }
-
- public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(),
- getFeature().getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion());
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = chunkReader.getAccessor().getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix);
- if (where != null)
- {
- builder.append(" AND "); //$NON-NLS-1$
- builder.append(where);
- }
-
- builder.append(sqlOrderByIndex);
-
- String sql = builder.toString();
- stmt = statementCache.getPreparedStatement(sql, ReuseProbability.LOW);
- setKeyFields(stmt, chunkReader.getRevision());
-
- resultSet = stmt.executeQuery();
-
- Chunk chunk = null;
- int chunkSize = 0;
- int chunkIndex = 0;
- int indexInChunk = 0;
-
- while (resultSet.next())
- {
- CDOID tag = idHandler.getCDOID(resultSet, 1);
- Object value = getTypeMapping(tag).readValue(resultSet);
-
- if (chunk == null)
- {
- chunk = chunks.get(chunkIndex++);
- chunkSize = chunk.size();
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(),
- chunkSize);
- }
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value);
- }
-
- chunk.add(indexInChunk++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value));
- if (indexInChunk == chunkSize)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Chunk finished");
- }
-
- chunk = null;
- indexInChunk = 0;
- }
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}", getContainingClass().getName(),
- getFeature(), chunkReader.getRevision());
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- CDOList values = revision.getList(getFeature());
-
- int idx = 0;
- for (Object element : values)
- {
- writeValue(accessor, revision, idx++, element);
- }
- }
-
- protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- if (TRACER.isEnabled())
- {
- TRACER
- .format(
- "Writing value for feature {0}.{1} index {2} of {3} : {4}", getContainingClass().getName(), getFeature(), idx, revision, value); //$NON-NLS-1$
- }
-
- try
- {
- FeatureMap.Entry entry = (FeatureMap.Entry)value;
- EStructuralFeature entryFeature = entry.getEStructuralFeature();
- CDOID tag = getTagByFeature(entryFeature, revision.getTimeStamp());
- String columnName = getColumnName(tag);
-
- stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.HIGH);
- setKeyFields(stmt, revision);
- int column = getKeyFields().length + 1;
-
- for (int i = 0; i < columnNames.size(); i++)
- {
- if (columnNames.get(i).equals(columnName))
- {
- getTypeMapping(tag).setValue(stmt, column++, entry.getValue());
- }
- else
- {
- stmt.setNull(column++, getDBTypes().get(i).getCode());
- }
- }
-
- stmt.setInt(column++, idx);
- idHandler.setCDOID(stmt, column++, tag);
- DBUtil.update(stmt, true);
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- /**
- * Get column name (lazy)
- *
- * @param tag
- * The feature's MetaID in CDO
- * @return the column name where the values are stored
- */
- protected String getColumnName(CDOID tag)
- {
- String column = tagMap.get(tag);
- if (column == null)
- {
- addFeature(tag);
- column = tagMap.get(tag);
- }
-
- return column;
- }
-
- /**
- * Get type mapping (lazy)
- *
- * @param tag
- * The feature's MetaID in CDO
- * @return the corresponding type mapping
- */
- protected ITypeMapping getTypeMapping(CDOID tag)
- {
- ITypeMapping typeMapping = typeMappings.get(tag);
- if (typeMapping == null)
- {
- addFeature(tag);
- typeMapping = typeMappings.get(tag);
- }
-
- return typeMapping;
- }
-
- /**
- * @param metaID
- * @return the column name where the values are stored
- */
- private EStructuralFeature getFeatureByTag(CDOID tag)
- {
- return (EStructuralFeature)getMappingStrategy().getStore().getMetaDataManager().getMetaInstance(tag);
- }
-
- /**
- * @param feature
- * The EStructuralFeature
- * @return The feature's MetaID in CDO
- */
- protected CDOID getTagByFeature(EStructuralFeature feature, long timeStamp)
- {
- return getMappingStrategy().getStore().getMetaDataManager().getMetaID(feature, timeStamp);
- }
-
- /**
- * Used by subclasses to indicate which fields should be in the table. I.e. just a pair of name and DBType ...
- *
- * @author Stefan Winkler
- */
- protected static class FieldInfo
- {
- private String name;
-
- private DBType dbType;
-
- public FieldInfo(String name, DBType dbType)
- {
- this.name = name;
- this.dbType = dbType;
- }
-
- public String getName()
- {
- return name;
- }
-
- public DBType getDbType()
- {
- return dbType;
- }
- }
-
- public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere,
- QueryXRefsContext context, String idString)
- {
- /*
- * must never be called (a feature map is not associated with an EReference feature, so XRefs are nor supported
- * here)
- */
- throw new ImplementationError("Should never be called!");
- }
-
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + * Christopher Albert - 254455: [DB] Support FeatureMaps bug 254455 + * Victor Roldan Betancort - Bug 283998: [DB] Chunk reading for multiple chunks fails + * Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDOList; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability; +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.CDODBSchema; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBIndex.Type; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.collection.MoveableList; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.FeatureMap; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * This abstract base class provides basic behavior needed for mapping many-valued attributes to tables. + * + * @author Eike Stepper + * @since 3.0 + */ +public abstract class AbstractFeatureMapTableMapping extends BasicAbstractListTableMapping +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractFeatureMapTableMapping.class); + + /** + * The table of this mapping. + */ + private IDBTable table; + + /** + * The tags mapped to column names + */ + private HashMap<CDOID, String> tagMap; + + /** + * Column name Set + */ + private List<String> columnNames; + + /** + * The type mappings for the value fields. + */ + private Map<CDOID, ITypeMapping> typeMappings; + + // --------- SQL strings - see initSQLStrings() ----------------- + private String sqlSelectChunksPrefix; + + private String sqlOrderByIndex; + + protected String sqlInsert; + + private List<DBType> dbTypes; + + public AbstractFeatureMapTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature) + { + super(mappingStrategy, eClass, feature); + initDBTypes(); + initTable(); + initSQLStrings(); + } + + private void initDBTypes() + { + // TODO add annotation processing here ... + ITypeMapping.Registry registry = getTypeMappingRegistry(); + dbTypes = new ArrayList<DBType>(registry.getDefaultFeatureMapDBTypes()); + } + + protected ITypeMapping.Registry getTypeMappingRegistry() + { + return ITypeMapping.Registry.INSTANCE; + } + + private void initTable() + { + IDBStore store = getMappingStrategy().getStore(); + String tableName = getMappingStrategy().getTableName(getContainingClass(), getFeature()); + table = store.getDBSchema().addTable(tableName); + + // add fields for keys (cdo_id, version, feature_id) + FieldInfo[] fields = getKeyFields(); + IDBField[] dbFields = new IDBField[fields.length]; + + for (int i = 0; i < fields.length; i++) + { + dbFields[i] = table.addField(fields[i].getName(), fields[i].getDbType()); + } + + // add field for list index + IDBField idxField = table.addField(CDODBSchema.FEATUREMAP_IDX, DBType.INTEGER); + + // add field for FeatureMap tag (MetaID for Feature in CDO registry) + IDBField tagField = table.addField(CDODBSchema.FEATUREMAP_TAG, store.getIDHandler().getDBType()); + + tagMap = new HashMap<CDOID, String>(); + typeMappings = new HashMap<CDOID, ITypeMapping>(); + columnNames = new ArrayList<String>(); + + // create columns for all DBTypes + for (DBType type : getDBTypes()) + { + String column = CDODBSchema.FEATUREMAP_VALUE + "_" + type.name(); + table.addField(column, type); + columnNames.add(column); + } + + table.addIndex(Type.NON_UNIQUE, dbFields); + table.addIndex(Type.NON_UNIQUE, idxField); + table.addIndex(Type.NON_UNIQUE, tagField); + } + + protected abstract FieldInfo[] getKeyFields(); + + protected abstract void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException; + + public Collection<IDBTable> getDBTables() + { + return Arrays.asList(table); + } + + private void initSQLStrings() + { + String tableName = getTable().getName(); + FieldInfo[] fields = getKeyFields(); + + // ---------------- SELECT to read chunks ---------------------------- + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); + + builder.append(CDODBSchema.FEATUREMAP_TAG); + builder.append(", "); + + Iterator<String> iter = columnNames.iterator(); + while (iter.hasNext()) + { + builder.append(iter.next()); + if (iter.hasNext()) + { + builder.append(", "); + } + } + + builder.append(" FROM "); + builder.append(tableName); + builder.append(" WHERE "); + + for (int i = 0; i < fields.length; i++) + { + builder.append(fields[i].getName()); + if (i + 1 < fields.length) + { + // more to come + builder.append("=? AND "); + } + else + { + // last one + builder.append("=? "); + } + } + + sqlSelectChunksPrefix = builder.toString(); + + sqlOrderByIndex = " ORDER BY " + CDODBSchema.FEATUREMAP_IDX; //$NON-NLS-1$ + + // INSERT with dynamic field name + // TODO: Better: universal INSERT-Statement, because of stmt caching! + + // ----------------- INSERT - prefix ----------------- + builder = new StringBuilder("INSERT INTO "); + builder.append(tableName); + builder.append(" ("); //$NON-NLS-1$ + for (int i = 0; i < fields.length; i++) + { + builder.append(fields[i].getName()); + builder.append(", "); //$NON-NLS-1$ + } + + for (int i = 0; i < columnNames.size(); i++) + { + builder.append(columnNames.get(i)); + builder.append(", "); //$NON-NLS-1$ + } + + builder.append(CDODBSchema.FEATUREMAP_IDX); + builder.append(", "); //$NON-NLS-1$ + builder.append(CDODBSchema.FEATUREMAP_TAG); + builder.append(") VALUES ("); //$NON-NLS-1$ + for (int i = 0; i < fields.length + columnNames.size(); i++) + { + builder.append("?, "); + } + + builder.append("?, ?)"); + sqlInsert = builder.toString(); + } + + protected List<DBType> getDBTypes() + { + return dbTypes; + } + + protected final IDBTable getTable() + { + return table; + } + + protected final List<String> getColumnNames() + { + return columnNames; + } + + protected final Map<CDOID, ITypeMapping> getTypeMappings() + { + return typeMappings; + } + + protected final Map<CDOID, String> getTagMap() + { + return tagMap; + } + + public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) + { + MoveableList<Object> list = revision.getList(getFeature()); + if (listChunk == 0 || list.size() == 0) + { + // nothing to read take shortcut + return; + } + + if (TRACER.isEnabled()) + { + TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), getFeature() + .getName(), revision.getID(), revision.getVersion()); + } + + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + try + { + String sql = sqlSelectChunksPrefix + sqlOrderByIndex; + stmt = statementCache.getPreparedStatement(sql, ReuseProbability.HIGH); + setKeyFields(stmt, revision); + + if (listChunk != CDORevision.UNCHUNKED) + { + stmt.setMaxRows(listChunk); // optimization - don't read unneeded rows. + } + + resultSet = stmt.executeQuery(); + int currentIndex = 0; + + while ((listChunk == CDORevision.UNCHUNKED || --listChunk >= 0) && resultSet.next()) + { + CDOID tag = idHandler.getCDOID(resultSet, 1); + Object value = getTypeMapping(tag).readValue(resultSet); + + if (TRACER.isEnabled()) + { + TRACER.format("Read value for index {0} from result set: {1}", list.size(), value); + } + + list.set(currentIndex++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + statementCache.releasePreparedStatement(stmt); + } + + if (TRACER.isEnabled()) + { + TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), + getFeature().getName(), revision.getID(), revision.getVersion()); + } + } + + private void addFeature(CDOID tag) + { + EStructuralFeature modelFeature = getFeatureByTag(tag); + + ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature); + String column = CDODBSchema.FEATUREMAP_VALUE + "_" + typeMapping.getDBType(); + + tagMap.put(tag, column); + typeMapping.setDBField(table, column); + typeMappings.put(tag, typeMapping); + } + + public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where) + { + if (TRACER.isEnabled()) + { + TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", getContainingClass().getName(), + getFeature().getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion()); + } + + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IPreparedStatementCache statementCache = chunkReader.getAccessor().getStatementCache(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + try + { + StringBuilder builder = new StringBuilder(sqlSelectChunksPrefix); + if (where != null) + { + builder.append(" AND "); //$NON-NLS-1$ + builder.append(where); + } + + builder.append(sqlOrderByIndex); + + String sql = builder.toString(); + stmt = statementCache.getPreparedStatement(sql, ReuseProbability.LOW); + setKeyFields(stmt, chunkReader.getRevision()); + + resultSet = stmt.executeQuery(); + + Chunk chunk = null; + int chunkSize = 0; + int chunkIndex = 0; + int indexInChunk = 0; + + while (resultSet.next()) + { + CDOID tag = idHandler.getCDOID(resultSet, 1); + Object value = getTypeMapping(tag).readValue(resultSet); + + if (chunk == null) + { + chunk = chunks.get(chunkIndex++); + chunkSize = chunk.size(); + + if (TRACER.isEnabled()) + { + TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(), + chunkSize); + } + } + + if (TRACER.isEnabled()) + { + TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value); + } + + chunk.add(indexInChunk++, CDORevisionUtil.createFeatureMapEntry(getFeatureByTag(tag), value)); + if (indexInChunk == chunkSize) + { + if (TRACER.isEnabled()) + { + TRACER.format("Chunk finished"); + } + + chunk = null; + indexInChunk = 0; + } + } + + if (TRACER.isEnabled()) + { + TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}", getContainingClass().getName(), + getFeature(), chunkReader.getRevision()); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + statementCache.releasePreparedStatement(stmt); + } + } + + public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) + { + CDOList values = revision.getList(getFeature()); + + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } + } + + protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + + if (TRACER.isEnabled()) + { + TRACER + .format( + "Writing value for feature {0}.{1} index {2} of {3} : {4}", getContainingClass().getName(), getFeature(), idx, revision, value); //$NON-NLS-1$ + } + + try + { + FeatureMap.Entry entry = (FeatureMap.Entry)value; + EStructuralFeature entryFeature = entry.getEStructuralFeature(); + CDOID tag = getTagByFeature(entryFeature, revision.getTimeStamp()); + String columnName = getColumnName(tag); + + stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.HIGH); + setKeyFields(stmt, revision); + int column = getKeyFields().length + 1; + + for (int i = 0; i < columnNames.size(); i++) + { + if (columnNames.get(i).equals(columnName)) + { + getTypeMapping(tag).setValue(stmt, column++, entry.getValue()); + } + else + { + stmt.setNull(column++, getDBTypes().get(i).getCode()); + } + } + + stmt.setInt(column++, idx); + idHandler.setCDOID(stmt, column++, tag); + DBUtil.update(stmt, true); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + statementCache.releasePreparedStatement(stmt); + } + } + + /** + * Get column name (lazy) + * + * @param tag + * The feature's MetaID in CDO + * @return the column name where the values are stored + */ + protected String getColumnName(CDOID tag) + { + String column = tagMap.get(tag); + if (column == null) + { + addFeature(tag); + column = tagMap.get(tag); + } + + return column; + } + + /** + * Get type mapping (lazy) + * + * @param tag + * The feature's MetaID in CDO + * @return the corresponding type mapping + */ + protected ITypeMapping getTypeMapping(CDOID tag) + { + ITypeMapping typeMapping = typeMappings.get(tag); + if (typeMapping == null) + { + addFeature(tag); + typeMapping = typeMappings.get(tag); + } + + return typeMapping; + } + + /** + * @param metaID + * @return the column name where the values are stored + */ + private EStructuralFeature getFeatureByTag(CDOID tag) + { + return (EStructuralFeature)getMappingStrategy().getStore().getMetaDataManager().getMetaInstance(tag); + } + + /** + * @param feature + * The EStructuralFeature + * @return The feature's MetaID in CDO + */ + protected CDOID getTagByFeature(EStructuralFeature feature, long timeStamp) + { + return getMappingStrategy().getStore().getMetaDataManager().getMetaID(feature, timeStamp); + } + + /** + * Used by subclasses to indicate which fields should be in the table. I.e. just a pair of name and DBType ... + * + * @author Stefan Winkler + */ + protected static class FieldInfo + { + private String name; + + private DBType dbType; + + public FieldInfo(String name, DBType dbType) + { + this.name = name; + this.dbType = dbType; + } + + public String getName() + { + return name; + } + + public DBType getDbType() + { + return dbType; + } + } + + public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere, + QueryXRefsContext context, String idString) + { + /* + * must never be called (a feature map is not associated with an EReference feature, so XRefs are nor supported + * here) + */ + throw new ImplementationError("Should never be called!"); + } + +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java index 370d3fee95..4662b38ff5 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 @@ -1,492 +1,492 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation;
-import org.eclipse.emf.cdo.common.id.CDOID;
-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.CDORevision;
-import org.eclipse.emf.cdo.eresource.CDOResourceNode;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.DBUtil.DeserializeRowHandler;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * * This abstract base class refines {@link AbstractMappingStrategy} by implementing aspects common to horizontal
- * mapping strategies -- namely:
- * <ul>
- * <li>object type cache (table cdo_objects)
- * <li>resource query handling
- * </ul>
- *
- * @author Eike Stepper
- * @since 2.0
- */
-public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingStrategy
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalMappingStrategy.class);
-
- /**
- * The associated object type mapper.
- */
- private IObjectTypeMapper objectTypeMapper;
-
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- return objectTypeMapper.getObjectType(accessor, id);
- }
-
- public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type)
- {
- objectTypeMapper.putObjectType(accessor, timeStamp, id, type);
- }
-
- public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection)
- {
- IDBStore store = getStore();
- if (store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE)
- {
- IIDHandler idHandler = store.getIDHandler();
-
- CDOID minLocalID = getMinLocalID(connection);
- idHandler.setNextLocalObjectID(minLocalID);
-
- CDOID maxID = objectTypeMapper.getMaxID(connection, idHandler);
- idHandler.setLastObjectID(maxID);
- }
- }
-
- public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context)
- {
- // only support timestamp in audit mode
- if (context.getTimeStamp() != CDORevision.UNSPECIFIED_DATE && !hasAuditSupport())
- {
- throw new IllegalArgumentException("Mapping Strategy does not support audits"); //$NON-NLS-1$
- }
-
- EresourcePackage resourcesPackage = EresourcePackage.eINSTANCE;
-
- // first query folders
- IClassMapping resourceFolder = getClassMapping(resourcesPackage.getCDOResourceFolder());
- boolean shallContinue = queryResources(accessor, resourceFolder, context);
-
- // not enough results? -> query resources
- if (shallContinue)
- {
- IClassMapping resource = getClassMapping(resourcesPackage.getCDOResource());
- queryResources(accessor, resource, context);
- }
- }
-
- public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context)
- {
- IIDHandler idHandler = getStore().getIDHandler();
- StringBuilder builder = null;
-
- // create a string containing "(id1,id2,...)"
- // NOTE: this might not scale infinitely, because of dbms-dependent
- // max size for SQL strings. But for now, it's the easiest way...
- for (CDOID targetID : context.getTargetObjects().keySet())
- {
- // NOTE: currently no support for external references!
- if (builder == null)
- {
- builder = new StringBuilder("(");
- }
- else
- {
- builder.append(",");
- }
-
- idHandler.appendCDOID(builder, targetID);
- }
-
- builder.append(")");
- String idString = builder.toString();
-
- for (EClass eClass : context.getSourceCandidates().keySet())
- {
- IClassMapping classMapping = getClassMapping(eClass);
- boolean more = classMapping.queryXRefs(accessor, context, idString);
- if (!more)
- {
- // cancel query (max results reached or user canceled)
- return;
- }
- }
- }
-
- public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int fromBranchID, int toBranchID,
- long fromCommitTime, long toCommitTime) throws IOException
- {
- StringBuilder builder = new StringBuilder();
- builder.append(" WHERE a_t."); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(" BETWEEN "); //$NON-NLS-1$
- builder.append(fromCommitTime);
- builder.append(" AND "); //$NON-NLS-1$
- builder.append(toCommitTime);
-
- String attrSuffix = builder.toString();
- Connection connection = accessor.getConnection();
-
- Collection<IClassMapping> classMappings = getClassMappings(true).values();
- out.writeInt(classMappings.size());
-
- for (IClassMapping classMapping : classMappings)
- {
- EClass eClass = classMapping.getEClass();
- out.writeCDOClassifierRef(eClass);
-
- IDBTable table = classMapping.getDBTables().get(0);
- DBUtil.serializeTable(out, connection, table, "a_t", attrSuffix);
-
- for (IListMapping listMapping : classMapping.getListMappings())
- {
- rawExportList(out, connection, listMapping, table, attrSuffix);
- }
- }
-
- objectTypeMapper.rawExport(connection, out, fromCommitTime, toCommitTime);
- }
-
- protected void rawExportList(CDODataOutput out, Connection connection, IListMapping listMapping, IDBTable attrTable,
- String attrSuffix) throws IOException
- {
- for (IDBTable table : listMapping.getDBTables())
- {
- String listSuffix = ", " + attrTable + " a_t" + attrSuffix;
- String listJoin = getListJoinForRawExport("a_t", "l_t");
- if (listJoin != null)
- {
- listSuffix += listJoin;
- }
-
- DBUtil.serializeTable(out, connection, table, "l_t", listSuffix);
- }
- }
-
- protected String getListJoinForRawExport(String attrTable, String listTable)
- {
- return getListJoin(attrTable, listTable);
- }
-
- public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- int size = in.readInt();
- if (size == 0)
- {
- return;
- }
-
- int objectTypeMapperWork = 10;
- monitor.begin(3 * size + objectTypeMapperWork);
-
- try
- {
- Connection connection = accessor.getConnection();
- for (int i = 0; i < size; i++)
- {
- EClass eClass = (EClass)in.readCDOClassifierRefAndResolve();
- IClassMapping classMapping = getClassMapping(eClass);
-
- IDBTable table = classMapping.getDBTables().get(0);
- DBUtil.deserializeTable(in, connection, table, monitor.fork());
- rawImportReviseOldRevisions(connection, table, monitor.fork());
- rawImportUnreviseNewRevisions(connection, table, fromCommitTime, toCommitTime, monitor.fork());
-
- List<IListMapping> listMappings = classMapping.getListMappings();
- int listSize = listMappings.size();
- if (listSize == 0)
- {
- monitor.worked();
- }
- else
- {
- OMMonitor listMonitor = monitor.fork();
- listMonitor.begin(listSize);
-
- try
- {
- for (IListMapping listMapping : listMappings)
- {
- rawImportList(in, connection, listMapping, listMonitor.fork());
- }
- }
- finally
- {
- listMonitor.done();
- }
- }
- }
-
- objectTypeMapper.rawImport(connection, in, monitor.fork(objectTypeMapperWork));
- }
- finally
- {
- monitor.done();
- }
- }
-
- protected void rawImportUnreviseNewRevisions(Connection connection, IDBTable table, long fromCommitTime,
- long toCommitTime, OMMonitor monitor)
- {
- throw new UnsupportedOperationException("Must be overridden");
- }
-
- protected void rawImportReviseOldRevisions(Connection connection, IDBTable table, OMMonitor monitor)
- {
- throw new UnsupportedOperationException("Must be overridden");
- }
-
- protected void rawImportList(CDODataInput in, Connection connection, IListMapping listMapping, OMMonitor monitor)
- throws IOException
- {
- Collection<IDBTable> tables = listMapping.getDBTables();
- int size = tables.size();
- if (size == 0)
- {
- return;
- }
-
- monitor.begin(size);
-
- try
- {
- for (IDBTable table : tables)
- {
- DBUtil.deserializeTable(in, connection, table, monitor.fork(), getImportListHandler());
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- protected DeserializeRowHandler getImportListHandler()
- {
- // Only needed with ranges
- return null;
- }
-
- public String getListJoin(String attrTable, String listTable)
- {
- return " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_ID + "=" + listTable + "." + CDODBSchema.LIST_REVISION_ID;
- }
-
- @Override
- protected boolean isMapped(EClass eClass)
- {
- return !eClass.isAbstract() && !eClass.isInterface();
- }
-
- @Override
- protected Collection<EClass> getClassesWithObjectInfo()
- {
- return getClassMappings().keySet();
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- if (objectTypeMapper == null)
- {
- objectTypeMapper = createObjectTypeMapper();
- }
-
- LifecycleUtil.activate(objectTypeMapper);
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(objectTypeMapper);
- super.doDeactivate();
- }
-
- private IObjectTypeMapper createObjectTypeMapper()
- {
- ObjectTypeTable table = new ObjectTypeTable();
- table.setMappingStrategy(this);
-
- int cacheSize = getObjectTypeCacheSize();
- if (cacheSize == 0)
- {
- return table;
- }
-
- ObjectTypeCache cache = new ObjectTypeCache(cacheSize);
- cache.setMappingStrategy(this);
- cache.setDelegate(table);
- return cache;
- }
-
- private int getObjectTypeCacheSize()
- {
- int objectTypeCacheSize = ObjectTypeCache.DEFAULT_CACHE_CAPACITY;
-
- Object value = getProperties().get(PROP_OBJECT_TYPE_CACHE_SIZE);
- if (value != null)
- {
- try
- {
- int intValue = Integer.parseInt((String)value);
- objectTypeCacheSize = intValue;
- }
- catch (NumberFormatException e)
- {
- OM.LOG.warn("Malformed configuration option for object type cache size. Using default.");
- }
- }
-
- return objectTypeCacheSize;
- }
-
- /**
- * This is an intermediate implementation. It should be changed after classmappings support a general way to implement
- * queries ...
- *
- * @param accessor
- * the accessor to use.
- * @param classMapping
- * the class mapping of a class instanceof {@link CDOResourceNode} which should be queried.
- * @param context
- * the query context containing the parameters and the result.
- * @return <code>true</code> if result context is not yet full and query should continue false, if result context is
- * full and query should stop.
- */
- private boolean queryResources(IDBStoreAccessor accessor, IClassMapping classMapping, QueryResourcesContext context)
- {
- IIDHandler idHandler = getStore().getIDHandler();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- CDOID folderID = context.getFolderID();
- String name = context.getName();
- boolean exactMatch = context.exactMatch();
-
- try
- {
- stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, context);
- resultSet = stmt.executeQuery();
-
- while (resultSet.next())
- {
- CDOID id = idHandler.getCDOID(resultSet, 1);
- if (TRACER.isEnabled())
- {
- TRACER.trace("Resource query returned ID " + id); //$NON-NLS-1$
- }
-
- if (!context.addResource(id))
- {
- // No more results allowed
- return false; // don't continue
- }
- }
-
- return true; // continue with other results
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- accessor.getStatementCache().releasePreparedStatement(stmt);
- }
- }
-
- private CDOID getMinLocalID(Connection connection)
- {
- IIDHandler idHandler = getStore().getIDHandler();
- CDOID min = idHandler.getMaxCDOID();
-
- // Do not call getClassMappings() at this point, as the package registry is not yet initialized!
- String dbName = getStore().getRepository().getName();
- List<String> names = DBUtil.getAllTableNames(connection, dbName);
-
- String prefix = "SELECT MIN(t." + CDODBSchema.ATTRIBUTES_ID + ") FROM " + dbName + "." + CDODBSchema.CDO_OBJECTS
- + " AS o, " + dbName + ".";
-
- String suffix = " AS t WHERE t." + CDODBSchema.ATTRIBUTES_BRANCH + "<0 AND t." + CDODBSchema.ATTRIBUTES_ID + "=o."
- + CDODBSchema.ATTRIBUTES_ID + " AND t." + CDODBSchema.ATTRIBUTES_CREATED + "=o."
- + CDODBSchema.ATTRIBUTES_CREATED;
-
- for (String name : names)
- {
- Statement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = connection.createStatement();
- resultSet = stmt.executeQuery(prefix + name + suffix);
-
- if (resultSet.next())
- {
- CDOID id = idHandler.getCDOID(resultSet, 1);
- if (id != null && idHandler.compare(id, min) < 0)
- {
- min = id;
- }
- }
- }
- catch (SQLException ex)
- {
- //$FALL-THROUGH$
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmt);
- }
- }
-
- return min;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - 271444: [DB] Multiple refactorings bug 271444 + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation; +import org.eclipse.emf.cdo.common.id.CDOID; +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.CDORevision; +import org.eclipse.emf.cdo.eresource.CDOResourceNode; +import org.eclipse.emf.cdo.eresource.EresourcePackage; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; +import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.DBUtil.DeserializeRowHandler; +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.ecore.EClass; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collection; +import java.util.List; + +/** + * * This abstract base class refines {@link AbstractMappingStrategy} by implementing aspects common to horizontal + * mapping strategies -- namely: + * <ul> + * <li>object type cache (table cdo_objects) + * <li>resource query handling + * </ul> + * + * @author Eike Stepper + * @since 2.0 + */ +public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingStrategy +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalMappingStrategy.class); + + /** + * The associated object type mapper. + */ + private IObjectTypeMapper objectTypeMapper; + + public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id) + { + return objectTypeMapper.getObjectType(accessor, id); + } + + public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type) + { + objectTypeMapper.putObjectType(accessor, timeStamp, id, type); + } + + public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection) + { + IDBStore store = getStore(); + if (store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE) + { + IIDHandler idHandler = store.getIDHandler(); + + CDOID minLocalID = getMinLocalID(connection); + idHandler.setNextLocalObjectID(minLocalID); + + CDOID maxID = objectTypeMapper.getMaxID(connection, idHandler); + idHandler.setLastObjectID(maxID); + } + } + + public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context) + { + // only support timestamp in audit mode + if (context.getTimeStamp() != CDORevision.UNSPECIFIED_DATE && !hasAuditSupport()) + { + throw new IllegalArgumentException("Mapping Strategy does not support audits"); //$NON-NLS-1$ + } + + EresourcePackage resourcesPackage = EresourcePackage.eINSTANCE; + + // first query folders + IClassMapping resourceFolder = getClassMapping(resourcesPackage.getCDOResourceFolder()); + boolean shallContinue = queryResources(accessor, resourceFolder, context); + + // not enough results? -> query resources + if (shallContinue) + { + IClassMapping resource = getClassMapping(resourcesPackage.getCDOResource()); + queryResources(accessor, resource, context); + } + } + + public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context) + { + IIDHandler idHandler = getStore().getIDHandler(); + StringBuilder builder = null; + + // create a string containing "(id1,id2,...)" + // NOTE: this might not scale infinitely, because of dbms-dependent + // max size for SQL strings. But for now, it's the easiest way... + for (CDOID targetID : context.getTargetObjects().keySet()) + { + // NOTE: currently no support for external references! + if (builder == null) + { + builder = new StringBuilder("("); + } + else + { + builder.append(","); + } + + idHandler.appendCDOID(builder, targetID); + } + + builder.append(")"); + String idString = builder.toString(); + + for (EClass eClass : context.getSourceCandidates().keySet()) + { + IClassMapping classMapping = getClassMapping(eClass); + boolean more = classMapping.queryXRefs(accessor, context, idString); + if (!more) + { + // cancel query (max results reached or user canceled) + return; + } + } + } + + public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int fromBranchID, int toBranchID, + long fromCommitTime, long toCommitTime) throws IOException + { + StringBuilder builder = new StringBuilder(); + builder.append(" WHERE a_t."); //$NON-NLS-1$ + builder.append(CDODBSchema.ATTRIBUTES_CREATED); + builder.append(" BETWEEN "); //$NON-NLS-1$ + builder.append(fromCommitTime); + builder.append(" AND "); //$NON-NLS-1$ + builder.append(toCommitTime); + + String attrSuffix = builder.toString(); + Connection connection = accessor.getConnection(); + + Collection<IClassMapping> classMappings = getClassMappings(true).values(); + out.writeInt(classMappings.size()); + + for (IClassMapping classMapping : classMappings) + { + EClass eClass = classMapping.getEClass(); + out.writeCDOClassifierRef(eClass); + + IDBTable table = classMapping.getDBTables().get(0); + DBUtil.serializeTable(out, connection, table, "a_t", attrSuffix); + + for (IListMapping listMapping : classMapping.getListMappings()) + { + rawExportList(out, connection, listMapping, table, attrSuffix); + } + } + + objectTypeMapper.rawExport(connection, out, fromCommitTime, toCommitTime); + } + + protected void rawExportList(CDODataOutput out, Connection connection, IListMapping listMapping, IDBTable attrTable, + String attrSuffix) throws IOException + { + for (IDBTable table : listMapping.getDBTables()) + { + String listSuffix = ", " + attrTable + " a_t" + attrSuffix; + String listJoin = getListJoinForRawExport("a_t", "l_t"); + if (listJoin != null) + { + listSuffix += listJoin; + } + + DBUtil.serializeTable(out, connection, table, "l_t", listSuffix); + } + } + + protected String getListJoinForRawExport(String attrTable, String listTable) + { + return getListJoin(attrTable, listTable); + } + + public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + int size = in.readInt(); + if (size == 0) + { + return; + } + + int objectTypeMapperWork = 10; + monitor.begin(3 * size + objectTypeMapperWork); + + try + { + Connection connection = accessor.getConnection(); + for (int i = 0; i < size; i++) + { + EClass eClass = (EClass)in.readCDOClassifierRefAndResolve(); + IClassMapping classMapping = getClassMapping(eClass); + + IDBTable table = classMapping.getDBTables().get(0); + DBUtil.deserializeTable(in, connection, table, monitor.fork()); + rawImportReviseOldRevisions(connection, table, monitor.fork()); + rawImportUnreviseNewRevisions(connection, table, fromCommitTime, toCommitTime, monitor.fork()); + + List<IListMapping> listMappings = classMapping.getListMappings(); + int listSize = listMappings.size(); + if (listSize == 0) + { + monitor.worked(); + } + else + { + OMMonitor listMonitor = monitor.fork(); + listMonitor.begin(listSize); + + try + { + for (IListMapping listMapping : listMappings) + { + rawImportList(in, connection, listMapping, listMonitor.fork()); + } + } + finally + { + listMonitor.done(); + } + } + } + + objectTypeMapper.rawImport(connection, in, monitor.fork(objectTypeMapperWork)); + } + finally + { + monitor.done(); + } + } + + protected void rawImportUnreviseNewRevisions(Connection connection, IDBTable table, long fromCommitTime, + long toCommitTime, OMMonitor monitor) + { + throw new UnsupportedOperationException("Must be overridden"); + } + + protected void rawImportReviseOldRevisions(Connection connection, IDBTable table, OMMonitor monitor) + { + throw new UnsupportedOperationException("Must be overridden"); + } + + protected void rawImportList(CDODataInput in, Connection connection, IListMapping listMapping, OMMonitor monitor) + throws IOException + { + Collection<IDBTable> tables = listMapping.getDBTables(); + int size = tables.size(); + if (size == 0) + { + return; + } + + monitor.begin(size); + + try + { + for (IDBTable table : tables) + { + DBUtil.deserializeTable(in, connection, table, monitor.fork(), getImportListHandler()); + } + } + finally + { + monitor.done(); + } + } + + protected DeserializeRowHandler getImportListHandler() + { + // Only needed with ranges + return null; + } + + public String getListJoin(String attrTable, String listTable) + { + return " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_ID + "=" + listTable + "." + CDODBSchema.LIST_REVISION_ID; + } + + @Override + protected boolean isMapped(EClass eClass) + { + return !eClass.isAbstract() && !eClass.isInterface(); + } + + @Override + protected Collection<EClass> getClassesWithObjectInfo() + { + return getClassMappings().keySet(); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + if (objectTypeMapper == null) + { + objectTypeMapper = createObjectTypeMapper(); + } + + LifecycleUtil.activate(objectTypeMapper); + } + + @Override + protected void doDeactivate() throws Exception + { + LifecycleUtil.deactivate(objectTypeMapper); + super.doDeactivate(); + } + + private IObjectTypeMapper createObjectTypeMapper() + { + ObjectTypeTable table = new ObjectTypeTable(); + table.setMappingStrategy(this); + + int cacheSize = getObjectTypeCacheSize(); + if (cacheSize == 0) + { + return table; + } + + ObjectTypeCache cache = new ObjectTypeCache(cacheSize); + cache.setMappingStrategy(this); + cache.setDelegate(table); + return cache; + } + + private int getObjectTypeCacheSize() + { + int objectTypeCacheSize = ObjectTypeCache.DEFAULT_CACHE_CAPACITY; + + Object value = getProperties().get(PROP_OBJECT_TYPE_CACHE_SIZE); + if (value != null) + { + try + { + int intValue = Integer.parseInt((String)value); + objectTypeCacheSize = intValue; + } + catch (NumberFormatException e) + { + OM.LOG.warn("Malformed configuration option for object type cache size. Using default."); + } + } + + return objectTypeCacheSize; + } + + /** + * This is an intermediate implementation. It should be changed after classmappings support a general way to implement + * queries ... + * + * @param accessor + * the accessor to use. + * @param classMapping + * the class mapping of a class instanceof {@link CDOResourceNode} which should be queried. + * @param context + * the query context containing the parameters and the result. + * @return <code>true</code> if result context is not yet full and query should continue false, if result context is + * full and query should stop. + */ + private boolean queryResources(IDBStoreAccessor accessor, IClassMapping classMapping, QueryResourcesContext context) + { + IIDHandler idHandler = getStore().getIDHandler(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + CDOID folderID = context.getFolderID(); + String name = context.getName(); + boolean exactMatch = context.exactMatch(); + + try + { + stmt = classMapping.createResourceQueryStatement(accessor, folderID, name, exactMatch, context); + resultSet = stmt.executeQuery(); + + while (resultSet.next()) + { + CDOID id = idHandler.getCDOID(resultSet, 1); + if (TRACER.isEnabled()) + { + TRACER.trace("Resource query returned ID " + id); //$NON-NLS-1$ + } + + if (!context.addResource(id)) + { + // No more results allowed + return false; // don't continue + } + } + + return true; // continue with other results + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + accessor.getStatementCache().releasePreparedStatement(stmt); + } + } + + private CDOID getMinLocalID(Connection connection) + { + IIDHandler idHandler = getStore().getIDHandler(); + CDOID min = idHandler.getMaxCDOID(); + + // Do not call getClassMappings() at this point, as the package registry is not yet initialized! + String dbName = getStore().getRepository().getName(); + List<String> names = DBUtil.getAllTableNames(connection, dbName); + + String prefix = "SELECT MIN(t." + CDODBSchema.ATTRIBUTES_ID + ") FROM " + dbName + "." + CDODBSchema.CDO_OBJECTS + + " AS o, " + dbName + "."; + + String suffix = " AS t WHERE t." + CDODBSchema.ATTRIBUTES_BRANCH + "<0 AND t." + CDODBSchema.ATTRIBUTES_ID + "=o." + + CDODBSchema.ATTRIBUTES_ID + " AND t." + CDODBSchema.ATTRIBUTES_CREATED + "=o." + + CDODBSchema.ATTRIBUTES_CREATED; + + for (String name : names) + { + Statement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = connection.createStatement(); + resultSet = stmt.executeQuery(prefix + name + suffix); + + if (resultSet.next()) + { + CDOID id = idHandler.getCDOID(resultSet, 1); + if (id != null && idHandler.compare(id, min) < 0) + { + min = id; + } + } + } + catch (SQLException ex) + { + //$FALL-THROUGH$ + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmt); + } + } + + return min; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractObjectTypeMapper.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractObjectTypeMapper.java index 0d60bb9f2d..aa4a768c9a 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractObjectTypeMapper.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractObjectTypeMapper.java @@ -1,69 +1,69 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - bug 259402
- * Stefan Winkler - redesign (prepared statements)
- * Stefan Winkler - bug 276926
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.server.db.IMetaDataManager;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper;
-
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public abstract class AbstractObjectTypeMapper extends Lifecycle implements IObjectTypeMapper
-{
- private IMappingStrategy mappingStrategy;
-
- private IMetaDataManager metaDataManager;
-
- public AbstractObjectTypeMapper()
- {
- }
-
- public IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public void setMappingStrategy(IMappingStrategy mappingStrategy)
- {
- this.mappingStrategy = mappingStrategy;
- }
-
- public IMetaDataManager getMetaDataManager()
- {
- return metaDataManager;
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkState(mappingStrategy, "mappingStrategy"); //$NON-NLS-1$
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- metaDataManager = getMappingStrategy().getStore().getMetaDataManager();
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- metaDataManager = null;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - bug 259402 + * Stefan Winkler - redesign (prepared statements) + * Stefan Winkler - bug 276926 + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.server.db.IMetaDataManager; +import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; +import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper; + +import org.eclipse.net4j.util.lifecycle.Lifecycle; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public abstract class AbstractObjectTypeMapper extends Lifecycle implements IObjectTypeMapper +{ + private IMappingStrategy mappingStrategy; + + private IMetaDataManager metaDataManager; + + public AbstractObjectTypeMapper() + { + } + + public IMappingStrategy getMappingStrategy() + { + return mappingStrategy; + } + + public void setMappingStrategy(IMappingStrategy mappingStrategy) + { + this.mappingStrategy = mappingStrategy; + } + + public IMetaDataManager getMetaDataManager() + { + return metaDataManager; + } + + @Override + protected void doBeforeActivate() throws Exception + { + super.doBeforeActivate(); + checkState(mappingStrategy, "mappingStrategy"); //$NON-NLS-1$ + } + + @Override + protected void doActivate() throws Exception + { + metaDataManager = getMappingStrategy().getStore().getMetaDataManager(); + } + + @Override + protected void doDeactivate() throws Exception + { + metaDataManager = null; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/DelegatingObjectTypeMapper.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/DelegatingObjectTypeMapper.java index ce0826761b..4d37f33999 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/DelegatingObjectTypeMapper.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/DelegatingObjectTypeMapper.java @@ -1,127 +1,127 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-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.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper;
-
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.io.IOException;
-import java.sql.Connection;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public abstract class DelegatingObjectTypeMapper extends AbstractObjectTypeMapper
-{
- private IObjectTypeMapper delegate;
-
- public DelegatingObjectTypeMapper()
- {
- }
-
- public IObjectTypeMapper getDelegate()
- {
- return delegate;
- }
-
- public void setDelegate(IObjectTypeMapper delegate)
- {
- this.delegate = delegate;
- }
-
- public CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- CDOID type = doGetObjectType(accessor, id);
- if (type != null)
- {
- EClass eClass = (EClass)getMetaDataManager().getMetaInstance(type);
- return new CDOClassifierRef(eClass);
- }
-
- return delegate.getObjectType(accessor, id);
- }
-
- public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type)
- {
- CDOID classID = getMetaDataManager().getMetaID(type, timeStamp);
- doPutObjectType(accessor, id, classID);
-
- delegate.putObjectType(accessor, timeStamp, id, type);
- }
-
- public void removeObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- doRemoveObjectType(accessor, id);
- delegate.removeObjectType(accessor, id);
- }
-
- public CDOID getMaxID(Connection connection, IIDHandler idHandler)
- {
- CDOID maxID = doGetMaxID(connection, idHandler);
- if (maxID != null)
- {
- return maxID;
- }
-
- return delegate.getMaxID(connection, idHandler);
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- delegate.rawExport(connection, out, fromCommitTime, toCommitTime);
- }
-
- public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException
- {
- delegate.rawImport(connection, in, monitor);
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkState(delegate, "delegate");
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- LifecycleUtil.activate(delegate);
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(delegate);
- super.doDeactivate();
- }
-
- protected abstract CDOID doGetObjectType(IDBStoreAccessor accessor, CDOID id);
-
- protected abstract void doPutObjectType(IDBStoreAccessor accessor, CDOID id, CDOID type);
-
- protected abstract void doRemoveObjectType(IDBStoreAccessor accessor, CDOID id);
-
- protected abstract CDOID doGetMaxID(Connection connection, IIDHandler idHandler);
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.id.CDOID; +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.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.internal.db.IObjectTypeMapper; + +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; + +import java.io.IOException; +import java.sql.Connection; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public abstract class DelegatingObjectTypeMapper extends AbstractObjectTypeMapper +{ + private IObjectTypeMapper delegate; + + public DelegatingObjectTypeMapper() + { + } + + public IObjectTypeMapper getDelegate() + { + return delegate; + } + + public void setDelegate(IObjectTypeMapper delegate) + { + this.delegate = delegate; + } + + public CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id) + { + CDOID type = doGetObjectType(accessor, id); + if (type != null) + { + EClass eClass = (EClass)getMetaDataManager().getMetaInstance(type); + return new CDOClassifierRef(eClass); + } + + return delegate.getObjectType(accessor, id); + } + + public void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type) + { + CDOID classID = getMetaDataManager().getMetaID(type, timeStamp); + doPutObjectType(accessor, id, classID); + + delegate.putObjectType(accessor, timeStamp, id, type); + } + + public void removeObjectType(IDBStoreAccessor accessor, CDOID id) + { + doRemoveObjectType(accessor, id); + delegate.removeObjectType(accessor, id); + } + + public CDOID getMaxID(Connection connection, IIDHandler idHandler) + { + CDOID maxID = doGetMaxID(connection, idHandler); + if (maxID != null) + { + return maxID; + } + + return delegate.getMaxID(connection, idHandler); + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + delegate.rawExport(connection, out, fromCommitTime, toCommitTime); + } + + public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException + { + delegate.rawImport(connection, in, monitor); + } + + @Override + protected void doBeforeActivate() throws Exception + { + super.doBeforeActivate(); + checkState(delegate, "delegate"); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + LifecycleUtil.activate(delegate); + } + + @Override + protected void doDeactivate() throws Exception + { + LifecycleUtil.deactivate(delegate); + super.doDeactivate(); + } + + protected abstract CDOID doGetObjectType(IDBStoreAccessor accessor, CDOID id); + + protected abstract void doPutObjectType(IDBStoreAccessor accessor, CDOID id, CDOID type); + + protected abstract void doRemoveObjectType(IDBStoreAccessor accessor, CDOID id); + + protected abstract CDOID doGetMaxID(Connection connection, IIDHandler idHandler); +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java index 52e1130dc8..d8f1bf8bb5 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java @@ -1,77 +1,77 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStrategy
-{
- public HorizontalAuditMappingStrategy()
- {
- }
-
- public boolean hasAuditSupport()
- {
- return true;
- }
-
- public boolean hasBranchingSupport()
- {
- return false;
- }
-
- public boolean hasDeltaSupport()
- {
- return false;
- }
-
- @Override
- public IClassMapping doCreateClassMapping(EClass eClass)
- {
- return new HorizontalAuditClassMapping(this, eClass);
- }
-
- @Override
- public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new AuditListTableMapping(this, containingClass, feature);
- }
-
- @Override
- public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new AuditFeatureMapTableMapping(this, containingClass, feature);
- }
-
- @Override
- public String getListJoin(String attrTable, String listTable)
- {
- String join = super.getListJoin(attrTable, listTable);
- return modifyListJoin(attrTable, listTable, join);
- }
-
- protected String modifyListJoin(String attrTable, String listTable, String join)
- {
- join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION;
- join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION;
- return join;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStrategy +{ + public HorizontalAuditMappingStrategy() + { + } + + public boolean hasAuditSupport() + { + return true; + } + + public boolean hasBranchingSupport() + { + return false; + } + + public boolean hasDeltaSupport() + { + return false; + } + + @Override + public IClassMapping doCreateClassMapping(EClass eClass) + { + return new HorizontalAuditClassMapping(this, eClass); + } + + @Override + public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature) + { + return new AuditListTableMapping(this, containingClass, feature); + } + + @Override + public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + return new AuditFeatureMapTableMapping(this, containingClass, feature); + } + + @Override + public String getListJoin(String attrTable, String listTable) + { + String join = super.getListJoin(attrTable, listTable); + return modifyListJoin(attrTable, listTable, join); + } + + protected String modifyListJoin(String attrTable, String listTable, String join) + { + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION; + join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION; + return join; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java index 7c3d7a1399..f57512ef66 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java @@ -1,66 +1,66 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class HorizontalAuditMappingStrategyWithRanges extends HorizontalAuditMappingStrategy
-{
- public HorizontalAuditMappingStrategyWithRanges()
- {
- }
-
- @Override
- public boolean hasDeltaSupport()
- {
- return true;
- }
-
- @Override
- public IClassMapping doCreateClassMapping(EClass eClass)
- {
- return new HorizontalAuditClassMapping(this, eClass);
- }
-
- @Override
- public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new AuditListTableMappingWithRanges(this, containingClass, feature);
- }
-
- @Override
- public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new AuditFeatureMapTableMappingWithRanges(this, containingClass, feature);
- }
-
- @Override
- protected String modifyListJoin(String attrTable, String listTable, String join)
- {
- join += " AND " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_ADDED;
- join += "<=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION;
- join += " AND (" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED;
- join += " IS NULL OR " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED;
- join += ">" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + ")";
- return join;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public class HorizontalAuditMappingStrategyWithRanges extends HorizontalAuditMappingStrategy +{ + public HorizontalAuditMappingStrategyWithRanges() + { + } + + @Override + public boolean hasDeltaSupport() + { + return true; + } + + @Override + public IClassMapping doCreateClassMapping(EClass eClass) + { + return new HorizontalAuditClassMapping(this, eClass); + } + + @Override + public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature) + { + return new AuditListTableMappingWithRanges(this, containingClass, feature); + } + + @Override + public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + return new AuditFeatureMapTableMappingWithRanges(this, containingClass, feature); + } + + @Override + protected String modifyListJoin(String attrTable, String listTable, String join) + { + join += " AND " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_ADDED; + join += "<=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION; + join += " AND (" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED; + join += " IS NULL OR " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED; + join += ">" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + ")"; + return join; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java index ac8026d72c..91944e92e3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java @@ -1,213 +1,213 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappingStrategy
-{
- public HorizontalBranchingMappingStrategy()
- {
- }
-
- public boolean hasAuditSupport()
- {
- return true;
- }
-
- public boolean hasBranchingSupport()
- {
- return true;
- }
-
- public boolean hasDeltaSupport()
- {
- return false;
- }
-
- @Override
- public IClassMapping doCreateClassMapping(EClass eClass)
- {
- return new HorizontalBranchingClassMapping(this, eClass);
- }
-
- @Override
- public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new BranchingListTableMapping(this, containingClass, feature);
- }
-
- @Override
- public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new BranchingFeatureMapTableMapping(this, containingClass, feature);
- }
-
- @Override
- public String getListJoin(String attrTable, String listTable)
- {
- String join = getListJoinBasic(attrTable, listTable);
- return modifyListJoin(attrTable, listTable, join, false);
- }
-
- @Override
- protected String getListJoinForRawExport(String attrTable, String listTable)
- {
- String join = getListJoinBasic(attrTable, listTable);
- return modifyListJoin(attrTable, listTable, join, true);
- }
-
- protected String getListJoinBasic(String attrTable, String listTable)
- {
- return super.getListJoin(attrTable, listTable);
- }
-
- protected String modifyListJoin(String attrTable, String listTable, String join, boolean forRawExport)
- {
- join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION;
- join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION;
- join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_BRANCH;
- join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH;
- return join;
- }
-
- @Override
- protected void rawImportReviseOldRevisions(Connection connection, IDBTable table, OMMonitor monitor)
- {
- String sqlUpdate = "UPDATE " + table + " SET " + CDODBSchema.ATTRIBUTES_REVISED + "=? WHERE "
- + CDODBSchema.ATTRIBUTES_ID + "=? AND " + CDODBSchema.ATTRIBUTES_BRANCH + "=? AND "
- + CDODBSchema.ATTRIBUTES_VERSION + "=?";
-
- String sqlQuery = "SELECT cdo1." + CDODBSchema.ATTRIBUTES_ID + ", cdo1." + CDODBSchema.ATTRIBUTES_BRANCH
- + ", cdo1." + CDODBSchema.ATTRIBUTES_VERSION + ", cdo2." + CDODBSchema.ATTRIBUTES_CREATED + " FROM " + table
- + " cdo1, " + table + " cdo2 WHERE cdo1." + CDODBSchema.ATTRIBUTES_ID + "=cdo2." + CDODBSchema.ATTRIBUTES_ID
- + " AND cdo1." + CDODBSchema.ATTRIBUTES_BRANCH + "=cdo2." + CDODBSchema.ATTRIBUTES_BRANCH + " AND (cdo1."
- + CDODBSchema.ATTRIBUTES_VERSION + "=cdo2." + CDODBSchema.ATTRIBUTES_VERSION + "-1 OR (cdo1."
- + CDODBSchema.ATTRIBUTES_VERSION + "+cdo2." + CDODBSchema.ATTRIBUTES_VERSION + "=-1 AND cdo1."
- + CDODBSchema.ATTRIBUTES_VERSION + ">cdo2." + CDODBSchema.ATTRIBUTES_VERSION + ")) AND cdo1."
- + CDODBSchema.ATTRIBUTES_REVISED + "=0";
-
- IIDHandler idHandler = getStore().getIDHandler();
- PreparedStatement stmtUpdate = null;
- PreparedStatement stmtQuery = null;
- ResultSet resultSet = null;
-
- try
- {
- stmtUpdate = connection.prepareStatement(sqlUpdate);
- stmtQuery = connection.prepareStatement(sqlQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
-
- resultSet = stmtQuery.executeQuery();
- int size = DBUtil.getRowCount(resultSet);
- if (size == 0)
- {
- return;
- }
-
- monitor.begin(2 * size);
- while (resultSet.next())
- {
- CDOID id = idHandler.getCDOID(resultSet, 1);
- int branch = resultSet.getInt(2);
- int version = resultSet.getInt(3);
- long revised = resultSet.getLong(4) - 1L;
-
- stmtUpdate.setLong(1, revised);
- idHandler.setCDOID(stmtUpdate, 2, id);
- stmtUpdate.setInt(3, branch);
- stmtUpdate.setInt(4, version);
- stmtUpdate.addBatch();
- monitor.worked();
- }
-
- Async async = monitor.forkAsync(size);
- try
- {
- stmtUpdate.executeBatch();
- }
- finally
- {
- async.stop();
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmtQuery);
- DBUtil.close(stmtUpdate);
- monitor.done();
- }
- }
-
- @Override
- protected void rawImportUnreviseNewRevisions(Connection connection, IDBTable table, long fromCommitTime,
- long toCommitTime, OMMonitor monitor)
- {
- String sqlUpdate = "UPDATE " + table + " SET " + CDODBSchema.ATTRIBUTES_REVISED + "=0 WHERE "
- + CDODBSchema.ATTRIBUTES_BRANCH + ">=0 AND " + CDODBSchema.ATTRIBUTES_CREATED + "<=" + toCommitTime + " AND "
- + CDODBSchema.ATTRIBUTES_REVISED + ">" + toCommitTime + " AND " + CDODBSchema.ATTRIBUTES_VERSION + ">0";
-
- PreparedStatement stmtUpdate = null;
-
- try
- {
- stmtUpdate = connection.prepareStatement(sqlUpdate);
-
- monitor.begin();
- Async async = monitor.forkAsync();
-
- try
- {
- stmtUpdate.executeUpdate();
- }
- finally
- {
- async.stop();
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(stmtUpdate);
- monitor.done();
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappingStrategy +{ + public HorizontalBranchingMappingStrategy() + { + } + + public boolean hasAuditSupport() + { + return true; + } + + public boolean hasBranchingSupport() + { + return true; + } + + public boolean hasDeltaSupport() + { + return false; + } + + @Override + public IClassMapping doCreateClassMapping(EClass eClass) + { + return new HorizontalBranchingClassMapping(this, eClass); + } + + @Override + public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature) + { + return new BranchingListTableMapping(this, containingClass, feature); + } + + @Override + public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + return new BranchingFeatureMapTableMapping(this, containingClass, feature); + } + + @Override + public String getListJoin(String attrTable, String listTable) + { + String join = getListJoinBasic(attrTable, listTable); + return modifyListJoin(attrTable, listTable, join, false); + } + + @Override + protected String getListJoinForRawExport(String attrTable, String listTable) + { + String join = getListJoinBasic(attrTable, listTable); + return modifyListJoin(attrTable, listTable, join, true); + } + + protected String getListJoinBasic(String attrTable, String listTable) + { + return super.getListJoin(attrTable, listTable); + } + + protected String modifyListJoin(String attrTable, String listTable, String join, boolean forRawExport) + { + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION; + join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION; + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_BRANCH; + join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH; + return join; + } + + @Override + protected void rawImportReviseOldRevisions(Connection connection, IDBTable table, OMMonitor monitor) + { + String sqlUpdate = "UPDATE " + table + " SET " + CDODBSchema.ATTRIBUTES_REVISED + "=? WHERE " + + CDODBSchema.ATTRIBUTES_ID + "=? AND " + CDODBSchema.ATTRIBUTES_BRANCH + "=? AND " + + CDODBSchema.ATTRIBUTES_VERSION + "=?"; + + String sqlQuery = "SELECT cdo1." + CDODBSchema.ATTRIBUTES_ID + ", cdo1." + CDODBSchema.ATTRIBUTES_BRANCH + + ", cdo1." + CDODBSchema.ATTRIBUTES_VERSION + ", cdo2." + CDODBSchema.ATTRIBUTES_CREATED + " FROM " + table + + " cdo1, " + table + " cdo2 WHERE cdo1." + CDODBSchema.ATTRIBUTES_ID + "=cdo2." + CDODBSchema.ATTRIBUTES_ID + + " AND cdo1." + CDODBSchema.ATTRIBUTES_BRANCH + "=cdo2." + CDODBSchema.ATTRIBUTES_BRANCH + " AND (cdo1." + + CDODBSchema.ATTRIBUTES_VERSION + "=cdo2." + CDODBSchema.ATTRIBUTES_VERSION + "-1 OR (cdo1." + + CDODBSchema.ATTRIBUTES_VERSION + "+cdo2." + CDODBSchema.ATTRIBUTES_VERSION + "=-1 AND cdo1." + + CDODBSchema.ATTRIBUTES_VERSION + ">cdo2." + CDODBSchema.ATTRIBUTES_VERSION + ")) AND cdo1." + + CDODBSchema.ATTRIBUTES_REVISED + "=0"; + + IIDHandler idHandler = getStore().getIDHandler(); + PreparedStatement stmtUpdate = null; + PreparedStatement stmtQuery = null; + ResultSet resultSet = null; + + try + { + stmtUpdate = connection.prepareStatement(sqlUpdate); + stmtQuery = connection.prepareStatement(sqlQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + + resultSet = stmtQuery.executeQuery(); + int size = DBUtil.getRowCount(resultSet); + if (size == 0) + { + return; + } + + monitor.begin(2 * size); + while (resultSet.next()) + { + CDOID id = idHandler.getCDOID(resultSet, 1); + int branch = resultSet.getInt(2); + int version = resultSet.getInt(3); + long revised = resultSet.getLong(4) - 1L; + + stmtUpdate.setLong(1, revised); + idHandler.setCDOID(stmtUpdate, 2, id); + stmtUpdate.setInt(3, branch); + stmtUpdate.setInt(4, version); + stmtUpdate.addBatch(); + monitor.worked(); + } + + Async async = monitor.forkAsync(size); + try + { + stmtUpdate.executeBatch(); + } + finally + { + async.stop(); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmtQuery); + DBUtil.close(stmtUpdate); + monitor.done(); + } + } + + @Override + protected void rawImportUnreviseNewRevisions(Connection connection, IDBTable table, long fromCommitTime, + long toCommitTime, OMMonitor monitor) + { + String sqlUpdate = "UPDATE " + table + " SET " + CDODBSchema.ATTRIBUTES_REVISED + "=0 WHERE " + + CDODBSchema.ATTRIBUTES_BRANCH + ">=0 AND " + CDODBSchema.ATTRIBUTES_CREATED + "<=" + toCommitTime + " AND " + + CDODBSchema.ATTRIBUTES_REVISED + ">" + toCommitTime + " AND " + CDODBSchema.ATTRIBUTES_VERSION + ">0"; + + PreparedStatement stmtUpdate = null; + + try + { + stmtUpdate = connection.prepareStatement(sqlUpdate); + + monitor.begin(); + Async async = monitor.forkAsync(); + + try + { + stmtUpdate.executeUpdate(); + } + finally + { + async.stop(); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmtUpdate); + monitor.done(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java index bfd4fee230..7310f2bea5 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategyWithRanges.java @@ -1,399 +1,399 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.DBUtil.DeserializeRowHandler;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.io.ExtendedDataInput;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class HorizontalBranchingMappingStrategyWithRanges extends HorizontalBranchingMappingStrategy
-{
- private boolean copyOnBranch;
-
- public HorizontalBranchingMappingStrategyWithRanges()
- {
- }
-
- @Override
- public boolean hasDeltaSupport()
- {
- return true;
- }
-
- public boolean shallCopyOnBranch()
- {
- return copyOnBranch;
- }
-
- @Override
- public IClassMapping doCreateClassMapping(EClass eClass)
- {
- return new HorizontalBranchingClassMapping(this, eClass);
- }
-
- @Override
- public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new BranchingListTableMappingWithRanges(this, containingClass, feature);
- }
-
- @Override
- public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new BranchingFeatureMapTableMappingWithRanges(this, containingClass, feature);
- }
-
- @Override
- protected void rawExportList(CDODataOutput out, Connection connection, IListMapping listMapping, IDBTable attrTable,
- String attrSuffix) throws IOException
- {
- super.rawExportList(out, connection, listMapping, attrTable, attrSuffix);
-
- for (IDBTable table : listMapping.getDBTables())
- {
- rawExportListPostProcess(out, connection, attrTable, attrSuffix, table);
- }
- }
-
- private void rawExportListPostProcess(CDODataOutput out, Connection connection, IDBTable attrTable,
- String attrSuffix, IDBTable table) throws IOException
- {
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT l_t.");
- builder.append(CDODBSchema.LIST_REVISION_ID);
- builder.append(", l_t.");
- builder.append(CDODBSchema.LIST_REVISION_BRANCH);
- builder.append(", l_t.");
- builder.append(CDODBSchema.LIST_REVISION_VERSION_ADDED);
- builder.append(", l_t.");
- builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED);
- builder.append(", l_t.");
- builder.append(CDODBSchema.LIST_IDX);
- builder.append(" FROM ");
- builder.append(table);
- builder.append(" l_t, ");
- builder.append(attrTable);
- builder.append(" a_t");
- builder.append(attrSuffix);
- builder.append(getListJoinForPostProcess("a_t", "l_t"));
- builder.append(" AND l_t.");
- builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED);
- builder.append(" IS NOT NULL");
- String sql = DBUtil.trace(builder.toString());
-
- IIDHandler idHandler = getStore().getIDHandler();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
- resultSet = stmt.executeQuery();
-
- // Write resultSet size for progress monitoring
- int size = DBUtil.getRowCount(resultSet);
- out.writeInt(size);
- if (size == 0)
- {
- return;
- }
-
- while (resultSet.next())
- {
- CDOID source = idHandler.getCDOID(resultSet, 1);
- int branch = resultSet.getInt(2);
- int versionAdded = resultSet.getInt(3);
- int versionRemoved = resultSet.getInt(4);
- int idx = resultSet.getInt(5);
-
- out.writeCDOID(source);
- out.writeInt(branch);
- out.writeInt(versionAdded);
- out.writeInt(versionRemoved);
- out.writeInt(idx);
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmt);
- }
- }
-
- @Override
- protected void rawImportList(CDODataInput in, Connection connection, IListMapping listMapping, OMMonitor monitor)
- throws IOException
- {
- Collection<IDBTable> tables = listMapping.getDBTables();
- int size = tables.size();
- if (size == 0)
- {
- return;
- }
-
- monitor.begin(2 * size);
-
- try
- {
- super.rawImportList(in, connection, listMapping, monitor.fork(size));
-
- for (IDBTable table : tables)
- {
- rawImportListPostProcess(in, connection, table, monitor.fork());
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void rawImportListPostProcess(CDODataInput in, Connection connection, IDBTable table, OMMonitor monitor)
- throws IOException
- {
- int size = in.readInt();
- if (size == 0)
- {
- return;
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("UPDATE "); //$NON-NLS-1$
- builder.append(table);
- builder.append(" SET "); //$NON-NLS-1$
- builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED);
- builder.append("=? WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.LIST_REVISION_ID);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.LIST_REVISION_BRANCH);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.LIST_REVISION_VERSION_ADDED);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.LIST_IDX);
- builder.append("=?"); //$NON-NLS-1$
- String sql = DBUtil.trace(builder.toString());
-
- IIDHandler idHandler = getStore().getIDHandler();
- PreparedStatement stmt = null;
-
- monitor.begin(1 + 2 * size);
-
- try
- {
- stmt = connection.prepareStatement(sql);
- monitor.worked();
-
- for (int row = 0; row < size; row++)
- {
- CDOID source = in.readCDOID();
- int branch = in.readInt();
- int versionAdded = in.readInt();
- int versionRemoved = in.readInt();
- int idx = in.readInt();
-
- stmt.setInt(1, versionRemoved);
- idHandler.setCDOID(stmt, 2, source);
- stmt.setInt(3, branch);
- stmt.setInt(4, versionAdded);
- stmt.setInt(5, idx);
-
- stmt.addBatch();
- monitor.worked();
- }
-
- Async async = monitor.forkAsync(size);
-
- try
- {
- stmt.executeBatch();
- }
- finally
- {
- async.stop();
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(stmt);
- monitor.done();
- }
- }
-
- protected String getListJoinForPostProcess(String attrTable, String listTable)
- {
- String join = getListJoinBasic(attrTable, listTable);
- return modifyListJoin2(attrTable, listTable, join, true, true);
- }
-
- @Override
- protected String modifyListJoin(String attrTable, String listTable, String join, boolean forRawExport)
- {
- return modifyListJoin2(attrTable, listTable, join, forRawExport, false);
- }
-
- private String modifyListJoin2(String attrTable, String listTable, String join, boolean forRawExport,
- boolean forPostProcess)
- {
- join += " AND " + listTable + ".";
-
- if (forRawExport)
- {
- if (forPostProcess)
- {
- join += CDODBSchema.LIST_REVISION_VERSION_REMOVED;
- }
- else
- {
- join += CDODBSchema.LIST_REVISION_VERSION_ADDED;
- }
-
- join += "=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION;
- }
- else
- {
- join += CDODBSchema.LIST_REVISION_VERSION_ADDED;
- join += "<=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION;
- join += " AND (" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED;
- join += " IS NULL OR " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED;
- join += ">" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + ")";
- }
-
- join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_BRANCH;
- join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH;
-
- if (forRawExport && !forPostProcess)
- {
- join += " ORDER BY " + listTable + "." + CDODBSchema.LIST_REVISION_ID;
- join += ", " + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH;
- join += ", " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_ADDED;
- join += ", " + listTable + "." + CDODBSchema.LIST_IDX;
- }
-
- return join;
- }
-
- @Override
- protected DeserializeRowHandler getImportListHandler()
- {
- return new ImportListHandler();
- }
-
- @Override
- protected void doAfterActivate() throws Exception
- {
- super.doAfterActivate();
-
- String value = getProperties().get(CDODBUtil.PROP_COPY_ON_BRANCH);
- copyOnBranch = value == null ? false : Boolean.valueOf(value);
- }
-
- /**
- * @author Eike Stepper
- */
- private final class ImportListHandler implements DeserializeRowHandler
- {
- private final IIDHandler idHandler = getStore().getIDHandler();
-
- private PreparedStatement stmt;
-
- public void handleRow(ExtendedDataInput in, Connection connection, IDBField[] fields, Object[] values)
- throws SQLException, IOException
- {
- int versionAdded = (Integer)values[2];
- if (versionAdded == CDOBranchVersion.FIRST_VERSION)
- {
- return;
- }
-
- if (stmt == null)
- {
- String sql = "UPDATE " + fields[0].getTable() //
- + " SET " + CDODBSchema.LIST_REVISION_VERSION_REMOVED + "=?" //
- + " WHERE " + CDODBSchema.LIST_REVISION_ID + "=?" //
- + " AND " + CDODBSchema.LIST_REVISION_BRANCH + "=?" //
- + " AND " + CDODBSchema.LIST_IDX + "=?" //
- + " AND " + CDODBSchema.LIST_REVISION_VERSION_ADDED + "<?" //
- + " AND " + CDODBSchema.LIST_REVISION_VERSION_REMOVED + " IS NULL";
- stmt = connection.prepareStatement(sql);
- }
-
- Object sourceID = values[0];
- int branch = (Integer)values[1];
- int index = (Integer)values[4];
-
- stmt.setInt(1, versionAdded);
- idHandler.setCDOIDRaw(stmt, 2, sourceID);
- stmt.setInt(3, branch);
- stmt.setInt(4, index);
- stmt.setInt(5, versionAdded);
-
- stmt.addBatch();
- }
-
- public void done(boolean successful) throws SQLException, IOException
- {
- if (stmt != null)
- {
- try
- {
- if (successful)
- {
- stmt.executeBatch();
- }
- }
- finally
- {
- DBUtil.close(stmt);
- stmt = null;
- }
- }
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.server.db.CDODBUtil; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.DBUtil.DeserializeRowHandler; +import org.eclipse.net4j.db.ddl.IDBField; +import org.eclipse.net4j.db.ddl.IDBTable; +import org.eclipse.net4j.util.io.ExtendedDataInput; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public class HorizontalBranchingMappingStrategyWithRanges extends HorizontalBranchingMappingStrategy +{ + private boolean copyOnBranch; + + public HorizontalBranchingMappingStrategyWithRanges() + { + } + + @Override + public boolean hasDeltaSupport() + { + return true; + } + + public boolean shallCopyOnBranch() + { + return copyOnBranch; + } + + @Override + public IClassMapping doCreateClassMapping(EClass eClass) + { + return new HorizontalBranchingClassMapping(this, eClass); + } + + @Override + public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature) + { + return new BranchingListTableMappingWithRanges(this, containingClass, feature); + } + + @Override + public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + return new BranchingFeatureMapTableMappingWithRanges(this, containingClass, feature); + } + + @Override + protected void rawExportList(CDODataOutput out, Connection connection, IListMapping listMapping, IDBTable attrTable, + String attrSuffix) throws IOException + { + super.rawExportList(out, connection, listMapping, attrTable, attrSuffix); + + for (IDBTable table : listMapping.getDBTables()) + { + rawExportListPostProcess(out, connection, attrTable, attrSuffix, table); + } + } + + private void rawExportListPostProcess(CDODataOutput out, Connection connection, IDBTable attrTable, + String attrSuffix, IDBTable table) throws IOException + { + StringBuilder builder = new StringBuilder(); + builder.append("SELECT l_t."); + builder.append(CDODBSchema.LIST_REVISION_ID); + builder.append(", l_t."); + builder.append(CDODBSchema.LIST_REVISION_BRANCH); + builder.append(", l_t."); + builder.append(CDODBSchema.LIST_REVISION_VERSION_ADDED); + builder.append(", l_t."); + builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED); + builder.append(", l_t."); + builder.append(CDODBSchema.LIST_IDX); + builder.append(" FROM "); + builder.append(table); + builder.append(" l_t, "); + builder.append(attrTable); + builder.append(" a_t"); + builder.append(attrSuffix); + builder.append(getListJoinForPostProcess("a_t", "l_t")); + builder.append(" AND l_t."); + builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED); + builder.append(" IS NOT NULL"); + String sql = DBUtil.trace(builder.toString()); + + IIDHandler idHandler = getStore().getIDHandler(); + PreparedStatement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + resultSet = stmt.executeQuery(); + + // Write resultSet size for progress monitoring + int size = DBUtil.getRowCount(resultSet); + out.writeInt(size); + if (size == 0) + { + return; + } + + while (resultSet.next()) + { + CDOID source = idHandler.getCDOID(resultSet, 1); + int branch = resultSet.getInt(2); + int versionAdded = resultSet.getInt(3); + int versionRemoved = resultSet.getInt(4); + int idx = resultSet.getInt(5); + + out.writeCDOID(source); + out.writeInt(branch); + out.writeInt(versionAdded); + out.writeInt(versionRemoved); + out.writeInt(idx); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmt); + } + } + + @Override + protected void rawImportList(CDODataInput in, Connection connection, IListMapping listMapping, OMMonitor monitor) + throws IOException + { + Collection<IDBTable> tables = listMapping.getDBTables(); + int size = tables.size(); + if (size == 0) + { + return; + } + + monitor.begin(2 * size); + + try + { + super.rawImportList(in, connection, listMapping, monitor.fork(size)); + + for (IDBTable table : tables) + { + rawImportListPostProcess(in, connection, table, monitor.fork()); + } + } + finally + { + monitor.done(); + } + } + + private void rawImportListPostProcess(CDODataInput in, Connection connection, IDBTable table, OMMonitor monitor) + throws IOException + { + int size = in.readInt(); + if (size == 0) + { + return; + } + + StringBuilder builder = new StringBuilder(); + builder.append("UPDATE "); //$NON-NLS-1$ + builder.append(table); + builder.append(" SET "); //$NON-NLS-1$ + builder.append(CDODBSchema.LIST_REVISION_VERSION_REMOVED); + builder.append("=? WHERE "); //$NON-NLS-1$ + builder.append(CDODBSchema.LIST_REVISION_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(CDODBSchema.LIST_REVISION_BRANCH); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(CDODBSchema.LIST_REVISION_VERSION_ADDED); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(CDODBSchema.LIST_IDX); + builder.append("=?"); //$NON-NLS-1$ + String sql = DBUtil.trace(builder.toString()); + + IIDHandler idHandler = getStore().getIDHandler(); + PreparedStatement stmt = null; + + monitor.begin(1 + 2 * size); + + try + { + stmt = connection.prepareStatement(sql); + monitor.worked(); + + for (int row = 0; row < size; row++) + { + CDOID source = in.readCDOID(); + int branch = in.readInt(); + int versionAdded = in.readInt(); + int versionRemoved = in.readInt(); + int idx = in.readInt(); + + stmt.setInt(1, versionRemoved); + idHandler.setCDOID(stmt, 2, source); + stmt.setInt(3, branch); + stmt.setInt(4, versionAdded); + stmt.setInt(5, idx); + + stmt.addBatch(); + monitor.worked(); + } + + Async async = monitor.forkAsync(size); + + try + { + stmt.executeBatch(); + } + finally + { + async.stop(); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + monitor.done(); + } + } + + protected String getListJoinForPostProcess(String attrTable, String listTable) + { + String join = getListJoinBasic(attrTable, listTable); + return modifyListJoin2(attrTable, listTable, join, true, true); + } + + @Override + protected String modifyListJoin(String attrTable, String listTable, String join, boolean forRawExport) + { + return modifyListJoin2(attrTable, listTable, join, forRawExport, false); + } + + private String modifyListJoin2(String attrTable, String listTable, String join, boolean forRawExport, + boolean forPostProcess) + { + join += " AND " + listTable + "."; + + if (forRawExport) + { + if (forPostProcess) + { + join += CDODBSchema.LIST_REVISION_VERSION_REMOVED; + } + else + { + join += CDODBSchema.LIST_REVISION_VERSION_ADDED; + } + + join += "=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION; + } + else + { + join += CDODBSchema.LIST_REVISION_VERSION_ADDED; + join += "<=" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION; + join += " AND (" + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED; + join += " IS NULL OR " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_REMOVED; + join += ">" + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + ")"; + } + + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_BRANCH; + join += "=" + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH; + + if (forRawExport && !forPostProcess) + { + join += " ORDER BY " + listTable + "." + CDODBSchema.LIST_REVISION_ID; + join += ", " + listTable + "." + CDODBSchema.LIST_REVISION_BRANCH; + join += ", " + listTable + "." + CDODBSchema.LIST_REVISION_VERSION_ADDED; + join += ", " + listTable + "." + CDODBSchema.LIST_IDX; + } + + return join; + } + + @Override + protected DeserializeRowHandler getImportListHandler() + { + return new ImportListHandler(); + } + + @Override + protected void doAfterActivate() throws Exception + { + super.doAfterActivate(); + + String value = getProperties().get(CDODBUtil.PROP_COPY_ON_BRANCH); + copyOnBranch = value == null ? false : Boolean.valueOf(value); + } + + /** + * @author Eike Stepper + */ + private final class ImportListHandler implements DeserializeRowHandler + { + private final IIDHandler idHandler = getStore().getIDHandler(); + + private PreparedStatement stmt; + + public void handleRow(ExtendedDataInput in, Connection connection, IDBField[] fields, Object[] values) + throws SQLException, IOException + { + int versionAdded = (Integer)values[2]; + if (versionAdded == CDOBranchVersion.FIRST_VERSION) + { + return; + } + + if (stmt == null) + { + String sql = "UPDATE " + fields[0].getTable() // + + " SET " + CDODBSchema.LIST_REVISION_VERSION_REMOVED + "=?" // + + " WHERE " + CDODBSchema.LIST_REVISION_ID + "=?" // + + " AND " + CDODBSchema.LIST_REVISION_BRANCH + "=?" // + + " AND " + CDODBSchema.LIST_IDX + "=?" // + + " AND " + CDODBSchema.LIST_REVISION_VERSION_ADDED + "<?" // + + " AND " + CDODBSchema.LIST_REVISION_VERSION_REMOVED + " IS NULL"; + stmt = connection.prepareStatement(sql); + } + + Object sourceID = values[0]; + int branch = (Integer)values[1]; + int index = (Integer)values[4]; + + stmt.setInt(1, versionAdded); + idHandler.setCDOIDRaw(stmt, 2, sourceID); + stmt.setInt(3, branch); + stmt.setInt(4, index); + stmt.setInt(5, versionAdded); + + stmt.addBatch(); + } + + public void done(boolean successful) throws SQLException, IOException + { + if (stmt != null) + { + try + { + if (successful) + { + stmt.executeBatch(); + } + } + finally + { + DBUtil.close(stmt); + stmt = null; + } + } + } + } +} 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 3c5f966124..3dc66f9057 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 @@ -1,272 +1,272 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.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.IStoreAccessor.QueryResourcesContext;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-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.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.util.collection.CloseableIterator;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.ENamedElement;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class HorizontalMappingStrategy extends Lifecycle implements IMappingStrategy
-{
- private Map<String, String> properties;
-
- private IDBStore store;
-
- private IMappingStrategy delegate;
-
- public HorizontalMappingStrategy()
- {
- }
-
- public IMappingStrategy getDelegate()
- {
- return delegate;
- }
-
- public Map<String, String> getProperties()
- {
- if (delegate != null)
- {
- return delegate.getProperties();
- }
-
- if (properties != null)
- {
- return properties;
- }
-
- return new HashMap<String, String>();
- }
-
- public void setProperties(Map<String, String> properties)
- {
- if (delegate != null)
- {
- delegate.setProperties(properties);
- }
- else
- {
- this.properties = properties;
- }
- }
-
- public IDBStore getStore()
- {
- if (delegate != null)
- {
- return delegate.getStore();
- }
-
- return store;
- }
-
- public void setStore(IDBStore store)
- {
- if (delegate != null)
- {
- delegate.setStore(store);
- }
- else
- {
- this.store = store;
- }
- }
-
- public ITypeMapping createValueMapping(EStructuralFeature feature)
- {
- return delegate.createValueMapping(feature);
- }
-
- public IListMapping createListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return delegate.createListMapping(containingClass, feature);
- }
-
- public String getTableName(ENamedElement element)
- {
- return delegate.getTableName(element);
- }
-
- public String getTableName(EClass containingClass, EStructuralFeature feature)
- {
- return delegate.getTableName(containingClass, feature);
- }
-
- public String getFieldName(EStructuralFeature feature)
- {
- return delegate.getFieldName(feature);
- }
-
- public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
- {
- delegate.createMapping(connection, packageUnits, monitor);
- }
-
- public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits)
- {
- delegate.removeMapping(connection, packageUnits);
- }
-
- public IClassMapping getClassMapping(EClass eClass)
- {
- return delegate.getClassMapping(eClass);
- }
-
- public Map<EClass, IClassMapping> getClassMappings()
- {
- return delegate.getClassMappings();
- }
-
- public Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand)
- {
- return delegate.getClassMappings(createOnDemand);
- }
-
- public boolean hasDeltaSupport()
- {
- return delegate.hasDeltaSupport();
- }
-
- public boolean hasAuditSupport()
- {
- return delegate.hasAuditSupport();
- }
-
- public boolean hasBranchingSupport()
- {
- return delegate.hasBranchingSupport();
- }
-
- public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context)
- {
- delegate.queryResources(accessor, context);
- }
-
- public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context)
- {
- delegate.queryXRefs(accessor, context);
- }
-
- public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- return delegate.readObjectType(accessor, id);
- }
-
- public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor)
- {
- return delegate.readObjectIDs(accessor);
- }
-
- public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection)
- {
- delegate.repairAfterCrash(dbAdapter, connection);
- }
-
- public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp,
- boolean exactTime, CDORevisionHandler handler)
- {
- delegate.handleRevisions(accessor, eClass, branch, timeStamp, exactTime, handler);
- }
-
- public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments)
- {
- return delegate.readChangeSet(accessor, monitor, segments);
- }
-
- public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int lastReplicatedBranchID, int lastBranchID,
- long lastReplicatedCommitTime, long lastCommitTime) throws IOException
- {
- delegate.rawExport(accessor, out, lastReplicatedBranchID, lastBranchID, lastReplicatedCommitTime, lastCommitTime);
- }
-
- public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime,
- OMMonitor monitor) throws IOException
- {
- delegate.rawImport(accessor, in, fromCommitTime, toCommitTime, monitor);
- }
-
- public String getListJoin(String attrTable, String listTable)
- {
- return delegate.getListJoin(attrTable, listTable);
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- boolean auditing = getBooleanProperty(Props.SUPPORTING_AUDITS);
- boolean branching = getBooleanProperty(Props.SUPPORTING_BRANCHES);
-
- boolean withRanges = false;
- if (auditing || branching)
- {
- withRanges = getBooleanProperty(CDODBUtil.PROP_WITH_RANGES);
- }
-
- delegate = CDODBUtil.createHorizontalMappingStrategy(auditing, branching, withRanges);
- delegate.setStore(store);
- delegate.setProperties(properties);
- LifecycleUtil.activate(delegate);
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(delegate);
- super.doDeactivate();
- }
-
- private boolean getBooleanProperty(String prop)
- {
- String valueAudits = properties.get(prop);
- if (valueAudits != null)
- {
- return Boolean.valueOf(valueAudits);
- }
-
- return false;
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.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.IStoreAccessor.QueryResourcesContext; +import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext; +import org.eclipse.emf.cdo.server.db.CDODBUtil; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +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.spi.common.commit.CDOChangeSetSegment; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; + +import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.util.collection.CloseableIterator; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.io.IOException; +import java.sql.Connection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public class HorizontalMappingStrategy extends Lifecycle implements IMappingStrategy +{ + private Map<String, String> properties; + + private IDBStore store; + + private IMappingStrategy delegate; + + public HorizontalMappingStrategy() + { + } + + public IMappingStrategy getDelegate() + { + return delegate; + } + + public Map<String, String> getProperties() + { + if (delegate != null) + { + return delegate.getProperties(); + } + + if (properties != null) + { + return properties; + } + + return new HashMap<String, String>(); + } + + public void setProperties(Map<String, String> properties) + { + if (delegate != null) + { + delegate.setProperties(properties); + } + else + { + this.properties = properties; + } + } + + public IDBStore getStore() + { + if (delegate != null) + { + return delegate.getStore(); + } + + return store; + } + + public void setStore(IDBStore store) + { + if (delegate != null) + { + delegate.setStore(store); + } + else + { + this.store = store; + } + } + + public ITypeMapping createValueMapping(EStructuralFeature feature) + { + return delegate.createValueMapping(feature); + } + + public IListMapping createListMapping(EClass containingClass, EStructuralFeature feature) + { + return delegate.createListMapping(containingClass, feature); + } + + public String getTableName(ENamedElement element) + { + return delegate.getTableName(element); + } + + public String getTableName(EClass containingClass, EStructuralFeature feature) + { + return delegate.getTableName(containingClass, feature); + } + + public String getFieldName(EStructuralFeature feature) + { + return delegate.getFieldName(feature); + } + + public void createMapping(Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) + { + delegate.createMapping(connection, packageUnits, monitor); + } + + public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits) + { + delegate.removeMapping(connection, packageUnits); + } + + public IClassMapping getClassMapping(EClass eClass) + { + return delegate.getClassMapping(eClass); + } + + public Map<EClass, IClassMapping> getClassMappings() + { + return delegate.getClassMappings(); + } + + public Map<EClass, IClassMapping> getClassMappings(boolean createOnDemand) + { + return delegate.getClassMappings(createOnDemand); + } + + public boolean hasDeltaSupport() + { + return delegate.hasDeltaSupport(); + } + + public boolean hasAuditSupport() + { + return delegate.hasAuditSupport(); + } + + public boolean hasBranchingSupport() + { + return delegate.hasBranchingSupport(); + } + + public void queryResources(IDBStoreAccessor accessor, QueryResourcesContext context) + { + delegate.queryResources(accessor, context); + } + + public void queryXRefs(IDBStoreAccessor accessor, QueryXRefsContext context) + { + delegate.queryXRefs(accessor, context); + } + + public CDOClassifierRef readObjectType(IDBStoreAccessor accessor, CDOID id) + { + return delegate.readObjectType(accessor, id); + } + + public CloseableIterator<CDOID> readObjectIDs(IDBStoreAccessor accessor) + { + return delegate.readObjectIDs(accessor); + } + + public void repairAfterCrash(IDBAdapter dbAdapter, Connection connection) + { + delegate.repairAfterCrash(dbAdapter, connection); + } + + public void handleRevisions(IDBStoreAccessor accessor, EClass eClass, CDOBranch branch, long timeStamp, + boolean exactTime, CDORevisionHandler handler) + { + delegate.handleRevisions(accessor, eClass, branch, timeStamp, exactTime, handler); + } + + public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments) + { + return delegate.readChangeSet(accessor, monitor, segments); + } + + public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, int lastReplicatedBranchID, int lastBranchID, + long lastReplicatedCommitTime, long lastCommitTime) throws IOException + { + delegate.rawExport(accessor, out, lastReplicatedBranchID, lastBranchID, lastReplicatedCommitTime, lastCommitTime); + } + + public void rawImport(IDBStoreAccessor accessor, CDODataInput in, long fromCommitTime, long toCommitTime, + OMMonitor monitor) throws IOException + { + delegate.rawImport(accessor, in, fromCommitTime, toCommitTime, monitor); + } + + public String getListJoin(String attrTable, String listTable) + { + return delegate.getListJoin(attrTable, listTable); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + + boolean auditing = getBooleanProperty(Props.SUPPORTING_AUDITS); + boolean branching = getBooleanProperty(Props.SUPPORTING_BRANCHES); + + boolean withRanges = false; + if (auditing || branching) + { + withRanges = getBooleanProperty(CDODBUtil.PROP_WITH_RANGES); + } + + delegate = CDODBUtil.createHorizontalMappingStrategy(auditing, branching, withRanges); + delegate.setStore(store); + delegate.setProperties(properties); + LifecycleUtil.activate(delegate); + } + + @Override + protected void doDeactivate() throws Exception + { + LifecycleUtil.deactivate(delegate); + super.doDeactivate(); + } + + private boolean getBooleanProperty(String prop) + { + String valueAudits = properties.get(prop); + if (valueAudits != null) + { + return Boolean.valueOf(valueAudits); + } + + return false; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java index 1531da0f10..7f6d87b1e3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java @@ -1,79 +1,79 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMappingStrategy
-{
- private boolean forceZeroBasedIndex;
-
- public HorizontalNonAuditMappingStrategy()
- {
- }
-
- public boolean hasAuditSupport()
- {
- return false;
- }
-
- public boolean hasBranchingSupport()
- {
- return false;
- }
-
- public boolean hasDeltaSupport()
- {
- return true;
- }
-
- public boolean shallForceZeroBasedIndex()
- {
- return forceZeroBasedIndex;
- }
-
- @Override
- public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new NonAuditListTableMapping(this, containingClass, feature);
- }
-
- @Override
- public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
- {
- return new NonAuditFeatureMapTableMapping(this, containingClass, feature);
- }
-
- @Override
- protected IClassMapping doCreateClassMapping(EClass eClass)
- {
- return new HorizontalNonAuditClassMapping(this, eClass);
- }
-
- @Override
- protected void doAfterActivate() throws Exception
- {
- super.doAfterActivate();
-
- String value = getProperties().get(CDODBUtil.PROP_ZEROBASED_INDEX);
- forceZeroBasedIndex = value == null ? false : Boolean.valueOf(value);
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - major refactoring + */ +package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.server.db.CDODBUtil; +import org.eclipse.emf.cdo.server.db.mapping.IClassMapping; +import org.eclipse.emf.cdo.server.db.mapping.IListMapping; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMappingStrategy +{ + private boolean forceZeroBasedIndex; + + public HorizontalNonAuditMappingStrategy() + { + } + + public boolean hasAuditSupport() + { + return false; + } + + public boolean hasBranchingSupport() + { + return false; + } + + public boolean hasDeltaSupport() + { + return true; + } + + public boolean shallForceZeroBasedIndex() + { + return forceZeroBasedIndex; + } + + @Override + public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature) + { + return new NonAuditListTableMapping(this, containingClass, feature); + } + + @Override + public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature) + { + return new NonAuditFeatureMapTableMapping(this, containingClass, feature); + } + + @Override + protected IClassMapping doCreateClassMapping(EClass eClass) + { + return new HorizontalNonAuditClassMapping(this, eClass); + } + + @Override + protected void doAfterActivate() throws Exception + { + super.doAfterActivate(); + + String value = getProperties().get(CDODBUtil.PROP_ZEROBASED_INDEX); + forceZeroBasedIndex = value == null ? false : Boolean.valueOf(value); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java index e039ccbb7b..8653aa1f91 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeCache.java @@ -1,98 +1,98 @@ -/*
- * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-
-import java.sql.Connection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public class ObjectTypeCache extends DelegatingObjectTypeMapper
-{
- public static final int DEFAULT_CACHE_CAPACITY = 100000;
-
- private Map<CDOID, CDOID> memoryCache;
-
- private int cacheSize;
-
- public ObjectTypeCache(int cacheSize)
- {
- this.cacheSize = cacheSize;
- }
-
- @Override
- protected CDOID doGetObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- return memoryCache.get(id);
- }
-
- @Override
- protected void doPutObjectType(IDBStoreAccessor accessor, CDOID id, CDOID type)
- {
- memoryCache.put(id, type);
- }
-
- @Override
- protected void doRemoveObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- memoryCache.remove(id);
- }
-
- @Override
- protected CDOID doGetMaxID(Connection connection, IIDHandler idHandler)
- {
- return null;
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- memoryCache = Collections.synchronizedMap(new MemoryCache(cacheSize));
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- memoryCache = null;
- super.doDeactivate();
- }
-
- /**
- * @author Stefan Winkler
- */
- private static final class MemoryCache extends LinkedHashMap<CDOID, CDOID>
- {
- private static final long serialVersionUID = 1L;
-
- private int capacity;
-
- public MemoryCache(int capacity)
- {
- super(capacity, 0.75f, true);
- this.capacity = capacity;
- }
-
- @Override
- protected boolean removeEldestEntry(java.util.Map.Entry<CDOID, CDOID> eldest)
- {
- return size() > capacity;
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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.server.internal.db.mapping.horizontal; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; + +import java.sql.Connection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public class ObjectTypeCache extends DelegatingObjectTypeMapper +{ + public static final int DEFAULT_CACHE_CAPACITY = 100000; + + private Map<CDOID, CDOID> memoryCache; + + private int cacheSize; + + public ObjectTypeCache(int cacheSize) + { + this.cacheSize = cacheSize; + } + + @Override + protected CDOID doGetObjectType(IDBStoreAccessor accessor, CDOID id) + { + return memoryCache.get(id); + } + + @Override + protected void doPutObjectType(IDBStoreAccessor accessor, CDOID id, CDOID type) + { + memoryCache.put(id, type); + } + + @Override + protected void doRemoveObjectType(IDBStoreAccessor accessor, CDOID id) + { + memoryCache.remove(id); + } + + @Override + protected CDOID doGetMaxID(Connection connection, IIDHandler idHandler) + { + return null; + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + memoryCache = Collections.synchronizedMap(new MemoryCache(cacheSize)); + } + + @Override + protected void doDeactivate() throws Exception + { + memoryCache = null; + super.doDeactivate(); + } + + /** + * @author Stefan Winkler + */ + private static final class MemoryCache extends LinkedHashMap<CDOID, CDOID> + { + private static final long serialVersionUID = 1L; + + private int capacity; + + public MemoryCache(int capacity) + { + super(capacity, 0.75f, true); + this.capacity = capacity; + } + + @Override + protected boolean removeEldestEntry(java.util.Map.Entry<CDOID, CDOID> eldest) + { + return size() > capacity; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java index 174bc8ec55..f087120de1 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java @@ -1,256 +1,256 @@ -/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - bug 259402
- * Stefan Winkler - redesign (prepared statements)
- * Stefan Winkler - bug 276926
- */
-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.CDOClassifierRef;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.server.db.IDBStore;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBAdapter;
-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.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public class ObjectTypeTable extends AbstractObjectTypeMapper
-{
- private IDBTable table;
-
- private IDBField idField;
-
- private IDBField typeField;
-
- private IDBField timeField;
-
- private String sqlDelete;
-
- private String sqlInsert;
-
- private String sqlSelect;
-
- public ObjectTypeTable()
- {
- }
-
- public final CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlSelect, ReuseProbability.MAX);
- idHandler.setCDOID(stmt, 1, id);
- DBUtil.trace(stmt.toString());
- ResultSet resultSet = stmt.executeQuery();
-
- if (!resultSet.next())
- {
- DBUtil.trace("ClassID for CDOID " + id + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
- return null;
- }
-
- CDOID classID = idHandler.getCDOID(resultSet, 1);
- EClass eClass = (EClass)getMetaDataManager().getMetaInstance(classID);
- return new CDOClassifierRef(eClass);
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public final void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type)
- {
- IDBStore store = getMappingStrategy().getStore();
- IIDHandler idHandler = store.getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.MAX);
- idHandler.setCDOID(stmt, 1, id);
- idHandler.setCDOID(stmt, 2, getMetaDataManager().getMetaID(type, timeStamp));
- stmt.setLong(3, timeStamp);
- DBUtil.trace(stmt.toString());
- int result = stmt.executeUpdate();
-
- if (result != 1)
- {
- throw new DBException("Object type could not be inserted: " + id); //$NON-NLS-1$
- }
- }
- catch (SQLException ex)
- {
- // Unique key violation can occur in rare cases (merging new objects from other branches)
- if (!store.getDBAdapter().isDuplicateKeyException(ex))
- {
- throw new DBException(ex);
- }
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public final void removeObjectType(IDBStoreAccessor accessor, CDOID id)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlDelete, ReuseProbability.MAX);
- idHandler.setCDOID(stmt, 1, id);
- DBUtil.trace(stmt.toString());
- int result = stmt.executeUpdate();
-
- if (result != 1)
- {
- throw new DBException("Object type could not be deleted: " + id); //$NON-NLS-1$
- }
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public CDOID getMaxID(Connection connection, IIDHandler idHandler)
- {
- Statement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = connection.createStatement();
- resultSet = stmt.executeQuery("SELECT MAX(" + idField + ") FROM " + table);
-
- if (resultSet.next())
- {
- return idHandler.getCDOID(resultSet, 1);
- }
-
- return null;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmt);
- }
- }
-
- public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
- throws IOException
- {
- String where = " WHERE " + timeField + " BETWEEN " + fromCommitTime + " AND " + toCommitTime;
- DBUtil.serializeTable(out, connection, table, null, where);
- }
-
- public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException
- {
- DBUtil.deserializeTable(in, connection, table, monitor);
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- IDBStore store = getMappingStrategy().getStore();
- IDBSchema schema = store.getDBSchema();
- DBType dbType = store.getIDHandler().getDBType();
-
- table = schema.addTable(CDODBSchema.CDO_OBJECTS);
- idField = table.addField(CDODBSchema.ATTRIBUTES_ID, dbType);
- typeField = table.addField(CDODBSchema.ATTRIBUTES_CLASS, dbType);
- timeField = table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT);
- table.addIndex(IDBIndex.Type.UNIQUE, idField);
-
- IDBAdapter dbAdapter = store.getDBAdapter();
- IDBStoreAccessor writer = store.getWriter(null);
- Connection connection = writer.getConnection();
- Statement statement = null;
-
- try
- {
- statement = connection.createStatement();
- dbAdapter.createTable(table, statement);
- connection.commit();
- }
- catch (SQLException ex)
- {
- connection.rollback();
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(statement);
- writer.release();
- }
-
- sqlSelect = "SELECT " + typeField + " FROM " + table + " WHERE " + idField + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- sqlInsert = "INSERT INTO " + table + "(" + idField + "," + typeField + "," + timeField + ") VALUES (?, ?, ?)";
- sqlDelete = "DELETE FROM " + table + " WHERE " + idField + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- table = null;
- idField = null;
- typeField = null;
- super.doDeactivate();
- }
-}
+/* + * Copyright (c) 2004 - 2012 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 + * Stefan Winkler - bug 259402 + * Stefan Winkler - redesign (prepared statements) + * Stefan Winkler - bug 276926 + */ +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.CDOClassifierRef; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.server.db.IDBStore; +import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; +import org.eclipse.emf.cdo.server.db.IIDHandler; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache; +import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBAdapter; +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.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EClass; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public class ObjectTypeTable extends AbstractObjectTypeMapper +{ + private IDBTable table; + + private IDBField idField; + + private IDBField typeField; + + private IDBField timeField; + + private String sqlDelete; + + private String sqlInsert; + + private String sqlSelect; + + public ObjectTypeTable() + { + } + + public final CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlSelect, ReuseProbability.MAX); + idHandler.setCDOID(stmt, 1, id); + DBUtil.trace(stmt.toString()); + ResultSet resultSet = stmt.executeQuery(); + + if (!resultSet.next()) + { + DBUtil.trace("ClassID for CDOID " + id + " not found"); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } + + CDOID classID = idHandler.getCDOID(resultSet, 1); + EClass eClass = (EClass)getMetaDataManager().getMetaInstance(classID); + return new CDOClassifierRef(eClass); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + statementCache.releasePreparedStatement(stmt); + } + } + + public final void putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type) + { + IDBStore store = getMappingStrategy().getStore(); + IIDHandler idHandler = store.getIDHandler(); + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlInsert, ReuseProbability.MAX); + idHandler.setCDOID(stmt, 1, id); + idHandler.setCDOID(stmt, 2, getMetaDataManager().getMetaID(type, timeStamp)); + stmt.setLong(3, timeStamp); + DBUtil.trace(stmt.toString()); + int result = stmt.executeUpdate(); + + if (result != 1) + { + throw new DBException("Object type could not be inserted: " + id); //$NON-NLS-1$ + } + } + catch (SQLException ex) + { + // Unique key violation can occur in rare cases (merging new objects from other branches) + if (!store.getDBAdapter().isDuplicateKeyException(ex)) + { + throw new DBException(ex); + } + } + finally + { + statementCache.releasePreparedStatement(stmt); + } + } + + public final void removeObjectType(IDBStoreAccessor accessor, CDOID id) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IPreparedStatementCache statementCache = accessor.getStatementCache(); + PreparedStatement stmt = null; + + try + { + stmt = statementCache.getPreparedStatement(sqlDelete, ReuseProbability.MAX); + idHandler.setCDOID(stmt, 1, id); + DBUtil.trace(stmt.toString()); + int result = stmt.executeUpdate(); + + if (result != 1) + { + throw new DBException("Object type could not be deleted: " + id); //$NON-NLS-1$ + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + statementCache.releasePreparedStatement(stmt); + } + } + + public CDOID getMaxID(Connection connection, IIDHandler idHandler) + { + Statement stmt = null; + ResultSet resultSet = null; + + try + { + stmt = connection.createStatement(); + resultSet = stmt.executeQuery("SELECT MAX(" + idField + ") FROM " + table); + + if (resultSet.next()) + { + return idHandler.getCDOID(resultSet, 1); + } + + return null; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmt); + } + } + + public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) + throws IOException + { + String where = " WHERE " + timeField + " BETWEEN " + fromCommitTime + " AND " + toCommitTime; + DBUtil.serializeTable(out, connection, table, null, where); + } + + public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException + { + DBUtil.deserializeTable(in, connection, table, monitor); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + + IDBStore store = getMappingStrategy().getStore(); + IDBSchema schema = store.getDBSchema(); + DBType dbType = store.getIDHandler().getDBType(); + + table = schema.addTable(CDODBSchema.CDO_OBJECTS); + idField = table.addField(CDODBSchema.ATTRIBUTES_ID, dbType); + typeField = table.addField(CDODBSchema.ATTRIBUTES_CLASS, dbType); + timeField = table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT); + table.addIndex(IDBIndex.Type.UNIQUE, idField); + + IDBAdapter dbAdapter = store.getDBAdapter(); + IDBStoreAccessor writer = store.getWriter(null); + Connection connection = writer.getConnection(); + Statement statement = null; + + try + { + statement = connection.createStatement(); + dbAdapter.createTable(table, statement); + connection.commit(); + } + catch (SQLException ex) + { + connection.rollback(); + throw new DBException(ex); + } + finally + { + DBUtil.close(statement); + writer.release(); + } + + sqlSelect = "SELECT " + typeField + " FROM " + table + " WHERE " + idField + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + sqlInsert = "INSERT INTO " + table + "(" + idField + "," + typeField + "," + timeField + ") VALUES (?, ?, ?)"; + sqlDelete = "DELETE FROM " + table + " WHERE " + idField + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + @Override + protected void doDeactivate() throws Exception + { + table = null; + idField = null; + typeField = null; + super.doDeactivate(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/Messages.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/Messages.java index 3975ce539c..ee1f366266 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/Messages.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/Messages.java @@ -1,41 +1,41 @@ -/*
- * Copyright (c) 2004 - 2012 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:
- * Victor Roldan Betancort - initial API and implementation
- * Eike Stepper - maintenance
- */
-package org.eclipse.emf.cdo.server.internal.db.messages;
-
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * @author Victor Roldan Betancort
- */
-public class Messages
-{
- private static final String BUNDLE_NAME = "org.eclipse.emf.cdo.server.internal.db.messages.messages"; //$NON-NLS-1$
-
- private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
-
- private Messages()
- {
- }
-
- public static String getString(String key)
- {
- try
- {
- return RESOURCE_BUNDLE.getString(key);
- }
- catch (MissingResourceException e)
- {
- return '!' + key + '!';
- }
- }
-}
+/* + * Copyright (c) 2004 - 2012 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: + * Victor Roldan Betancort - initial API and implementation + * Eike Stepper - maintenance + */ +package org.eclipse.emf.cdo.server.internal.db.messages; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @author Victor Roldan Betancort + */ +public class Messages +{ + private static final String BUNDLE_NAME = "org.eclipse.emf.cdo.server.internal.db.messages.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String getString(String key) + { + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/messages.properties b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/messages.properties index f2b4b488a1..e4d2c0b35e 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/messages.properties +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/messages/messages.properties @@ -1,31 +1,31 @@ -# Copyright (c) 2004 - 2012 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:
-# Victor Roldan Betancort - initial API and implementation
-# Eike Stepper - maintenance
-# Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support
-
-DBStore.0=dbConnectionProvider is null
-DBStore.1=dbAdapter is null
-DBStore.2=mappingStrategy is null
-DBStore.3=idHandler is null
-DBStore.9=Detected crash of repository {0}
-DBStore.10=Repaired crash of repository {0}: lastObjectID={1}, nextLocalObjectID={2}, lastBranchID={3}, lastCommitTime={4}, lastNonLocalCommitTime={5}
-DBStore.10b=Repaired crash of repository {0}: lastBranchID={1}, lastCommitTime={2}, lastNonLocalCommitTime={3}
-DBStore.11=Repairing crash of repository {0} failed.
-
-
-TypeMappingRegistry.1=No type mapping factory found for {0}: {1} --> DBType.{2}
-TypeMappingRegistry.2=TypeMapping {0} annotated at feature {1} could not be found in registry.
-TypeMappingRegistry.3=Runtime removal of ITypeMapping.Factory extensions is currently not supported.
-TypeMappingRegistry.4=Duplicate source:target typeMapping pairs are currently not supported!
-TypeMappingRegistry.5=Duplicate typeMapping ID: {0}
-
-FactoryTypeParserException.1=Invalid format for typeMapping factoryType {0}
-FactoryTypeParserException.2=EPackage {0} could not be resolved while registering typeMapping factoryType {1}
-FactoryTypeParserException.3=EClassifier {0} could not be resolved while registering typeMapping factoryType {1}
-FactoryTypeParserException.4=DBType {0} could not be resolved while registering typeMapping factoryType {1}
+# Copyright (c) 2004 - 2012 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: +# Victor Roldan Betancort - initial API and implementation +# Eike Stepper - maintenance +# Stefan Winkler - Bug 285426: [DB] Implement user-defined typeMapping support + +DBStore.0=dbConnectionProvider is null +DBStore.1=dbAdapter is null +DBStore.2=mappingStrategy is null +DBStore.3=idHandler is null +DBStore.9=Detected crash of repository {0} +DBStore.10=Repaired crash of repository {0}: lastObjectID={1}, nextLocalObjectID={2}, lastBranchID={3}, lastCommitTime={4}, lastNonLocalCommitTime={5} +DBStore.10b=Repaired crash of repository {0}: lastBranchID={1}, lastCommitTime={2}, lastNonLocalCommitTime={3} +DBStore.11=Repairing crash of repository {0} failed. + + +TypeMappingRegistry.1=No type mapping factory found for {0}: {1} --> DBType.{2} +TypeMappingRegistry.2=TypeMapping {0} annotated at feature {1} could not be found in registry. +TypeMappingRegistry.3=Runtime removal of ITypeMapping.Factory extensions is currently not supported. +TypeMappingRegistry.4=Duplicate source:target typeMapping pairs are currently not supported! +TypeMappingRegistry.5=Duplicate typeMapping ID: {0} + +FactoryTypeParserException.1=Invalid format for typeMapping factoryType {0} +FactoryTypeParserException.2=EPackage {0} could not be resolved while registering typeMapping factoryType {1} +FactoryTypeParserException.3=EClassifier {0} could not be resolved while registering typeMapping factoryType {1} +FactoryTypeParserException.4=DBType {0} could not be resolved while registering typeMapping factoryType {1} |