diff options
author | Eike Stepper | 2013-03-08 10:48:38 +0000 |
---|---|---|
committer | Eike Stepper | 2013-03-08 10:48:38 +0000 |
commit | c359069dd7114dd2ab4038bae89c5f42350cb885 (patch) | |
tree | 4a242e816f83de8de718a33668bc242a586f64fe /plugins/org.eclipse.net4j.db/src/org | |
parent | f2879b592ade925aa9b793a36e3884efc63e52ba (diff) | |
download | cdo-c359069dd7114dd2ab4038bae89c5f42350cb885.tar.gz cdo-c359069dd7114dd2ab4038bae89c5f42350cb885.tar.xz cdo-c359069dd7114dd2ab4038bae89c5f42350cb885.zip |
[401763] Make CDO Server more robust against data dictionary changes
https://bugs.eclipse.org/bugs/show_bug.cgi?id=401763
Diffstat (limited to 'plugins/org.eclipse.net4j.db/src/org')
14 files changed, 218 insertions, 10 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 82c00288cf..f115dc24a0 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,6 +11,8 @@ 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.util.collection.Closeable; import org.eclipse.net4j.util.container.IContainer; @@ -41,4 +43,25 @@ public interface IDBDatabase extends IContainer<IDBTransaction>, Closeable public int getStatementCacheCapacity(); 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); + + public IDBTable ensureTable(String name, RunnableWithTable runnable); + + /** + * @author Eike Stepper + */ + public interface RunnableWithSchemaElement<T extends IDBSchemaElement, P extends IDBSchemaElement> + { + public T run(P parent, String name); + } + + /** + * @author Eike Stepper + */ + public interface RunnableWithTable + { + public void run(IDBTable table); + } } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java index 0ab991768e..370fafde1d 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java @@ -24,6 +24,11 @@ public interface IDBField extends IDBSchemaElement, PositionProvider { public static final int DEFAULT = -1; + /** + * @since 4.2 + */ + public IDBTable getParent(); + public IDBTable getTable(); public DBType getType(); 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 8e9de00991..d0f4198630 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 @@ -19,6 +19,11 @@ package org.eclipse.net4j.db.ddl; */ public interface IDBIndex extends IDBSchemaElement { + /** + * @since 4.2 + */ + public IDBTable getParent(); + public IDBTable getTable(); public Type getType(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndexField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndexField.java index 73b20f5598..0758d572ae 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndexField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBIndexField.java @@ -22,6 +22,11 @@ import org.eclipse.net4j.util.collection.PositionProvider; */ public interface IDBIndexField extends IDBSchemaElement, PositionProvider { + /** + * @since 4.2 + */ + public IDBIndex getParent(); + public IDBIndex getIndex(); public IDBField getField(); 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 d6971757de..39eda29ca8 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 @@ -36,6 +36,11 @@ public interface IDBSchema extends IDBSchemaElement */ public boolean isLocked(); + /** + * @since 4.2 + */ + public <T extends IDBSchemaElement> T findElement(IDBSchemaElement prototype); + public IDBTable addTable(String name) throws DBException; /** diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchemaElement.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchemaElement.java index 15e36e9a4a..bf75072b5e 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchemaElement.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchemaElement.java @@ -35,6 +35,11 @@ public interface IDBSchemaElement extends IDBNamedElement, IContainer<IDBSchemaE /** * @since 4.2 */ + public IDBSchemaElement getParent(); + + /** + * @since 4.2 + */ @Deprecated public void setName(String name); @@ -43,6 +48,11 @@ public interface IDBSchemaElement extends IDBNamedElement, IContainer<IDBSchemaE /** * @since 4.2 */ + public <T extends IDBSchemaElement> T getElement(Class<T> type, String name); + + /** + * @since 4.2 + */ public void accept(IDBSchemaVisitor visitor); /** 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 554727e02d..de3893a5dd 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 @@ -21,6 +21,11 @@ import org.eclipse.net4j.db.DBType; */ public interface IDBTable extends IDBSchemaElement { + /** + * @since 4.2 + */ + public IDBSchema getParent(); + public IDBField addField(String name, DBType type); public IDBField addField(String name, DBType type, boolean notNull); 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 c52be7c5a3..9a3178e28b 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 @@ -15,6 +15,9 @@ import org.eclipse.net4j.db.DBUtil.RunnableWithConnection; import org.eclipse.net4j.db.IDBConnectionProvider; import org.eclipse.net4j.db.IDBDatabase; 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.spi.db.DBAdapter; import org.eclipse.net4j.spi.db.DBSchema; import org.eclipse.net4j.util.WrappedException; @@ -69,16 +72,6 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID return connectionProvider; } - public int getStatementCacheCapacity() - { - return statementCacheCapacity; - } - - public void setStatementCacheCapacity(int statementCacheCapacity) - { - this.statementCacheCapacity = statementCacheCapacity; - } - public DBSchema getSchema() { return schema; @@ -131,6 +124,59 @@ public final class DBDatabase extends SetContainer<IDBTransaction> implements ID return getElements(); } + public int getStatementCacheCapacity() + { + return statementCacheCapacity; + } + + public void setStatementCacheCapacity(int statementCacheCapacity) + { + this.statementCacheCapacity = statementCacheCapacity; + } + + public <T extends IDBSchemaElement, P extends IDBSchemaElement> T ensureSchemaElement(P parent, Class<T> type, + String name, RunnableWithSchemaElement<T, P> runnable) + { + T element = parent.getElement(type, name); + if (element == null) + { + DBSchemaTransaction schemaTransaction = openSchemaTransaction(); + + try + { + DBSchema workingCopy = schemaTransaction.getWorkingCopy(); + P parentCopy = workingCopy.findElement(parent); + + T elementCopy = runnable.run(parentCopy, name); + + schemaTransaction.commit(); + if (elementCopy != null) + { + element = parent.getSchema().findElement(elementCopy); + } + } + finally + { + schemaTransaction.close(); + } + } + + return element; + } + + public IDBTable ensureTable(String name, final RunnableWithTable runnable) + { + return ensureSchemaElement(schema, IDBTable.class, name, new RunnableWithSchemaElement<IDBTable, IDBSchema>() + { + public IDBTable run(IDBSchema parent, String name) + { + IDBTable table = parent.addTable(name); + runnable.run(table); + return table; + } + }); + } + public boolean isClosed() { return !isActive(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java index b0f0c066d9..d82915ffa9 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java @@ -113,6 +113,11 @@ public class DBField extends DBSchemaElement implements IDBField return table; } + public DBTable getParent() + { + return getTable(); + } + public DBType getType() { return type; 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 9cc7c31681..1db215abe2 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 @@ -79,6 +79,11 @@ public class DBIndex extends DBSchemaElement implements IDBIndex return table; } + public DBTable getParent() + { + return getTable(); + } + public Type getType() { return type; diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndexField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndexField.java index 9ae7afa357..9fac7e7eb3 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndexField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndexField.java @@ -56,6 +56,11 @@ public class DBIndexField extends DBSchemaElement implements IDBIndexField return index; } + public DBIndex getParent() + { + return getIndex(); + } + public DBField getField() { return field; 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 20c824d88f..0ab09e568f 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 @@ -65,6 +65,11 @@ public class DBTable extends DBSchemaElement implements IDBTable return schema; } + public DBSchema getParent() + { + return getSchema(); + } + public DBField addField(String name, DBType type) { return addField(name, type, IDBField.DEFAULT, IDBField.DEFAULT, false); 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 69a41840a8..fe7d643b98 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 @@ -17,6 +17,7 @@ import org.eclipse.net4j.db.IDBConnectionProvider; import org.eclipse.net4j.db.IDBRowHandler; import org.eclipse.net4j.db.ddl.IDBField; import org.eclipse.net4j.db.ddl.IDBIndex; +import org.eclipse.net4j.db.ddl.IDBIndexField; import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBSchemaElement; import org.eclipse.net4j.db.ddl.IDBSchemaVisitor; @@ -113,12 +114,79 @@ public class DBSchema extends DBSchemaElement implements IDBSchema return this; } + /** + * @since 4.2 + */ + public final IDBSchemaElement getParent() + { + return null; + } + public String getFullName() { return getName(); } /** + * @since 4.2 + */ + @SuppressWarnings("unchecked") + public final <T extends IDBSchemaElement> T findElement(IDBSchemaElement prototype) + { + SchemaElementType schemaElementType = prototype.getSchemaElementType(); + switch (schemaElementType) + { + case SCHEMA: + return (T)(prototype.equals(this) ? this : null); + + case TABLE: + return (T)getElement(IDBTable.class, prototype.getName()); + + case FIELD: + { + IDBTable table = getElement(IDBTable.class, prototype.getParent().getName()); + if (table == null) + { + return null; + } + + return (T)table.getElement(IDBField.class, prototype.getName()); + } + + case INDEX: + { + IDBTable table = getElement(IDBTable.class, prototype.getParent().getName()); + if (table == null) + { + return null; + } + + return (T)table.getElement(IDBIndex.class, prototype.getName()); + } + + case INDEX_FIELD: + { + IDBTable table = getElement(IDBTable.class, prototype.getParent().getParent().getName()); + if (table == null) + { + return null; + } + + IDBIndex index = table.getElement(IDBIndex.class, prototype.getParent().getName()); + if (index == null) + { + return null; + } + + return (T)index.getElement(IDBIndexField.class, prototype.getName()); + } + + default: + throw new IllegalStateException("Illegal schema element type: " + schemaElementType); + } + } + + /** * @since 2.0 */ public IDBTable addTable(String name) throws DBException diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchemaElement.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchemaElement.java index c421770e7a..56ad7399b2 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchemaElement.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBSchemaElement.java @@ -98,6 +98,22 @@ public abstract class DBSchemaElement extends DBNamedElement implements IDBSchem protected abstract void collectElements(List<IDBSchemaElement> elements); + public final <T extends IDBSchemaElement> T getElement(Class<T> type, String name) + { + name = name(name); + for (IDBSchemaElement element : getElements()) + { + if (element.getName() == name && type.isAssignableFrom(element.getClass())) + { + @SuppressWarnings("unchecked") + T result = (T)element; + return result; + } + } + + return null; + } + public final void accept(IDBSchemaVisitor visitor) { try |