From: James Ahlborn Date: Thu, 29 Nov 2007 16:12:26 +0000 (+0000) Subject: more minor tweaks and enhanced cursor tests X-Git-Tag: rel_1_1_10~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=34b536c894ff35270905026db1087ecbdf205880;p=jackcess.git more minor tweaks and enhanced cursor tests git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@191 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/java/com/healthmarketscience/jackcess/Cursor.java b/src/java/com/healthmarketscience/jackcess/Cursor.java index 901019c..3bba37e 100644 --- a/src/java/com/healthmarketscience/jackcess/Cursor.java +++ b/src/java/com/healthmarketscience/jackcess/Cursor.java @@ -135,6 +135,56 @@ public abstract class Cursor implements Iterable> return null; } + /** + * Convenience method for finding a specific row in an indexed table which + * matches a given row "pattern. See {@link #findRow(Map)} for details on + * the rowPattern. + * + * @param table the table to search + * @param index index to assist the search + * @param rowPattern pattern to be used to find the row + * @return the matching row or {@code null} if a match could not be found. + */ + public static Map findRow(Table table, Index index, + Map rowPattern) + throws IOException + { + Cursor cursor = createIndexCursor(table, index); + if(cursor.findRow(rowPattern)) { + return cursor.getCurrentRow(); + } + return null; + } + + /** + * Convenience method for finding a specific row in a table which matches a + * given row "pattern. See {@link #findRow(Column,Object)} for details on + * the pattern. + *

+ * Note, a {@code null} result value is ambiguous in that it could imply no + * match or a matching row with {@code null} for the desired value. If + * distinguishing this situation is important, you will need to use a Cursor + * directly instead of this convenience method. + * + * @param table the table to search + * @param index index to assist the search + * @param column column whose value should be returned + * @param columnPattern column being matched by the valuePattern + * @param valuePattern value from the columnPattern which will match the + * desired row + * @return the matching row or {@code null} if a match could not be found. + */ + public static Object findValue(Table table, Index index, Column column, + Column columnPattern, Object valuePattern) + throws IOException + { + Cursor cursor = createIndexCursor(table, index); + if(cursor.findRow(columnPattern, valuePattern)) { + return cursor.getCurrentRowValue(column); + } + return null; + } + public Table getTable() { return _table; } @@ -147,18 +197,23 @@ public abstract class Cursor implements Iterable> return getTable().getPageChannel(); } - public Position getCurrentPosition() { - return _curPos; + /** + * Returns the current state of the cursor which can be restored at a future + * point in time by a call to {@link #restoreSavepoint}. + */ + public Savepoint getSavepoint() { + return new Savepoint(_curPos, _prevPos); } /** - * Moves the cursor to a position previously returned from - * {@link #getCurrentPosition}. + * Moves the cursor to a savepoint previously returned from + * {@link #getSavepoint}. */ - public void setCurrentPosition(Position curPos) + public void restoreSavepoint(Savepoint savepoint) throws IOException { - restorePosition(curPos); + restorePosition(savepoint.getCurrentPosition(), + savepoint.getPreviousPosition()); } /** @@ -1079,6 +1134,34 @@ public abstract class Cursor implements Iterable> } + /** + * Value object which represents a complete save state of the cursor. + */ + public static final class Savepoint + { + private final Position _curPos; + private final Position _prevPos; + + private Savepoint(Position curPos, Position prevPos) { + _curPos = curPos; + _prevPos = prevPos; + } + + public Position getCurrentPosition() { + return _curPos; + } + + private Position getPreviousPosition() { + return _prevPos; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " CurPosition " + _curPos + + ", PrevPosition " + _prevPos; + } + } + /** * Value object which maintains the current position of the cursor. */ diff --git a/src/java/com/healthmarketscience/jackcess/Index.java b/src/java/com/healthmarketscience/jackcess/Index.java index fcfade3..7aed345 100644 --- a/src/java/com/healthmarketscience/jackcess/Index.java +++ b/src/java/com/healthmarketscience/jackcess/Index.java @@ -1535,7 +1535,6 @@ public class Index implements Comparable { private Position updatePosition(Entry entry) { int curIdx = FIRST_ENTRY_IDX; boolean between = false; - RowId rowId = entry.getRowId(); if(entry.isValid()) { // find the new position for this entry int idx = findEntry(entry); diff --git a/test/src/java/com/healthmarketscience/jackcess/CursorTest.java b/test/src/java/com/healthmarketscience/jackcess/CursorTest.java index c87b29e..f6b829d 100644 --- a/test/src/java/com/healthmarketscience/jackcess/CursorTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/CursorTest.java @@ -142,6 +142,15 @@ public class CursorTest extends TestCase { assertEquals(3, cursor.moveNextRows(3)); assertFalse(cursor.isBeforeFirst()); assertFalse(cursor.isAfterLast()); + + Map expectedRow = cursor.getCurrentRow(); + Cursor.Savepoint savepoint = cursor.getSavepoint(); + assertEquals(2, cursor.movePreviousRows(2)); + assertEquals(2, cursor.moveNextRows(2)); + assertTrue(cursor.moveToNextRow()); + assertTrue(cursor.moveToPreviousRow()); + assertEquals(expectedRow, cursor.getCurrentRow()); + while(cursor.moveToNextRow()) { foundRows.add(cursor.getCurrentRow()); } @@ -150,6 +159,17 @@ public class CursorTest extends TestCase { assertTrue(cursor.isAfterLast()); assertEquals(0, cursor.moveNextRows(3)); + + cursor.beforeFirst(); + assertTrue(cursor.isBeforeFirst()); + assertFalse(cursor.isAfterLast()); + + cursor.afterLast(); + assertFalse(cursor.isBeforeFirst()); + assertTrue(cursor.isAfterLast()); + + cursor.restoreSavepoint(savepoint); + assertEquals(expectedRow, cursor.getCurrentRow()); } public void testSearch() throws Exception { @@ -157,14 +177,14 @@ public class CursorTest extends TestCase { Table table = db.getTable("test"); Cursor cursor = Cursor.createCursor(table); - doTestSearch(table, cursor); + doTestSearch(table, cursor, null); db.close(); } - private void doTestSearch(Table table, Cursor cursor) throws Exception { - List> expectedRows = createTestTableData(); - + private void doTestSearch(Table table, Cursor cursor, Index index) + throws Exception + { assertTrue(cursor.findRow(table.getColumn("id"), 3)); assertEquals(createExpectedRow("id", 3, "value", "data" + 3), @@ -178,16 +198,42 @@ public class CursorTest extends TestCase { cursor.getCurrentRow()); assertFalse(cursor.findRow(createExpectedRow( - "id", 13, - "value", "data" + 8))); + "id", 8, + "value", "data" + 13))); + assertFalse(cursor.findRow(table.getColumn("id"), 13)); assertEquals(createExpectedRow("id", 6, "value", "data" + 6), cursor.getCurrentRow()); + + assertTrue(cursor.findRow(createExpectedRow( + "value", "data" + 7))); + assertEquals(createExpectedRow("id", 7, + "value", "data" + 7), + cursor.getCurrentRow()); + + assertTrue(cursor.findRow(table.getColumn("value"), "data" + 2)); + assertEquals(createExpectedRow("id", 2, + "value", "data" + 2), + cursor.getCurrentRow()); assertEquals("data" + 9, Cursor.findValue(table, table.getColumn("value"), table.getColumn("id"), 9)); + assertEquals(createExpectedRow("id", 9, + "value", "data" + 9), + Cursor.findRow(table, + createExpectedRow("id", 9))); + if(index != null) { + assertEquals("data" + 9, + Cursor.findValue(table, index, + table.getColumn("value"), + table.getColumn("id"), 9)); + assertEquals(createExpectedRow("id", 9, + "value", "data" + 9), + Cursor.findRow(table, index, + createExpectedRow("id", 9))); + } } public void testReverse() throws Exception { @@ -343,7 +389,7 @@ public class CursorTest extends TestCase { Table table = db.getTable("test"); Index idx = table.getIndexes().get(0); Cursor cursor = Cursor.createIndexCursor(table, idx); - doTestSearch(table, cursor); + doTestSearch(table, cursor, idx); db.close(); }