diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2013-11-26 23:53:55 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2013-11-26 23:53:55 +0000 |
commit | a3c4f6214b309667186d783daac2ea1351da30d2 (patch) | |
tree | 2efa3d7a8cd64565b155ca5548fce0564176ac27 /src/main/java | |
parent | aa1c80cbff3a58a97f1d134babdde1ebad9dcfac (diff) | |
download | jackcess-a3c4f6214b309667186d783daac2ea1351da30d2.tar.gz jackcess-a3c4f6214b309667186d783daac2ea1351da30d2.zip |
attempt to restore autonumbers on some add row failures
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@838 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java | 30 | ||||
-rw-r--r-- | src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java | 38 |
2 files changed, 67 insertions, 1 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java index a6cba97..ae68a17 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java @@ -1994,6 +1994,11 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> { public abstract Object getNext(Object prevRowValue); /** + * Restores a previous autonumber generated by this generator. + */ + public abstract void restoreLast(Object last); + + /** * Returns the type of values generated by this generator. */ public abstract DataType getType(); @@ -2016,6 +2021,13 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> { } @Override + public void restoreLast(Object last) { + if(last instanceof Integer) { + getTable().restoreLastLongAutoNumber((Integer)last); + } + } + + @Override public DataType getType() { return DataType.LONG; } @@ -2040,6 +2052,11 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> { } @Override + public void restoreLast(Object last) { + _lastAutoNumber = null; + } + + @Override public DataType getType() { return DataType.GUID; } @@ -2067,6 +2084,14 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> { } @Override + public void restoreLast(Object last) { + if(last instanceof ComplexValueForeignKey) { + getTable().restoreLastComplexTypeAutoNumber( + ((ComplexValueForeignKey)last).get()); + } + } + + @Override public DataType getType() { return DataType.COMPLEX_TYPE; } @@ -2091,6 +2116,11 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> { } @Override + public void restoreLast(Object last) { + throw new UnsupportedOperationException(); + } + + @Override public DataType getType() { return _genType; } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java index 638f7fc..15dfaec 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java @@ -1503,6 +1503,7 @@ public class TableImpl implements Table ByteBuffer dataPage = null; int pageNumber = PageChannel.INVALID_PAGE_NUMBER; int updateCount = 0; + int autoNumAssignCount = 0; try { List<Object[]> dupeRows = null; @@ -1529,6 +1530,7 @@ public class TableImpl implements Table // fill in autonumbers handleAutoNumbersForAdd(row); + ++autoNumAssignCount; // write the row of data to a temporary buffer ByteBuffer rowData = createRow( @@ -1592,6 +1594,14 @@ public class TableImpl implements Table } catch(Exception rowWriteFailure) { + boolean isWriteFailure = isWriteFailure(rowWriteFailure); + + if(!isWriteFailure && (autoNumAssignCount > updateCount)) { + // we assigned some autonumbers which won't get written. attempt to + // recover them so we don't get ugly "holes" + restoreAutoNumbersFromAdd(rows.get(autoNumAssignCount - 1)); + } + if(!isBatchWrite) { // just re-throw the original exception if(rowWriteFailure instanceof IOException) { @@ -1601,7 +1611,7 @@ public class TableImpl implements Table } // attempt to resolve a partial batch write - if(isWriteFailure(rowWriteFailure)) { + if(isWriteFailure) { // we don't really know the status of any of the rows, so clear the // update count @@ -2149,6 +2159,22 @@ public class TableImpl implements Table } } + /** + * Restores all autonumber column values from a failed add row. + */ + private void restoreAutoNumbersFromAdd(Object[] row) + throws IOException + { + if(_autoNumColumns.isEmpty()) { + return; + } + + for(ColumnImpl col : _autoNumColumns) { + // restore the last value from the row + col.getAutoNumberGenerator().restoreLast(col.getRowValue(row)); + } + } + private static void padRowBuffer(ByteBuffer buffer, int minRowSize, int trailerSize) { @@ -2174,6 +2200,11 @@ public class TableImpl implements Table // gets the last used auto number (does not modify) return _lastLongAutoNumber; } + + void restoreLastLongAutoNumber(int lastLongAutoNumber) { + // restores the last used auto number + _lastLongAutoNumber = lastLongAutoNumber - 1; + } int getNextComplexTypeAutoNumber() { // note, the saved value is the last one handed out, so pre-increment @@ -2184,6 +2215,11 @@ public class TableImpl implements Table // gets the last used auto number (does not modify) return _lastComplexTypeAutoNumber; } + + void restoreLastComplexTypeAutoNumber(int lastComplexTypeAutoNumber) { + // restores the last used auto number + _lastComplexTypeAutoNumber = lastComplexTypeAutoNumber - 1; + } @Override public String toString() { |