]> source.dussan.org Git - jackcess.git/commitdiff
Change multi-value complex columns so that they return all relevant column properties.
authorJames Ahlborn <jtahlborn@yahoo.com>
Sun, 4 Sep 2016 03:17:38 +0000 (03:17 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Sun, 4 Sep 2016 03:17:38 +0000 (03:17 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1022 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/main/java/com/healthmarketscience/jackcess/PropertyMap.java
src/main/java/com/healthmarketscience/jackcess/impl/ComplexColumnImpl.java
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java
src/main/java/com/healthmarketscience/jackcess/impl/complex/MultiValueColumnPropertyMap.java [new file with mode: 0644]
src/test/java/com/healthmarketscience/jackcess/ComplexColumnTest.java

index d9bfccdcd101c694d6de8882d98c5544613a7a56..25c81899085f20e94a5dbefb250464dddb02b0ff 100644 (file)
@@ -4,6 +4,12 @@
     <author email="javajedi@users.sf.net">Tim McCune</author>
   </properties>
   <body>
+    <release version="2.1.5" date="TBD">
+      <action dev="jahlborn" type="update">
+        Change multi-value complex columns so that they return all relevant
+        column properties.
+      </action>
+    </release>
     <release version="2.1.4" date="2016-05-18">
       <action dev="jahlborn" type="fix" system="SourceForge2" issue="131">
         Fix missing column names in AppendQuery SQL strings.
index 6a78a3fd0cf21fcfae35aedb01d815d3f8581b4a..89a98c1a098a56236a9184763f14d6accd63ec08 100644 (file)
@@ -44,6 +44,7 @@ public interface PropertyMap extends Iterable<PropertyMap.Property>
   public static final String DESCRIPTION_PROP = "Description";
   public static final String RESULT_TYPE_PROP = "ResultType";
   public static final String EXPRESSION_PROP = "Expression";
+  public static final String ALLOW_MULTI_VALUE_PROP = "AllowMultipleValues";
 
 
   public String getName();
index f1432391e64a0eb4b9b331114d02e99fdeba270e..0e6124b47f5fe1c341af2268a12c20bfc9cf2ec5 100644 (file)
@@ -18,9 +18,13 @@ package com.healthmarketscience.jackcess.impl;
 
 import java.io.IOException;
 
+import com.healthmarketscience.jackcess.PropertyMap;
 import com.healthmarketscience.jackcess.complex.ComplexColumnInfo;
+import com.healthmarketscience.jackcess.complex.ComplexDataType;
 import com.healthmarketscience.jackcess.complex.ComplexValue;
 import com.healthmarketscience.jackcess.impl.complex.ComplexColumnInfoImpl;
+import com.healthmarketscience.jackcess.impl.complex.MultiValueColumnInfoImpl;
+import com.healthmarketscience.jackcess.impl.complex.MultiValueColumnPropertyMap;
 
 /**
  * ColumnImpl subclass which is used for complex data types.
@@ -32,6 +36,8 @@ class ComplexColumnImpl extends ColumnImpl
 {
   /** additional information specific to complex columns */
   private final ComplexColumnInfo<? extends ComplexValue> _complexInfo;
+  /** properties for multi-value column */
+  private PropertyMap _mvProps;
 
   ComplexColumnImpl(InitArgs args) throws IOException
   {
@@ -48,6 +54,20 @@ class ComplexColumnImpl extends ColumnImpl
     super.postTableLoadInit();
   }
 
+  @Override
+  public PropertyMap getProperties() throws IOException {
+    if(_complexInfo.getType() == ComplexDataType.MULTI_VALUE) {
+      if(_mvProps == null) {
+        PropertyMap primaryProps = super.getProperties();
+        PropertyMap complexProps = ((MultiValueColumnInfoImpl)_complexInfo)
+          .getValueColumn().getProperties();
+        _mvProps = new MultiValueColumnPropertyMap(primaryProps, complexProps);
+      }
+      return _mvProps;
+    }
+    return super.getProperties();
+  }
+
   @Override
   public ComplexColumnInfo<? extends ComplexValue> getComplexInfo() {
     return _complexInfo;
index 25bb5315733bb6a56f69b919be53a651c00bd5b7..619da07e5fb005f10f04ea642ccb166861f9332b 100644 (file)
@@ -120,14 +120,18 @@ public class PropertyMapImpl implements PropertyMap
     }
 
     for(Property prop : props) {
-      byte flag = 0;
-      if(prop instanceof PropertyImpl) {
-        flag = ((PropertyImpl)prop).getFlag();
-      }
-      put(prop.getName(), prop.getType(), flag, prop.getValue());
+      put(prop);
     }
   }  
   
+  public PropertyImpl put(Property prop) {
+    byte flag = 0;
+    if(prop instanceof PropertyImpl) {
+      flag = ((PropertyImpl)prop).getFlag();
+    }
+    return put(prop.getName(), prop.getType(), flag, prop.getValue());
+  }
+
   /**
    * Puts a property into this map with the given information.
    */
@@ -151,11 +155,15 @@ public class PropertyMapImpl implements PropertyMap
 
   @Override
   public String toString() {
+    return toString(this);
+  }      
+
+  public static String toString(PropertyMap map) {
     StringBuilder sb = new StringBuilder();
-    sb.append(PropertyMaps.DEFAULT_NAME.equals(getName()) ?
-              "<DEFAULT>" : getName())
+    sb.append(PropertyMaps.DEFAULT_NAME.equals(map.getName()) ?
+              "<DEFAULT>" : map.getName())
       .append(" {");
-    for(Iterator<Property> iter = iterator(); iter.hasNext(); ) {
+    for(Iterator<Property> iter = map.iterator(); iter.hasNext(); ) {
       sb.append(iter.next());
       if(iter.hasNext()) {
         sb.append(",");
@@ -163,7 +171,7 @@ public class PropertyMapImpl implements PropertyMap
     }
     sb.append("}");
     return sb.toString();
-  }      
+  }
 
   public static Property createProperty(String name, DataType type, Object value) {
     return createProperty(name, type, (byte)0, value);
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/complex/MultiValueColumnPropertyMap.java b/src/main/java/com/healthmarketscience/jackcess/impl/complex/MultiValueColumnPropertyMap.java
new file mode 100644 (file)
index 0000000..08f472c
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+Copyright (c) 2016 James Ahlborn
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package com.healthmarketscience.jackcess.impl.complex;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import com.healthmarketscience.jackcess.DataType;
+import com.healthmarketscience.jackcess.PropertyMap;
+import com.healthmarketscience.jackcess.impl.PropertyMapImpl;
+
+/**
+ * PropertyMap implementation for multi-value, complex properties.  The
+ * properties for these columns seem to be dispersed between both the primary
+ * column and the complex value column.  The primary column only seems to have
+ * the simple "multi-value" property and the rest seem to be on the complex
+ * value column.  This PropertyMap implementation combines them into one
+ * synthetic map.
+ *
+ * @author James Ahlborn
+ */
+public class MultiValueColumnPropertyMap implements PropertyMap
+{
+  /** properties from the primary column */
+  private final PropertyMap _primary;
+  /** properties from the complex column */
+  private final PropertyMap _complex;
+
+  public MultiValueColumnPropertyMap(PropertyMap primary, PropertyMap complex) 
+  {
+    _primary = primary;
+    _complex = complex;
+  }
+
+  public String getName() {
+    return _primary.getName();
+  }
+
+  public int getSize() {
+    return _primary.getSize() + _complex.getSize();
+  }
+
+  public boolean isEmpty() {
+    return _primary.isEmpty() && _complex.isEmpty();
+  }
+
+  public Property get(String name) {
+    Property prop = _primary.get(name);
+    if(prop != null) {
+      return prop;
+    }
+    return _complex.get(name);
+  }
+
+  public Object getValue(String name) {
+    return getValue(name, null);
+  }
+
+  public Object getValue(String name, Object defaultValue) {
+    Property prop = get(name);
+    return ((prop != null) ? prop.getValue() : defaultValue);
+  }
+
+  public Property put(String name, Object value) {
+    return put(name, null, value);
+  }
+
+  public Property put(String name, DataType type, Object value) {
+    // the only property which seems to go in the "primary" is the "multi
+    // value" property
+    if(ALLOW_MULTI_VALUE_PROP.equals(name)) {
+      return _primary.put(name, DataType.BOOLEAN, value);
+    }
+    return _complex.put(name, value);
+  }
+
+  public void putAll(Iterable<? extends Property> props) {
+    if(props == null) {
+      return;
+    }
+
+    for(Property prop : props) {
+      if(ALLOW_MULTI_VALUE_PROP.equals(prop.getName())) {
+        ((PropertyMapImpl)_primary).put(prop);
+      } else {
+        ((PropertyMapImpl)_complex).put(prop);
+      }
+    }
+  }  
+
+  public Property remove(String name) {
+    if(ALLOW_MULTI_VALUE_PROP.equals(name)) {
+      return _primary.remove(name);
+    }
+    return _complex.remove(name);
+  }
+
+  public void save() throws IOException {
+    _primary.save();
+    _complex.save();
+  }
+
+  public Iterator<Property> iterator() {
+    final List<Iterator<Property>> iters = new ArrayList<Iterator<Property>>(2);
+    iters.add(_primary.iterator());
+    iters.add(_complex.iterator());
+
+    return new Iterator<Property>() {
+      private Iterator<Property> _cur;
+      private Property _next = findNext();
+
+      private Property findNext() {
+        while(!iters.isEmpty()) {
+          _cur = iters.get(0);
+          if(_cur.hasNext()) {
+            return _cur.next();
+          }
+          iters.remove(0);
+          _cur = null;
+        }
+        return null;
+      }
+
+      public boolean hasNext() {
+        return (_next != null);
+      }
+
+      public Property next() {
+        if(!hasNext()) {
+          throw new NoSuchElementException();
+        }
+        Property prop = _next;
+        _next = findNext();
+        return prop;
+      }
+
+      public void remove() {
+        if(_cur != null) {
+          _cur.remove();
+          _cur = null;
+        }
+      }
+    };
+  }
+
+  @Override
+  public String toString() {
+    return PropertyMapImpl.toString(this);
+  }
+}
index a2fd2eb486b7d292d6d524fea90d852803d37191..acecf57daa854b8b71d0874f619c305feaa11e9f 100644 (file)
@@ -302,6 +302,13 @@ public class ComplexColumnTest extends TestCase
         cursor.getCurrentRowValue(col);
       row3ValFk.deleteAllValues();
       checkMultiValues(3, row3ValFk);
+
+      // test multi-value col props
+      PropertyMap props = col.getProperties();
+      assertEquals(Boolean.TRUE, props.getValue(PropertyMap.ALLOW_MULTI_VALUE_PROP));
+      assertEquals("Value List", props.getValue("RowSourceType"));
+      assertEquals("\"value1\";\"value2\";\"value3\";\"value4\"", 
+                   props.getValue("RowSource"));      
     
       db.close();
     }