]> source.dussan.org Git - jackcess.git/commitdiff
implement complex value deletion
authorJames Ahlborn <jtahlborn@yahoo.com>
Tue, 8 Nov 2011 03:01:41 +0000 (03:01 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Tue, 8 Nov 2011 03:01:41 +0000 (03:01 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@589 f203690c-595d-4dc9-a70b-905162fa7fd2

src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java
src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java
src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java
src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java
src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java
src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java
test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java

index b86b9d16c8dbe304bcd3abdcb7739e31035487bb..5410e41e28713679de98216db0a1c45f30bf50d9 100644 (file)
@@ -297,11 +297,14 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
       _flags = fileFlags;
     }  
 
-    @Override
     public void update() throws IOException {
       getComplexValueForeignKey().updateAttachment(this);
     }
     
+    public void delete() throws IOException {
+      getComplexValueForeignKey().deleteAttachment(this);
+    }
+    
     @Override
     public String toString()
     {
index bcdaf9fd2d21a11870104542e29f3c6faafbb828..f9de56d753814e9f724a54e77e94fe46f221fdab 100644 (file)
@@ -186,9 +186,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     return _typeCols;
   }
   
-  public int countValues(int complexValueFk)
-    throws IOException
-  {
+  public int countValues(int complexValueFk) throws IOException {
     return getRawValues(complexValueFk,
                         Collections.singleton(_complexValFkCol.getName()))
       .size();
@@ -199,9 +197,9 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
   {
     return getRawValues(complexValueFk, null);
   }
-  
-  public List<Map<String,Object>> getRawValues(int complexValueFk,
-                                               Collection<String> columnNames)
+
+  private Iterator<Map<String,Object>> getComplexValFkIter(
+      int complexValueFk, Collection<String> columnNames)
     throws IOException
   {
     if(_complexValIdCursor == null) {
@@ -210,8 +208,15 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
         .toIndexCursor();
     }
 
+    return _complexValIdCursor.entryIterator(columnNames, complexValueFk);
+  }
+  
+  public List<Map<String,Object>> getRawValues(int complexValueFk,
+                                               Collection<String> columnNames)
+    throws IOException
+  {
     Iterator<Map<String,Object>> entryIter =
-      _complexValIdCursor.entryIterator(columnNames, complexValueFk);
+      getComplexValFkIter(complexValueFk, columnNames);
     if(!entryIter.hasNext()) {
       return Collections.emptyList();
     }
@@ -224,8 +229,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     return values;
   }
 
-  public List<V> getValues(
-      ComplexValueForeignKey complexValueFk)
+  public List<V> getValues(ComplexValueForeignKey complexValueFk)
     throws IOException
   {
     List<Map<String,Object>> rawValues = getRawValues(complexValueFk.get());
@@ -262,9 +266,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     return id;
   }
 
-  public void addValues(Collection<? extends V> values)
-    throws IOException
-  {
+  public void addValues(Collection<? extends V> values) throws IOException {
     for(V value : values) {
       addValue(value);
     }
@@ -282,15 +284,49 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     return id;
   }
 
-  public void updateValues(Collection<? extends V> values)
-    throws IOException
-  {
+  public void updateValues(Collection<? extends V> values) throws IOException {
     for(V value : values) {
       updateValue(value);
     }
   }
 
-  private void updateRow(Integer id, Object[] row) throws IOException {
+  public void deleteRawValue(Map<String,Object> rawValue) throws IOException {
+    deleteRow((Integer)_pkCol.getRowValue(rawValue));
+  }
+  
+  public void deleteValue(V value) throws IOException {
+    deleteRow(value.getId());
+  }
+
+  public void deleteValues(Collection<? extends V> values) throws IOException {
+    for(V value : values) {
+      deleteValue(value);
+    }
+  }
+
+  public void deleteAllValues(int complexValueFk) throws IOException {
+    Iterator<Map<String,Object>> entryIter =
+      getComplexValFkIter(complexValueFk, Collections.<String>emptySet());
+    try {
+      while(entryIter.hasNext()) {
+        entryIter.next();
+        entryIter.remove();
+      }
+    } catch(RuntimeException e) {
+      if(e.getCause() instanceof IOException) {
+        throw (IOException)e.getCause();
+      }
+      throw e;
+    }
+  }
+
+  public void deleteAllValues(ComplexValueForeignKey complexValueFk)
+    throws IOException
+  {
+    deleteAllValues(complexValueFk.get());
+  }
+
+  private void moveToRow(Integer id) throws IOException {
     if(_pkCursor == null) {
       _pkCursor = new CursorBuilder(_flatTable)
         .setIndexByColumns(_pkCol)
@@ -300,11 +336,19 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     if(!_pkCursor.findRowByEntry(id)) {
       throw new IllegalArgumentException("Row with id " + id +
                                          " does not exist");
-    }
-    
+    }    
+  }
+
+  private void updateRow(Integer id, Object[] row) throws IOException {
+    moveToRow(id);
     _pkCursor.updateCurrentRow(row);
   }
   
+  private void deleteRow(Integer id) throws IOException {
+    moveToRow(id);
+    _pkCursor.deleteCurrentRow();
+  }
+  
   protected Object[] asRow(Object[] row, V value) {
     int id = value.getId();
     _pkCol.setRowValue(row, ((id != INVALID_ID) ? id : Column.AUTO_NUMBER));
@@ -355,7 +399,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
       Map<String,Object> rawValues)
     throws IOException;
   
-  protected static class ComplexValueImpl implements ComplexValue
+  protected static abstract class ComplexValueImpl implements ComplexValue
   {
     private int _id;
     private ComplexValueForeignKey _complexValueFk;
@@ -391,11 +435,6 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
     public Column getColumn() {
       return _complexValueFk.getColumn();
     }
-
-    public void update() throws IOException {
-      throw new UnsupportedOperationException(
-          "This column does not support value updates");
-    }
     
     @Override
     public int hashCode() {
index b2f7d8c04e4831ca38972022a1c2e702d9a3e04b..4e6f19a7b7904a38a53e15110ab16749dadce5ff 100644 (file)
@@ -63,4 +63,10 @@ public interface ComplexValue
    * Writes any updated data for this complex value to the database.
    */
   public void update() throws IOException;
+
+  /**
+   * Deletes the data for this complex value from the database.
+   */
+  public void delete() throws IOException;
+
 }
index 843cc5ed1794a274d9ad779c6c83f0863d5b215a..d236afed1cb984eed1de9099b59fd427914950da 100644 (file)
@@ -213,6 +213,14 @@ public class ComplexValueForeignKey extends Number
     return attachment;
   }
   
+  public Attachment deleteAttachment(Attachment attachment)
+    throws IOException
+  {
+    reset();
+    getAttachmentInfo().deleteValue(attachment);
+    return attachment;
+  }
+  
   public SingleValue addMultiValue(Object value)
     throws IOException
   {
@@ -230,6 +238,14 @@ public class ComplexValueForeignKey extends Number
     return value;
   }
   
+  public SingleValue deleteMultiValue(SingleValue value)
+    throws IOException
+  {
+    reset();
+    getMultiValueInfo().deleteValue(value);
+    return value;
+  }
+  
   public UnsupportedValue addUnsupportedValue(Map<String,Object> values)
     throws IOException
   {
@@ -247,6 +263,21 @@ public class ComplexValueForeignKey extends Number
     return value;
   }
   
+  public UnsupportedValue deleteUnsupportedValue(UnsupportedValue value)
+    throws IOException
+  {
+    reset();
+    getUnsupportedInfo().deleteValue(value);
+    return value;
+  }
+  
+  public void deleteAllValues()
+    throws IOException
+  {
+    reset();
+    getComplexInfo().deleteAllValues(this);
+  }
+  
   private Object writeReplace() throws ObjectStreamException {
     // if we are going to serialize this ComplexValueForeignKey, convert it
     // back to a normal Integer (in case it is restored outside of the context
index 61488c1039e7f534217129fd39be32c215a86e96..b1bec203164cdec06e282bcee00aa5c4af6811cc 100644 (file)
@@ -116,11 +116,14 @@ public class MultiValueColumnInfo extends ComplexColumnInfo<SingleValue>
       _value = value;
     }
 
-    @Override
     public void update() throws IOException {
       getComplexValueForeignKey().updateMultiValue(this);
     }
     
+    public void delete() throws IOException {
+      getComplexValueForeignKey().deleteMultiValue(this);
+    }
+    
     @Override
     public String toString()
     {
index d362aa7374f6fac4cc1d6b050ed2ea33b76fb7f3..727551137b3101619777197ed5cb45019d50b71c 100644 (file)
@@ -110,11 +110,14 @@ public class UnsupportedColumnInfo extends ComplexColumnInfo<UnsupportedValue>
       getValues().put(columnName, value);
     }
 
-    @Override
     public void update() throws IOException {
       getComplexValueForeignKey().updateUnsupportedValue(this);
     }
     
+    public void delete() throws IOException {
+      getComplexValueForeignKey().deleteUnsupportedValue(this);
+    }
+    
     @Override
     public String toString()
     {
index ba987089b6e298f2106c0dc5eec32f0e678d8971..8fc56221ba4d4988fe4ea14d360ed883668b0008 100644 (file)
@@ -31,6 +31,11 @@ import com.healthmarketscience.jackcess.Table;
 /**
  * Complex column info for a column which tracking the version history of an
  * "append only" memo column.
+ * <p>
+ * Note, the strongly typed update/delete methods are <i>not</i> supported for
+ * version history columns (the data is supposed to be immutable).  That said,
+ * the "raw" update/delete methods are supported for those that <i>really</i>
+ * want to muck with the version history data.
  *
  * @author James Ahlborn
  */
@@ -88,6 +93,24 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo<Version>
     return ComplexDataType.VERSION_HISTORY;
   }
 
+  @Override
+  public int updateValue(Version value) throws IOException {
+    throw new UnsupportedOperationException(
+        "This column does not support value updates");
+  }
+
+  @Override
+  public void deleteValue(Version value) throws IOException {
+    throw new UnsupportedOperationException(
+        "This column does not support value deletes");
+  }
+
+  @Override
+  public void deleteAllValues(int complexValueFk) throws IOException {
+    throw new UnsupportedOperationException(
+        "This column does not support value deletes");
+  }
+
   @Override
   protected List<Version> toValues(ComplexValueForeignKey complexValueFk,
                                    List<Map<String,Object>> rawValues)
@@ -200,6 +223,16 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo<Version>
               ((id1 < id2) ? 1 : 0));
     }
 
+    public void update() throws IOException {
+      throw new UnsupportedOperationException(
+          "This column does not support value updates");
+    }
+    
+    public void delete() throws IOException {
+      throw new UnsupportedOperationException(
+          "This column does not support value deletes");
+    }
+
     @Override
     public String toString()
     {
index e4e8a2620d95d8a38427caadc8476745f76c7d18..f9f4445f44f7b443d1cfc132a22533971596078c 100644 (file)
@@ -113,6 +113,38 @@ public class ComplexColumnTest extends TestCase
       } catch(UnsupportedOperationException expected) {
         // success
       }
+
+      checkVersions(3, row3ValFk, "new-value",
+                    "new-value", upTime,
+                    "row3-memo-again", new Date(1315876965382L),
+                    "row3-memo-revised", new Date(1315876953077L),
+                    "row3-memo", new Date(1315876879126L));
+    
+      try {
+        v.delete();
+        fail("UnsupportedOperationException should have been thrown");
+      } catch(UnsupportedOperationException expected) {
+        // success
+      }
+
+      checkVersions(3, row3ValFk, "new-value",
+                    "new-value", upTime,
+                    "row3-memo-again", new Date(1315876965382L),
+                    "row3-memo-revised", new Date(1315876953077L),
+                    "row3-memo", new Date(1315876879126L));
+    
+      try {
+        v.getComplexValueForeignKey().deleteAllValues();
+        fail("UnsupportedOperationException should have been thrown");
+      } catch(UnsupportedOperationException expected) {
+        // success
+      }
+
+      checkVersions(3, row3ValFk, "new-value",
+                    "new-value", upTime,
+                    "row3-memo-again", new Date(1315876965382L),
+                    "row3-memo-revised", new Date(1315876953077L),
+                    "row3-memo", new Date(1315876879126L));
     
       db.close();
     }
@@ -178,6 +210,17 @@ public class ComplexColumnTest extends TestCase
       assertEquals("xml", updated.getFileType());
       assertEquals("some_data.xml", updated.getFileName());
       assertTrue(Arrays.equals(newBytes, updated.getFileData()));
+
+      updated.delete();
+      checkAttachments(4, row4ValFk, "test_data2.txt");
+      row4ValFk.getAttachments().get(0).delete();
+      checkAttachments(4, row4ValFk);
+
+      assertTrue(cursor.findRow(t1.getColumn("id"), "row2"));
+      ComplexValueForeignKey row2ValFk = (ComplexValueForeignKey)
+        cursor.getCurrentRowValue(col);
+      row2ValFk.deleteAllValues();
+      checkAttachments(2, row2ValFk);      
     
       db.close();
     }
@@ -235,6 +278,21 @@ public class ComplexColumnTest extends TestCase
       v.set("value5");
       v.update();
       checkMultiValues(2, row2ValFk, "value1", "value4", "value5", "value3");
+
+      v.delete();
+      checkMultiValues(2, row2ValFk, "value1", "value4", "value3");
+      row2ValFk.getMultiValues().get(0).delete();
+      checkMultiValues(2, row2ValFk, "value4", "value3");
+      row2ValFk.getMultiValues().get(1).delete();
+      checkMultiValues(2, row2ValFk, "value4");
+      row2ValFk.getMultiValues().get(0).delete();
+      checkMultiValues(2, row2ValFk);
+
+      assertTrue(cursor.findRow(t1.getColumn("id"), "row3"));
+      ComplexValueForeignKey row3ValFk = (ComplexValueForeignKey)
+        cursor.getCurrentRowValue(col);
+      row3ValFk.deleteAllValues();
+      checkMultiValues(3, row3ValFk);
     
       db.close();
     }