From: James Ahlborn Date: Tue, 8 Nov 2011 03:01:41 +0000 (+0000) Subject: implement complex value deletion X-Git-Tag: jackcess-1.2.6~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=eaccccc1358f9af0214a48ba93c05df5b759d091;p=jackcess.git implement complex value deletion git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@589 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java index b86b9d1..5410e41 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java @@ -297,11 +297,14 @@ public class AttachmentColumnInfo extends ComplexColumnInfo _flags = fileFlags; } - @Override public void update() throws IOException { getComplexValueForeignKey().updateAttachment(this); } + public void delete() throws IOException { + getComplexValueForeignKey().deleteAttachment(this); + } + @Override public String toString() { diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java index bcdaf9f..f9de56d 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java @@ -186,9 +186,7 @@ public abstract class ComplexColumnInfo 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 { return getRawValues(complexValueFk, null); } - - public List> getRawValues(int complexValueFk, - Collection columnNames) + + private Iterator> getComplexValFkIter( + int complexValueFk, Collection columnNames) throws IOException { if(_complexValIdCursor == null) { @@ -210,8 +208,15 @@ public abstract class ComplexColumnInfo .toIndexCursor(); } + return _complexValIdCursor.entryIterator(columnNames, complexValueFk); + } + + public List> getRawValues(int complexValueFk, + Collection columnNames) + throws IOException + { Iterator> entryIter = - _complexValIdCursor.entryIterator(columnNames, complexValueFk); + getComplexValFkIter(complexValueFk, columnNames); if(!entryIter.hasNext()) { return Collections.emptyList(); } @@ -224,8 +229,7 @@ public abstract class ComplexColumnInfo return values; } - public List getValues( - ComplexValueForeignKey complexValueFk) + public List getValues(ComplexValueForeignKey complexValueFk) throws IOException { List> rawValues = getRawValues(complexValueFk.get()); @@ -262,9 +266,7 @@ public abstract class ComplexColumnInfo return id; } - public void addValues(Collection values) - throws IOException - { + public void addValues(Collection values) throws IOException { for(V value : values) { addValue(value); } @@ -282,15 +284,49 @@ public abstract class ComplexColumnInfo return id; } - public void updateValues(Collection values) - throws IOException - { + public void updateValues(Collection values) throws IOException { for(V value : values) { updateValue(value); } } - private void updateRow(Integer id, Object[] row) throws IOException { + public void deleteRawValue(Map rawValue) throws IOException { + deleteRow((Integer)_pkCol.getRowValue(rawValue)); + } + + public void deleteValue(V value) throws IOException { + deleteRow(value.getId()); + } + + public void deleteValues(Collection values) throws IOException { + for(V value : values) { + deleteValue(value); + } + } + + public void deleteAllValues(int complexValueFk) throws IOException { + Iterator> entryIter = + getComplexValFkIter(complexValueFk, Collections.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 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 Map 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 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() { diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java index b2f7d8c..4e6f19a 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java @@ -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; + } diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java index 843cc5e..d236afe 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java @@ -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 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 diff --git a/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java index 61488c1..b1bec20 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java @@ -116,11 +116,14 @@ public class MultiValueColumnInfo extends ComplexColumnInfo _value = value; } - @Override public void update() throws IOException { getComplexValueForeignKey().updateMultiValue(this); } + public void delete() throws IOException { + getComplexValueForeignKey().deleteMultiValue(this); + } + @Override public String toString() { diff --git a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java index d362aa7..7275511 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java @@ -110,11 +110,14 @@ public class UnsupportedColumnInfo extends ComplexColumnInfo 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() { diff --git a/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java index ba98708..8fc5622 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java @@ -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. + *

+ * Note, the strongly typed update/delete methods are not supported for + * version history columns (the data is supposed to be immutable). That said, + * the "raw" update/delete methods are supported for those that really + * want to muck with the version history data. * * @author James Ahlborn */ @@ -88,6 +93,24 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo 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 toValues(ComplexValueForeignKey complexValueFk, List> rawValues) @@ -200,6 +223,16 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo ((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() { diff --git a/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java b/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java index e4e8a26..f9f4445 100644 --- a/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java @@ -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(); }