aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java36
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java7
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java74
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java4
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java4
5 files changed, 63 insertions, 62 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
index 200a13d..fc70fe4 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
@@ -53,6 +53,7 @@ import com.healthmarketscience.jackcess.CursorBuilder;
import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
+import com.healthmarketscience.jackcess.Index;
import com.healthmarketscience.jackcess.IndexBuilder;
import com.healthmarketscience.jackcess.IndexCursor;
import com.healthmarketscience.jackcess.PropertyMap;
@@ -1171,9 +1172,7 @@ public class DatabaseImpl implements Database
{
initRelationships();
- String name = findUniqueRelationshipName(
- creator.getPrimaryTable().getName() +
- creator.getSecondaryTable().getName());
+ String name = createRelationshipName(creator);
RelationshipImpl newRel = creator.createRelationshipImpl(name);
ColumnImpl ccol = _relationships.getColumn(REL_COL_COLUMN_COUNT);
@@ -1226,9 +1225,28 @@ public class DatabaseImpl implements Database
}
}
- private String findUniqueRelationshipName(String origName) throws IOException {
+ private String createRelationshipName(RelationshipCreator creator)
+ throws IOException
+ {
+ // ensure that the final identifier name does not get too long
+ // - the primary name is limited to ((max / 2) - 3)
+ // - the total name is limited to (max - 3)
+ int maxIdLen = getFormat().MAX_INDEX_NAME_LENGTH;
+ int limit = (maxIdLen / 2) - 3;
+ String origName = creator.getPrimaryTable().getName();
+ if(origName.length() > limit) {
+ origName = origName.substring(0, limit);
+ }
+ limit = maxIdLen - 3;
+ origName += creator.getSecondaryTable().getName();
+ if(origName.length() > limit) {
+ origName = origName.substring(0, limit);
+ }
+
+ // now ensure name is unique
Set<String> names = new HashSet<String>();
+ // collect the names of all relationships for uniqueness check
for(Row row :
CursorImpl.createCursor(_systemCatalog).newIterable().setColumnNames(
SYSTEM_CATALOG_COLUMNS))
@@ -1239,6 +1257,14 @@ public class DatabaseImpl implements Database
}
}
+ if(creator.hasReferentialIntegrity()) {
+ // relationship name will also be index name in secondary table, so must
+ // check those names as well
+ for(Index idx : creator.getSecondaryTable().getIndexes()) {
+ names.add(toLookupName(idx.getName()));
+ }
+ }
+
String baseName = toLookupName(origName);
String name = baseName;
int i = 0;
@@ -1246,8 +1272,6 @@ public class DatabaseImpl implements Database
name = baseName + (++i);
}
- // FIXME, truncate to max identifier length
-
return ((i == 0) ? origName : (origName + i));
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
index 2d97e75..8cdb54c 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
@@ -54,10 +54,9 @@ public class IndexImpl implements Index, Comparable<IndexImpl>
private static final byte CASCADE_NULL_FLAG = (byte)2;
/** index table type for the "primary" table in a foreign key index */
- static final byte PRIMARY_TABLE_TYPE = (byte)1;
-
+ static final byte FK_PRIMARY_TABLE_TYPE = (byte)1;
/** index table type for the "secondary" table in a foreign key index */
- static final byte SECONDARY_TABLE_TYPE = (byte)2;
+ static final byte FK_SECONDARY_TABLE_TYPE = (byte)2;
/** indicate an invalid index number for foreign key field */
private static final int INVALID_INDEX_NUMBER = -1;
@@ -434,7 +433,7 @@ public class IndexImpl implements Index, Comparable<IndexImpl>
}
public boolean isPrimaryTable() {
- return(getTableType() == PRIMARY_TABLE_TYPE);
+ return(getTableType() == FK_PRIMARY_TABLE_TYPE);
}
public int getOtherIndexNumber() {
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
index 80c8acf..dcfdf3d 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
@@ -53,16 +53,8 @@ public class RelationshipCreator extends DBMutator
private List<ColumnImpl> _primaryCols;
private List<ColumnImpl> _secondaryCols;
private int _flags;
+ private String _name;
- // - primary table must have unique index
- // - primary table index name ".rC", ".rD"...
- // - secondary index name "<PTable><STable>"
- // - add <name>1, <name>2 after names to make unique (index names and
- // relationship names)
- // - enforcing rel integrity can't have dupe cols
- // FIXME
- // - what about index name clashes?
-
public RelationshipCreator(DatabaseImpl database)
{
super(database);
@@ -76,7 +68,12 @@ public class RelationshipCreator extends DBMutator
return _secondaryTable;
}
+ public boolean hasReferentialIntegrity() {
+ return _relationship.hasReferentialIntegrity();
+ }
+
public RelationshipImpl createRelationshipImpl(String name) {
+ _name = name;
RelationshipImpl newRel = new RelationshipImpl(
name, _primaryTable, _secondaryTable, _flags,
_primaryCols, _secondaryCols);
@@ -105,7 +102,7 @@ public class RelationshipCreator extends DBMutator
RelationshipImpl newRel = getDatabase().writeRelationship(this);
- if(_relationship.hasReferentialIntegrity()) {
+ if(hasReferentialIntegrity()) {
addPrimaryIndex();
addSecondaryIndex();
}
@@ -136,13 +133,13 @@ public class RelationshipCreator extends DBMutator
int otherTableNum = 0;
int otherIdxNum = 0;
if(isPrimary) {
- tableType = IndexImpl.PRIMARY_TABLE_TYPE;
+ tableType = IndexImpl.FK_PRIMARY_TABLE_TYPE;
otherTableNum = _secondaryTable.getTableDefPageNumber();
// we create the primary index first, so the secondary index does not
// exist yet
otherIdxNum = _secondaryTable.getLogicalIndexCount();
} else {
- tableType = IndexImpl.SECONDARY_TABLE_TYPE;
+ tableType = IndexImpl.FK_SECONDARY_TABLE_TYPE;
otherTableNum = _primaryTable.getTableDefPageNumber();
// at this point, we've already created the primary index, it's the last
// one on the primary table
@@ -191,7 +188,7 @@ public class RelationshipCreator extends DBMutator
}
}
- if(!_relationship.hasReferentialIntegrity()) {
+ if(!hasReferentialIntegrity()) {
if((_relationship.getFlags() & CASCADE_FLAGS) != 0) {
throw new IllegalArgumentException(withErrorContext(
@@ -248,18 +245,15 @@ public class RelationshipCreator extends DBMutator
}
private IndexBuilder createPrimaryIndex() {
- String name = getUniqueIndexName(_primaryTable);
- // FIXME?
+ String name = createPrimaryIndexName();
return createIndex(name, _primaryCols)
.setUnique()
.setType(IndexImpl.FOREIGN_KEY_INDEX_TYPE);
}
private IndexBuilder createSecondaryIndex() {
- String name = getUniqueIndexName(_secondaryTable);
- // FIXME?
-
- return createIndex(name, _secondaryCols)
+ // secondary index uses relationship name
+ return createIndex(_name, _secondaryCols)
.setType(IndexImpl.FOREIGN_KEY_INDEX_TYPE);
}
@@ -271,45 +265,29 @@ public class RelationshipCreator extends DBMutator
return idx;
}
- private String getUniqueIndexName(TableImpl table) {
- Set<String> idxNames = TableUpdater.getIndexNames(table, null);
+ private String createPrimaryIndexName() {
+ Set<String> idxNames = TableUpdater.getIndexNames(_primaryTable, null);
- boolean isPrimary = (table == _primaryTable);
- String baseName = null;
- String suffix = null;
- if(isPrimary) {
- // primary naming scheme: ".rB", .rC", ".rD", "rE" ...
- baseName = ".r";
- suffix = "B";
- } else {
- // secondary naming scheme: "<t1><t2>", "<t1><t2>1", "<t1><t2>2"
- baseName = _primaryTable.getName() + _secondaryTable.getName();
- suffix = "";
- }
+ // primary naming scheme: ".rB", .rC", ".rD", "rE" ...
+ String baseName = ".r";
+ String suffix = "B";
- int count = 0;
while(true) {
String idxName = baseName + suffix;
- if(!idxNames.contains(idxName.toUpperCase())) {
+ if(!idxNames.contains(DatabaseImpl.toLookupName(idxName))) {
return idxName;
}
- ++count;
- if(isPrimary) {
- char c = (char)(suffix.charAt(0) + 1);
- if(c == '[') {
- c = 'a';
- }
- suffix = "" + c;
- } else {
- suffix = "" + count;
- }
+ char c = (char)(suffix.charAt(0) + 1);
+ if(c == '[') {
+ c = 'a';
+ }
+ suffix = "" + c;
}
-
- // FIXME, truncate to max index name length
}
- private static List<ColumnImpl> getColumns(TableImpl table, List<String> colNames) {
+ private static List<ColumnImpl> getColumns(TableImpl table,
+ List<String> colNames) {
List<ColumnImpl> cols = new ArrayList<ColumnImpl>();
for(String colName : colNames) {
cols.add(table.getColumn(colName));
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
index 5bc7e11..65bb8dc 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
@@ -63,7 +63,7 @@ public abstract class TableMutator extends DBMutator
}
column.validate(getFormat());
- if(!colNames.add(column.getName().toUpperCase())) {
+ if(!colNames.add(DatabaseImpl.toLookupName(column.getName()))) {
throw new IllegalArgumentException(withErrorContext(
"duplicate column name: " + column.getName()));
}
@@ -75,7 +75,7 @@ public abstract class TableMutator extends DBMutator
boolean[] foundPk, IndexBuilder index) {
index.validate(colNames, getFormat());
- if(!idxNames.add(index.getName().toUpperCase())) {
+ if(!idxNames.add(DatabaseImpl.toLookupName(index.getName()))) {
throw new IllegalArgumentException(withErrorContext(
"duplicate index name: " + index.getName()));
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
index de208c9..724a1fa 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
@@ -240,7 +240,7 @@ public class TableUpdater extends TableMutator
private Set<String> getColumnNames() {
Set<String> colNames = new HashSet<String>();
for(ColumnImpl column : _table.getColumns()) {
- colNames.add(column.getName().toUpperCase());
+ colNames.add(DatabaseImpl.toLookupName(column.getName()));
}
return colNames;
}
@@ -248,7 +248,7 @@ public class TableUpdater extends TableMutator
static Set<String> getIndexNames(TableImpl table, boolean[] foundPk) {
Set<String> idxNames = new HashSet<String>();
for(IndexImpl index : table.getIndexes()) {
- idxNames.add(index.getName().toUpperCase());
+ idxNames.add(DatabaseImpl.toLookupName(index.getName()));
if(index.isPrimaryKey() && (foundPk != null)) {
foundPk[0] = true;
}