Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-04-06 10:53:35 +0000
committerEike Stepper2013-04-06 10:53:57 +0000
commitf9e529b18c114b639aff4510bc1313c04171199e (patch)
tree815417e248389ecb6d7d2e8f50b18e7bf97b026b
parent6e703893541443e59cab2ef3635591f78f17d7eb (diff)
downloadcdo-f9e529b18c114b639aff4510bc1313c04171199e.tar.gz
cdo-f9e529b18c114b639aff4510bc1313c04171199e.tar.xz
cdo-f9e529b18c114b639aff4510bc1313c04171199e.zip
[404047] DB-Migration from 4.1 to 4.2 failed drops/I20130406-0717
https://bugs.eclipse.org/bugs/show_bug.cgi?id=404047
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java32
-rw-r--r--plugins/org.eclipse.net4j.db.mysql/src/org/eclipse/net4j/db/mysql/MYSQLAdapter.java6
-rw-r--r--plugins/org.eclipse.net4j.db.oracle/src/org/eclipse/net4j/db/oracle/OracleAdapter.java6
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java115
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java5
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java6
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBIndex.java5
7 files changed, 140 insertions, 35 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
index 6f22ca9faa..e3f7e7601d 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
@@ -618,7 +618,10 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
DBUtil.close(connection);
}
- database = DBUtil.openDatabase(dbAdapter, dbConnectionProvider, repository.getName());
+ String schemaName = repository.getName();
+ boolean fixNullableIndexColumns = schemaVersion < FIRST_VERSION_WITH_NULLABLE_CHECKS;
+
+ database = DBUtil.openDatabase(dbAdapter, dbConnectionProvider, schemaName, fixNullableIndexColumns);
IDBSchemaTransaction schemaTransaction = database.openSchemaTransaction();
try
@@ -897,6 +900,8 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
public abstract void migrateSchema(DBStore store, Connection connection) throws Exception;
}
+ private static final int FIRST_VERSION_WITH_NULLABLE_CHECKS = 4;
+
private static final SchemaMigrator NO_MIGRATION_NEEDED = null;
private static final SchemaMigrator NON_AUDIT_MIGRATION = new SchemaMigrator()
@@ -956,31 +961,8 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
}
};
- private static final SchemaMigrator NULLABLE_COLUMNS_MIGRATION = new SchemaMigrator()
- {
- @Override
- public void migrateSchema(DBStore store, final Connection connection) throws Exception
- {
- IDBAdapter dbAdapter = store.getDBAdapter();
- IDBSchema schema = DBUtil.createSchema("MIGRATION");
- IDBField field1 = schema.addTable(null).addField(null, null);
-
- Statement statement = null;
-
- try
- {
- statement = connection.createStatement();
- statement.execute(dbAdapter.sqlModifyField(field1));
- }
- finally
- {
- DBUtil.close(statement);
- }
- }
- };
-
private static final SchemaMigrator[] SCHEMA_MIGRATORS = { NO_MIGRATION_NEEDED, NON_AUDIT_MIGRATION,
- LOB_SIZE_MIGRATION, NULLABLE_COLUMNS_MIGRATION };
+ LOB_SIZE_MIGRATION, NO_MIGRATION_NEEDED };
static
{
diff --git a/plugins/org.eclipse.net4j.db.mysql/src/org/eclipse/net4j/db/mysql/MYSQLAdapter.java b/plugins/org.eclipse.net4j.db.mysql/src/org/eclipse/net4j/db/mysql/MYSQLAdapter.java
index afb275b38f..5d046c5bb1 100644
--- a/plugins/org.eclipse.net4j.db.mysql/src/org/eclipse/net4j/db/mysql/MYSQLAdapter.java
+++ b/plugins/org.eclipse.net4j.db.mysql/src/org/eclipse/net4j/db/mysql/MYSQLAdapter.java
@@ -153,4 +153,10 @@ public class MYSQLAdapter extends DBAdapter
return "ALTER TABLE " + field.getTable() + " CHANGE COLUMN " + oldName + " " + field + " "
+ createFieldDefinition(field);
}
+
+ @Override
+ protected String sqlModifyField(String tableName, String fieldName, String definition)
+ {
+ return "ALTER TABLE " + tableName + " MODIFY " + fieldName + " " + definition;
+ }
}
diff --git a/plugins/org.eclipse.net4j.db.oracle/src/org/eclipse/net4j/db/oracle/OracleAdapter.java b/plugins/org.eclipse.net4j.db.oracle/src/org/eclipse/net4j/db/oracle/OracleAdapter.java
index a0d51011a8..761486a4d6 100644
--- a/plugins/org.eclipse.net4j.db.oracle/src/org/eclipse/net4j/db/oracle/OracleAdapter.java
+++ b/plugins/org.eclipse.net4j.db.oracle/src/org/eclipse/net4j/db/oracle/OracleAdapter.java
@@ -137,4 +137,10 @@ public class OracleAdapter extends DBAdapter
String message = ex.getMessage();
return message != null && message.toLowerCase().contains("ora-00001") && "23000".equals(ex.getSQLState());
}
+
+ @Override
+ protected String sqlModifyField(String tableName, String fieldName, String definition)
+ {
+ return "ALTER TABLE " + tableName + " MODIFY " + fieldName + " " + definition;
+ }
}
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 8f1106166a..e5aa6c30cd 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
@@ -11,15 +11,19 @@
package org.eclipse.net4j.db;
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.IDBNamedElement;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.internal.db.DBDatabase;
import org.eclipse.net4j.internal.db.DataSourceConnectionProvider;
import org.eclipse.net4j.internal.db.bundle.OM;
+import org.eclipse.net4j.internal.db.ddl.DBIndex;
import org.eclipse.net4j.internal.db.ddl.DBNamedElement;
import org.eclipse.net4j.spi.db.DBAdapter;
import org.eclipse.net4j.util.ReflectUtil;
+import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.io.ExtendedDataInput;
import org.eclipse.net4j.util.io.ExtendedDataOutput;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
@@ -170,7 +174,16 @@ public final class DBUtil
*/
public static IDBDatabase openDatabase(IDBAdapter adapter, IDBConnectionProvider connectionProvider, String schemaName)
{
- return new DBDatabase((DBAdapter)adapter, connectionProvider, schemaName);
+ return openDatabase(adapter, connectionProvider, schemaName, false);
+ }
+
+ /**
+ * @since 4.2
+ */
+ public static IDBDatabase openDatabase(IDBAdapter adapter, IDBConnectionProvider connectionProvider,
+ String schemaName, boolean fixNullableIndexColumns)
+ {
+ return new DBDatabase((DBAdapter)adapter, connectionProvider, schemaName, fixNullableIndexColumns);
}
// /**
@@ -225,19 +238,109 @@ public final class DBUtil
/**
* @since 4.2
*/
+ public static void readSchema(IDBAdapter adapter, Connection connection, IDBSchema schema)
+ {
+ adapter.readSchema(connection, schema);
+ }
+
+ /**
+ * @since 4.2
+ */
public static IDBSchema readSchema(IDBAdapter adapter, Connection connection, String name)
{
- IDBSchema schema = new org.eclipse.net4j.internal.db.ddl.DBSchema(name);
- readSchema(adapter, connection, schema);
- return schema;
+ return readSchema(adapter, connection, name, false);
}
/**
* @since 4.2
*/
- public static void readSchema(IDBAdapter adapter, Connection connection, IDBSchema schema)
+ public static IDBSchema readSchema(IDBAdapter adapter, Connection connection, String name,
+ boolean fixNullableIndexColumns)
{
- adapter.readSchema(connection, schema);
+ IDBSchema schema = new org.eclipse.net4j.internal.db.ddl.DBSchema(name);
+
+ if (fixNullableIndexColumns)
+ {
+ DBIndex.FIX_NULLABLE_INDEX_COLUMNS.set(true);
+ }
+
+ try
+ {
+ readSchema(adapter, connection, schema);
+ }
+ finally
+ {
+ if (fixNullableIndexColumns)
+ {
+ try
+ {
+ fixNullableIndexColumns(adapter, connection, schema);
+ }
+ finally
+ {
+ DBIndex.FIX_NULLABLE_INDEX_COLUMNS.remove();
+ }
+ }
+ }
+
+ return schema;
+ }
+
+ private static void fixNullableIndexColumns(IDBAdapter adapter, Connection connection, IDBSchema schema)
+ {
+ Statement statement = null;
+ StringBuilder builder = new StringBuilder();
+
+ try
+ {
+ for (IDBTable table : schema.getTables())
+ {
+ for (IDBIndex index : table.getIndices())
+ {
+ if (index.getType() != IDBIndex.Type.NON_UNIQUE)
+ {
+ for (IDBIndexField indexField : index.getIndexFields())
+ {
+ IDBField field = indexField.getField();
+ boolean nullable = !field.isNotNull();
+ if (nullable)
+ {
+ field.setNotNull(true);
+
+ if (statement == null)
+ {
+ statement = connection.createStatement();
+ builder.append("The internal schema migration has fixed the following nullable index columns:");
+ builder.append(StringUtil.NL);
+ }
+
+ String sql = adapter.sqlModifyField(field);
+ builder.append("- ");
+ builder.append(sql);
+ builder.append(StringUtil.NL);
+
+ statement.execute(sql);
+ }
+ }
+ }
+ }
+ }
+
+ if (statement != null)
+ {
+ connection.commit();
+ OM.LOG.info(builder.toString());
+ }
+ }
+ catch (SQLException ex)
+ {
+ rollback(connection);
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(statement);
+ }
}
/**
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 c7566e6a62..4e59bc8f30 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
@@ -46,7 +46,8 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB
private final LinkedList<SchemaAccess> schemaAccessQueue = new LinkedList<SchemaAccess>();
- public DBDatabase(final DBAdapter adapter, IDBConnectionProvider connectionProvider, final String schemaName)
+ public DBDatabase(final DBAdapter adapter, IDBConnectionProvider connectionProvider, final String schemaName,
+ final boolean fixNullableIndexColumns)
{
super(IDBConnection.class);
this.adapter = adapter;
@@ -56,7 +57,7 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB
{
public IDBSchema run(Connection connection) throws SQLException
{
- return adapter.readSchema(connection, schemaName);
+ return DBUtil.readSchema(adapter, connection, schemaName, fixNullableIndexColumns);
}
});
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 e2414bcfd3..999d08938d 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
@@ -198,7 +198,11 @@ public class DBField extends DBSchemaElement implements InternalDBField
public void setNotNull(boolean notNull)
{
- assertUnlocked();
+ if (DBIndex.FIX_NULLABLE_INDEX_COLUMNS.get() != Boolean.TRUE)
+ {
+ assertUnlocked();
+ }
+
this.notNull = notNull;
}
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 c00a5e6ede..31ea531b4a 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
@@ -37,6 +37,8 @@ import java.util.List;
*/
public class DBIndex extends DBSchemaElement implements InternalDBIndex
{
+ public static final ThreadLocal<Boolean> FIX_NULLABLE_INDEX_COLUMNS = new InheritableThreadLocal<Boolean>();
+
private static final boolean DISABLE_NULLABLE_CHECK = Boolean.parseBoolean(OMPlatform.INSTANCE.getProperty(
"org.eclipse.net4j.db.DisableNullableCheck", "true"));
@@ -116,7 +118,8 @@ public class DBIndex extends DBSchemaElement implements InternalDBIndex
{
assertUnlocked();
- if (type != Type.NON_UNIQUE && !field.isNotNull() && !DISABLE_NULLABLE_CHECK)
+ if (type != Type.NON_UNIQUE && !field.isNotNull() && !DISABLE_NULLABLE_CHECK
+ && FIX_NULLABLE_INDEX_COLUMNS.get() != Boolean.TRUE)
{
Exception constructionStackTrace = ((InternalDBField)field).getConstructionStackTrace();
throw new DBException(

Back to the top