Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-03-09 09:21:12 +0000
committerEike Stepper2013-03-09 11:59:26 +0000
commitf08335da87834546e311c8d7240edc63c39afa2e (patch)
tree352c5f06d7f34abfc7d69d11b6ff2bfbbc181a4f
parent5bc362a99567e233660fdffbd512a6f1b973ad1b (diff)
downloadcdo-f08335da87834546e311c8d7240edc63c39afa2e.tar.gz
cdo-f08335da87834546e311c8d7240edc63c39afa2e.tar.xz
cdo-f08335da87834546e311c8d7240edc63c39afa2e.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.java28
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndex.java11
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java10
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/SchemaElementNotFoundException.java7
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java119
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java9
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java24
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java32
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchema.java19
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/ObjectUtil.java13
11 files changed, 227 insertions, 50 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 f115dc24a0..928180ccea 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
@@ -13,8 +13,10 @@ package org.eclipse.net4j.db;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBSchemaElement;
import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.util.collection.Closeable;
import org.eclipse.net4j.util.container.IContainer;
+import org.eclipse.net4j.util.event.IEvent;
/**
* @author Eike Stepper
@@ -36,6 +38,13 @@ public interface IDBDatabase extends IContainer<IDBTransaction>, Closeable
public IDBSchemaTransaction getSchemaTransaction();
+ public void ensureSchemaElement(RunnableWithSchema updateRunnable, RunnableWithSchema commitRunnable);
+
+ public <T extends IDBSchemaElement, P extends IDBSchemaElement> T ensureSchemaElement(P parent, Class<T> type,
+ String name, RunnableWithSchemaElement<T, P> runnable);
+
+ public IDBTable ensureTable(String name, RunnableWithTable runnable);
+
public IDBTransaction openTransaction();
public IDBTransaction[] getTransactions();
@@ -44,10 +53,23 @@ public interface IDBDatabase extends IContainer<IDBTransaction>, Closeable
public void setStatementCacheCapacity(int statementCacheCapacity);
- public <T extends IDBSchemaElement, P extends IDBSchemaElement> T ensureSchemaElement(P parent, Class<T> type,
- String name, RunnableWithSchemaElement<T, P> runnable);
+ /**
+ * @author Eike Stepper
+ */
+ public interface SchemaChangedEvent extends IEvent
+ {
+ public IDBDatabase getSource();
- public IDBTable ensureTable(String name, RunnableWithTable runnable);
+ public IDBSchemaDelta getSchemaDelta();
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface RunnableWithSchema
+ {
+ public void run(IDBSchema schema);
+ }
/**
* @author Eike Stepper
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndex.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndex.java
index 00fdd6003a..8f40730e75 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndex.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndex.java
@@ -10,7 +10,6 @@
*/
package org.eclipse.net4j.db.ddl;
-
/**
* An index specification in a {@link IDBTable DB table}.
*
@@ -50,6 +49,11 @@ public interface IDBIndex extends IDBSchemaElement
/**
* @since 4.2
*/
+ public IDBIndexField getIndexFieldSafe(String name) throws SchemaElementNotFoundException;
+
+ /**
+ * @since 4.2
+ */
public IDBIndexField getIndexField(String name);
/**
@@ -60,6 +64,11 @@ public interface IDBIndex extends IDBSchemaElement
/**
* @since 4.2
*/
+ public IDBField getFieldSafe(String name) throws SchemaElementNotFoundException;
+
+ /**
+ * @since 4.2
+ */
public IDBField getField(String name);
public IDBField getField(int position);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java
index 39eda29ca8..a1e16a4728 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java
@@ -48,6 +48,11 @@ public interface IDBSchema extends IDBSchemaElement
*/
public IDBTable removeTable(String name) throws DBException;
+ /**
+ * @since 4.2
+ */
+ public IDBTable getTableSafe(String name) throws SchemaElementNotFoundException;
+
public IDBTable getTable(String name);
public IDBTable[] getTables();
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java
index d7af67b16c..d953725a03 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBTable.java
@@ -38,6 +38,11 @@ public interface IDBTable extends IDBSchemaElement
public IDBField addField(String name, DBType type, int precision, int scale, boolean notNull);
+ /**
+ * @since 4.2
+ */
+ public IDBField getFieldSafe(String name) throws SchemaElementNotFoundException;
+
public IDBField getField(String name);
public IDBField getField(int position);
@@ -81,6 +86,11 @@ public interface IDBTable extends IDBSchemaElement
/**
* @since 4.2
*/
+ public IDBIndex getIndexSafe(String name) throws SchemaElementNotFoundException;
+
+ /**
+ * @since 4.2
+ */
public IDBIndex getIndex(String name);
/**
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/SchemaElementNotFoundException.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/SchemaElementNotFoundException.java
index e663db898f..d807be831c 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/SchemaElementNotFoundException.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/SchemaElementNotFoundException.java
@@ -11,7 +11,7 @@
package org.eclipse.net4j.db.ddl;
import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.spi.db.DBSchemaElement;
/**
* @since 4.2
@@ -29,10 +29,11 @@ public class SchemaElementNotFoundException extends DBException
public SchemaElementNotFoundException(IDBSchemaElement parent, IDBSchemaElement.SchemaElementType type, String name)
{
- super("Schema element '" + name + "' of type " + type + " not found in " + DBUtil.dumpToString(parent));
+ super(type.toString() + " " + DBSchemaElement.name(name) + " not found in " + parent.getSchemaElementType() + " "
+ + parent);
this.parent = parent;
this.type = type;
- this.name = name;
+ this.name = DBSchemaElement.name(name);
}
public IDBSchemaElement getParent()
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 9a3178e28b..eb61cc3dea 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
@@ -18,10 +18,15 @@ import org.eclipse.net4j.db.IDBTransaction;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBSchemaElement;
import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
+import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta;
import org.eclipse.net4j.spi.db.DBAdapter;
import org.eclipse.net4j.spi.db.DBSchema;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.container.SetContainer;
+import org.eclipse.net4j.util.event.Event;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
import java.sql.Connection;
import java.sql.SQLException;
@@ -86,7 +91,7 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
return schemaTransaction;
}
- public void closeSchemaTransaction()
+ public void closeSchemaTransaction(DBSchemaDelta delta)
{
try
{
@@ -94,6 +99,8 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
{
((DBTransaction)transaction).invalidateStatementCache();
}
+
+ fireEvent(new SchemaChangedEventImpl(delta));
}
finally
{
@@ -107,31 +114,35 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
return schemaTransaction;
}
- public DBTransaction openTransaction()
- {
- DBTransaction transaction = new DBTransaction(this);
- addElement(transaction);
- return transaction;
- }
-
- public void closeTransaction(DBTransaction transaction)
- {
- removeElement(transaction);
- }
-
- public IDBTransaction[] getTransactions()
- {
- return getElements();
- }
-
- public int getStatementCacheCapacity()
+ public void ensureSchemaElement(RunnableWithSchema updateRunnable, final RunnableWithSchema commitRunnable)
{
- return statementCacheCapacity;
- }
+ if (schemaTransaction != null)
+ {
+ DBSchema workingCopy = schemaTransaction.getWorkingCopy();
+ updateRunnable.run(workingCopy);
- public void setStatementCacheCapacity(int statementCacheCapacity)
- {
- this.statementCacheCapacity = statementCacheCapacity;
+ if (commitRunnable != null)
+ {
+ addListener(new IListener()
+ {
+ public void notifyEvent(IEvent event)
+ {
+ if (event instanceof SchemaChangedEvent)
+ {
+ commitRunnable.run(schema);
+ removeListener(this);
+ }
+ }
+ });
+ }
+ }
+ else
+ {
+ if (commitRunnable != null)
+ {
+ commitRunnable.run(schema);
+ }
+ }
}
public <T extends IDBSchemaElement, P extends IDBSchemaElement> T ensureSchemaElement(P parent, Class<T> type,
@@ -177,6 +188,33 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
});
}
+ public DBTransaction openTransaction()
+ {
+ DBTransaction transaction = new DBTransaction(this);
+ addElement(transaction);
+ return transaction;
+ }
+
+ public void closeTransaction(DBTransaction transaction)
+ {
+ removeElement(transaction);
+ }
+
+ public IDBTransaction[] getTransactions()
+ {
+ return getElements();
+ }
+
+ public int getStatementCacheCapacity()
+ {
+ return statementCacheCapacity;
+ }
+
+ public void setStatementCacheCapacity(int statementCacheCapacity)
+ {
+ this.statementCacheCapacity = statementCacheCapacity;
+ }
+
public boolean isClosed()
{
return !isActive();
@@ -271,14 +309,14 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
/**
* @author Eike Stepper
*/
- public interface SchemaAccess
+ private interface SchemaAccess
{
}
/**
* @author Eike Stepper
*/
- public final class ReadSchemaAccess implements SchemaAccess
+ private final class ReadSchemaAccess implements SchemaAccess
{
private int readers;
@@ -302,7 +340,7 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
/**
* @author Eike Stepper
*/
- public final class WriteSchemaAccess implements SchemaAccess
+ private final class WriteSchemaAccess implements SchemaAccess
{
@Override
public String toString()
@@ -310,4 +348,31 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID
return "WRITER";
}
}
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class SchemaChangedEventImpl extends Event implements SchemaChangedEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private final IDBSchemaDelta schemaDelta;
+
+ public SchemaChangedEventImpl(IDBSchemaDelta schemaDelta)
+ {
+ super(DBDatabase.this);
+ this.schemaDelta = schemaDelta;
+ }
+
+ @Override
+ public IDBDatabase getSource()
+ {
+ return (IDBDatabase)super.getSource();
+ }
+
+ public IDBSchemaDelta getSchemaDelta()
+ {
+ return schemaDelta;
+ }
+ }
}
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java
index c5da299906..823f8ede51 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBSchemaTransaction.java
@@ -121,7 +121,7 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable
finally
{
oldSchema.lock();
- close();
+ doClose(delta);
}
return delta;
@@ -129,9 +129,14 @@ public final class DBSchemaTransaction implements IDBSchemaTransaction, Runnable
public void close()
{
+ doClose(null);
+ }
+
+ private void doClose(DBSchemaDelta delta)
+ {
if (!isClosed())
{
- database.closeSchemaTransaction();
+ database.closeSchemaTransaction(delta);
transaction = null;
oldSchema = null;
workingCopy = null;
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java
index 1bd9cc0706..2ea7b4160a 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java
@@ -137,12 +137,7 @@ public class DBIndex extends DBSchemaElement implements IDBIndex
public IDBIndexField addIndexField(String name) throws SchemaElementNotFoundException
{
- DBField field = table.getField(name);
- if (field == null)
- {
- throw new SchemaElementNotFoundException(this, SchemaElementType.FIELD, name);
- }
-
+ DBField field = table.getFieldSafe(name);
return addIndexField(field);
}
@@ -168,6 +163,17 @@ public class DBIndex extends DBSchemaElement implements IDBIndex
resetElements();
}
+ public DBIndexField getIndexFieldSafe(String name) throws SchemaElementNotFoundException
+ {
+ DBIndexField indexField = getIndexField(name);
+ if (indexField == null)
+ {
+ throw new SchemaElementNotFoundException(this, SchemaElementType.INDEX_FIELD, name);
+ }
+
+ return indexField;
+ }
+
public DBIndexField getIndexField(String name)
{
return findElement(getIndexFields(), name);
@@ -178,6 +184,12 @@ public class DBIndex extends DBSchemaElement implements IDBIndex
return indexFields.get(position);
}
+ public DBField getFieldSafe(String name) throws SchemaElementNotFoundException
+ {
+ DBIndexField indexField = getIndexFieldSafe(name);
+ return indexField.getField();
+ }
+
public DBField getField(String name)
{
name = name(name);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java
index fc3d939d0e..555bcd97bb 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBTable.java
@@ -133,6 +133,17 @@ public class DBTable extends DBSchemaElement implements IDBTable
resetElements();
}
+ public DBField getFieldSafe(String name) throws SchemaElementNotFoundException
+ {
+ DBField field = getField(name);
+ if (field == null)
+ {
+ throw new SchemaElementNotFoundException(this, SchemaElementType.FIELD, name);
+ }
+
+ return field;
+ }
+
public DBField getField(String name)
{
return findElement(getFields(), name);
@@ -158,11 +169,8 @@ public class DBTable extends DBSchemaElement implements IDBTable
List<DBField> result = new ArrayList<DBField>();
for (String fieldName : fieldNames)
{
- DBField field = getField(fieldName);
- if (field == null)
- {
- throw new SchemaElementNotFoundException(this, SchemaElementType.FIELD, fieldName);
- }
+ DBField field = getFieldSafe(fieldName);
+ result.add(field);
}
return result.toArray(new DBField[result.size()]);
@@ -217,7 +225,8 @@ public class DBTable extends DBSchemaElement implements IDBTable
public DBIndex addIndex(IDBIndex.Type type, String... fieldNames)
{
- return addIndex(type, getFields(fieldNames));
+ DBField[] fields = getFields(fieldNames);
+ return addIndex(type, fields);
}
public DBIndex addIndexEmpty(IDBIndex.Type type)
@@ -248,6 +257,17 @@ public class DBTable extends DBSchemaElement implements IDBTable
resetElements();
}
+ public DBIndex getIndexSafe(String name) throws SchemaElementNotFoundException
+ {
+ DBIndex index = getIndex(name);
+ if (index == null)
+ {
+ throw new SchemaElementNotFoundException(this, SchemaElementType.INDEX, name);
+ }
+
+ return index;
+ }
+
public DBIndex getIndex(String name)
{
return findElement(getIndices(), name);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchema.java
index 5be3817622..8afdead23e 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchema.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchema.java
@@ -22,6 +22,7 @@ import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBSchemaElement;
import org.eclipse.net4j.db.ddl.IDBSchemaVisitor;
import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.db.ddl.SchemaElementNotFoundException;
import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.internal.db.ddl.DBField;
import org.eclipse.net4j.internal.db.ddl.DBIndex;
@@ -52,12 +53,12 @@ public class DBSchema extends DBSchemaElement implements IDBSchema
private static final long serialVersionUID = 1L;
+ private static int indexCounter;
+
private Map<String, DBTable> tables = new HashMap<String, DBTable>();
private transient boolean locked;
- private transient int indexCounter;
-
public DBSchema(String name)
{
super(name);
@@ -216,6 +217,20 @@ public class DBSchema extends DBSchemaElement implements IDBSchema
}
/**
+ * @since 4.2
+ */
+ public final IDBTable getTableSafe(String name) throws SchemaElementNotFoundException
+ {
+ IDBTable table = getTable(name);
+ if (table == null)
+ {
+ throw new SchemaElementNotFoundException(this, SchemaElementType.TABLE, name);
+ }
+
+ return table;
+ }
+
+ /**
* @since 2.0
*/
public IDBTable getTable(String name)
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/ObjectUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/ObjectUtil.java
index 988468aa64..c0c0320444 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/ObjectUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/ObjectUtil.java
@@ -135,4 +135,17 @@ public final class ObjectUtil
return null;
}
+
+ /**
+ * @since 3.3
+ */
+ public static <T> T notNull(T object)
+ {
+ if (object == null)
+ {
+ throw new NullPointerException();
+ }
+
+ return object;
+ }
}

Back to the top