Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-03-07 10:22:18 +0000
committerEike Stepper2013-03-07 13:45:03 +0000
commitfec13815dd6c0d3cb112cf93d06b1734a898f452 (patch)
tree3b0fe546a34f3f28a81d21c00f08bf9b36d1da98
parentf80f4be34da8b3290d671676c2d69c13e6180b33 (diff)
downloadcdo-fec13815dd6c0d3cb112cf93d06b1734a898f452.tar.gz
cdo-fec13815dd6c0d3cb112cf93d06b1734a898f452.tar.xz
cdo-fec13815dd6c0d3cb112cf93d06b1734a898f452.zip
[401763] Make CDO Server more robust against data dictionary changes
https://bugs.eclipse.org/bugs/show_bug.cgi?id=401763
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java6
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDelta.java2
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDeltaVisitor.java583
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java6
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBSchemaDelta.java4
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBTableDelta.java10
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java38
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTransaction.java18
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBDelta.java2
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java23
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexFieldDelta.java4
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java12
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBTableDelta.java33
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java14
14 files changed, 641 insertions, 114 deletions
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java
index f1c316eba4..a3ed4dd563 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBDatabase.java
@@ -11,9 +11,12 @@
package org.eclipse.net4j.db;
import org.eclipse.net4j.db.ddl.IDBSchema;
+import org.eclipse.net4j.db.ddl.delta.IDBDelta.ChangeKind;
import org.eclipse.net4j.util.collection.Closeable;
import org.eclipse.net4j.util.container.IContainer;
+import java.util.Map;
+
/**
* @author Eike Stepper
* @noimplement This interface is not intended to be implemented by clients.
@@ -34,6 +37,8 @@ public interface IDBDatabase extends IContainer<IDBTransaction>, Closeable
public IDBSchemaTransaction getSchemaTransaction();
+ public void ensureSchema(IDBSchema schema, Map<ChangeKind, Boolean> policy);
+
public IDBTransaction openTransaction();
public IDBTransaction[] getTransactions();
@@ -41,5 +46,4 @@ public interface IDBDatabase extends IContainer<IDBTransaction>, Closeable
public int getStatementCacheCapacity();
public void setStatementCacheCapacity(int statementCacheCapacity);
-
}
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDelta.java
index caac6a2c4e..8a531f9d8d 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDelta.java
@@ -48,6 +48,6 @@ public interface IDBDelta extends IDBNamedElement, IContainer<IDBDelta>, Compara
*/
public enum ChangeKind
{
- ADDED, REMOVED, CHANGED
+ ADD, REMOVE, CHANGE
}
}
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDeltaVisitor.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDeltaVisitor.java
index 217a47129a..e63aa1d820 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDeltaVisitor.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBDeltaVisitor.java
@@ -11,6 +11,20 @@
package org.eclipse.net4j.db.ddl.delta;
import org.eclipse.net4j.db.ddl.delta.IDBDelta.ChangeKind;
+import org.eclipse.net4j.db.ddl.delta.IDBDelta.DeltaType;
+import org.eclipse.net4j.internal.db.ddl.delta.DBDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBDeltaWithProperties;
+import org.eclipse.net4j.internal.db.ddl.delta.DBFieldDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBIndexDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBIndexFieldDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBPropertyDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBTableDelta;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
/**
* @since 4.2
@@ -35,29 +49,28 @@ public interface IDBDeltaVisitor
*/
public static class Default implements IDBDeltaVisitor
{
- protected void visitDefault(IDBDelta delta)
- {
- }
-
public void visit(IDBSchemaDelta delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -78,23 +91,26 @@ public interface IDBDeltaVisitor
public void visit(IDBTableDelta delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -115,23 +131,26 @@ public interface IDBDeltaVisitor
public void visit(IDBFieldDelta delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -152,23 +171,26 @@ public interface IDBDeltaVisitor
public void visit(IDBIndexDelta delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -189,23 +211,26 @@ public interface IDBDeltaVisitor
public void visit(IDBIndexFieldDelta delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -226,23 +251,26 @@ public interface IDBDeltaVisitor
public void visit(IDBPropertyDelta<?> delta)
{
- ChangeKind changeKind = delta.getChangeKind();
- switch (changeKind)
+ if (handle(delta))
{
- case ADDED:
- added(delta);
- break;
-
- case REMOVED:
- removed(delta);
- break;
-
- case CHANGED:
- changed(delta);
- break;
-
- default:
- throw new IllegalStateException("Illegal change kind: " + changeKind);
+ ChangeKind changeKind = delta.getChangeKind();
+ switch (changeKind)
+ {
+ case ADD:
+ added(delta);
+ break;
+
+ case REMOVE:
+ removed(delta);
+ break;
+
+ case CHANGE:
+ changed(delta);
+ break;
+
+ default:
+ illegalChangeKind(changeKind);
+ }
}
}
@@ -261,5 +289,360 @@ public interface IDBDeltaVisitor
{
visitDefault(delta);
}
+
+ protected void visitDefault(IDBDelta delta)
+ {
+ }
+
+ protected boolean handle(IDBDelta delta)
+ {
+ return true;
+ }
+
+ private void illegalChangeKind(ChangeKind changeKind)
+ {
+ throw new IllegalStateException("Illegal change kind: " + changeKind);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Filter extends Default
+ {
+ public static final Map<ChangeKind, Boolean> DEFAULT_POLICY = createPolicy(null, null);
+
+ public static final Boolean ALLOWED = Boolean.TRUE;
+
+ public static final Boolean FORBIDDEN = Boolean.FALSE;
+
+ private Map<ChangeKind, Boolean> policy;
+
+ public Filter()
+ {
+ this(null);
+ }
+
+ public Filter(Map<ChangeKind, Boolean> policy)
+ {
+ this.policy = policy == null ? DEFAULT_POLICY : policy;
+ }
+
+ public Filter(Set<ChangeKind> ignoredChanges, Set<ChangeKind> forbiddenChanges)
+ {
+ this(createPolicy(ignoredChanges, forbiddenChanges));
+ }
+
+ public final Map<ChangeKind, Boolean> getPolicy()
+ {
+ return policy;
+ }
+
+ @Override
+ protected void added(IDBSchemaDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void added(IDBTableDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void added(IDBFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void added(IDBIndexDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void added(IDBIndexFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void added(IDBPropertyDelta<?> delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBSchemaDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBTableDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBIndexDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBIndexFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void removed(IDBPropertyDelta<?> delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBSchemaDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBTableDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBIndexDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBIndexFieldDelta delta)
+ {
+ doVisit(delta);
+ }
+
+ @Override
+ protected void changed(IDBPropertyDelta<?> delta)
+ {
+ doVisit(delta);
+ }
+
+ protected void doVisit(IDBSchemaDelta delta)
+ {
+ visitDefault(delta);
+ }
+
+ protected void doVisit(IDBTableDelta delta)
+ {
+ visitDefault(delta);
+ }
+
+ protected void doVisit(IDBFieldDelta delta)
+ {
+ visitDefault(delta);
+ }
+
+ protected void doVisit(IDBIndexDelta delta)
+ {
+ visitDefault(delta);
+ }
+
+ protected void doVisit(IDBIndexFieldDelta delta)
+ {
+ visitDefault(delta);
+ }
+
+ protected void doVisit(IDBPropertyDelta<?> delta)
+ {
+ visitDefault(delta);
+ }
+
+ @Override
+ protected boolean handle(IDBDelta delta)
+ {
+ Boolean deltaPolicy = policy.get(delta.getChangeKind());
+ if (deltaPolicy == FORBIDDEN)
+ {
+ throw new ForbiddenChangeException(delta);
+ }
+
+ return deltaPolicy == ALLOWED;
+ }
+
+ public static Map<ChangeKind, Boolean> createPolicy(Set<ChangeKind> ignoredChanges, Set<ChangeKind> forbiddenChanges)
+ {
+ if (ignoredChanges == null)
+ {
+ ignoredChanges = Collections.emptySet();
+ }
+
+ if (forbiddenChanges == null)
+ {
+ forbiddenChanges = Collections.emptySet();
+ }
+
+ Map<ChangeKind, Boolean> policy = new HashMap<IDBDelta.ChangeKind, Boolean>();
+ for (ChangeKind changeKind : ChangeKind.values())
+ {
+ if (!ignoredChanges.contains(changeKind))
+ {
+ policy.put(changeKind, ALLOWED);
+ }
+ }
+
+ for (ChangeKind changeKind : forbiddenChanges)
+ {
+ policy.put(changeKind, FORBIDDEN);
+ }
+
+ return policy;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class ForbiddenChangeException extends RuntimeException
+ {
+ private static final long serialVersionUID = 1L;
+
+ private final IDBDelta delta;
+
+ public ForbiddenChangeException(IDBDelta delta)
+ {
+ super("Forbidden change: " + delta);
+ this.delta = delta;
+ }
+
+ public IDBDelta getDelta()
+ {
+ return delta;
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Copier extends Filter
+ {
+ private DBSchemaDelta result;
+
+ public Copier()
+ {
+ }
+
+ public Copier(Map<ChangeKind, Boolean> policies)
+ {
+ super(policies);
+ }
+
+ public Copier(Set<ChangeKind> ignoredChanges, Set<ChangeKind> forbiddenChanges)
+ {
+ super(ignoredChanges, forbiddenChanges);
+ }
+
+ public final IDBSchemaDelta getResult()
+ {
+ return result;
+ }
+
+ @Override
+ protected void doVisit(IDBSchemaDelta delta)
+ {
+ result = new DBSchemaDelta(delta.getName(), delta.getChangeKind());
+ }
+
+ @Override
+ protected void doVisit(IDBTableDelta delta)
+ {
+ DBTableDelta copy = new DBTableDelta(result, delta.getName(), delta.getChangeKind());
+ result.addTableDelta(copy);
+ }
+
+ @Override
+ protected void doVisit(IDBFieldDelta delta)
+ {
+ DBTableDelta parentCopy = getParentCopy(delta);
+ DBFieldDelta copy = new DBFieldDelta(parentCopy, delta.getName(), delta.getChangeKind());
+ parentCopy.addFieldDelta(copy);
+ }
+
+ @Override
+ protected void doVisit(IDBIndexDelta delta)
+ {
+ DBTableDelta parentCopy = getParentCopy(delta);
+ DBIndexDelta copy = new DBIndexDelta(parentCopy, delta.getName(), delta.getChangeKind());
+ parentCopy.addIndexDelta(copy);
+ }
+
+ @Override
+ protected void doVisit(IDBIndexFieldDelta delta)
+ {
+ DBIndexDelta parentCopy = getParentCopy(delta);
+ DBIndexFieldDelta copy = new DBIndexFieldDelta(parentCopy, delta.getName(), delta.getChangeKind());
+ parentCopy.addIndexFieldDelta(copy);
+ }
+
+ @Override
+ protected void doVisit(IDBPropertyDelta<?> delta)
+ {
+ DBDeltaWithProperties parentCopy = getParentCopy(delta);
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ DBPropertyDelta<?> copy = new DBPropertyDelta(parentCopy, delta.getName(), delta.getType(), delta.getValue(),
+ delta.getOldValue());
+ parentCopy.addPropertyDelta(copy);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends DBDelta> T getParentCopy(IDBDelta delta)
+ {
+ if (result == null)
+ {
+ throw new IllegalStateException("Copier can only be accepted by schema deltas");
+ }
+
+ DBDelta parent = (DBDelta)delta.getParent();
+ DeltaType deltaType = parent.getDeltaType();
+ switch (deltaType)
+ {
+ case SCHEMA:
+ return (T)result;
+
+ case TABLE:
+ return (T)result.getTableDelta(parent.getName());
+
+ case FIELD:
+ return (T)result.getTableDelta(parent.getParent().getName()).getFieldDelta(parent.getName());
+
+ case INDEX:
+ return (T)result.getTableDelta(parent.getParent().getName()).getIndexDelta(parent.getName());
+
+ case INDEX_FIELD:
+ return (T)result.getTableDelta(parent.getParent().getParent().getName())
+ .getIndexDelta(parent.getParent().getName()).getIndexFieldDelta(parent.getName());
+
+ default:
+ throw new IllegalStateException("Illegal delta type: " + deltaType);
+ }
+ }
}
}
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java
index 0e81804731..118dc483b2 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBIndexDelta.java
@@ -27,6 +27,12 @@ public interface IDBIndexDelta extends IDBDeltaWithProperties
public IDBTableDelta getParent();
+ public int getIndexFieldDeltaCount();
+
+ public IDBIndexFieldDelta getIndexFieldDelta(int position);
+
+ public IDBIndexFieldDelta getIndexFieldDelta(String name);
+
public Map<String, IDBIndexFieldDelta> getIndexFieldDeltas();
public IDBIndexFieldDelta[] getIndexFieldDeltasSortedByPosition();
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBSchemaDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBSchemaDelta.java
index cdb8daf61d..d9517e6b3d 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBSchemaDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBSchemaDelta.java
@@ -22,6 +22,10 @@ import java.util.Map;
*/
public interface IDBSchemaDelta extends IDBDelta
{
+ public int getTableDeltaCount();
+
+ public IDBTableDelta getTableDelta(String name);
+
public Map<String, IDBTableDelta> getTableDeltas();
public IDBTableDelta[] getTableDeltasSortedByName();
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBTableDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBTableDelta.java
index 9457142c69..994f23e232 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBTableDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/delta/IDBTableDelta.java
@@ -25,6 +25,16 @@ public interface IDBTableDelta extends IDBDelta
{
public IDBSchemaDelta getParent();
+ public int getFieldDeltaCount();
+
+ public int getIndexDeltaCount();
+
+ public IDBFieldDelta getFieldDelta(int position);
+
+ public IDBFieldDelta getFieldDelta(String name);
+
+ public IDBIndexDelta getIndexDelta(String name);
+
public Map<String, IDBFieldDelta> getFieldDeltas();
public Map<String, IDBIndexDelta> getIndexDeltas();
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java
index 4af7eb9d01..9cef71223d 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java
@@ -14,7 +14,12 @@ import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.DBUtil.RunnableWithConnection;
import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.db.IDBDatabase;
+import org.eclipse.net4j.db.IDBSchemaTransaction;
import org.eclipse.net4j.db.IDBTransaction;
+import org.eclipse.net4j.db.ddl.IDBSchema;
+import org.eclipse.net4j.db.ddl.delta.IDBDelta.ChangeKind;
+import org.eclipse.net4j.db.ddl.delta.IDBDeltaVisitor;
+import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.spi.db.DBAdapter;
import org.eclipse.net4j.spi.db.DBSchema;
import org.eclipse.net4j.util.WrappedException;
@@ -23,6 +28,7 @@ import org.eclipse.net4j.util.container.SetContainer;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;
+import java.util.Map;
/**
* @author Eike Stepper
@@ -114,6 +120,38 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
return schemaTransaction;
}
+ public void ensureSchema(IDBSchema schema)
+ {
+ ensureSchema(schema, null);
+ }
+
+ public void ensureSchema(IDBSchema schema, Map<ChangeKind, Boolean> policy)
+ {
+ IDBSchemaTransaction schemaTransaction = null;
+
+ try
+ {
+ schemaTransaction = openSchemaTransaction();
+ IDBSchema workingCopy = schemaTransaction.getSchema();
+
+ IDBSchemaDelta delta = schema.compare(workingCopy);
+
+ IDBDeltaVisitor.Copier copier = new IDBDeltaVisitor.Copier(policy);
+ delta.accept(copier);
+ IDBSchemaDelta result = copier.getResult();
+
+ result.applyTo(workingCopy);
+ schemaTransaction.commit();
+ }
+ finally
+ {
+ if (schemaTransaction != null)
+ {
+ schemaTransaction.close();
+ }
+ }
+ }
+
public DBTransaction openTransaction()
{
DBTransaction transaction = new DBTransaction(this);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTransaction.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTransaction.java
index a8f2309416..c32d1592cc 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTransaction.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBTransaction.java
@@ -12,6 +12,7 @@ package org.eclipse.net4j.internal.db;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.db.IDBPreparedStatement;
import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability;
import org.eclipse.net4j.db.IDBSchemaTransaction;
@@ -44,7 +45,22 @@ public final class DBTransaction implements IDBTransaction
public DBTransaction(DBDatabase database)
{
this.database = database;
- connection = database.getConnectionProvider().getConnection();
+
+ IDBConnectionProvider connectionProvider = database.getConnectionProvider();
+ connection = connectionProvider.getConnection();
+ if (connection == null)
+ {
+ throw new DBException("No connection from connection provider: " + connectionProvider);
+ }
+
+ try
+ {
+ connection.setAutoCommit(false);
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex, "SET AUTO COMMIT = false");
+ }
}
public DBDatabase getDatabase()
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBDelta.java
index 03ee54958e..ec00146c92 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBDelta.java
@@ -169,7 +169,7 @@ public abstract class DBDelta extends DBNamedElement implements IDBDelta
public static ChangeKind getChangeKind(Object object, Object oldObject)
{
- return object == null ? ChangeKind.REMOVED : oldObject == null ? ChangeKind.ADDED : ChangeKind.CHANGED;
+ return object == null ? ChangeKind.REMOVE : oldObject == null ? ChangeKind.ADD : ChangeKind.CHANGE;
}
protected static <T extends IDBSchemaElement> void compare(T[] elements, T[] oldElements,
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java
index 2ba9c0f9c5..bfe0ba64ce 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexDelta.java
@@ -90,6 +90,29 @@ public final class DBIndexDelta extends DBDeltaWithProperties implements IDBInde
return (DBTableDelta)super.getParent();
}
+ public int getIndexFieldDeltaCount()
+ {
+ return indexFieldDeltas.size();
+ }
+
+ public DBIndexFieldDelta getIndexFieldDelta(int position)
+ {
+ for (IDBIndexFieldDelta indexFieldDelta : indexFieldDeltas.values())
+ {
+ if (indexFieldDelta.getPosition() == position)
+ {
+ return (DBIndexFieldDelta)indexFieldDelta;
+ }
+ }
+
+ return null;
+ }
+
+ public DBIndexFieldDelta getIndexFieldDelta(String name)
+ {
+ return (DBIndexFieldDelta)indexFieldDeltas.get(name);
+ }
+
public Map<String, IDBIndexFieldDelta> getIndexFieldDeltas()
{
return Collections.unmodifiableMap(indexFieldDeltas);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexFieldDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexFieldDelta.java
index 3afebddd83..e6f3ad509f 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexFieldDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBIndexFieldDelta.java
@@ -27,14 +27,14 @@ public final class DBIndexFieldDelta extends DBDeltaWithPosition implements IDBI
{
private static final long serialVersionUID = 1L;
- public DBIndexFieldDelta(DBDelta parent, ChangeKind changeKind, String name)
+ public DBIndexFieldDelta(DBDelta parent, String name, ChangeKind changeKind)
{
super(parent, name, changeKind);
}
public DBIndexFieldDelta(DBIndexDelta parent, DBIndexField indexField, DBIndexField oldIndexField)
{
- this(parent, getChangeKind(indexField, oldIndexField), getName(indexField, oldIndexField));
+ this(parent, getName(indexField, oldIndexField), getChangeKind(indexField, oldIndexField));
Integer position = indexField == null ? null : indexField.getPosition();
Integer oldPosition = oldIndexField == null ? null : oldIndexField.getPosition();
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
index 279694f3e0..b25dac5916 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBSchemaDelta.java
@@ -49,7 +49,7 @@ public final class DBSchemaDelta extends DBDelta implements IDBSchemaDelta
public DBSchemaDelta(DBSchema schema, IDBSchema oldSchema)
{
- this(schema.getName(), oldSchema == null ? ChangeKind.ADDED : ChangeKind.CHANGED);
+ this(schema.getName(), oldSchema == null ? ChangeKind.ADD : ChangeKind.CHANGE);
IDBTable[] tables = schema.getTables();
IDBTable[] oldTables = oldSchema == null ? DBSchema.NO_TABLES : oldSchema.getTables();
@@ -78,6 +78,16 @@ public final class DBSchemaDelta extends DBDelta implements IDBSchemaDelta
return DeltaType.SCHEMA;
}
+ public int getTableDeltaCount()
+ {
+ return tableDeltas.size();
+ }
+
+ public DBTableDelta getTableDelta(String name)
+ {
+ return (DBTableDelta)tableDeltas.get(name);
+ }
+
public Map<String, IDBTableDelta> getTableDeltas()
{
return Collections.unmodifiableMap(tableDeltas);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBTableDelta.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBTableDelta.java
index 286064240a..1b7e1d0b8d 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBTableDelta.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/delta/DBTableDelta.java
@@ -96,6 +96,39 @@ public final class DBTableDelta extends DBDelta implements IDBTableDelta
return (DBSchemaDelta)super.getParent();
}
+ public int getFieldDeltaCount()
+ {
+ return fieldDeltas.size();
+ }
+
+ public int getIndexDeltaCount()
+ {
+ return indexDeltas.size();
+ }
+
+ public DBFieldDelta getFieldDelta(int position)
+ {
+ for (IDBFieldDelta fieldDelta : fieldDeltas.values())
+ {
+ if (fieldDelta.getPosition() == position)
+ {
+ return (DBFieldDelta)fieldDelta;
+ }
+ }
+
+ return null;
+ }
+
+ public DBFieldDelta getFieldDelta(String name)
+ {
+ return (DBFieldDelta)fieldDeltas.get(name);
+ }
+
+ public DBIndexDelta getIndexDelta(String name)
+ {
+ return (DBIndexDelta)indexDeltas.get(name);
+ }
+
public Map<String, IDBFieldDelta> getFieldDeltas()
{
return Collections.unmodifiableMap(fieldDeltas);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
index f678542cb9..85e9b82144 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
@@ -340,15 +340,15 @@ public abstract class DBAdapter implements IDBAdapter
ChangeKind changeKind = delta.getChangeKind();
switch (changeKind)
{
- case ADDED:
+ case ADD:
createTable(connection, table, delta);
break;
- case REMOVED:
+ case REMOVE:
dropTable(connection, table, delta);
break;
- case CHANGED:
+ case CHANGE:
alterTable(connection, table, delta);
break;
@@ -364,15 +364,15 @@ public abstract class DBAdapter implements IDBAdapter
ChangeKind changeKind = delta.getChangeKind();
switch (changeKind)
{
- case ADDED:
+ case ADD:
createIndex(connection, element, delta);
break;
- case REMOVED:
+ case REMOVE:
dropIndex(connection, element, delta);
break;
- case CHANGED:
+ case CHANGE:
dropIndex(connection, element, delta);
createIndex(connection, element, delta);
break;
@@ -391,7 +391,7 @@ public abstract class DBAdapter implements IDBAdapter
*/
protected void createTable(Connection connection, IDBTable table, IDBTableDelta delta)
{
- CheckUtil.checkArg(delta.getChangeKind() == ChangeKind.ADDED, "Not added: " + delta.getName());
+ CheckUtil.checkArg(delta.getChangeKind() == ChangeKind.ADD, "Not added: " + delta.getName());
StringBuilder builder = new StringBuilder();
builder.append("CREATE TABLE "); //$NON-NLS-1$

Back to the top