aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2013-11-26 23:53:55 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2013-11-26 23:53:55 +0000
commita3c4f6214b309667186d783daac2ea1351da30d2 (patch)
tree2efa3d7a8cd64565b155ca5548fce0564176ac27 /src/main/java
parentaa1c80cbff3a58a97f1d134babdde1ebad9dcfac (diff)
downloadjackcess-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.java30
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java38
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() {