From 278e8a6062c12ee55a24860feb3971872a3e228a Mon Sep 17 00:00:00 2001 From: Eike Stepper Date: Sun, 7 Oct 2007 07:23:57 +0000 Subject: [205652] Prevent duplicate resources https://bugs.eclipse.org/bugs/show_bug.cgi?id=205652 --- .../emf/cdo/server/internal/db/ClassMapping.java | 39 ++++++++--- .../cdo/server/internal/db/DBStoreAccessor.java | 14 ++++ .../cdo/server/internal/db/MappingStrategy.java | 3 + .../emf/cdo/internal/server/NOOPStoreAccessor.java | 6 ++ .../protocol/CommitTransactionIndication.java | 45 ++++++++---- .../org/eclipse/emf/cdo/server/IStoreWriter.java | 4 ++ .../emf/cdo/internal/ui/editor/CDOEditor.java | 1 + .../src/org/eclipse/emf/cdo/CDOTransaction.java | 4 +- .../emf/internal/cdo/CDOTransactionImpl.java | 11 ++- .../cdo/protocol/CommitTransactionRequest.java | 79 ++++++++++++---------- .../cdo/protocol/CommitTransactionResult.java | 12 ++++ .../src/org/eclipse/net4j/db/IDBField.java | 2 + .../src/org/eclipse/net4j/db/IDBTable.java | 4 +- .../org/eclipse/net4j/internal/db/DBAdapter.java | 41 ++++++++++- .../src/org/eclipse/net4j/internal/db/DBField.java | 5 ++ .../src/org/eclipse/net4j/internal/db/DBTable.java | 8 +-- .../internal/util/transaction/Transaction.java | 22 +++++- 17 files changed, 224 insertions(+), 76 deletions(-) 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 a052d624ac..128b367014 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.internal.protocol.revision.CDORevisionImpl; import org.eclipse.emf.cdo.protocol.model.CDOClass; import org.eclipse.emf.cdo.protocol.model.CDOFeature; import org.eclipse.emf.cdo.protocol.model.CDOType; +import org.eclipse.emf.cdo.protocol.model.resource.CDOResourceClass; import org.eclipse.emf.cdo.server.db.IAttributeMapping; import org.eclipse.emf.cdo.server.db.IClassMapping; import org.eclipse.emf.cdo.server.db.IDBStore; @@ -27,6 +28,7 @@ import org.eclipse.net4j.db.DBType; import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.IDBAdapter; import org.eclipse.net4j.db.IDBField; +import org.eclipse.net4j.db.IDBIndex; import org.eclipse.net4j.db.IDBTable; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; import org.eclipse.net4j.util.ImplementationError; @@ -69,11 +71,30 @@ public abstract class ClassMapping implements IClassMapping table = addTable(cdoClass.getName()); initTable(table, hasFullRevisionInfo()); - if (features != null) { attributeMappings = createAttributeMappings(features); referenceMappings = createReferenceMappings(features); + + // Special handling of CDOResource table + CDOResourceClass resourceClass = cdoClass.getPackageManager().getCDOResourcePackage().getCDOResourceClass(); + if (cdoClass == resourceClass) + { + // Create a unique index to prevent duplicate resource paths + for (IAttributeMapping attributeMapping : attributeMappings) + { + if (attributeMapping.getFeature() == resourceClass.getCDOPathFeature()) + { + IDBField versionField = table.getField(CDODBSchema.ATTRIBUTES_VERSION); + IDBField pathField = attributeMapping.getField(); + pathField.setNotNull(true); + + // Create a unique index to prevent duplicate resource paths + table.addIndex(IDBIndex.Type.UNIQUE, versionField, pathField); + break; + } + } + } } selectPrefix = createSelectPrefix(false); @@ -102,16 +123,16 @@ public abstract class ClassMapping implements IClassMapping protected void initTable(IDBTable table, boolean full) { - table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT); - table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER); + table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true); + table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true); if (full) { - table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.INTEGER); - table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT); - table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT); - table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT); - table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT); - table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER); + table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.INTEGER, true); + table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true); + table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT, true); + table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT, true); + table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true); + table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true); } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java index 5c5fade83f..0ce132dac1 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java @@ -31,6 +31,7 @@ import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IRevisionManager; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IStoreChunkReader; +import org.eclipse.emf.cdo.server.IStoreWriter; import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.server.db.IClassMapping; import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; @@ -43,6 +44,7 @@ import org.eclipse.net4j.db.IDBRowHandler; import org.eclipse.net4j.db.IDBTable; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; import org.eclipse.net4j.util.io.CloseableIterator; +import org.eclipse.net4j.util.transaction.ITransaction; import java.sql.Connection; import java.sql.SQLException; @@ -367,6 +369,18 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor mapping.writeRevision(this, revision); } + public void rollback(IView view, ITransaction storeTransaction) + { + try + { + connection.rollback(); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + public CloseableIterator readObjectIDs(boolean withTypes) { if (TRACER.isEnabled()) diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java index 8b46ca1f16..922809559f 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java @@ -406,6 +406,9 @@ public abstract class MappingStrategy implements IMappingStrategy return getType(); } + /** + * The implementation of this method must take care of creating a unique index to prevent duplicate resource paths. + */ protected abstract IClassMapping createClassMapping(CDOClass cdoClass); protected abstract List getClassesWithObjectInfo(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java index 4c7f38584c..91529a5209 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java @@ -19,9 +19,11 @@ import org.eclipse.emf.cdo.protocol.model.CDOPackageInfo; import org.eclipse.emf.cdo.protocol.revision.CDORevision; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IStoreChunkReader; +import org.eclipse.emf.cdo.server.IStoreWriter; import org.eclipse.emf.cdo.server.IView; import org.eclipse.net4j.util.io.CloseableIterator; +import org.eclipse.net4j.util.transaction.ITransaction; import java.util.Collection; import java.util.Collections; @@ -104,4 +106,8 @@ public class NOOPStoreAccessor extends StoreAccessor public void writeRevision(CDORevisionImpl revision) { } + + public void rollback(IView view, ITransaction storeTransaction) + { + } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java index 67698fe57a..a33365f1ab 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java @@ -73,6 +73,8 @@ public class CommitTransactionIndication extends CDOServerIndication private View view; + private String rollbackMessage; + public CommitTransactionIndication() { } @@ -108,12 +110,20 @@ public class CommitTransactionIndication extends CDOServerIndication newObjects = readNewObjects(in, storeWriter); dirtyObjects = readDirtyObjects(in, storeWriter); - ITransaction storeTransaction = new Transaction(storeWriter); - addPackages(storeTransaction, newPackages); - addRevisions(storeTransaction, newResources); - addRevisions(storeTransaction, newObjects); - addRevisions(storeTransaction, dirtyObjects); - storeTransaction.commit(); + ITransaction storeTransaction = new Transaction(storeWriter, false); + try + { + addPackages(storeTransaction, newPackages); + addRevisions(storeTransaction, newResources); + addRevisions(storeTransaction, newObjects); + addRevisions(storeTransaction, dirtyObjects); + storeTransaction.commit(); + } + catch (RuntimeException ex) + { + rollbackMessage = ex.getLocalizedMessage(); + storeWriter.rollback(view, storeTransaction); + } } finally { @@ -125,16 +135,25 @@ public class CommitTransactionIndication extends CDOServerIndication @Override protected void responding(ExtendedDataOutputStream out) throws IOException { - out.writeLong(timeStamp); - for (CDOPackageImpl newPackage : newPackages) + if (rollbackMessage != null) { - CDOIDRangeImpl.write(out, newPackage.getMetaIDRange()); + out.writeBoolean(false); + out.writeString(rollbackMessage); } - - writeIDMappings(out); - if (dirtyObjects.length > 0) + else { - getSessionManager().notifyInvalidation(timeStamp, dirtyObjects, getSession()); + out.writeBoolean(true); + out.writeLong(timeStamp); + for (CDOPackageImpl newPackage : newPackages) + { + CDOIDRangeImpl.write(out, newPackage.getMetaIDRange()); + } + + writeIDMappings(out); + if (dirtyObjects.length > 0) + { + getSessionManager().notifyInvalidation(timeStamp, dirtyObjects, getSession()); + } } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java index a269159615..6a1691767d 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java @@ -19,6 +19,8 @@ import org.eclipse.emf.cdo.protocol.CDOID; import org.eclipse.emf.cdo.protocol.model.CDOClass; import org.eclipse.emf.cdo.protocol.model.CDOFeature; +import org.eclipse.net4j.util.transaction.ITransaction; + /** * @author Eike Stepper */ @@ -45,4 +47,6 @@ public interface IStoreWriter extends IStoreReader public void writeRevision(CDORevisionImpl revision); public CDOID primeNewObject(CDOClass cdoClass); + + public void rollback(IView view, ITransaction storeTransaction); } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java index e92b8e0e62..d8fb3d1ede 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java @@ -1567,6 +1567,7 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv OM.LOG.error(exception); resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception)); } + first = false; } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java index ac74b4d6a4..d869e63fc6 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java @@ -19,6 +19,8 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.net4j.util.transaction.TransactionException; + import java.util.List; import java.util.Map; @@ -39,7 +41,7 @@ public interface CDOTransaction extends CDOView /** * @see CDOTransaction#commit() */ - public void commit(); + public void commit() throws TransactionException; /** * @see CDOTransaction#rollback() diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java index c8478c4155..d02c0e561f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java @@ -37,6 +37,7 @@ import org.eclipse.net4j.internal.util.event.Notifier; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; import org.eclipse.net4j.signal.IFailOverStrategy; import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.transaction.TransactionException; import java.text.MessageFormat; import java.util.ArrayList; @@ -147,7 +148,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction return (CDOResource)getResourceSet().createResource(createURI); } - public void commit() + public void commit() throws TransactionException { checkWritable(); if (dirty) @@ -173,8 +174,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction IChannel channel = session.getChannel(); IFailOverStrategy failOverStrategy = session.getFailOverStrategy(); CommitTransactionRequest request = new CommitTransactionRequest(channel, this); - CommitTransactionResult result = failOverStrategy.send(request, 100000L); + // TODO Change timeout semantics in Net4j + CommitTransactionResult result = failOverStrategy.send(request, 100000L); + String rollbackMessage = result.getRollbackMessage(); + if (rollbackMessage != null) + { + throw new TransactionException(rollbackMessage); + } postCommit(newResources, result); postCommit(newObjects, result); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java index 3ce55f051c..1a48f1f554 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java @@ -67,6 +67,49 @@ public class CommitTransactionRequest extends CDOClientRequest newPackages = transaction.getNewPackages(); + for (CDOPackage newPackage : newPackages) + { + CDOIDRange oldRange = newPackage.getMetaIDRange(); + CDOIDRange newRange = CDOIDRangeImpl.read(in); + ((CDOPackageImpl)newPackage).setMetaIDRange(newRange); + for (long i = 0; i < oldRange.getCount(); i++) + { + CDOID oldID = oldRange.get(i); + CDOID newID = newRange.get(i); + transaction.getSession().remapMetaInstance(oldID, newID); + result.addIDMapping(oldID, newID); + } + } + + for (;;) + { + CDOID oldID = CDOIDImpl.read(in); + if (oldID.isNull()) + { + break; + } + + CDOID newID = CDOIDImpl.read(in); + result.addIDMapping(oldID, newID); + } + + return result; + } + private void writeNewPackages(ExtendedDataOutputStream out) throws IOException { List newPackages = transaction.getNewPackages(); @@ -125,40 +168,4 @@ public class CommitTransactionRequest extends CDOClientRequest newPackages = transaction.getNewPackages(); - for (CDOPackage newPackage : newPackages) - { - CDOIDRange oldRange = newPackage.getMetaIDRange(); - CDOIDRange newRange = CDOIDRangeImpl.read(in); - ((CDOPackageImpl)newPackage).setMetaIDRange(newRange); - for (long i = 0; i < oldRange.getCount(); i++) - { - CDOID oldID = oldRange.get(i); - CDOID newID = newRange.get(i); - transaction.getSession().remapMetaInstance(oldID, newID); - result.addIDMapping(oldID, newID); - } - } - - for (;;) - { - CDOID oldID = CDOIDImpl.read(in); - if (oldID.isNull()) - { - break; - } - - CDOID newID = CDOIDImpl.read(in); - result.addIDMapping(oldID, newID); - } - - return result; - } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java index cd9bf95688..748aa8b074 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java @@ -20,15 +20,27 @@ import java.util.Map; */ public final class CommitTransactionResult { + private String rollbackMessage; + private long timeStamp; private Map idMappings = new HashMap(); + public CommitTransactionResult(String rollbackMessage) + { + this.rollbackMessage = rollbackMessage; + } + public CommitTransactionResult(long timeStamp) { this.timeStamp = timeStamp; } + public String getRollbackMessage() + { + return rollbackMessage; + } + public long getTimeStamp() { return timeStamp; diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBField.java index e89abc8f18..f82cd3d64f 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBField.java @@ -27,6 +27,8 @@ public interface IDBField extends IDBElement public boolean isNotNull(); + public void setNotNull(boolean on); + public int getPosition(); public String getFullName(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBTable.java index 9a7c736e2a..5a1f694c16 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBTable.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBTable.java @@ -37,9 +37,7 @@ public interface IDBTable extends IDBElement public IDBField[] getFields(); - public IDBIndex addIndex(IDBIndex.Type type, IDBField field); - - public IDBIndex addIndex(IDBIndex.Type type, IDBField[] fields); + public IDBIndex addIndex(IDBIndex.Type type, IDBField... fields); public int getIndexCount(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java index 8d85226692..873054449d 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java @@ -15,6 +15,7 @@ import org.eclipse.net4j.db.DBType; import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.IDBAdapter; import org.eclipse.net4j.db.IDBField; +import org.eclipse.net4j.db.IDBIndex; import org.eclipse.net4j.db.IDBTable; import org.eclipse.net4j.internal.db.bundle.OM; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; @@ -140,11 +141,47 @@ public abstract class DBAdapter implements IDBAdapter builder.append(")"); String sql = builder.toString(); - if (TRACER.isEnabled()) + if (TRACER.isEnabled()) TRACER.trace(sql); + statement.execute(sql); + + DBIndex[] indices = table.getIndices(); + for (int i = 0; i < indices.length; i++) + { + createIndex(indices[i], statement, i); + } + } + + protected void createIndex(DBIndex index, Statement statement, int num) throws SQLException + { + DBTable table = index.getTable(); + StringBuilder builder = new StringBuilder(); + builder.append("CREATE "); + if (index.getType() == IDBIndex.Type.UNIQUE) { - TRACER.trace(sql); + builder.append("UNIQUE "); } + builder.append("INDEX "); + builder.append(table); + builder.append("_idx"); + builder.append(num); + builder.append(" ON "); + builder.append(table); + builder.append(" ("); + IDBField[] fields = index.getFields(); + for (int i = 0; i < fields.length; i++) + { + if (i != 0) + { + builder.append(", "); + } + + builder.append(fields[i]); + } + + builder.append(")"); + String sql = builder.toString(); + if (TRACER.isEnabled()) TRACER.trace(sql); statement.execute(sql); } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBField.java index 1eb7a781c0..f787c30457 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBField.java @@ -81,6 +81,11 @@ public class DBField extends DBElement implements IDBField return notNull; } + public void setNotNull(boolean on) + { + notNull = on; + } + public int getPosition() { return position; diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTable.java index bf1d1e89d2..af7c8bd274 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTable.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTable.java @@ -116,13 +116,7 @@ public class DBTable extends DBElement implements IDBTable return fields.toArray(new DBField[fields.size()]); } - public DBIndex addIndex(Type type, IDBField field) - { - IDBField[] fields = { field }; - return addIndex(type, fields); - } - - public DBIndex addIndex(Type type, IDBField[] fields) + public DBIndex addIndex(Type type, IDBField... fields) { schema.assertUnlocked(); DBIndex index = new DBIndex(this, type, fields, indices.size()); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/transaction/Transaction.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/transaction/Transaction.java index 8205477b2e..78253a13e3 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/transaction/Transaction.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/transaction/Transaction.java @@ -26,9 +26,22 @@ public class Transaction implements ITransaction private CONTEXT context; - public Transaction(CONTEXT context) + private boolean undoPhase1OnRollback; + + public Transaction(CONTEXT context, boolean undoPhase1OnRollback) { this.context = context; + this.undoPhase1OnRollback = undoPhase1OnRollback; + } + + public Transaction(CONTEXT context) + { + this(context, true); + } + + public boolean isUndoPhase1OnRollback() + { + return undoPhase1OnRollback; } public boolean isActive() @@ -75,9 +88,12 @@ public class Transaction implements ITransaction public void rollback() { - for (ITransactionalOperation operation : end()) + if (undoPhase1OnRollback) { - operation.undoPhase1(context); + for (ITransactionalOperation operation : end()) + { + operation.undoPhase1(context); + } } } -- cgit v1.2.3