浏览代码

Add Cursor.findRow(RowId) for moving to a specific Table row using only the RowId

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@864 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.0.5
James Ahlborn 10 年前
父节点
当前提交
7049764860

+ 6
- 0
src/changes/changes.xml 查看文件

@@ -4,6 +4,12 @@
<author email="javajedi@users.sf.net">Tim McCune</author>
</properties>
<body>
<release version="2.0.5" date="TBD">
<action dev="jahlborn" type="add">
Add Cursor.findRow(RowId) for moving to a specific Table row using
only the RowId.
</action>
</release>
<release version="2.0.4" date="2014-04-05">
<action dev="jahlborn" type="add">
Add ColumnValidator interface which allows column values to be easily

+ 9
- 0
src/main/java/com/healthmarketscience/jackcess/Cursor.java 查看文件

@@ -224,6 +224,15 @@ public interface Cursor extends Iterable<Row>
* otherwise
*/
public boolean moveToPreviousRow() throws IOException;
/**
* Moves to the row with the given rowId. If the row is not found (or an
* exception is thrown), the cursor is restored to its previous state.
*
* @return {@code true} if a valid row was found with the given id,
* {@code false} if no row was found
*/
public boolean findRow(RowId rowId) throws IOException;

/**
* Moves to the first row (as defined by the cursor) where the given column

+ 36
- 0
src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java 查看文件

@@ -38,6 +38,7 @@ import com.healthmarketscience.jackcess.Column;
import com.healthmarketscience.jackcess.Cursor;
import com.healthmarketscience.jackcess.CursorBuilder;
import com.healthmarketscience.jackcess.Row;
import com.healthmarketscience.jackcess.RowId;
import com.healthmarketscience.jackcess.RuntimeIOException;
import com.healthmarketscience.jackcess.impl.TableImpl.RowState;
import com.healthmarketscience.jackcess.util.ColumnMatcher;
@@ -417,6 +418,34 @@ public abstract class CursorImpl implements Cursor
return(!_curPos.equals(getDirHandler(moveForward).getEndPosition()));
}

public boolean findRow(RowId rowId) throws IOException
{
RowIdImpl rowIdImpl = (RowIdImpl)rowId;
PositionImpl curPos = _curPos;
PositionImpl prevPos = _prevPos;
boolean found = false;
try {
reset(MOVE_FORWARD);
if(TableImpl.positionAtRowHeader(_rowState, rowIdImpl) == null) {
return false;
}
restorePosition(getRowPosition(rowIdImpl));
if(!isCurrentRowValid()) {
return false;
}
found = true;
return true;
} finally {
if(!found) {
try {
restorePosition(curPos, prevPos);
} catch(IOException e) {
LOG.error("Failed restoring position", e);
}
}
}
}

public boolean findFirstRow(Column columnPattern, Object valuePattern)
throws IOException
{
@@ -688,6 +717,13 @@ public abstract class CursorImpl implements Cursor
return getClass().getSimpleName() + " CurPosition " + _curPos +
", PrevPosition " + _prevPos;
}

/**
* Returns the appropriate position information for the given row (which is
* the current row and is valid).
*/
protected abstract PositionImpl getRowPosition(RowIdImpl rowId)
throws IOException;
/**
* Finds the next non-deleted row after the given row (as defined by this

+ 22
- 9
src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java 查看文件

@@ -121,6 +121,18 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor
return cursor;
}

private Set<String> getIndexEntryPattern()
{
if(_indexEntryPattern == null) {
// init our set of index column names
_indexEntryPattern = new HashSet<String>();
for(IndexData.ColumnDescriptor col : getIndex().getColumns()) {
_indexEntryPattern.add(col.getName());
}
}
return _indexEntryPattern;
}

public IndexImpl getIndex() {
return _index;
}
@@ -222,6 +234,15 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor
super.restorePositionImpl(curPos, prevPos);
}

@Override
protected PositionImpl getRowPosition(RowIdImpl rowId) throws IOException
{
// we need to get the index entry which corresponds with this row
Row row = getTable().getRow(getRowState(), rowId, getIndexEntryPattern());
_entryCursor.beforeEntry(getTable().asRow(row));
return new IndexPosition(_entryCursor.getNextEntry());
}

@Override
protected boolean findAnotherRowImpl(
ColumnImpl columnPattern, Object valuePattern, boolean moveForward,
@@ -348,16 +369,8 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor
ColumnMatcher columnMatcher)
throws IOException
{
if(_indexEntryPattern == null) {
// init our set of index column names
_indexEntryPattern = new HashSet<String>();
for(IndexData.ColumnDescriptor col : getIndex().getColumns()) {
_indexEntryPattern.add(col.getName());
}
}

// check the next row to see if it actually matches
Row row = getCurrentRow(_indexEntryPattern);
Row row = getCurrentRow(getIndexEntryPattern());

for(IndexData.ColumnDescriptor col : getIndex().getColumns()) {
String columnName = col.getName();

+ 6
- 0
src/main/java/com/healthmarketscience/jackcess/impl/TableScanCursor.java 查看文件

@@ -84,6 +84,12 @@ public class TableScanCursor extends CursorImpl
super.restorePositionImpl(curPos, prevPos);
}

@Override
protected PositionImpl getRowPosition(RowIdImpl rowId) throws IOException
{
return new ScanPosition(rowId);
}

@Override
protected PositionImpl findAnotherPosition(
RowState rowState, PositionImpl curPos, boolean moveForward)

+ 70
- 0
src/test/java/com/healthmarketscience/jackcess/CursorTest.java 查看文件

@@ -1205,5 +1205,75 @@ public class CursorTest extends TestCase {
}
}
public void testFindByRowId() throws Exception {
for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
Database db = createTestTable(fileFormat);

Table table = db.getTable("test");
Cursor cursor = CursorBuilder.createCursor(table);
doTestFindByRowId(cursor);
db.close();
}
}

public void testFindByRowIdIndex() throws Exception {
for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
Database db = createTestIndexTable(indexCursorDB);

Table table = db.getTable("test");
Index idx = table.getIndexes().get(0);

assertTable(createUnorderedTestTableData(), table);

Cursor cursor = CursorBuilder.createCursor(idx);
doTestFindByRowId(cursor);

db.close();
}
}

private static void doTestFindByRowId(Cursor cursor)
throws Exception
{
for(int i = 0; i < 3; ++i) {
cursor.moveToNextRow();
}

Row r1 = cursor.getCurrentRow();

for(int i = 0; i < 3; ++i) {
cursor.moveToNextRow();
}

Row r2 = cursor.getCurrentRow();

doTestFindByRowId(cursor, r1, 2);

doTestFindByRowId(cursor, r2, 5);
}

private static void doTestFindByRowId(Cursor cursor, Row row, int id)
throws Exception
{
cursor.reset();
assertTrue(cursor.findRow(row.getId()));
Row rFound = cursor.getCurrentRow();
assertEquals(id, rFound.get("id"));
assertEquals(row, rFound);
Cursor.Savepoint save = cursor.getSavepoint();

assertTrue(cursor.moveToNextRow());
assertEquals(id + 1, cursor.getCurrentRow().get("id"));

cursor.restoreSavepoint(save);

assertTrue(cursor.moveToPreviousRow());
assertEquals(id - 1, cursor.getCurrentRow().get("id"));

assertFalse(cursor.findRow(RowIdImpl.FIRST_ROW_ID));

assertEquals(id - 1, cursor.getCurrentRow().get("id"));
}

}

正在加载...
取消
保存