From cea1bf2b3852c2a0867650162812ad8cb214cbf3 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Fri, 19 Aug 2016 03:08:18 +0000 Subject: [PATCH] implement logic to determine if relationship is one-to-one git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/mutateops@1009 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/CursorBuilder.java | 32 ++-------------- .../jackcess/impl/RelationshipCreator.java | 37 +++++++++++++++---- .../jackcess/impl/TableImpl.java | 30 +++++++++++++++ 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/CursorBuilder.java b/src/main/java/com/healthmarketscience/jackcess/CursorBuilder.java index f545366..688eb9e 100644 --- a/src/main/java/com/healthmarketscience/jackcess/CursorBuilder.java +++ b/src/main/java/com/healthmarketscience/jackcess/CursorBuilder.java @@ -19,8 +19,6 @@ package com.healthmarketscience.jackcess; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -147,37 +145,13 @@ public class CursorBuilder { * Searches for an index with the given column names. */ private CursorBuilder setIndexByColumns(List searchColumns) { - boolean found = false; - for(IndexImpl index : _table.getIndexes()) { - - Collection indexColumns = index.getColumns(); - if(indexColumns.size() != searchColumns.size()) { - continue; - } - Iterator sIter = searchColumns.iterator(); - Iterator iIter = indexColumns.iterator(); - boolean matches = true; - while(sIter.hasNext()) { - String sColName = sIter.next(); - String iColName = iIter.next().getName(); - if((sColName != iColName) && - ((sColName == null) || !sColName.equalsIgnoreCase(iColName))) { - matches = false; - break; - } - } - - if(matches) { - _index = index; - found = true; - break; - } - } - if(!found) { + IndexImpl index = _table.findIndexForColumns(searchColumns, false); + if(index == null) { throw new IllegalArgumentException("Index with columns " + searchColumns + " does not exist in table " + _table); } + _index = index; return this; } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java index b2ef89e..78ddcda 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java @@ -18,10 +18,11 @@ package com.healthmarketscience.jackcess.impl; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Set; -import com.healthmarketscience.jackcess.Column; import com.healthmarketscience.jackcess.IndexBuilder; import com.healthmarketscience.jackcess.RelationshipBuilder; @@ -81,9 +82,11 @@ public class RelationshipCreator extends DBMutator validate(); - // FIXME determine if rel is one to one (integ enforced and both unique) _flags = _relationship.getFlags(); - + // need to determine the one-to-one flag on our own + if(isOneToOne()) { + _flags |= RelationshipImpl.ONE_TO_ONE_FLAG; + } getPageChannel().startExclusiveWrite(); try { @@ -222,17 +225,35 @@ public class RelationshipCreator extends DBMutator return cols; } + private static Collection getColumnNames( + List cols, Collection colNames) { + for(ColumnImpl col : cols) { + colNames.add(col.getName()); + } + return colNames; + } + + private boolean isOneToOne() { + // 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()), true); + if(idx == null) { + return false; + } + idx = _secondaryTable.findIndexForColumns( + getColumnNames(_secondaryCols, new HashSet()), true); + return (idx != null); + } + private static String getTableErrorContext( TableImpl table, List cols, - String tableName, List colNames) { + String tableName, Collection colNames) { if(table != null) { tableName = table.getName(); } if(cols != null) { - colNames = new ArrayList(); - for(ColumnImpl col : cols) { - colNames.add(col.getName()); - } + colNames = getColumnNames(cols, new ArrayList()); } return CustomToStringStyle.valueBuilder(tableName) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java index a4dfd6d..83f96f6 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java @@ -41,6 +41,7 @@ import com.healthmarketscience.jackcess.Column; import com.healthmarketscience.jackcess.ColumnBuilder; import com.healthmarketscience.jackcess.ConstraintViolationException; import com.healthmarketscience.jackcess.CursorBuilder; +import com.healthmarketscience.jackcess.Index; import com.healthmarketscience.jackcess.IndexBuilder; import com.healthmarketscience.jackcess.JackcessException; import com.healthmarketscience.jackcess.PropertyMap; @@ -500,6 +501,35 @@ public class TableImpl implements Table return _indexCount; } + public IndexImpl findIndexForColumns(Collection searchColumns, + boolean uniqueOnly) { + for(IndexImpl index : _indexes) { + + Collection indexColumns = index.getColumns(); + if(indexColumns.size() != searchColumns.size()) { + continue; + } + Iterator sIter = searchColumns.iterator(); + Iterator iIter = indexColumns.iterator(); + boolean matches = true; + while(sIter.hasNext()) { + String sColName = sIter.next(); + String iColName = iIter.next().getName(); + if((sColName != iColName) && + ((sColName == null) || !sColName.equalsIgnoreCase(iColName))) { + matches = false; + break; + } + } + + if(matches && (!uniqueOnly || index.isUnique())) { + return index; + } + } + + return null; + } + List getAutoNumberColumns() { return _autoNumColumns; } -- 2.39.5