From 358d74325c4ad654eb218a95f8942bb393533096 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 21 Dec 2006 22:34:06 +0000 Subject: [PATCH] Automatically add and remove indices and primary key (though it's extremely unlikely that one would do the latter), automatically remove obsolete columns (might be dangerous, I could be pursuaded to reconsider). --- .../jdbc/depot/DepotMarshaller.java | 90 ++++++++++++++----- 1 file changed, 69 insertions(+), 21 deletions(-) diff --git a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java index 56e02e4..cc85153 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java +++ b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java @@ -217,18 +217,14 @@ public class DepotMarshaller if (entity != null) { for (Index index : entity.indices()) { // TODO: delegate this to a database specific SQL generator - _declarations.add("INDEX " + index.name() + " " + index.type() + + _declarations.add(index.type() + "index " + index.name() + " (" + StringUtil.join(index.columns(), ", ") + ")"); } } // add the primary key, if we have one if (hasPrimaryKey()) { - String[] pkcols = new String[_pkColumns.size()]; - for (int ii = 0; ii < pkcols.length; ii ++) { - pkcols[ii] = _pkColumns.get(ii).getColumnName(); - } - _declarations.add("PRIMARY KEY (" + StringUtil.join(pkcols, ", ") + ")"); + _declarations.add("PRIMARY KEY (" + getPrimaryKeyColumns() + ")"); } // if we did not find a schema version field, complain @@ -632,22 +628,10 @@ public class DepotMarshaller return; } + // otherwise try to migrate the schema log.info("Migrating " + getTableName() + " from " + currentVersion + " to " + _schemaVersion + "..."); - // otherwise try to migrate the schema - final HashSet columns = new HashSet(); - ctx.invoke(new Modifier(null) { - public int invoke (Connection conn) throws SQLException { - DatabaseMetaData meta = conn.getMetaData(); - ResultSet rs = meta.getColumns(null, null, getTableName(), "%"); - while (rs.next()) { - columns.add(rs.getString("COLUMN_NAME")); - } - return 0; - } - }); - // run our pre-default-migrations for (EntityMigration migration : _migrations) { if (migration.runBeforeDefault() && @@ -656,10 +640,28 @@ public class DepotMarshaller } } - // do our "default" migrations magically + // enumerate all of the columns now that we've run our pre-migrations + final HashSet columns = new HashSet(); + final HashSet indices = new HashSet(); + ctx.invoke(new Modifier(null) { + public int invoke (Connection conn) throws SQLException { + DatabaseMetaData meta = conn.getMetaData(); + ResultSet rs = meta.getColumns(null, null, getTableName(), "%"); + while (rs.next()) { + columns.add(rs.getString("COLUMN_NAME")); + } + rs = meta.getIndexInfo(null, null, getTableName(), false, false); + while (rs.next()) { + indices.add(rs.getString("INDEX_NAME")); + } + return 0; + } + }); + + // add any missing columns for (String fname : _columnFields) { FieldMarshaller fmarsh = _fields.get(fname); - if (columns.contains(fmarsh.getColumnName())) { + if (columns.remove(fmarsh.getColumnName())) { continue; } @@ -689,6 +691,43 @@ public class DepotMarshaller } } + // add or remove the primary key as needed + if (hasPrimaryKey() && !indices.remove("PRIMARY")) { + String pkdef = "primary key (" + getPrimaryKeyColumns() + ")"; + log.info("Adding primary key to " + getTableName() + ": " + pkdef); + ctx.invoke(new Modifier.Simple("alter table " + getTableName() + " add " + pkdef)); + + } else if (!hasPrimaryKey() && indices.remove("PRIMARY")) { + log.info("Dropping primary from " + getTableName()); + ctx.invoke(new Modifier.Simple("alter table " + getTableName() + " drop primary key")); + } + + // add any missing indices + Entity entity = _pclass.getAnnotation(Entity.class); + for (Index index : (entity == null ? new Index[0] : entity.indices())) { + if (indices.remove(index.name())) { + continue; + } + String indexdef = "create " + index.type() + " index " + index.name() + + " on " + getTableName() + " (" + StringUtil.join(index.columns(), ", ") + ")"; + log.info("Adding index: " + indexdef); + ctx.invoke(new Modifier.Simple(indexdef)); + } + + // remove any extra columns + for (String column : columns) { + log.info("Dropping old column '" + column + "' from " + getTableName()); + String query = "alter table " + getTableName() + " drop index " + column; + ctx.invoke(new Modifier.Simple(query)); + } + + // remove any extra indices + for (String index : indices) { + log.info("Dropping old index '" + index + "' from " + getTableName()); + String query = "alter table " + getTableName() + " drop index " + index; + ctx.invoke(new Modifier.Simple(query)); + } + // run our post-default-migrations for (EntityMigration migration : _migrations) { if (!migration.runBeforeDefault() && @@ -706,6 +745,15 @@ public class DepotMarshaller }); } + protected String getPrimaryKeyColumns () + { + String[] pkcols = new String[_pkColumns.size()]; + for (int ii = 0; ii < pkcols.length; ii ++) { + pkcols[ii] = _pkColumns.get(ii).getColumnName(); + } + return StringUtil.join(pkcols, ", "); + } + protected void updateVersion (Connection conn, int version) throws SQLException {