From: James Ahlborn Date: Sun, 30 Jul 2006 03:22:36 +0000 (+0000) Subject: handle more tables with more idnex slots than actual indexes (fix bug 1530312) X-Git-Tag: rel_1_1_6~18 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=805cc8cf030fc2ebe36c1b9e051dec156e2241b2;p=jackcess.git handle more tables with more idnex slots than actual indexes (fix bug 1530312) git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@78 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/java/com/healthmarketscience/jackcess/JetFormat.java b/src/java/com/healthmarketscience/jackcess/JetFormat.java index dc127b1..ec5c73e 100644 --- a/src/java/com/healthmarketscience/jackcess/JetFormat.java +++ b/src/java/com/healthmarketscience/jackcess/JetFormat.java @@ -68,6 +68,7 @@ public abstract class JetFormat { public final int OFFSET_MAX_COLS; public final int OFFSET_NUM_VAR_COLS; public final int OFFSET_NUM_COLS; + public final int OFFSET_NUM_INDEX_SLOTS; public final int OFFSET_NUM_INDEXES; public final int OFFSET_OWNED_PAGES; public final int OFFSET_FREE_SPACE_PAGES; @@ -151,6 +152,7 @@ public abstract class JetFormat { OFFSET_MAX_COLS = defineOffsetMaxCols(); OFFSET_NUM_VAR_COLS = defineOffsetNumVarCols(); OFFSET_NUM_COLS = defineOffsetNumCols(); + OFFSET_NUM_INDEX_SLOTS = defineOffsetNumIndexSlots(); OFFSET_NUM_INDEXES = defineOffsetNumIndexes(); OFFSET_OWNED_PAGES = defineOffsetOwnedPages(); OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages(); @@ -213,6 +215,7 @@ public abstract class JetFormat { protected abstract int defineOffsetMaxCols(); protected abstract int defineOffsetNumVarCols(); protected abstract int defineOffsetNumCols(); + protected abstract int defineOffsetNumIndexSlots(); protected abstract int defineOffsetNumIndexes(); protected abstract int defineOffsetOwnedPages(); protected abstract int defineOffsetFreeSpacePages(); @@ -276,6 +279,7 @@ public abstract class JetFormat { protected int defineOffsetMaxCols() { return 41; } protected int defineOffsetNumVarCols() { return 43; } protected int defineOffsetNumCols() { return 45; } + protected int defineOffsetNumIndexSlots() { return 47; } protected int defineOffsetNumIndexes() { return 51; } protected int defineOffsetOwnedPages() { return 55; } protected int defineOffsetFreeSpacePages() { return 59; } diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java index c1bf455..9637c4e 100644 --- a/src/java/com/healthmarketscience/jackcess/Table.java +++ b/src/java/com/healthmarketscience/jackcess/Table.java @@ -63,6 +63,8 @@ public class Table { private int _currentRowInPage; /** Number of indexes on the table */ private int _indexCount; + /** Number of index slots for the table */ + private int _indexSlotCount; /** Offset index in the buffer where the last row read started */ private short _lastRowStart; /** Number of rows in the table */ @@ -164,6 +166,13 @@ public class Table { public List getIndexes() { return Collections.unmodifiableList(_indexes); } + + /** + * Only called by unit tests + */ + int getIndexSlotCount() { + return _indexSlotCount; + } /** * After calling this method, getNextRow will return the first row in the table @@ -334,6 +343,7 @@ public class Table { _maxColumnCount = _buffer.getShort(_format.OFFSET_MAX_COLS); _maxVarColumnCount = _buffer.getShort(_format.OFFSET_NUM_VAR_COLS); _columnCount = _buffer.getShort(_format.OFFSET_NUM_COLS); + _indexSlotCount = _buffer.getInt(_format.OFFSET_NUM_INDEX_SLOTS); _indexCount = _buffer.getInt(_format.OFFSET_NUM_INDEXES); byte rowNum = _buffer.get(_format.OFFSET_OWNED_PAGES); @@ -379,14 +389,34 @@ public class Table { int idxOffset = _buffer.position(); _buffer.position(idxOffset + (_format.OFFSET_INDEX_NUMBER_BLOCK * _indexCount)); - for (int i = 0; i < _indexCount; i++) { - Index index = _indexes.get(i); + + // there are _indexSlotCount blocks here, we ignore any slot with an index + // number greater than the number of actual indexes + int curIndex = 0; + for (int i = 0; i < _indexSlotCount; i++) { + _buffer.getInt(); //Forward past Unknown - index.setIndexNumber(_buffer.getInt()); + int indexNumber = _buffer.getInt(); _buffer.position(_buffer.position() + 15); - index.setPrimaryKey(_buffer.get() == 1); + byte indexType = _buffer.get(); _buffer.position(_buffer.position() + 4); + + if(indexNumber < _indexCount) { + Index index = _indexes.get(curIndex++); + index.setIndexNumber(indexNumber); + index.setPrimaryKey(indexType == 1); + } } + + // for each empty index slot, there is some weird sort of name + for(int i = 0; i < (_indexSlotCount - _indexCount); ++i) { + int skipBytes = _buffer.getShort(); + _buffer.position(_buffer.position() + skipBytes); + } + + // read actual index names + // FIXME, we still are not always getting the names matched correctly with + // the index info, some weird indexing we are not figuring out yet for (int i = 0; i < _indexCount; i++) { byte[] nameBytes = new byte[_buffer.getShort()]; _buffer.get(nameBytes); diff --git a/test/data/indexTest.mdb b/test/data/indexTest.mdb new file mode 100644 index 0000000..7e8bd98 Binary files /dev/null and b/test/data/indexTest.mdb differ diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index f22edcb..084fa65 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -423,6 +423,23 @@ public class DatabaseTest extends TestCase { } } + public void testIndexSlots() throws Exception + { + Database mdb = Database.open(new File("test/data/indexTest.mdb")); + + Table table = mdb.getTable("Table1"); + assertEquals(4, table.getIndexes().size()); + assertEquals(4, table.getIndexSlotCount()); + + table = mdb.getTable("Table2"); + assertEquals(2, table.getIndexes().size()); + assertEquals(3, table.getIndexSlotCount()); + + table = mdb.getTable("Table3"); + assertEquals(2, table.getIndexes().size()); + assertEquals(3, table.getIndexSlotCount()); + } + private Object[] createTestRow() { return new Object[] {"Tim", "R", "McCune", 1234, (byte) 0xad, 555.66d, 777.88f, (short) 999, new Date()};