Reinstate automatic schema migration, per Zell.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2159 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -84,7 +84,8 @@ public abstract class BaseLiaison implements DatabaseLiaison
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public boolean addIndexToTable (Connection conn, String table, String[] columns, String ixName)
|
||||
public boolean addIndexToTable (
|
||||
Connection conn, String table, String[] columns, String ixName, boolean unique)
|
||||
throws SQLException
|
||||
{
|
||||
if (tableContainsIndex(conn, table, ixName)) {
|
||||
@@ -92,8 +93,12 @@ public abstract class BaseLiaison implements DatabaseLiaison
|
||||
}
|
||||
ixName = (ixName != null ? ixName : StringUtil.join(columns, "_"));
|
||||
|
||||
StringBuilder update = new StringBuilder("CREATE INDEX ").append(indexSQL(ixName)).
|
||||
append(" on ").append(tableSQL(table)).append(" (");
|
||||
StringBuilder update = new StringBuilder("CREATE ");
|
||||
if (unique) {
|
||||
update.append("UNIQUE ");
|
||||
}
|
||||
update.append("INDEX ").append(indexSQL(ixName)).append(" ON ").
|
||||
append(tableSQL(table)).append(" (");
|
||||
for (int ii = 0; ii < columns.length; ii ++) {
|
||||
if (ii > 0) {
|
||||
update.append(", ");
|
||||
@@ -113,6 +118,49 @@ public abstract class BaseLiaison implements DatabaseLiaison
|
||||
return true;
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public void addPrimaryKey (Connection conn, String table, String[] columns)
|
||||
throws SQLException
|
||||
{
|
||||
StringBuilder fields = new StringBuilder("(");
|
||||
for (int ii = 0; ii < columns.length; ii ++) {
|
||||
if (ii > 0) {
|
||||
fields.append(", ");
|
||||
}
|
||||
fields.append(columnSQL(columns[ii]));
|
||||
}
|
||||
fields.append(")");
|
||||
String update = "ALTER TABLE " + tableSQL(table) + " ADD PRIMARY KEY " + fields.toString();
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
stmt.executeUpdate(update.toString());
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
|
||||
Log.info("Primary key " + fields + " added to table '" + table + "'");
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public void dropIndex (Connection conn, String table, String index) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
stmt.executeUpdate(
|
||||
"ALTER TABLE " + tableSQL(table) + " DROP CONSTRAINT " + columnSQL(index));
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public void dropPrimaryKey (Connection conn, String table, String pkName)
|
||||
throws SQLException
|
||||
{
|
||||
dropIndex(conn, table, pkName);
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public boolean addColumn (
|
||||
Connection conn, String table, String column, String definition, boolean check)
|
||||
|
||||
@@ -84,7 +84,27 @@ public interface DatabaseLiaison
|
||||
* Adds a named index to a table on the given columns. Returns true or false if the database
|
||||
* did or did not report a schema modification.
|
||||
*/
|
||||
public boolean addIndexToTable (Connection conn, String table, String[] columns, String index)
|
||||
public boolean addIndexToTable (
|
||||
Connection conn, String table, String[] columns, String index, boolean unique)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Drops the named index from the given table.
|
||||
*/
|
||||
public void dropIndex (Connection conn, String table, String index)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Adds a primary key to a table of the given name and on the given columns. Returns true or
|
||||
* false if the database did nor did not report a schema modification.
|
||||
*/
|
||||
public void addPrimaryKey (Connection conn, String table, String[] columns)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Deletes the primary key from a table, if it exists.
|
||||
*/
|
||||
public void dropPrimaryKey (Connection conn, String table, String pkName)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,6 @@ package com.samskivert.jdbc;
|
||||
import java.sql.*;
|
||||
|
||||
import com.samskivert.Log;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A database liaison for the MySQL database.
|
||||
@@ -39,15 +38,15 @@ public class MySQLLiaison extends BaseLiaison
|
||||
// from DatabaseLiaison
|
||||
public boolean isDuplicateRowException (SQLException sqe)
|
||||
{
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null && msg.indexOf("Duplicate entry") != -1);
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null && msg.indexOf("Duplicate entry") != -1);
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public boolean isTransientException (SQLException sqe)
|
||||
{
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null && (msg.indexOf("Lost connection") != -1 ||
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null && (msg.indexOf("Lost connection") != -1 ||
|
||||
msg.indexOf("link failure") != -1 ||
|
||||
msg.indexOf("Broken pipe") != -1));
|
||||
}
|
||||
@@ -77,18 +76,21 @@ public class MySQLLiaison extends BaseLiaison
|
||||
}
|
||||
|
||||
@Override // from BaseLiaison
|
||||
public boolean addIndexToTable (Connection conn, String table, String[] columns, String ixName)
|
||||
public boolean addIndexToTable (
|
||||
Connection conn, String table, String[] columns, String ixName, boolean unique)
|
||||
throws SQLException
|
||||
{
|
||||
if (tableContainsIndex(conn, table, ixName)) {
|
||||
return false;
|
||||
}
|
||||
ixName = (ixName != null ? ixName : StringUtil.join(columns, "_"));
|
||||
|
||||
// MySQL's "CREATE INDEX" is buggy, it actually changes the case of the table names you're
|
||||
// working with. Luckily (?) ALTER TABLE ADD INDEX works, so we do that here.
|
||||
StringBuilder update = new StringBuilder("ALTER TABLE ").append(table).
|
||||
append(" ADD INDEX ").append(indexSQL(ixName)).append(" (");
|
||||
StringBuilder update = new StringBuilder("ALTER TABLE ").append(table).append(" ADD ");
|
||||
if (unique) {
|
||||
update.append("UNIQUE ");
|
||||
}
|
||||
update.append("INDEX ").append(indexSQL(ixName)).append(" (");
|
||||
for (int ii = 0; ii < columns.length; ii ++) {
|
||||
if (ii > 0) {
|
||||
update.append(", ");
|
||||
@@ -109,6 +111,31 @@ public class MySQLLiaison extends BaseLiaison
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override // from BaseLiaison
|
||||
public void dropIndex (Connection conn, String table, String index)
|
||||
throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
stmt.executeUpdate(
|
||||
"ALTER TABLE " + tableSQL(table) + " DROP INDEX " + columnSQL(index));
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // from BaseLiaison
|
||||
public void dropPrimaryKey (Connection conn, String table, String pkName)
|
||||
throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
try {
|
||||
stmt.executeUpdate("ALTER TABLE " + tableSQL(table) + " DROP PRIMARY KEY");
|
||||
} finally {
|
||||
JDBCUtil.close(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// from DatabaseLiaison
|
||||
public String columnSQL (String column)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ public class PostgreSQLLiaison extends BaseLiaison
|
||||
// from DatabaseLiaison
|
||||
public boolean isDuplicateRowException (SQLException sqe)
|
||||
{
|
||||
String msg = sqe.getMessage();
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null && msg.indexOf("duplicate key") != -1);
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ public class PostgreSQLLiaison extends BaseLiaison
|
||||
public boolean isTransientException (SQLException sqe)
|
||||
{
|
||||
// TODO: Add more error messages here as we encounter them.
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null &&
|
||||
String msg = sqe.getMessage();
|
||||
return (msg != null &&
|
||||
msg.indexOf("An I/O error occured while sending to the backend") != -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -551,60 +552,61 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
}
|
||||
});
|
||||
|
||||
// now create the table for our persistent class if it does not exist
|
||||
final String[] fDeclarations = declarations;
|
||||
final String[][] fUniqueConstraintColumns = uniqueConstraintColumns;
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
String[] columns = new String[_columnFields.length];
|
||||
for (int ii = 0; ii < columns.length; ii ++) {
|
||||
columns[ii] = _fields.get(_columnFields[ii]).getColumnName();
|
||||
}
|
||||
String[] primaryKeyColumns = null;
|
||||
if (_pkColumns != null) {
|
||||
primaryKeyColumns = new String[_pkColumns.size()];
|
||||
for (int ii = 0; ii < primaryKeyColumns.length; ii ++) {
|
||||
primaryKeyColumns[ii] = _pkColumns.get(ii).getColumnName();
|
||||
}
|
||||
}
|
||||
if (liaison.createTableIfMissing(conn, getTableName(), columns, fDeclarations,
|
||||
fUniqueConstraintColumns, primaryKeyColumns)) {
|
||||
for (FullTextIndex fti : _fullTextIndexes.values()) {
|
||||
builder.addFullTextSearch(conn, DepotMarshaller.this, fti);
|
||||
}
|
||||
}
|
||||
|
||||
updateVersion(conn, liaison, _schemaVersion);
|
||||
return 0;
|
||||
// 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());
|
||||
}
|
||||
});
|
||||
|
||||
// ensure that all indices are created
|
||||
final Entity entity = _pclass.getAnnotation(Entity.class);
|
||||
if (entity != null && entity.indices().length > 0) {
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
for (Index idx : entity.indices()) {
|
||||
liaison.addIndexToTable(conn, getTableName(), idx.columns(), idx.name());
|
||||
}
|
||||
return entity.indices().length;
|
||||
}
|
||||
});
|
||||
}
|
||||
// if the table does not exist, create it
|
||||
if (!metaData.tableExists) {
|
||||
final Entity entity = _pclass.getAnnotation(Entity.class);
|
||||
final String[] fDeclarations = declarations;
|
||||
final String[][] fUniqueConstraintColumns = uniqueConstraintColumns;
|
||||
|
||||
// if we have a key generator, initialize that too
|
||||
if (_keyGenerator != null) {
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
_keyGenerator.init(conn, liaison);
|
||||
// create the table
|
||||
String[] columns = new String[_columnFields.length];
|
||||
for (int ii = 0; ii < columns.length; ii ++) {
|
||||
columns[ii] = _fields.get(_columnFields[ii]).getColumnName();
|
||||
}
|
||||
String[] primaryKeyColumns = null;
|
||||
if (_pkColumns != null) {
|
||||
primaryKeyColumns = new String[_pkColumns.size()];
|
||||
for (int ii = 0; ii < primaryKeyColumns.length; ii ++) {
|
||||
primaryKeyColumns[ii] = _pkColumns.get(ii).getColumnName();
|
||||
}
|
||||
}
|
||||
liaison.createTableIfMissing(conn, getTableName(), columns, fDeclarations,
|
||||
fUniqueConstraintColumns, primaryKeyColumns);
|
||||
|
||||
// add its indexen
|
||||
for (Index idx : entity.indices()) {
|
||||
liaison.addIndexToTable(
|
||||
conn, getTableName(), idx.columns(), idx.name(), idx.unique());
|
||||
}
|
||||
if (_keyGenerator != null) {
|
||||
_keyGenerator.init(conn, liaison);
|
||||
}
|
||||
for (FullTextIndex fti : _fullTextIndexes.values()) {
|
||||
builder.addFullTextSearch(conn, DepotMarshaller.this, fti);
|
||||
}
|
||||
|
||||
updateVersion(conn, liaison, _schemaVersion);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
// and we're done
|
||||
return;
|
||||
}
|
||||
|
||||
// if schema versioning is disabled, stop now
|
||||
// if the table exists, see if should attempt automatic schema migration
|
||||
if (_schemaVersion < 0) {
|
||||
verifySchemasMatch(ctx);
|
||||
// nope, versioning disabled
|
||||
verifySchemasMatch(metaData, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -625,20 +627,15 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
}
|
||||
}
|
||||
});
|
||||
if (currentVersion == _schemaVersion) {
|
||||
verifySchemasMatch(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (true) {
|
||||
log.warning("Automatic schema migration is temporarily disabled.");
|
||||
verifySchemasMatch(ctx);
|
||||
if (currentVersion == _schemaVersion) {
|
||||
verifySchemasMatch(metaData, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise try to migrate the schema
|
||||
log.info("Migrating " + getTableName() + " from " +
|
||||
currentVersion + " to " + _schemaVersion + "...");
|
||||
log.info("Migrating " + getTableName() + " from " + currentVersion + " to " +
|
||||
_schemaVersion + "...");
|
||||
|
||||
// run our pre-default-migrations
|
||||
for (EntityMigration migration : _migrations) {
|
||||
@@ -649,9 +646,6 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
}
|
||||
}
|
||||
|
||||
// enumerate all columns and indexes now that we've run our pre-migrations
|
||||
TableMetaData metaData = loadMetaData(ctx);
|
||||
|
||||
// this is a little silly, but we need a copy for name disambiguation later
|
||||
Set<String> indicesCopy = new HashSet<String>(metaData.indexColumns.keySet());
|
||||
|
||||
@@ -691,70 +685,77 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This needs more work to be database-independent, I think. Assuming the index name
|
||||
// is going to be PRIMARY seems like a MySQL-ism, and we'll do the rest of the index work
|
||||
// when we do that.
|
||||
// add or remove the primary key as needed
|
||||
if (hasPrimaryKey() && metaData.pkName == null) {
|
||||
log.info("Adding primary key.");
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
liaison.addPrimaryKey(conn, getTableName(), getPrimaryKeyFields());
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
// // add or remove the primary key as needed
|
||||
// if (hasPrimaryKey() && !indexColumns.containsKey("PRIMARY")) {
|
||||
// String pkdef = "primary key (" + getJoinedKeyColumns() + ")";
|
||||
// log.info("Adding primary key to " + getTableName() + ": " + pkdef);
|
||||
// ctx.invoke(new Modifier.Simple("alter table " + getTableName() + " add " + pkdef));
|
||||
//
|
||||
// } else if (!hasPrimaryKey() && indexColumns.containsKey("PRIMARY")) {
|
||||
// indexColumns.remove("PRIMARY");
|
||||
// log.info("Dropping primary from " + getTableName());
|
||||
// ctx.invoke(new Modifier.Simple("alter table " + getTableName() + " drop primary key"));
|
||||
// }
|
||||
//
|
||||
// // add any missing indices
|
||||
// for (Index index : (entity == null ? new Index[0] : entity.indices())) {
|
||||
// if (indexColumns.containsKey(index.name())) {
|
||||
// indexColumns.remove(index.name());
|
||||
// continue;
|
||||
// }
|
||||
// String indexdef =
|
||||
// "create " + index.type() + " index " + _liaison.indexSQL(index.name()) +
|
||||
// " on " + _liaison.tableSQL(getTableName()) + " (" + StringUtil.join(index.columns(), ", ") + ")";
|
||||
// log.info("Adding index: " + indexdef);
|
||||
// ctx.invoke(new Modifier.Simple(indexdef));
|
||||
// }
|
||||
//
|
||||
// // to get the @Table(uniqueIndices...) indices, we use our clever set of column name sets
|
||||
// Set<Set<String>> uniqueIndices = new HashSet<Set<String>>(indexColumns.values());
|
||||
// Table table;
|
||||
// if (getTableName() != null && (table = _pclass.getAnnotation(Table.class)) != null) {
|
||||
// Set<String> colSet = new HashSet<String>();
|
||||
// for (UniqueConstraint constraint : table.uniqueConstraints()) {
|
||||
// // for each given UniqueConstraint, build a new column set
|
||||
// colSet.clear();
|
||||
// for (String column : constraint.columnNames()) {
|
||||
// colSet.add(column);
|
||||
// }
|
||||
// // and check if the table contained this set
|
||||
// if (uniqueIndices.contains(colSet)) {
|
||||
// continue; // good, carry on
|
||||
// }
|
||||
//
|
||||
// // else build the index; we'll use mysql's convention of naming it after a column,
|
||||
// // with possible _N disambiguation; luckily we made a copy of the index names!
|
||||
// String indexName = colSet.iterator().next();
|
||||
// if (indicesCopy.contains(indexName)) {
|
||||
// int num = 1;
|
||||
// indexName += "_";
|
||||
// while (indicesCopy.contains(indexName + num)) {
|
||||
// num ++;
|
||||
// }
|
||||
// indexName += num;
|
||||
// }
|
||||
//
|
||||
// String[] columnArr = colSet.toArray(new String[colSet.size()]);
|
||||
// String indexdef = "create unique index " + indexName + " on " +
|
||||
// getTableName() + " (" + StringUtil.join(columnArr, ", ") + ")";
|
||||
// log.info("Adding unique index: " + indexdef);
|
||||
// ctx.invoke(new Modifier.Simple(indexdef));
|
||||
// }
|
||||
// }
|
||||
} else if (!hasPrimaryKey() && metaData.pkName != null) {
|
||||
log.info("Dropping primary key.");
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
liaison.dropPrimaryKey(conn, getTableName(), metaData.pkName);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Entity entity = _pclass.getAnnotation(Entity.class);
|
||||
// add any missing indices
|
||||
for (final Index index : (entity == null ? new Index[0] : entity.indices())) {
|
||||
if (metaData.indexColumns.containsKey(index.name())) {
|
||||
metaData.indexColumns.remove(index.name());
|
||||
continue;
|
||||
}
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
liaison.addIndexToTable(
|
||||
conn, getTableName(), index.columns(), index.name(), index.unique());
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// to get the @Table(uniqueIndices...) indices, we use our clever set of column name sets
|
||||
Set<Set<String>> uniqueIndices = new HashSet<Set<String>>(metaData.indexColumns.values());
|
||||
|
||||
if (getTableName() != null && table != null) {
|
||||
for (UniqueConstraint constraint : table.uniqueConstraints()) {
|
||||
// for each given UniqueConstraint, build a new column set
|
||||
Set<String> colSet = new HashSet<String>(Arrays.asList(constraint.fieldNames()));
|
||||
|
||||
// and check if the table contained this set
|
||||
if (uniqueIndices.contains(colSet)) {
|
||||
continue; // good, carry on
|
||||
}
|
||||
|
||||
// else build the index; we'll use mysql's convention of naming it after a column,
|
||||
// with possible _N disambiguation; luckily we made a copy of the index names!
|
||||
String indexName = colSet.iterator().next();
|
||||
if (indicesCopy.contains(indexName)) {
|
||||
int num = 1;
|
||||
indexName += "_";
|
||||
while (indicesCopy.contains(indexName + num)) {
|
||||
num ++;
|
||||
}
|
||||
indexName += num;
|
||||
}
|
||||
|
||||
final String[] colArr = colSet.toArray(new String[colSet.size()]);
|
||||
final String fName = indexName;
|
||||
ctx.invoke(new Modifier() {
|
||||
public int invoke (Connection conn, DatabaseLiaison dl) throws SQLException {
|
||||
dl.addIndexToTable(conn, getTableName(), colArr, fName, true);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// we do not auto-remove columns but rather require that EntityMigration.Drop records be
|
||||
// registered by hand to avoid accidentally causing the loss of data
|
||||
@@ -781,19 +782,9 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
});
|
||||
}
|
||||
|
||||
protected TableMetaData loadMetaData (PersistenceContext ctx)
|
||||
throws PersistenceException
|
||||
{
|
||||
return ctx.invoke(new Query.TrivialQuery<TableMetaData>() {
|
||||
public TableMetaData invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException {
|
||||
return new TableMetaData(conn.getMetaData());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected class TableMetaData
|
||||
{
|
||||
public boolean tableExists;
|
||||
public Set<String> tableColumns = new HashSet<String>();
|
||||
public Map<String, Set<String>> indexColumns = new HashMap<String, Set<String>>();
|
||||
public String pkName;
|
||||
@@ -802,6 +793,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
public TableMetaData (DatabaseMetaData meta)
|
||||
throws SQLException
|
||||
{
|
||||
tableExists = meta.getTables("", "", getTableName(), null).next();
|
||||
if (!tableExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResultSet rs = meta.getColumns(null, null, getTableName(), "%");
|
||||
while (rs.next()) {
|
||||
tableColumns.add(rs.getString("COLUMN_NAME"));
|
||||
@@ -838,10 +834,9 @@ public class DepotMarshaller<T extends PersistentRecord>
|
||||
/**
|
||||
* Checks that there are no database columns for which we no longer have Java fields.
|
||||
*/
|
||||
protected void verifySchemasMatch (PersistenceContext ctx)
|
||||
protected void verifySchemasMatch (TableMetaData meta, PersistenceContext ctx)
|
||||
throws PersistenceException
|
||||
{
|
||||
TableMetaData meta = loadMetaData(ctx);
|
||||
for (String fname : _columnFields) {
|
||||
FieldMarshaller fmarsh = _fields.get(fname);
|
||||
meta.tableColumns.remove(fmarsh.getColumnName());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -46,13 +46,13 @@ public interface Query<T>
|
||||
public void updateCache (PersistenceContext ctx, T result) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Any query may elect to utilize the built-in cache by returning a non-null {@link CacheKey}
|
||||
* in this method. This is done automatically by the {@link DepotRepository} when looking up
|
||||
* single entities by primary key, but even entire collections can be cached under a single
|
||||
* key.
|
||||
*
|
||||
*
|
||||
* Great care must be taken to invalidate such cached collections when their constituent
|
||||
* entities are invalidated. This is generally done using {@link CacheListener} and
|
||||
* {@link CacheInvalidator}.
|
||||
@@ -60,7 +60,7 @@ public interface Query<T>
|
||||
public CacheKey getCacheKey ();
|
||||
|
||||
/**
|
||||
* Performs the actual JDBC operations associated with this query.
|
||||
* Performs the actual JDBC operations associated with this query.
|
||||
*/
|
||||
public T invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException;
|
||||
|
||||
@@ -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
|
||||
@@ -34,9 +34,8 @@ public @interface Index
|
||||
/** Defines the name of the index. */
|
||||
String name ();
|
||||
|
||||
/** Configures the type of this index if necessary. MySQL supports FULLTEXT, SPATIAL and
|
||||
* UNIQUE. */
|
||||
String type () default "";
|
||||
/** Does this index enforce a uniqueness constraint? */
|
||||
boolean unique () default false;
|
||||
|
||||
/** Defines the columns on which the index operates. */
|
||||
String[] columns () default {};
|
||||
|
||||
Reference in New Issue
Block a user