Browse Source

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
tags/jackcess-2.1.5
James Ahlborn 7 years ago
parent
commit
8d88e1737d

+ 8
- 0
src/main/java/com/healthmarketscience/jackcess/IndexBuilder.java View File

@@ -123,6 +123,14 @@ public class IndexBuilder
return setUnique();
}

/**
* @usage _advanced_method_
*/
public IndexBuilder setType(byte type) {
_type = type;
return this;
}

/**
* Sets this index to enforce uniqueness.
*/

+ 26
- 2
src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java View File

@@ -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
{

+ 28
- 6
src/main/java/com/healthmarketscience/jackcess/impl/IndexImpl.java View File

@@ -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
}


+ 9
- 7
src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java View File

@@ -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)

+ 2
- 1
src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java View File

@@ -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() + ")";
}
}

+ 23
- 12
src/main/java/com/healthmarketscience/jackcess/impl/TableMutator.java View File

@@ -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_

+ 12
- 1
src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java View File

@@ -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();

Loading…
Cancel
Save