package com.txtr.hibernatedelta.model;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
public class HibernateIndexUtil {
private HibernateIndexUtil() {
}
public static List<HibernateIndex> getIndexes(HibernateTable table) {
List<HibernateIndex> result = new ArrayList<HibernateIndex>();
List<String> pkColumns = new ArrayList<String>();
List<String> fkColumns = new ArrayList<String>();
for (HibernateColumn column : table.getColumns()) {
if (column.getTargetTable() != null) {
fkColumns.add(column.getName());
}
if (column.isPrimaryKey()) {
pkColumns.add(column.getName());
}
}
for (ExplicitHibernateIndex index : table.getExplicitIndexes()) {
result.add(new HibernateIndex(index.getName(), getIndexType(fkColumns, index), index.getColumns()));
}
if (!pkColumns.isEmpty()) {
String firstColumn = pkColumns.get(0);
String pkIndexName = table.getIndexPrefix() + "0";
if (pkColumns.size() == 1 && fkColumns.contains(firstColumn)) {
fkColumns.remove(firstColumn);
table.getColumn(firstColumn).setIndexName(new HibernateIndexName(pkIndexName, table.getName(), ImmutableList.of(firstColumn)));
result.add(new HibernateIndex(pkIndexName, HibernateIndexType.JOINED_PRIMARY_KEY, pkColumns));
} else {
result.add(new HibernateIndex(pkIndexName, HibernateIndexType.PRIMARY_KEY, pkColumns));
}
}
for (String fkColumn : fkColumns) {
final HibernateColumn hibernateColumn = table.getColumn(fkColumn);
result.add(new HibernateIndex(hibernateColumn.getForeignKeyIndexName(), HibernateIndexType.FOREIGN_KEY, ImmutableList.of(fkColumn)));
}
filterDominatedIndexes(result);
return result;
}
private static void filterDominatedIndexes(List<HibernateIndex> indexes) {
for (HibernateIndex index : Lists.newArrayList(indexes)) {
if (isDominated(indexes, index)) {
indexes.remove(index);
}
}
}
private static boolean isDominated(List<HibernateIndex> indexes, HibernateIndex index) {
for (HibernateIndex longer : indexes) {
if (isDominated(index.getColumns(), longer.getColumns())) {
return true;
}
}
return false;
}
private static boolean isDominated(List<String> loser, List<String> winner) {
if (loser.size() >= winner.size()) {
return false;
}
for (int i = 0; i < loser.size(); i++) {
if (!loser.get(i).equalsIgnoreCase(winner.get(i))) {
return false;
}
}
return true;
}
private static HibernateIndexType getIndexType(List<String> fkColumns, ExplicitHibernateIndex index) {
// if the first column is an fk column, reuse this as an fk index
if (fkColumns.contains(index.getColumns().get(0))) {
fkColumns.remove(index.getColumns().get(0));
return index.isUnique() ? HibernateIndexType.UNIQUE_FOREIGN_KEY : HibernateIndexType.FOREIGN_KEY;
}
if (!index.isUnique()) {
return HibernateIndexType.NON_UNIQUE;
}
return index.isFunctional() ? HibernateIndexType.FUNCTIONAL_UNIQUE : HibernateIndexType.UNIQUE;
}
}