diff options
author | Eike Stepper | 2013-03-12 07:48:24 +0000 |
---|---|---|
committer | Eike Stepper | 2013-03-12 08:11:57 +0000 |
commit | 077d8780066f74d02b2716d329ef55afbd1d41ee (patch) | |
tree | 5db9211b8ced79ded9eb6a2ae7da70800c6ab1cd | |
parent | f86cc1a1116425a9bc0ace0dfc1aa1b354f51cca (diff) | |
download | cdo-077d8780066f74d02b2716d329ef55afbd1d41ee.tar.gz cdo-077d8780066f74d02b2716d329ef55afbd1d41ee.tar.xz cdo-077d8780066f74d02b2716d329ef55afbd1d41ee.zip |
[401763] Make CDO Server more robust against data dictionary changes
https://bugs.eclipse.org/bugs/show_bug.cgi?id=401763
12 files changed, 134 insertions, 102 deletions
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 0e94199c24..5320675c9e 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 @@ -780,7 +780,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, connectionKeepAliveTask.cancel(); connectionKeepAliveTask = null; - ObjectUtil.close(connection); + DBUtil.close(connection); connection = null; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java index be8da39a9d..3f6f07172b 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java @@ -46,7 +46,6 @@ import org.eclipse.net4j.db.IDBSchemaTransaction; import org.eclipse.net4j.db.ddl.IDBSchema; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.ObjectUtil; import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.lifecycle.Lifecycle; @@ -424,17 +423,16 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp try { async = monitor.forkAsync(); - IDBSchemaTransaction schemaTransaction = null; + IDBSchemaTransaction schemaTransaction = store.getDatabase().openSchemaTransaction(); try { - schemaTransaction = store.getDatabase().openSchemaTransaction(); mapPackageUnits(packageUnits, connection, false); schemaTransaction.commit(); } finally { - ObjectUtil.close(schemaTransaction); + schemaTransaction.close(); if (async != null) { async.stop(); @@ -449,7 +447,17 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp public void removeMapping(Connection connection, InternalCDOPackageUnit[] packageUnits) { - mapPackageUnits(packageUnits, connection, true); + IDBSchemaTransaction schemaTransaction = store.getDatabase().openSchemaTransaction(); + + try + { + mapPackageUnits(packageUnits, connection, true); + schemaTransaction.commit(); + } + finally + { + schemaTransaction.close(); + } } private void mapPackageUnits(InternalCDOPackageUnit[] packageUnits, Connection connection, boolean unmap) @@ -492,17 +500,11 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp if (unmap) { - int todo; - // IClassMapping mapping = removeClassMapping(eClass); - // getStore().getDBAdapter().dropTables(mapping.getDBTables(), connection); + removeClassMapping(eClass); } else { createClassMapping(eClass); - - // TODO Bug 296087: Before we go ahead with creation, we should check if it's already there - // IClassMapping mapping = createClassMapping(eClass); - // getStore().getDBAdapter().createTables(mapping.getDBTables(), connection); } } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java index df97a1d1bb..fb144a7d25 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java @@ -445,7 +445,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I CDOID existingID = accessor.readResourceID(folderID, name, revision.getBranch().getHead()); if (existingID != null && !existingID.equals(revision.getID())) { - throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID); //$NON-NLS-1$ //$NON-NLS-2$ + throw new IllegalStateException("Duplicate resource node in folder " + folderID + ": " + name); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java index 3d2aa629c4..1568f455f8 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java @@ -1486,8 +1486,7 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList CDOBranchPoint base = branch.getBase(); if (base.getBranch() == null) { - // Branch is main branch! - throw new IllegalArgumentException("Base of main branch is null"); + throw new IllegalArgumentException("Base branch is null: " + branch); } InternalCDORevisionManager revisionManager = repository.getRevisionManager(); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java index 5baa748f4b..e6e0ecedff 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java @@ -1367,8 +1367,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM CDOBranchPoint base = branch.getBase(); if (base.getBranch() == null) { - // Branch is main branch! - throw new IllegalArgumentException("Base of main branch is null"); + throw new IllegalArgumentException("Base branch is null: " + branch); } InternalCDORevisionManager revisionManager = repository.getRevisionManager(); diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java index 056769c997..445b17c6b8 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java @@ -12,7 +12,6 @@ package org.eclipse.emf.cdo.tests.db; import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation; -import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.IDBAdapter; import org.eclipse.net4j.db.h2.H2Adapter; import org.eclipse.net4j.util.io.IOUtil; @@ -69,7 +68,7 @@ public class H2Config extends DBConfig defaultDataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test"); } - DBUtil.createSchema(defaultDataSource, repoName, !isRestarting()); + H2Adapter.createSchema(defaultDataSource, repoName, !isRestarting()); JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test;SCHEMA=" + repoName); diff --git a/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java b/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java index 3d87768d4b..171e957724 100644 --- a/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests.lissome/src/org/eclipse/emf/cdo/tests/lissome/LissomeConfig.java @@ -19,7 +19,7 @@ import org.eclipse.emf.cdo.server.internal.lissome.file.Journal; import org.eclipse.emf.cdo.server.internal.lissome.file.Vob; import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig; -import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.h2.H2Adapter; import org.eclipse.net4j.util.container.IPluginContainer; import org.eclipse.net4j.util.io.IOUtil; @@ -75,7 +75,7 @@ public class LissomeConfig extends RepositoryConfig boolean dropIfExists = !isRestarting(); DataSource dataSource = Index.createDataSource(reusableFolder, repoName, null); - DBUtil.createSchema(dataSource, repoName, dropIfExists); + H2Adapter.createSchema(dataSource, repoName, dropIfExists); if (dropIfExists) { diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_314264_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_314264_Test.java index 91a4c52f93..bcf6e7be8a 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_314264_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_314264_Test.java @@ -16,6 +16,7 @@ import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.AbstractCDOTest; import org.eclipse.emf.cdo.tests.config.IRepositoryConfig; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore; +import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires; import org.eclipse.emf.cdo.tests.model2.TaskContainer; import org.eclipse.emf.cdo.tests.util.TestAdapter; import org.eclipse.emf.cdo.transaction.CDOTransaction; @@ -31,6 +32,7 @@ import org.eclipse.emf.spi.cdo.DefaultCDOMerger; * See bug 314264 */ @CleanRepositoriesBefore +@Requires(IRepositoryConfig.CAPABILITY_BRANCHING) public class Bugzilla_314264_Test extends AbstractCDOTest { @Override @@ -40,7 +42,6 @@ public class Bugzilla_314264_Test extends AbstractCDOTest skipStoreWithoutChangeSets(); } - @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) public void testMerge() throws Exception { // Setup transaction. @@ -48,7 +49,7 @@ public class Bugzilla_314264_Test extends AbstractCDOTest CDOTransaction tr1 = session.openTransaction(); tr1.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); - CDOResource resource = tr1.createResource(getResourcePath("/test")); + CDOResource resource = tr1.getOrCreateResource(getResourcePath("/test")); TaskContainer container1 = getModel2Factory().createTaskContainer(); resource.getContents().add(container1); @@ -76,33 +77,15 @@ public class Bugzilla_314264_Test extends AbstractCDOTest tr1.commit(); assertEquals(false, tr1.isDirty()); + session.close(); } - @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) - public void testMerge1() throws Exception + public void testMerge10() throws Exception { // Try again after some warm up. See bug 383602. testMerge(); - } - - @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) - public void testMerge2() throws Exception - { - // Try again after some warm up. See bug 383602. testMerge(); - } - - @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) - public void testMerge3() throws Exception - { - // Try again after some warm up. See bug 383602. testMerge(); - } - - @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) - public void testMerge4() throws Exception - { - // Try again after some warm up. See bug 383602. testMerge(); } diff --git a/plugins/org.eclipse.net4j.db.h2/src/org/eclipse/net4j/db/h2/H2Adapter.java b/plugins/org.eclipse.net4j.db.h2/src/org/eclipse/net4j/db/h2/H2Adapter.java index 5ffb0e4566..07746b9098 100644 --- a/plugins/org.eclipse.net4j.db.h2/src/org/eclipse/net4j/db/h2/H2Adapter.java +++ b/plugins/org.eclipse.net4j.db.h2/src/org/eclipse/net4j/db/h2/H2Adapter.java @@ -11,12 +11,16 @@ package org.eclipse.net4j.db.h2; import org.eclipse.net4j.db.DBType; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.DBUtil.RunnableWithConnection; import org.eclipse.net4j.db.IDBAdapter; import org.eclipse.net4j.db.ddl.IDBField; import org.eclipse.net4j.db.ddl.IDBIndex.Type; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.spi.db.DBAdapter; +import javax.sql.DataSource; + import java.sql.Connection; import java.sql.SQLException; @@ -91,4 +95,24 @@ public class H2Adapter extends DBAdapter { return "ALTER TABLE " + field.getTable() + " ALTER COLUMN " + oldName + " RENAME TO " + field; } + + /** + * @since 4.2 + */ + public static void createSchema(DataSource dataSource, final String name, final boolean dropIfExists) + { + DBUtil.execute(DBUtil.createConnectionProvider(dataSource), new RunnableWithConnection<Object>() + { + public Object run(Connection connection) throws SQLException + { + if (dropIfExists) + { + DBUtil.execute(connection, "DROP SCHEMA IF EXISTS " + name); + } + + DBUtil.execute(connection, "CREATE SCHEMA IF NOT EXISTS " + name); + return null; + } + }); + } } diff --git a/plugins/org.eclipse.net4j.db.tests/src/org/eclipse/net4j/db/tests/H2Test.java b/plugins/org.eclipse.net4j.db.tests/src/org/eclipse/net4j/db/tests/H2Test.java index d5371a8991..aba3034879 100644 --- a/plugins/org.eclipse.net4j.db.tests/src/org/eclipse/net4j/db/tests/H2Test.java +++ b/plugins/org.eclipse.net4j.db.tests/src/org/eclipse/net4j/db/tests/H2Test.java @@ -10,8 +10,8 @@ */ package org.eclipse.net4j.db.tests; -import org.eclipse.net4j.db.DBUtil; import org.eclipse.net4j.db.IDBAdapter; +import org.eclipse.net4j.db.h2.H2Adapter; import org.eclipse.net4j.util.io.IOUtil; import org.h2.jdbcx.JdbcDataSource; @@ -44,7 +44,7 @@ public class H2Test extends AbstractDBTest JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL(url); - DBUtil.createSchema(dataSource, SCHEMA_NAME, true); + H2Adapter.createSchema(dataSource, SCHEMA_NAME, true); dataSource = new JdbcDataSource(); dataSource.setURL(url + ";SCHEMA=" + SCHEMA_NAME); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java index 32f3789876..ea485c7c4b 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java @@ -171,6 +171,50 @@ public final class DBUtil return new DBDatabase((DBAdapter)adapter, connectionProvider, schemaName); } + // /** + // * @since 4.2 + // */ + // public static <T> T updateSchema(IDBConnectionProvider connectionProvider, RunnableWithConnection<T> runnable) + // { + // return execute(connectionProvider, new RunnableWithConnection<T>() + // { + // public T run(Connection connection) throws SQLException + // { + // return null; + // } + // }); + // } + // + // /** + // * @since 4.2 + // */ + // public static <T> T updateSchema(Connection connection, RunnableWithConnection<T> runnable) + // { + // DBConnection dbConnection = null; + // + // try + // { + // if (connection instanceof DBConnection) + // { + // dbConnection = (DBConnection)connection; + // dbConnection.getDatabase().beginSchemaAccess(true); + // } + // + // return runnable.run(connection); + // } + // catch (SQLException ex) + // { + // throw new DBException(ex); + // } + // finally + // { + // if (dbConnection != null) + // { + // + // } + // } + // } + public static IDBSchema createSchema(String name) { return new org.eclipse.net4j.internal.db.ddl.DBSchema(name); @@ -230,28 +274,36 @@ public final class DBUtil } /** - * Can only be used when Eclipse is running. In standalone scenarios create the adapter instance by directly calling - * the constructor of the adapter class. + * Retrieves an {@link IDBAdapter adapter} from the {@link IDBAdapter#REGISTRY adapter registry}. + * <p> + * If Eclipse is running adapters are automatically created from descriptors that are contributed to the extension point <code>org.eclipse.net4j.db.dbAdapters</code>. + * <p> + * In standalone scenarios the needed adapter instances must be registered with the {@link IDBAdapter#REGISTRY adapter registry} manually. */ public static IDBAdapter getDBAdapter(String adapterName) { return IDBAdapter.REGISTRY.get(adapterName); } - public static Exception close(Connection connection) + public static Exception close(ResultSet resultSet) { - if (connection != null) + if (resultSet != null) { try { - // Only for connections with autoCommit = false, we try a rollback - // first to clear any open transactions. - if (!connection.getAutoCommit()) + Statement statement = resultSet.getStatement(); + if (statement != null && statement.getMaxRows() != 0) { - rollback(connection); + statement.setMaxRows(0); } + } + catch (Exception ignore) + { + } - connection.close(); + try + { + resultSet.close(); } catch (Exception ex) { @@ -263,18 +315,6 @@ public final class DBUtil return null; } - private static void rollback(Connection connection) - { - try - { - connection.rollback(); - } - catch (Exception ex) - { - OM.LOG.error(ex); - } - } - public static Exception close(Statement statement) { if (statement != null) @@ -293,25 +333,20 @@ public final class DBUtil return null; } - public static Exception close(ResultSet resultSet) + public static Exception close(Connection connection) { - if (resultSet != null) + if (connection != null) { try { - Statement statement = resultSet.getStatement(); - if (statement != null && statement.getMaxRows() != 0) + // Only for connections with autoCommit = false, we try a rollback + // first to clear any open transactions. + if (!connection.getAutoCommit()) { - statement.setMaxRows(0); + rollback(connection); } - } - catch (Exception ignore) - { - } - try - { - resultSet.close(); + connection.close(); } catch (Exception ex) { @@ -323,6 +358,18 @@ public final class DBUtil return null; } + private static void rollback(Connection connection) + { + try + { + connection.rollback(); + } + catch (Exception ex) + { + OM.LOG.error(ex); + } + } + /** * @since 3.0 * @deprecated As of 4.2 use {@link #getAllSchemaNames(Connection)}. @@ -426,26 +473,6 @@ public final class DBUtil } /** - * @since 4.2 - */ - public static void createSchema(DataSource dataSource, final String name, final boolean dropIfExists) - { - execute(createConnectionProvider(dataSource), new RunnableWithConnection<Object>() - { - public Object run(Connection connection) throws SQLException - { - if (dropIfExists) - { - execute(connection, "DROP SCHEMA IF EXISTS " + name); - } - - execute(connection, "CREATE SCHEMA IF NOT EXISTS " + name); - return null; - } - }); - } - - /** * @since 4.0 */ public static List<Exception> dropAllTables(Connection connection, String dbName) 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 d35d963cbf..26459a0b61 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 @@ -28,9 +28,8 @@ import java.util.concurrent.ExecutorService; /** * @author Eike Stepper - * @deprecated As of 4.2 call {@link DBUtil#createSchema(String)}, {@link DBUtil#createSchema(DataSource, String, boolean)}, - * {@link DBUtil#readSchema(IDBAdapter, Connection, IDBSchema)}, {@link DBUtil#readSchema(IDBAdapter, Connection, String)} - * or {@link DBUtil#copySchema(IDBSchema)}. + * @deprecated As of 4.2 call {@link DBUtil#createSchema(String)}, {@link DBUtil#readSchema(IDBAdapter, Connection, IDBSchema)}, + * {@link DBUtil#readSchema(IDBAdapter, Connection, String)} or {@link DBUtil#copySchema(IDBSchema)}. */ @Deprecated public class DBSchema extends org.eclipse.net4j.internal.db.ddl.DBSchema |