aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/com/healthmarketscience
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2016-08-27 04:02:40 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2016-08-27 04:02:40 +0000
commit8d88e1737d30f0017cb8fe4de6856482d38067d8 (patch)
tree681e1d271ad87fff2a910f54b1dc30e2e283f2c7 /src/main/java/com/healthmarketscience
parent832fb5e6a6afb92a18da38706cf71c913743741b (diff)
downloadjackcess-8d88e1737d30f0017cb8fe4de6856482d38067d8.tar.gz
jackcess-8d88e1737d30f0017cb8fe4de6856482d38067d8.zip
implement fkref writing; more error context; make relationship name unique
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/mutateops@1012 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/main/java/com/healthmarketscience')
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java8
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java28
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java34
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java16
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java3
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java35
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java13
7 files changed, 108 insertions, 29 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java b/src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java
index 7822b2d..472740e 100644
--- a/src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java
+++ b/src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java
@@ -124,6 +124,14 @@ public class IndexBuilder
}
/**
+ * @usage _advanced_method_
+ */
+ public IndexBuilder setType(byte type) {
+ _type = type;
+ return this;
+ }
+
+ /**
* Sets this index to enforce uniqueness.
*/
public IndexBuilder setUnique() {
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
index fb1120c..5bfac3c 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
@@ -1170,8 +1170,9 @@ public class DatabaseImpl implements Database
{
initRelationships();
- String name = creator.getPrimaryTable().getName() +
- creator.getSecondaryTable().getName(); // FIXME make unique
+ String name = findUniqueRelationshipName(
+ creator.getPrimaryTable().getName() +
+ creator.getSecondaryTable().getName());
RelationshipImpl newRel = creator.createRelationshipImpl(name);
ColumnImpl ccol = _relationships.getColumn(REL_COL_COLUMN_COUNT);
@@ -1222,6 +1223,29 @@ public class DatabaseImpl implements Database
_relationships = getRequiredSystemTable(TABLE_SYSTEM_RELATIONSHIPS);
}
}
+
+ private String findUniqueRelationshipName(String origName) throws IOException {
+ Set<String> names = new HashSet<String>();
+
+ for(Row row :
+ CursorImpl.createCursor(_systemCatalog).newIterable().setColumnNames(
+ SYSTEM_CATALOG_COLUMNS))
+ {
+ String name = row.getString(CAT_COL_NAME);
+ if (name != null && TYPE_RELATIONSHIP.equals(row.get(CAT_COL_TYPE))) {
+ names.add(toLookupName(name));
+ }
+ }
+
+ String baseName = toLookupName(origName);
+ String name = baseName;
+ int i = 0;
+ while(names.contains(name)) {
+ name = baseName + (++i);
+ }
+
+ return ((i == 0) ? origName : (origName + i));
+ }
public List<Query> getQueries() throws IOException
{
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
index 833ee98..8ea7ed8 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java
@@ -360,12 +360,34 @@ public class IndexImpl implements Index, Comparable<IndexImpl>
buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); // seemingly constant magic value which matches the table def
buffer.putInt(idx.getIndexNumber()); // index num
buffer.putInt(idxDataState.getIndexDataNumber()); // index data num
- buffer.put((byte)0); // related table type
- buffer.putInt(INVALID_INDEX_NUMBER); // related index num
- buffer.putInt(0); // related table definition page number
- buffer.put((byte)0); // cascade updates flag
- buffer.put((byte)0); // cascade deletes flag
- buffer.put(idx.getType()); // index type flags
+
+ byte idxType = idx.getType();
+ if(idxType != FOREIGN_KEY_INDEX_TYPE) {
+ buffer.put((byte)0); // related table type
+ buffer.putInt(INVALID_INDEX_NUMBER); // related index num
+ buffer.putInt(0); // related table definition page number
+ buffer.put((byte)0); // cascade updates flag
+ buffer.put((byte)0); // cascade deletes flag
+ } else {
+ ForeignKeyReference reference = mutator.getForeignKey(idx);
+ buffer.put(reference.getTableType()); // related table type
+ buffer.putInt(reference.getOtherIndexNumber()); // related index num
+ buffer.putInt(reference.getOtherTablePageNumber()); // related table definition page number
+ byte updateFlags = 0;
+ if(reference.isCascadeUpdates()) {
+ updateFlags |= CASCADE_UPDATES_FLAG;
+ }
+ byte deleteFlags = 0;
+ if(reference.isCascadeDeletes()) {
+ deleteFlags |= CASCADE_DELETES_FLAG;
+ }
+ if(reference.isCascadeNullOnDelete()) {
+ deleteFlags |= CASCADE_NULL_FLAG;
+ }
+ buffer.put(updateFlags); // cascade updates flag
+ buffer.put(deleteFlags); // cascade deletes flag
+ }
+ buffer.put(idxType); // index type flags
buffer.putInt(0); // unknown
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
index 0d6fe26..c137f7f 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java
@@ -50,8 +50,7 @@ public class RelationshipCreator extends DBMutator
// - secondary index name "<PTable><STable>"
// - add <name>1, <name>2 after names to make unique (index names and
// relationship names)
- // FIXME
- // - relationships also have entry in MSysObjects table
+ // - enforcing rel integrity can't have dupe cols
public RelationshipCreator(DatabaseImpl database)
{
@@ -148,6 +147,9 @@ public class RelationshipCreator extends DBMutator
return;
}
+ // for now, we will require the unique index on the primary table (just
+ // like access does). we could just create it auto-magically...
+ // FIXME
// - same number cols
@@ -227,8 +229,8 @@ public class RelationshipCreator extends DBMutator
return cols;
}
- private static Collection<String> getColumnNames(
- List<ColumnImpl> cols, Collection<String> colNames) {
+ private static List<String> getColumnNames(List<ColumnImpl> cols) {
+ List<String> colNames = new ArrayList<String>();
for(ColumnImpl col : cols) {
colNames.add(col.getName());
}
@@ -239,12 +241,12 @@ public class RelationshipCreator extends DBMutator
// a relationship is one to one if the two sides of the relationship have
// unique indexes on the relevant columns
IndexImpl idx = _primaryTable.findIndexForColumns(
- getColumnNames(_primaryCols, new HashSet<String>()), true);
+ getColumnNames(_primaryCols), true);
if(idx == null) {
return false;
}
idx = _secondaryTable.findIndexForColumns(
- getColumnNames(_secondaryCols, new HashSet<String>()), true);
+ getColumnNames(_secondaryCols), true);
return (idx != null);
}
@@ -255,7 +257,7 @@ public class RelationshipCreator extends DBMutator
tableName = table.getName();
}
if(cols != null) {
- colNames = getColumnNames(cols, new ArrayList<String>());
+ colNames = getColumnNames(cols);
}
return CustomToStringStyle.valueBuilder(tableName)
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java
index 36c866d..df6076a 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java
@@ -333,7 +333,8 @@ public class TableCreator extends TableMutator
(col1.getFlags() == col2.getFlags()));
}
- private String withErrorContext(String msg) {
+ @Override
+ protected String withErrorContext(String msg) {
return msg + "(Table=" + getName() + ")";
}
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
index 494bfb7..5bc7e11 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java
@@ -50,18 +50,22 @@ public abstract class TableMutator extends DBMutator
return _colOffsets;
}
+ public IndexImpl.ForeignKeyReference getForeignKey(IndexBuilder idx) {
+ return null;
+ }
+
protected void validateColumn(Set<String> colNames, ColumnBuilder column) {
// FIXME for now, we can't create complex columns
if(column.getType() == DataType.COMPLEX_TYPE) {
- throw new UnsupportedOperationException(
- "Complex column creation is not yet implemented");
+ throw new UnsupportedOperationException(withErrorContext(
+ "Complex column creation is not yet implemented"));
}
column.validate(getFormat());
if(!colNames.add(column.getName().toUpperCase())) {
- throw new IllegalArgumentException("duplicate column name: " +
- column.getName());
+ throw new IllegalArgumentException(withErrorContext(
+ "duplicate column name: " + column.getName()));
}
setColumnSortOrder(column);
@@ -72,26 +76,31 @@ public abstract class TableMutator extends DBMutator
index.validate(colNames, getFormat());
if(!idxNames.add(index.getName().toUpperCase())) {
- throw new IllegalArgumentException("duplicate index name: " +
- index.getName());
+ throw new IllegalArgumentException(withErrorContext(
+ "duplicate index name: " + index.getName()));
}
if(index.isPrimaryKey()) {
if(foundPk[0]) {
- throw new IllegalArgumentException(
- "found second primary key index: " + index.getName());
+ throw new IllegalArgumentException(withErrorContext(
+ "found second primary key index: " + index.getName()));
}
foundPk[0] = true;
+ } else if(index.getType() == IndexImpl.FOREIGN_KEY_INDEX_TYPE) {
+ if(getForeignKey(index) == null) {
+ throw new IllegalArgumentException(withErrorContext(
+ "missing foreign key info for " + index.getName()));
+ }
}
}
- protected static void validateAutoNumberColumn(Set<DataType> autoTypes,
- ColumnBuilder column)
+ protected void validateAutoNumberColumn(Set<DataType> autoTypes,
+ ColumnBuilder column)
{
if(!column.getType().isMultipleAutoNumberAllowed() &&
!autoTypes.add(column.getType())) {
- throw new IllegalArgumentException(
+ throw new IllegalArgumentException(withErrorContext(
"Can have at most one AutoNumber column of type " + column.getType() +
- " per table");
+ " per table"));
}
}
@@ -112,6 +121,8 @@ public abstract class TableMutator extends DBMutator
public abstract IndexDataState getIndexDataState(IndexBuilder idx);
+ protected abstract String withErrorContext(String msg);
+
/**
* Maintains additional state used during column writing.
* @usage _advanced_class_
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
index 54bfd68..a6cbdea 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java
@@ -45,6 +45,7 @@ public class TableUpdater extends TableMutator
private List<Integer> _nextPages = new ArrayList<Integer>(1);
private ColumnState _colState;
private IndexDataState _idxDataState;
+ private IndexImpl.ForeignKeyReference _fkReference;
public TableUpdater(TableImpl table) {
super(table.getDatabase());
@@ -89,6 +90,15 @@ public class TableUpdater extends TableMutator
return ((idx == _index) ? _idxDataState : null);
}
+ void setForeignKey(IndexImpl.ForeignKeyReference fkReference) {
+ _fkReference = fkReference;
+ }
+
+ @Override
+ public IndexImpl.ForeignKeyReference getForeignKey(IndexBuilder idx) {
+ return ((idx == _index) ? _fkReference : null);
+ }
+
int getAddedTdefLen() {
return _addedTdefLen;
}
@@ -294,7 +304,8 @@ public class TableUpdater extends TableMutator
(col2.getFlags() | ignoreColFlags)));
}
- private String withErrorContext(String msg) {
+ @Override
+ protected String withErrorContext(String msg) {
String objStr = "";
if(_column != null) {
objStr = ";Column=" + _column.getName();