diff options
author | Stefan Winkler | 2009-01-08 12:38:06 +0000 |
---|---|---|
committer | Stefan Winkler | 2009-01-08 12:38:06 +0000 |
commit | e784c45dcef5899e9fc077e063eae159cb8757c3 (patch) | |
tree | 88905f99e5d0007f7a7ef036bf9a70ec267c27fe | |
parent | 01eaaed429318e591fbe8496b7104d48401a39a3 (diff) | |
download | cdo-e784c45dcef5899e9fc077e063eae159cb8757c3.tar.gz cdo-e784c45dcef5899e9fc077e063eae159cb8757c3.tar.xz cdo-e784c45dcef5899e9fc077e063eae159cb8757c3.zip |
[253110] [DB] Support non-auditing mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=253110
12 files changed, 518 insertions, 42 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java index 3ef1fc11bd..ff7b991b3b 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IJDBCDelegate.java @@ -35,25 +35,39 @@ import java.util.List; public interface IJDBCDelegate { /** - * Insert a reference row. Note: this is likely to be replaced by an implementation that supports storing multiple - * references in one batch. + * Insert a reference row. */ public void insertReference(CDORevision sourceRevision, int index, CDOID targetId, IReferenceMapping referenceMapping); /** + * Delete all reference rows of a cdoid. + */ + public void deleteReferences(CDOID id, IReferenceMapping referenceMapping); + + /** * Insert an attribute row. */ public void insertAttributes(CDORevision revision, IClassMapping classMapping); /** + * Update an attribute row. + */ + public void updateAttributes(CDORevision revision, IClassMapping classMapping); + + /** + * Remove an attribute row. + */ + public void deleteAttributes(CDOID id, IClassMapping classMapping); + + /** * Set the revised date of a specific revision's previous version. */ - public void updateRevised(CDORevision revision, IClassMapping classMapping); + public void updateRevisedForReplace(CDORevision revision, IClassMapping classMapping); /** * Set the revised date of all unrevised rows of cdoid */ - public void updateRevised(CDOID cdoid, long revised, IClassMapping classMapping); + public void updateRevisedForDetach(CDOID id, long revised, IClassMapping classMapping); /** * Select a revision's attributes diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java index 133ccda2ff..194afb2128 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IObjectTypeCache.java @@ -28,4 +28,9 @@ public interface IObjectTypeCache * @since 2.0 */ public void putObjectType(IDBStoreAccessor accessor, CDOID id, CDOClass type); + + /** + * @since 2.0 + */ + public void removeObjectType(IDBStoreAccessor accessor, CDOID id); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IReferenceMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IReferenceMapping.java index 5c341e301a..2fe04848dd 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IReferenceMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IReferenceMapping.java @@ -10,6 +10,7 @@ **************************************************************************/ package org.eclipse.emf.cdo.server.db; +import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; @@ -40,4 +41,9 @@ public interface IReferenceMapping extends IFeatureMapping public void readReference(IDBStoreAccessor accessor, CDORevision revision, int referenceChunk); public void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String string); + + /** + * @since 2.0 + */ + public void deleteReference(IDBStoreAccessor accessor, CDOID id); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java index ea630f842d..4f40e49a7d 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java @@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.model.CDOClass; import org.eclipse.emf.cdo.common.model.CDOFeature; import org.eclipse.emf.cdo.common.model.CDOType; import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.IStore; import org.eclipse.emf.cdo.server.db.IAttributeMapping; import org.eclipse.emf.cdo.server.db.IClassMapping; import org.eclipse.emf.cdo.server.db.IDBStore; @@ -325,7 +326,8 @@ public abstract class ClassMapping implements IClassMapping { // TODO Better monitoring monitor.begin(10); - if (revision.getVersion() > 1 && hasFullRevisionInfo()) + + if (revision.getVersion() > 1 && hasFullRevisionInfo() && isAuditing()) { writeRevisedRow(accessor, (InternalCDORevision)revision); } @@ -358,6 +360,11 @@ public abstract class ClassMapping implements IClassMapping } } + private boolean isAuditing() + { + return mappingStrategy.getStore().getRevisionTemporality() == IStore.RevisionTemporality.AUDITING; + } + protected abstract void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException; @@ -368,8 +375,33 @@ public abstract class ClassMapping implements IClassMapping monitor.begin(); if (hasFullRevisionInfo()) { - writeRevisedRow(accessor, id, revised); + if (isAuditing()) + { + writeRevisedRow(accessor, id, revised); + monitor.worked(1); + } + else + { + deleteRevision(accessor, id, monitor.fork(1)); + } } + // TODO handle !hasFullRevisionInfo() case + } + finally + { + monitor.done(); + } + } + + protected void deleteRevision(IDBStoreAccessor accessor, CDOID id, OMMonitor monitor) + { + try + { + monitor.begin(2); + deleteAttributes(accessor, id); + monitor.worked(1); + deleteReferences(accessor, id); + monitor.worked(1); } finally { @@ -379,21 +411,49 @@ public abstract class ClassMapping implements IClassMapping protected final void writeRevisedRow(IDBStoreAccessor accessor, InternalCDORevision revision) { - accessor.getJDBCDelegate().updateRevised(revision, this); + accessor.getJDBCDelegate().updateRevisedForReplace(revision, this); } protected final void writeRevisedRow(IDBStoreAccessor accessor, CDOID id, long revised) { - accessor.getJDBCDelegate().updateRevised(id, revised, this); + accessor.getJDBCDelegate().updateRevisedForDetach(id, revised, this); } protected final void writeAttributes(IDBStoreAccessor accessor, InternalCDORevision revision) { - accessor.getJDBCDelegate().insertAttributes(revision, this); + if (revision.getVersion() == 1 || isAuditing()) + { + accessor.getJDBCDelegate().insertAttributes(revision, this); + } + else + { + accessor.getJDBCDelegate().updateAttributes(revision, this); + } + } + + protected final void deleteAttributes(IDBStoreAccessor accessor, CDOID id) + { + accessor.getJDBCDelegate().deleteAttributes(id, this); + } + + protected final void deleteReferences(IDBStoreAccessor accessor, CDOID id) + { + if (referenceMappings != null) + { + for (IReferenceMapping referenceMapping : referenceMappings) + { + referenceMapping.deleteReference(accessor, id); + } + } } protected void writeReferences(IDBStoreAccessor accessor, InternalCDORevision revision) { + if (mappingStrategy.getStore().getRevisionTemporality() == IStore.RevisionTemporality.NONE) + { + deleteReferences(accessor, revision.getID()); + } + for (IReferenceMapping referenceMapping : referenceMappings) { referenceMapping.writeReference(accessor, 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 621c8f42f7..eebfc75944 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 @@ -93,7 +93,8 @@ public class DBStore extends LongIDStore implements IDBStore public DBStore() { - super(TYPE, set(ChangeFormat.REVISION), set(RevisionTemporality.AUDITING), set(RevisionParallelism.NONE)); + super(TYPE, set(ChangeFormat.REVISION), set(RevisionTemporality.AUDITING, RevisionTemporality.NONE), + set(RevisionParallelism.NONE)); setRevisionTemporality(RevisionTemporality.AUDITING); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/HorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/HorizontalClassMapping.java index 4a8f7a9150..6af034bded 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/HorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/HorizontalClassMapping.java @@ -65,19 +65,17 @@ public class HorizontalClassMapping extends ClassMapping protected void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException { IRepository repository = getMappingStrategy().getStore().getRepository(); - if (repository.isSupportingAudits()) - { - IPackageManager packageManager = repository.getPackageManager(); - CDOResourceNodeClass resourceNodeClass = packageManager.getCDOResourcePackage().getCDOResourceNodeClass(); - CDOFeature resourceNameFeature = resourceNodeClass.getCDONameFeature(); + IPackageManager packageManager = repository.getPackageManager(); + CDOResourceNodeClass resourceNodeClass = packageManager.getCDOResourcePackage().getCDOResourceNodeClass(); + CDOFeature resourceNameFeature = resourceNodeClass.getCDONameFeature(); - CDOID folderID = (CDOID)revision.data().getContainerID(); - String name = (String)revision.data().get(resourceNameFeature, 0); + CDOID folderID = (CDOID)revision.data().getContainerID(); + String name = (String)revision.data().get(resourceNameFeature, 0); - if (accessor.readResourceID(folderID, name, revision.getCreated()) != null) - { - throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID); - } + CDOID existingID = accessor.readResourceID(folderID, name, revision.getCreated()); + if (existingID != null && !existingID.equals(revision.getID())) + { + throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID); } } @@ -91,4 +89,20 @@ public class HorizontalClassMapping extends ClassMapping { return true; } + + @Override + protected void deleteRevision(IDBStoreAccessor accessor, CDOID id, OMMonitor monitor) + { + try + { + monitor.begin(2); + super.deleteRevision(accessor, id, monitor.fork(1)); + getMappingStrategy().getObjectTypeCache().removeObjectType(accessor, id); + monitor.worked(1); + } + finally + { + monitor.done(); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java index 6945f9c764..0f8d692d12 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ObjectTypeCache.java @@ -131,6 +131,35 @@ public class ObjectTypeCache extends Lifecycle implements IObjectTypeCache } } + public final void removeObjectType(IDBStoreAccessor accessor, CDOID id) + { + Statement statement = accessor.getJDBCDelegate().getStatement(); + initialize(statement); + + StringBuilder builder = new StringBuilder(); + builder.append("DELETE FROM "); + builder.append(table); + builder.append(" WHERE "); + builder.append(idField); + builder.append(" = "); + builder.append(CDOIDUtil.getLong(id)); + String sql = builder.toString(); + DBUtil.trace(sql); + + try + { + statement.execute(sql); + if (statement.getUpdateCount() != 1) + { + throw new DBException("Object type could not be deleted: " + id); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + private void initialize(Statement statement) { synchronized (initializeLock) diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ReferenceMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ReferenceMapping.java index e45f041ec5..348780b5e0 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ReferenceMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ReferenceMapping.java @@ -65,6 +65,11 @@ public class ReferenceMapping extends FeatureMapping implements IReferenceMappin } } + public void deleteReference(IDBStoreAccessor accessor, CDOID id) + { + accessor.getJDBCDelegate().deleteReferences(id, this); + } + public final void readReference(IDBStoreAccessor accessor, CDORevision revision, int referenceChunk) { accessor.getJDBCDelegate().selectRevisionReferences(revision, this, referenceChunk); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java index e1618797b2..616319ce55 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/AbstractJDBCDelegate.java @@ -157,6 +157,17 @@ public abstract class AbstractJDBCDelegate extends Lifecycle implements IJDBCDel .hasFullRevisionInfo()); } + public final void updateAttributes(CDORevision revision, IClassMapping classMapping) + { + doUpdateAttributes(classMapping.getTable().getName(), revision, classMapping.getAttributeMappings(), classMapping + .hasFullRevisionInfo()); + } + + public void deleteAttributes(CDOID id, IClassMapping classMapping) + { + doDeleteAttributes(classMapping.getTable().getName(), CDOIDUtil.getLong(id)); + } + public final void insertReference(CDORevision sourceRevision, int index, CDOID targetId, IReferenceMapping referenceMapping) { @@ -165,15 +176,21 @@ public abstract class AbstractJDBCDelegate extends Lifecycle implements IJDBCDel .getVersion(), index, CDOIDUtil.getLong(targetId)); } - public final void updateRevised(CDORevision revision, IClassMapping classMapping) + public void deleteReferences(CDOID id, IReferenceMapping referenceMapping) + { + doDeleteReferences(referenceMapping.getTable().getName(), referenceMapping.isWithFeature() ? FeatureServerInfo + .getDBID(referenceMapping.getFeature()) : 0, CDOIDUtil.getLong(id)); + } + + public final void updateRevisedForReplace(CDORevision revision, IClassMapping classMapping) { - doUpdateRevised(classMapping.getTable().getName(), revision.getCreated() - 1, CDOIDUtil.getLong(revision.getID()), - revision.getVersion() - 1); + doUpdateRevisedForReplace(classMapping.getTable().getName(), revision.getCreated() - 1, CDOIDUtil.getLong(revision + .getID()), revision.getVersion() - 1); } - public final void updateRevised(CDOID id, long revised, IClassMapping classMapping) + public final void updateRevisedForDetach(CDOID id, long revised, IClassMapping classMapping) { - doUpdateRevised(classMapping.getTable().getName(), revised, CDOIDUtil.getLong(id)); + doUpdateRevisedForDetach(classMapping.getTable().getName(), revised, CDOIDUtil.getLong(id)); } public final boolean selectRevisionAttributes(CDORevision revision, IClassMapping classMapping, String where) @@ -350,20 +367,36 @@ public abstract class AbstractJDBCDelegate extends Lifecycle implements IJDBCDel List<IAttributeMapping> attributeMappings, boolean withFullRevisionInfo); /** + * Update an attribute row. + */ + protected abstract void doUpdateAttributes(String name, CDORevision revision, + List<IAttributeMapping> attributeMappings, boolean hasFullRevisionInfo); + + /** + * Delete an attribute row. + */ + protected abstract void doDeleteAttributes(String name, long cdoid1); + + /** * Insert a reference row. Note: this is likely to be replaced by an implementation that supports storing multiple * references in one batch. */ protected abstract void doInsertReference(String tableName, int dbId, long source, int version, int i, long target); /** - * Set the revised date of all unrevised rows of cdoid + * Delete all references of a particular CDOID. + */ + protected abstract void doDeleteReferences(String name, int dbId, long cdoid); + + /** + * Set the revised date of a cdoid (the cdoid is to be detached) */ - protected abstract void doUpdateRevised(String tableName, long revised, long cdoid); + protected abstract void doUpdateRevisedForDetach(String tableName, long revised, long cdoid); /** - * Set the revised date of a specific revision's previous version. + * Set the revised date of a specific revision's previous version (the previous version is to be replaced). */ - protected abstract void doUpdateRevised(String tableName, long revisedStamp, long cdoid, int version); + protected abstract void doUpdateRevisedForReplace(String tableName, long revisedStamp, long cdoid, int version); /** * Select a revision's attributes. The caller is resposible for closing resultSet and associated statement, if diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java index 90c0ee0e01..64546429e3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/JDBCPerformanceReporter.java @@ -138,20 +138,44 @@ public class JDBCPerformanceReporter extends Lifecycle implements IJDBCDelegate registerCall("selectReferences", time); } - public final void updateRevised(CDORevision revision, IClassMapping classMapping) + public final void updateRevisedForReplace(CDORevision revision, IClassMapping classMapping) { long time = System.currentTimeMillis(); - delegate.updateRevised(revision, classMapping); + delegate.updateRevisedForReplace(revision, classMapping); time = System.currentTimeMillis() - time; - registerCall("updateRevisedRevision", time); + registerCall("updateRevisedForReplace", time); } - public final void updateRevised(CDOID cdoid, long revised, IClassMapping classMapping) + public final void updateRevisedForDetach(CDOID cdoid, long revised, IClassMapping classMapping) { long time = System.currentTimeMillis(); - delegate.updateRevised(cdoid, revised, classMapping); + delegate.updateRevisedForDetach(cdoid, revised, classMapping); time = System.currentTimeMillis() - time; - registerCall("updateRevisedID", time); + registerCall("updateRevisedForDetach", time); + } + + public void deleteAttributes(CDOID id, IClassMapping classMapping) + { + long time = System.currentTimeMillis(); + delegate.deleteAttributes(id, classMapping); + time = System.currentTimeMillis() - time; + registerCall("deleteAttributes", time); + } + + public void deleteReferences(CDOID id, IReferenceMapping referenceMapping) + { + long time = System.currentTimeMillis(); + delegate.deleteReferences(id, referenceMapping); + time = System.currentTimeMillis() - time; + registerCall("deleteReferences", time); + } + + public void updateAttributes(CDORevision revision, IClassMapping classMapping) + { + long time = System.currentTimeMillis(); + delegate.updateAttributes(revision, classMapping); + time = System.currentTimeMillis() - time; + registerCall("updateAttributes", time); } public void setConnectionProvider(IDBConnectionProvider connectionProvider) diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java index cf63bb8ea1..0f139dd85a 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java @@ -131,7 +131,8 @@ public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate for (int result : results) { - checkState(result == 1, "Batch execution did not return '1' for " + entry.getKey().toString()); + checkState(entry.getKey().getElement1() != StmtType.DELETE_REFERENCES && result == 1, + "Batch execution did not return '1' for " + entry.getKey().toString()); } } catch (SQLException ex) @@ -347,6 +348,150 @@ public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate } @Override + protected void doUpdateAttributes(String tableName, CDORevision rev, List<IAttributeMapping> attributeMappings, + boolean withFullRevisionInfo) + { + boolean firstBatch = false; + + InternalCDORevision revision = (InternalCDORevision)rev; + if (attributeMappings == null) + { + attributeMappings = Collections.emptyList(); + } + + PreparedStatement stmt = getDirtyStatement(StmtType.UPDATE_ATTRIBUTES, tableName); + if (stmt == null && cacheStatements) + { + firstBatch = true; + stmt = getAndRemoveCachedStatement(StmtType.UPDATE_ATTRIBUTES, tableName); + } + + try + { + firstBatch = true; + if (stmt == null) + { + StringBuilder sql = new StringBuilder(); + + sql.append("UPDATE "); + sql.append(tableName); + sql.append(" SET "); + sql.append(CDODBSchema.ATTRIBUTES_VERSION); + sql.append(" = ? "); + if (withFullRevisionInfo) + { + sql.append(", "); + sql.append(CDODBSchema.ATTRIBUTES_RESOURCE); + sql.append(" = ?,"); + sql.append(CDODBSchema.ATTRIBUTES_CONTAINER); + sql.append(" = ?,"); + sql.append(CDODBSchema.ATTRIBUTES_FEATURE); + sql.append(" = ?"); + } + + for (IAttributeMapping attributeMapping : attributeMappings) + { + sql.append(", "); + sql.append(attributeMapping.getField()); + sql.append(" = ?"); + } + + sql.append(" WHERE "); + sql.append(CDODBSchema.ATTRIBUTES_ID); + sql.append(" = ? "); + + stmt = getConnection().prepareStatement(sql.toString()); + } + + int col = 1; + if (TRACER.isEnabled()) + { + TRACER.trace(stmt.toString()); + } + + stmt.setInt(col++, revision.getVersion()); + if (withFullRevisionInfo) + { + stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID())); + stmt.setLong(col++, CDOIDUtil.getLong((CDOID)revision.getContainerID())); + stmt.setInt(col++, revision.getContainingFeatureID()); + } + + for (IAttributeMapping attributeMapping : attributeMappings) + { + Object value = attributeMapping.getRevisionValue(revision); + if (value == null) + { + stmt.setNull(col++, attributeMapping.getField().getType().getCode()); + } + else + { + stmt.setObject(col++, value); + } + } + + stmt.setLong(col++, CDOIDUtil.getLong(revision.getID())); + if (firstBatch) + { + addDirtyStatement(StmtType.UPDATE_ATTRIBUTES, tableName, stmt); + } + + stmt.addBatch(); + } + catch (SQLException e) + { + throw new DBException(e); + } + } + + @Override + protected void doDeleteAttributes(String tableName, long cdoid) + { + PreparedStatement stmt = null; + if (cacheStatements) + { + stmt = getCachedStatement(StmtType.DELETE_ATTRIBUTES, tableName); + } + + try + { + if (stmt == null) + { + StringBuilder sql = new StringBuilder("DELETE FROM "); + sql.append(tableName); + sql.append(" WHERE "); + sql.append(CDODBSchema.ATTRIBUTES_ID); + sql.append(" = ? "); + + stmt = getConnection().prepareStatement(sql.toString()); + if (cacheStatements) + { + cacheStatement(StmtType.DELETE_ATTRIBUTES, tableName, stmt); + } + } + + stmt.setLong(1, cdoid); + if (TRACER.isEnabled()) + { + TRACER.trace(stmt.toString()); + } + + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + if (!cacheStatements) + { + DBUtil.close(stmt); + } + } + } + + @Override protected void doInsertReference(String tableName, int dbID, long source, int version, int index, long target) { boolean firstBatch = false; @@ -398,7 +543,66 @@ public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate } @Override - protected void doUpdateRevised(String tableName, long revisedStamp, long cdoid, int version) + protected void doDeleteReferences(String tableName, int dbId, long cdoid) + { + PreparedStatement stmt = null; + if (cacheStatements) + { + stmt = getCachedStatement(StmtType.DELETE_REFERENCES, tableName); + } + + try + { + if (stmt == null) + { + StringBuilder sql = new StringBuilder("DELETE FROM "); + sql.append(tableName); + sql.append(" WHERE "); + sql.append(CDODBSchema.REFERENCES_SOURCE); + sql.append(" = ? "); + + if (dbId != 0) + { + sql.append("AND"); + sql.append(CDODBSchema.REFERENCES_FEATURE); + sql.append(" = ? "); + } + + stmt = getConnection().prepareStatement(sql.toString()); + if (cacheStatements) + { + cacheStatement(StmtType.DELETE_REFERENCES, tableName, stmt); + } + } + + stmt.setLong(1, cdoid); + if (dbId != 0) + { + stmt.setInt(2, dbId); + } + + if (TRACER.isEnabled()) + { + TRACER.trace(stmt.toString()); + } + + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + if (!cacheStatements) + { + DBUtil.close(stmt); + } + } + } + + @Override + protected void doUpdateRevisedForReplace(String tableName, long revisedStamp, long cdoid, int version) { PreparedStatement stmt = null; if (cacheStatements) @@ -445,7 +649,7 @@ public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate } @Override - protected void doUpdateRevised(String tableName, long revisedStamp, long cdoid) + protected void doUpdateRevisedForDetach(String tableName, long revisedStamp, long cdoid) { PreparedStatement stmt = null; if (cacheStatements) @@ -712,7 +916,7 @@ public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate */ private static enum StmtType { - INSERT_ATTRIBUTES, INSERT_REFERENCES, REVISE_VERSION, REVISE_UNREVISED, GENERAL + INSERT_ATTRIBUTES, UPDATE_ATTRIBUTES, DELETE_ATTRIBUTES, INSERT_REFERENCES, DELETE_REFERENCES, REVISE_VERSION, REVISE_UNREVISED, GENERAL } /** diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java index 7981f285cf..a750868750 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/jdbc/StatementJDBCDelegate.java @@ -89,7 +89,55 @@ public class StatementJDBCDelegate extends AbstractJDBCDelegate } @Override - protected void doUpdateRevised(String table, long revisedStamp, long cdoid, int version) + protected void doUpdateAttributes(String tableName, CDORevision revision, List<IAttributeMapping> attributeMappings, + boolean withFullRevisionInfo) + { + StringBuilder builder = new StringBuilder(); + builder.append("UPDATE "); + builder.append(tableName); + builder.append(" SET "); + builder.append(CDODBSchema.ATTRIBUTES_VERSION); + builder.append(" = "); + builder.append(revision.getVersion()); + + if (withFullRevisionInfo) + { + CDORevisionData data = revision.data(); + builder.append(", "); + builder.append(CDODBSchema.ATTRIBUTES_RESOURCE); + builder.append(" = "); + builder.append(CDOIDUtil.getLong(data.getResourceID())); + builder.append(", "); + builder.append(CDODBSchema.ATTRIBUTES_CONTAINER); + builder.append(" = "); + builder.append(CDOIDUtil.getLong((CDOID)data.getContainerID())); + builder.append(", "); + builder.append(CDODBSchema.ATTRIBUTES_FEATURE); + builder.append(" = "); + builder.append(data.getContainingFeatureID()); + } + + if (attributeMappings != null) + { + for (IAttributeMapping attributeMapping : attributeMappings) + { + builder.append(", "); + builder.append(attributeMapping.getField()); + builder.append(" = "); + attributeMapping.appendValue(builder, revision); + } + } + + builder.append(" WHERE "); + builder.append(CDODBSchema.ATTRIBUTES_ID); + builder.append(" = "); + builder.append(CDOIDUtil.getLong(revision.getID())); + + sqlUpdate(builder.toString()); + } + + @Override + protected void doUpdateRevisedForReplace(String table, long revisedStamp, long cdoid, int version) { StringBuilder builder = new StringBuilder(); builder.append("UPDATE "); @@ -110,7 +158,20 @@ public class StatementJDBCDelegate extends AbstractJDBCDelegate } @Override - protected void doUpdateRevised(String table, long revisedStamp, long cdoid) + protected void doDeleteAttributes(String name, long cdoid) + { + StringBuilder builder = new StringBuilder(); + builder.append("DELETE FROM "); + builder.append(name); + builder.append(" WHERE "); + builder.append(CDODBSchema.ATTRIBUTES_ID); + builder.append(" = "); + builder.append(cdoid); + sqlUpdate(builder.toString()); + } + + @Override + protected void doUpdateRevisedForDetach(String table, long revisedStamp, long cdoid) { StringBuilder builder = new StringBuilder(); builder.append("UPDATE "); @@ -153,6 +214,26 @@ public class StatementJDBCDelegate extends AbstractJDBCDelegate } @Override + protected void doDeleteReferences(String name, int dbId, long cdoid) + { + StringBuilder builder = new StringBuilder(); + builder.append("DELETE FROM "); + builder.append(name); + builder.append(" WHERE "); + builder.append(CDODBSchema.REFERENCES_SOURCE); + builder.append(" = "); + builder.append(cdoid); + if (dbId != 0) + { + builder.append(" AND "); + builder.append(CDODBSchema.REFERENCES_FEATURE); + builder.append(" = "); + builder.append(dbId); + } + sqlUpdate(builder.toString()); + } + + @Override protected ResultSet doSelectRevisionAttributes(String tableName, long revisionId, List<IAttributeMapping> attributeMappings, boolean hasFullRevisionInfo, String where) throws SQLException { |