import java.io.IOException;
import java.util.List;
+import java.util.Set;
+
+import com.healthmarketscience.jackcess.IndexBuilder;
import com.healthmarketscience.jackcess.RelationshipBuilder;
/**
// FIXME
}
+
+ private IndexBuilder createPrimaryIndex() {
+ String name = getUniqueIndexName(_primaryTable);
+ // FIXME?
+ return createIndex(name, _primaryCols).setUnique();
+ }
+
+ private IndexBuilder createSecondaryIndex() {
+ String name = getUniqueIndexName(_secondaryTable);
+ // FIXME?
+
+ return createIndex(name, _primaryCols);
+ }
+
+ private static IndexBuilder createIndex(String name, List<ColumnImpl> cols) {
+ IndexBuilder idx = new IndexBuilder(name);
+ for(ColumnImpl col : cols) {
+ idx.addColumns(col.getName());
+ }
+ return idx;
+ }
+
+ private String getUniqueIndexName(TableImpl table) {
+ Set<String> idxNames = TableUpdater.getIndexNames(table, null);
+
+ boolean isPrimary = (table == _primaryTable);
+ String baseName = null;
+ String suffix = null;
+ if(isPrimary) {
+ // primary naming scheme: ".rC", ".rD", "rE" ...
+ baseName = ".r";
+ suffix = "C";
+ } else {
+ // secondary naming scheme: "<t1><t2>", "<t1><t2>1", "<t1><t2>2"
+ baseName = _primaryTable.getName() + _secondaryTable.getName();
+ suffix = "";
+ }
+
+ int count = 0;
+ while(true) {
+ String idxName = baseName + suffix;
+ if(!idxNames.contains(idxName.toUpperCase())) {
+ return idxName;
+ }
+
+ ++count;
+ if(isPrimary) {
+ char c = (char)(suffix.charAt(0) + 1);
+ if(c == '[') {
+ c = 'a';
+ }
+ suffix = "" + c;
+ } else {
+ suffix = "" + count;
+ }
+ }
+ }
}
int indexNumber = _table.getLogicalIndexCount();
_index.setIndexNumber(indexNumber);
- // find backing index state
- findIndexDataState();
+ // initialize backing index state
+ initIndexDataState();
getPageChannel().startExclusiveWrite();
try {
}
boolean foundPk[] = new boolean[1];
- Set<String> idxNames = getIndexNames(foundPk);
+ Set<String> idxNames = getIndexNames(_table, foundPk);
// next, validate the index definition
validateIndex(getColumnNames(), idxNames, foundPk, _index);
}
return colNames;
}
- private Set<String> getIndexNames(boolean[] foundPk) {
+ static Set<String> getIndexNames(TableImpl table, boolean[] foundPk) {
Set<String> idxNames = new HashSet<String>();
- for(IndexImpl index : _table.getIndexes()) {
+ for(IndexImpl index : table.getIndexes()) {
idxNames.add(index.getName().toUpperCase());
- if(index.isPrimaryKey()) {
+ if(index.isPrimaryKey() && (foundPk != null)) {
foundPk[0] = true;
}
}
return idxNames;
}
- private void findIndexDataState() {
+ private void initIndexDataState() {
_idxDataState = new IndexDataState();
_idxDataState.addIndex(_index);
// search for an existing index which matches the given index (in terms of
// the backing data)
- for(IndexData idxData : _table.getIndexDatas()) {
- if(sameIndexData(_index, idxData)) {
- _idxDataState.setIndexDataNumber(idxData.getIndexDataNumber());
- return;
- }
- }
+ IndexData idxData = findIndexData(_index, _table, (byte)0, (byte)0);
- // no matches found, need new index data state
- _idxDataState.setIndexDataNumber(_table.getIndexCount());
+ int idxDataNumber = ((idxData != null) ?
+ idxData.getIndexDataNumber() :
+ _table.getIndexCount());
+
+ _idxDataState.setIndexDataNumber(idxDataNumber);
}
- private static boolean sameIndexData(IndexBuilder idx1, IndexData idx2) {
+ static IndexData findIndexData(IndexBuilder idx, TableImpl table,
+ byte ignoreIdxFlags, byte ignoreColFlags)
+ {
+ for(IndexData idxData : table.getIndexDatas()) {
+ if(sameIndexData(idx, idxData, ignoreIdxFlags, ignoreColFlags)) {
+ return idxData;
+ }
+ }
+ return null;
+ }
+
+ private static boolean sameIndexData(IndexBuilder idx1, IndexData idx2,
+ byte ignoreIdxFlags, byte ignoreColFlags) {
// index data can be combined if flags match and columns (and col flags)
// match
- if(idx1.getFlags() != idx2.getIndexFlags()) {
+ if((idx1.getFlags() | ignoreIdxFlags) !=
+ (idx2.getIndexFlags() | ignoreIdxFlags)) {
return false;
}
IndexBuilder.Column col1 = idx1.getColumns().get(i);
IndexData.ColumnDescriptor col2 = idx2.getColumns().get(i);
- if(!sameIndexData(col1, col2)) {
+ if(!sameIndexData(col1, col2, ignoreColFlags)) {
return false;
}
}
}
private static boolean sameIndexData(
- IndexBuilder.Column col1, IndexData.ColumnDescriptor col2) {
+ IndexBuilder.Column col1, IndexData.ColumnDescriptor col2,
+ int ignoreColFlags) {
return (col1.getName().equals(col2.getName()) &&
- (col1.getFlags() == col2.getFlags()));
+ ((col1.getFlags() | ignoreColFlags) ==
+ (col2.getFlags() | ignoreColFlags)));
}
}