More Zell changes:
- Re-read the table metadata after we run pre-default migrations, since those are pretty much guaranteed to change the table. - Changed EntityMigration.Rename to a pre-default rather than a post-default migration. - Made all the static EntityMigration subclasses use the generic liaison rather than JDBCUtil.
This commit is contained in:
@@ -531,18 +531,20 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
});
|
||||
|
||||
// fetch all relevant information regarding our table from the database
|
||||
final TableMetaData metaData = ctx.invoke(new Query.TrivialQuery<TableMetaData>() {
|
||||
public TableMetaData invoke (Connection conn, DatabaseLiaison dl) throws SQLException {
|
||||
return new TableMetaData(conn.getMetaData());
|
||||
}
|
||||
});
|
||||
TableMetaData metaData = TableMetaData.load(ctx, getTableName());
|
||||
|
||||
// compute relevant information from our persistent record, too
|
||||
final RecordMetaData rMeta = new RecordMetaData(_pclass, _fields);
|
||||
RecordMetaData rMeta = new RecordMetaData(_pclass, _fields);
|
||||
|
||||
// if the table does not exist, create it
|
||||
if (!metaData.tableExists) {
|
||||
final String[] fDeclarations = declarations;
|
||||
final String[][] uniqueConCols = new String[rMeta.uniqueConstraints.size()][];
|
||||
int kk = 0;
|
||||
for (Set<String> colSet : rMeta.uniqueConstraints) {
|
||||
uniqueConCols[kk++] = colSet.toArray(new String[colSet.size()]);
|
||||
}
|
||||
final Iterable<Index> indexen = rMeta.indices.values();
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
// create the table
|
||||
@@ -557,16 +559,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
primaryKeyColumns[ii] = _pkColumns.get(ii).getColumnName();
|
||||
}
|
||||
}
|
||||
String[][] uniqueConCols = new String[rMeta.uniqueConstraints.size()][];
|
||||
int kk = 0;
|
||||
for (Set<String> colSet : rMeta.uniqueConstraints) {
|
||||
uniqueConCols[kk++] = colSet.toArray(new String[colSet.size()]);
|
||||
}
|
||||
liaison.createTableIfMissing(conn, getTableName(), columns, fDeclarations,
|
||||
uniqueConCols, primaryKeyColumns);
|
||||
|
||||
// add its indexen
|
||||
for (Index idx : rMeta.indices.values()) {
|
||||
for (Index idx : indexen) {
|
||||
liaison.addIndexToTable(
|
||||
conn, getTableName(), idx.columns(),
|
||||
getTableName() + "_" + idx.name(), idx.unique());
|
||||
@@ -621,13 +618,18 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
log.info("Migrating " + getTableName() + " from " + currentVersion + " to " +
|
||||
_schemaVersion + "...");
|
||||
|
||||
// run our pre-default-migrations
|
||||
for (EntityMigration migration : _migrations) {
|
||||
if (migration.runBeforeDefault() &&
|
||||
migration.shouldRunMigration(currentVersion, _schemaVersion)) {
|
||||
migration.init(getTableName(), _fields);
|
||||
ctx.invoke(migration);
|
||||
if (_migrations.size() > 0) {
|
||||
// run our pre-default-migrations
|
||||
for (EntityMigration migration : _migrations) {
|
||||
if (migration.runBeforeDefault() &&
|
||||
migration.shouldRunMigration(currentVersion, _schemaVersion)) {
|
||||
migration.init(getTableName(), _fields);
|
||||
ctx.invoke(migration);
|
||||
}
|
||||
}
|
||||
|
||||
// we don't know what the pre-migrations did so we have to re-read metadata
|
||||
metaData = TableMetaData.load(ctx, getTableName());
|
||||
}
|
||||
|
||||
// this is a little silly, but we need a copy for name disambiguation later
|
||||
@@ -635,7 +637,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
|
||||
// add any missing columns
|
||||
for (String fname : _columnFields) {
|
||||
@SuppressWarnings("unchecked") final FieldMarshaller<T> fmarsh = _fields.get(fname);
|
||||
final FieldMarshaller fmarsh = _fields.get(fname);
|
||||
if (metaData.tableColumns.remove(fmarsh.getColumnName())) {
|
||||
continue;
|
||||
}
|
||||
@@ -680,10 +682,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
});
|
||||
|
||||
} else if (!hasPrimaryKey() && metaData.pkName != null) {
|
||||
log.info("Dropping primary key.");
|
||||
final String pkName = metaData.pkName;
|
||||
log.info("Dropping primary key: " + pkName);
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
liaison.dropPrimaryKey(conn, getTableName(), metaData.pkName);
|
||||
liaison.dropPrimaryKey(conn, getTableName(), pkName);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
@@ -761,7 +764,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
});
|
||||
}
|
||||
|
||||
protected class TableMetaData
|
||||
protected static class TableMetaData
|
||||
{
|
||||
public boolean tableExists;
|
||||
public Set<String> tableColumns = new HashSet<String>();
|
||||
@@ -769,20 +772,31 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
public String pkName;
|
||||
public Set<String> pkColumns = new HashSet<String>();
|
||||
|
||||
public TableMetaData (DatabaseMetaData meta)
|
||||
public static TableMetaData load (PersistenceContext ctx, final String tableName)
|
||||
throws PersistenceException
|
||||
{
|
||||
return ctx.invoke(new Query.TrivialQuery<TableMetaData>() {
|
||||
public TableMetaData invoke (Connection conn, DatabaseLiaison dl)
|
||||
throws SQLException {
|
||||
return new TableMetaData(conn.getMetaData(), tableName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TableMetaData (DatabaseMetaData meta, String tableName)
|
||||
throws SQLException
|
||||
{
|
||||
tableExists = meta.getTables("", "", getTableName(), null).next();
|
||||
tableExists = meta.getTables("", "", tableName, null).next();
|
||||
if (!tableExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResultSet rs = meta.getColumns(null, null, getTableName(), "%");
|
||||
ResultSet rs = meta.getColumns(null, null, tableName, "%");
|
||||
while (rs.next()) {
|
||||
tableColumns.add(rs.getString("COLUMN_NAME"));
|
||||
}
|
||||
|
||||
rs = meta.getIndexInfo(null, null, getTableName(), false, false);
|
||||
rs = meta.getIndexInfo(null, null, tableName, false, false);
|
||||
while (rs.next()) {
|
||||
String indexName = rs.getString("INDEX_NAME");
|
||||
Set<String> set = indexColumns.get(indexName);
|
||||
@@ -802,7 +816,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
}
|
||||
}
|
||||
|
||||
rs = meta.getPrimaryKeys(null, null, getTableName());
|
||||
rs = meta.getPrimaryKeys(null, null, tableName);
|
||||
while (rs.next()) {
|
||||
pkName = rs.getString("PK_NAME");
|
||||
pkColumns.add(rs.getString("COLUMN_NAME"));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2006-2007 Michael Bayne, Pär Winzell
|
||||
//
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
@@ -25,8 +25,6 @@ import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.samskivert.jdbc.DatabaseLiaison;
|
||||
import com.samskivert.jdbc.JDBCUtil;
|
||||
import com.samskivert.jdbc.LiaisonRegistry;
|
||||
|
||||
import static com.samskivert.jdbc.depot.Log.log;
|
||||
|
||||
@@ -49,7 +47,7 @@ public abstract class EntityMigration extends Modifier
|
||||
}
|
||||
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
if (!JDBCUtil.tableContainsColumn(conn, _tableName, _columnName)) {
|
||||
if (!liaison.tableContainsColumn(conn, _tableName, _columnName)) {
|
||||
// we'll accept this inconsistency
|
||||
log.warning(_tableName + "." + _columnName + " already dropped.");
|
||||
return 0;
|
||||
@@ -74,8 +72,8 @@ public abstract class EntityMigration extends Modifier
|
||||
}
|
||||
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
if (!JDBCUtil.tableContainsColumn(conn, _tableName, _oldColumnName)) {
|
||||
if (JDBCUtil.tableContainsColumn(conn, _tableName, _newColumnName)) {
|
||||
if (!liaison.tableContainsColumn(conn, _tableName, _oldColumnName)) {
|
||||
if (liaison.tableContainsColumn(conn, _tableName, _newColumnName)) {
|
||||
// we'll accept this inconsistency
|
||||
log.warning(_tableName + "." + _oldColumnName + " already renamed to " +
|
||||
_newColumnName + ".");
|
||||
@@ -87,7 +85,7 @@ public abstract class EntityMigration extends Modifier
|
||||
}
|
||||
|
||||
// nor is this
|
||||
if (JDBCUtil.tableContainsColumn(conn, _tableName, _newColumnName)) {
|
||||
if (liaison.tableContainsColumn(conn, _tableName, _newColumnName)) {
|
||||
throw new IllegalArgumentException(
|
||||
_tableName + " already contains '" + _newColumnName + "'");
|
||||
}
|
||||
@@ -98,7 +96,7 @@ public abstract class EntityMigration extends Modifier
|
||||
}
|
||||
|
||||
public boolean runBeforeDefault () {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String _oldColumnName, _newColumnName;
|
||||
|
||||
@@ -96,7 +96,7 @@ public abstract class SQLBuilder
|
||||
* TODO: This method should be split into several parts that are more easily overridden on a
|
||||
* case-by-case basis in the dialectal subclasses.
|
||||
*/
|
||||
public <T> String buildColumnDefinition (FieldMarshaller<T> fm)
|
||||
public String buildColumnDefinition (FieldMarshaller fm)
|
||||
{
|
||||
// if this field is @Computed, it has no SQL definition
|
||||
if (fm.getComputed() != null) {
|
||||
|
||||
Reference in New Issue
Block a user