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:
Michael Bayne
2007-08-13 19:42:46 +00:00
parent f4dfccbf97
commit f76ab3592a
3 changed files with 48 additions and 36 deletions
@@ -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) {