Check for stale indexes, too. Use our knowledge of full text indexes to better decide if a column or index is internal to Depot's or the DB's workings. Finally, allow com.samskivert.depot.verifyschema to be set, forcing a staleness check (which slows down initialization somewhat).
This commit is contained in:
@@ -133,7 +133,7 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
|
||||
try {
|
||||
_schemaVersion = (Integer)field.get(null);
|
||||
} catch (Exception e) {
|
||||
log.warning("Failed to read schema version [class=" + _pClass + "].", e);
|
||||
log.warning("Failed to read schema version", "class", pClass, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,9 +545,10 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
|
||||
// now check whether we need to migrate our database schema
|
||||
while (true) {
|
||||
if (currentVersion >= _schemaVersion) {
|
||||
// TODO: we used to check for staleness here, but that's slow; currently we do it
|
||||
// only after migration, we should reinstate a check maybe the first time a table
|
||||
// is read or something so that developers are more likely to get the warning
|
||||
// no migrations to do, but maybe we should do an explicit staleness check
|
||||
if (Boolean.getBoolean("com.samskivert.depot.verifyschema")) {
|
||||
checkForStaleness(TableMetaData.load(ctx, getTableName()), ctx, builder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1003,11 +1004,22 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
|
||||
meta.tableColumns.remove(fmarsh.getColumnName());
|
||||
}
|
||||
for (String column : meta.tableColumns) {
|
||||
if (builder.isPrivateColumn(column)) {
|
||||
if (builder.isPrivateColumn(column, _fullTextIndexes)) {
|
||||
continue;
|
||||
}
|
||||
log.warning(getTableName() + " contains stale column '" + column + "'.");
|
||||
log.warning("Stale column", "table", getTableName(), "column", column);
|
||||
}
|
||||
|
||||
for (CreateIndexClause clause : _indexes) {
|
||||
meta.indexColumns.remove(clause.getName());
|
||||
}
|
||||
for (String index : meta.indexColumns.keySet()) {
|
||||
if (builder.isPrivateIndex(index, _fullTextIndexes)) {
|
||||
continue;
|
||||
}
|
||||
log.warning("Stale index", "table", getTableName(), "index", index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void checkHasPrimaryKey ()
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -223,12 +224,19 @@ public class HSQLBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateColumn (String column)
|
||||
public boolean isPrivateColumn (String column, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// The HSQLDB builder does not yet have any private columns.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateIndex (String index, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// The HSQLDB builder does not yet have any private indexes;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBooleanDefault ()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@ package com.samskivert.depot.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.samskivert.depot.PersistentRecord;
|
||||
@@ -208,12 +210,19 @@ public class MySQLBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateColumn (String column)
|
||||
public boolean isPrivateColumn (String column, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// The MySQL builder does not yet have any private columns.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateIndex (String index, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// The MySQL builder does not yet have any private indexes.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBooleanDefault ()
|
||||
{
|
||||
|
||||
@@ -23,6 +23,8 @@ package com.samskivert.depot.impl;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.samskivert.jdbc.DatabaseLiaison;
|
||||
@@ -243,10 +245,32 @@ public class PostgreSQLBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateColumn (String column)
|
||||
public boolean isPrivateColumn (String column, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// filter out any column that we created as part of FTS support
|
||||
return column.startsWith("ftsCol_");
|
||||
for (FullTextIndex fti : fullTextIndexes.values()) {
|
||||
if (("ftsCol_" + fti.name()).equals(column)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateIndex (String index, Map<String, FullTextIndex> fullTextIndexes)
|
||||
{
|
||||
// filter out any index that looks like PostgreSQL created it
|
||||
if (index.endsWith("_key") || index.endsWith("_pkey")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// filter out any index that we created as part of FTS support
|
||||
for (FullTextIndex fti : fullTextIndexes.values()) {
|
||||
if (index.endsWith("_ftsIx_" + fti.name())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
package com.samskivert.depot.impl;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -203,7 +205,16 @@ public abstract class SQLBuilder
|
||||
* e.g. PostgreSQL's full text search data is stored in a table column that should otherwise
|
||||
* not be visible to Depot; this method helps mask it.
|
||||
*/
|
||||
public abstract boolean isPrivateColumn (String column);
|
||||
public abstract boolean isPrivateColumn (
|
||||
String column, Map<String, FullTextIndex> fullTextIndexes);
|
||||
|
||||
/**
|
||||
* Return true if the supplied index is an internal consideration of this {@link SQLBuilder},
|
||||
* e.g. PostgreSQL automatically creates indexes that end in _key for unique columns, and its
|
||||
* primary keys have indices ending in _pkey.
|
||||
*/
|
||||
public abstract boolean isPrivateIndex (
|
||||
String index, Map<String, FullTextIndex> fullTextIndexes);
|
||||
|
||||
/**
|
||||
* Figure out what full text search indexes already exist on this table and add the names of
|
||||
|
||||
Reference in New Issue
Block a user