From fce56371ce1e3a09ba995b05eb4cd6d44d160415 Mon Sep 17 00:00:00 2001 From: Tim McCune Date: Tue, 30 Aug 2005 06:33:27 +0000 Subject: [PATCH] Added ability to delete current row. Fixed bug where adding a new row to a table whose last row had been deleted failed. git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@29 f203690c-595d-4dc9-a70b-905162fa7fd2 --- project.xml | 2 +- .../healthmarketscience/jackcess/Table.java | 18 +++++ .../jackcess/UsageMap.java | 10 ++- .../jackcess/DatabaseTest.java | 72 ++++++++++++++----- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/project.xml b/project.xml index ed4ba93..27bbac0 100644 --- a/project.xml +++ b/project.xml @@ -3,7 +3,7 @@ 1 jackcess Jackcess - 1.1.2 + 1.1.3 Health Market Science, Inc. http://www.healthmarketscience.com diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java index 96b51ca..b0223b6 100644 --- a/src/java/com/healthmarketscience/jackcess/Table.java +++ b/src/java/com/healthmarketscience/jackcess/Table.java @@ -139,6 +139,7 @@ public class Table { public void reset() { _rowsLeftOnPage = 0; _ownedPages.reset(); + _currentRowInPage = 0; } /** @@ -147,6 +148,19 @@ public class Table { public Map getNextRow() throws IOException { return getNextRow(null); } + + /** + * Delete the current row (retrieved by a call to {@link #getNextRow}). + */ + public void deleteCurrentRow() throws IOException { + if (_currentRowInPage == 0) { + throw new IllegalStateException("Must call getNextRow first"); + } + int index = _format.OFFSET_DATA_ROW_LOCATION_BLOCK + (_currentRowInPage - 1) * + _format.SIZE_ROW_LOCATION + 1; + _buffer.put(index, (byte) (_buffer.get(index) | 0xc0)); + _pageChannel.writePage(_buffer, _ownedPages.getCurrentPageNumber()); + } /** * @param columnNames Only column names in this collection will be returned @@ -384,6 +398,10 @@ public class Table { if (rowCount > 0) { rowLocation = dataPage.getShort(_format.OFFSET_DATA_ROW_LOCATION_BLOCK + (rowCount - 1) * _format.SIZE_ROW_LOCATION); + if (rowLocation < 0) { + // Deleted row + rowLocation &= ~0xc000; + } } rowLocation -= rowSize; dataPage.putShort(_format.OFFSET_DATA_ROW_LOCATION_BLOCK + diff --git a/src/java/com/healthmarketscience/jackcess/UsageMap.java b/src/java/com/healthmarketscience/jackcess/UsageMap.java index c6ddbc7..642470b 100644 --- a/src/java/com/healthmarketscience/jackcess/UsageMap.java +++ b/src/java/com/healthmarketscience/jackcess/UsageMap.java @@ -128,7 +128,11 @@ public abstract class UsageMap { public List getPageNumbers() { return _pageNumbers; } - + + public Integer getCurrentPageNumber() { + return _pageNumbers.get(_currentPageIndex - 1); + } + protected void setStartOffset(int startOffset) { _startOffset = startOffset; } @@ -166,8 +170,8 @@ public abstract class UsageMap { */ public boolean getNextPage(ByteBuffer buffer) throws IOException { if (_pageNumbers.size() > _currentPageIndex) { - Integer pageNumber = (Integer) _pageNumbers.get(_currentPageIndex++); - _pageChannel.readPage(buffer, pageNumber.intValue()); + Integer pageNumber = _pageNumbers.get(_currentPageIndex++); + _pageChannel.readPage(buffer, pageNumber); return true; } else { return false; diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index 94ee826..f72b6c6 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -103,16 +103,8 @@ public class DatabaseTest extends TestCase { public void testWriteAndRead() throws Exception { Database db = create(); createTestTable(db); - Object[] row = new Object[9]; - row[0] = "Tim"; - row[1] = "R"; - row[2] = "McCune"; + Object[] row = createTestRow(); row[3] = null; - row[4] = new Byte((byte) 0xad); - row[5] = new Double(555.66d); - row[6] = new Float(777.88d); - row[7] = new Short((short) 999); - row[8] = new Date(); Table table = db.getTable("Test"); int count = 1000; for (int i = 0; i < count; i++) { @@ -136,16 +128,7 @@ public class DatabaseTest extends TestCase { createTestTable(db); int count = 1000; List rows = new ArrayList(count); - Object[] row = new Object[9]; - row[0] = "Tim"; - row[1] = "R"; - row[2] = "McCune"; - row[3] = new Integer(1234); - row[4] = new Byte((byte) 0xad); - row[5] = new Double(555.66d); - row[6] = new Float(777.88d); - row[7] = new Short((short) 999); - row[8] = new Date(); + Object[] row = createTestRow(); for (int i = 0; i < count; i++) { rows.add(row); } @@ -163,6 +146,57 @@ public class DatabaseTest extends TestCase { assertEquals(row[7], readRow.get("H")); } } + + public void testDeleteCurrentRow() throws Exception { + Database db = create(); + createTestTable(db); + Object[] row = createTestRow(); + Table table = db.getTable("Test"); + for (int i = 0; i < 10; i++) { + row[3] = i; + table.addRow(row); + } + row[3] = 1974; + assertEquals(10, countRows(table)); + table.reset(); + table.getNextRow(); + table.deleteCurrentRow(); + assertEquals(9, countRows(table)); + table.reset(); + table.getNextRow(); + table.deleteCurrentRow(); + assertEquals(8, countRows(table)); + table.reset(); + for (int i = 0; i < 8; i++) { + table.getNextRow(); + } + table.deleteCurrentRow(); + assertEquals(7, countRows(table)); + table.addRow(row); + assertEquals(8, countRows(table)); + table.reset(); + for (int i = 0; i < 3; i++) { + table.getNextRow(); + } + table.deleteCurrentRow(); + assertEquals(7, countRows(table)); + table.reset(); + assertEquals(2, table.getNextRow().get("D")); + } + + private int countRows(Table table) throws Exception { + table.reset(); + int rtn = 0; + while (table.getNextRow() != null) { + rtn++; + } + return rtn; + } + + private Object[] createTestRow() { + return new Object[] {"Tim", "R", "McCune", 1234, (byte) 0xad, 555.66d, + 777.88f, (short) 999, new Date()}; + } private void createTestTable(Database db) throws Exception { List columns = new ArrayList(); -- 2.39.5