/** [#14966] */ public void testDirtyReadPartialGet() throws DatabaseException { SecondaryDatabase secDb = initDb(); Database priDb = secDb.getPrimaryDatabase(); DatabaseEntry data = new DatabaseEntry(); DatabaseEntry key = new DatabaseEntry(); DatabaseEntry secKey = new DatabaseEntry(); OperationStatus status; /* Put a record */ Transaction txn = txnBegin(); status = priDb.put(txn, entry(0), entry(0)); assertSame(OperationStatus.SUCCESS, status); txnCommit(txn); /* Regular get */ status = secDb.get(null, entry(0 + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(0), key); assertDataEquals(entry(0), data); /* Dirty read returning no data */ data.setPartial(0, 0, true); status = secDb.get(null, entry(0 + KEY_OFFSET), key, data, LockMode.READ_UNCOMMITTED); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(0), key); assertEquals(0, data.getData().length); assertEquals(0, data.getSize()); /* Dirty read returning partial data */ data.setPartial(0, 1, true); status = secDb.get(null, entry(0 + KEY_OFFSET), key, data, LockMode.READ_UNCOMMITTED); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(0), key); assertEquals(1, data.getData().length); assertEquals(1, data.getSize()); secDb.close(); priDb.close(); }
public E get(Transaction txn, SK key, LockMode lockMode) throws DatabaseException { DatabaseEntry keyEntry = new DatabaseEntry(); DatabaseEntry pkeyEntry = new DatabaseEntry(); DatabaseEntry dataEntry = new DatabaseEntry(); keyBinding.objectToEntry(key, keyEntry); OperationStatus status = secDb.get(txn, keyEntry, pkeyEntry, dataEntry, lockMode); if (status == OperationStatus.SUCCESS) { return (E) entityBinding.entryToObject(pkeyEntry, dataEntry); } else { return null; } }
/** Test that null can be passed for the LockMode to all get methods. */ public void testNullLockMode() throws DatabaseException { SecondaryDatabase secDb = initDb(); Database priDb = secDb.getPrimaryDatabase(); Transaction txn = txnBegin(); DatabaseEntry key = entry(0); DatabaseEntry data = entry(0); DatabaseEntry secKey = entry(KEY_OFFSET); DatabaseEntry found = new DatabaseEntry(); DatabaseEntry found2 = new DatabaseEntry(); DatabaseEntry found3 = new DatabaseEntry(); assertEquals(OperationStatus.SUCCESS, priDb.put(txn, key, data)); assertEquals(OperationStatus.SUCCESS, priDb.put(txn, entry(1), data)); assertEquals(OperationStatus.SUCCESS, priDb.put(txn, entry(2), entry(2))); /* Database operations. */ assertEquals(OperationStatus.SUCCESS, priDb.get(txn, key, found, null)); assertEquals(OperationStatus.SUCCESS, priDb.getSearchBoth(txn, key, data, null)); assertEquals(OperationStatus.SUCCESS, secDb.get(txn, secKey, found, null)); assertEquals(OperationStatus.SUCCESS, secDb.get(txn, secKey, found, found2, null)); assertEquals(OperationStatus.SUCCESS, secDb.getSearchBoth(txn, secKey, key, found, null)); /* Cursor operations. */ txnCommit(txn); txn = txnBeginCursor(); Cursor cursor = priDb.openCursor(txn, null); SecondaryCursor secCursor = secDb.openSecondaryCursor(txn, null); assertEquals(OperationStatus.SUCCESS, cursor.getSearchKey(key, found, null)); assertEquals(OperationStatus.SUCCESS, cursor.getSearchBoth(key, data, null)); assertEquals(OperationStatus.SUCCESS, cursor.getSearchKeyRange(key, found, null)); assertEquals(OperationStatus.SUCCESS, cursor.getSearchBothRange(key, data, null)); assertEquals(OperationStatus.SUCCESS, cursor.getFirst(found, found2, null)); assertEquals(OperationStatus.SUCCESS, cursor.getNext(found, found2, null)); assertEquals(OperationStatus.SUCCESS, cursor.getPrev(found, found2, null)); assertEquals(OperationStatus.NOTFOUND, cursor.getNextDup(found, found2, null)); assertEquals(OperationStatus.NOTFOUND, cursor.getPrevDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, cursor.getNextNoDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, cursor.getPrevNoDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, cursor.getLast(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchKey(secKey, found, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchKeyRange(secKey, found, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getFirst(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNext(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrev(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNextDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrevDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNextNoDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrevNoDup(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getLast(found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchKey(secKey, found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchBoth(secKey, data, found, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchKeyRange(secKey, found, found2, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getSearchBothRange(secKey, data, found, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getFirst(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNext(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrev(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNextDup(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrevDup(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getNextNoDup(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getPrevNoDup(found, found2, found3, null)); assertEquals(OperationStatus.SUCCESS, secCursor.getLast(found, found2, found3, null)); secCursor.close(); cursor.close(); txnCommit(txn); secDb.close(); priDb.close(); env.close(); env = null; }
public void testUniqueSecondaryKey() throws DatabaseException { Database priDb = openDatabase(false, "testDB", false); SecondaryDatabase secDb = openSecondary(priDb, false, "testSecDB", false, false); DatabaseEntry key; DatabaseEntry data; DatabaseEntry pkey = new DatabaseEntry(); Transaction txn; /* Put {0, 0} */ txn = txnBegin(); key = entry(0); data = entry(0); priDb.put(txn, key, data); txnCommit(txn); assertEquals(OperationStatus.SUCCESS, secDb.get(null, entry(0 + KEY_OFFSET), pkey, data, null)); assertEquals(0, TestUtils.getTestVal(pkey.getData())); assertEquals(0, TestUtils.getTestVal(data.getData())); /* Put {1, 1} */ txn = txnBegin(); key = entry(1); data = entry(1); priDb.put(txn, key, data); txnCommit(txn); assertEquals(OperationStatus.SUCCESS, secDb.get(null, entry(1 + KEY_OFFSET), pkey, data, null)); assertEquals(1, TestUtils.getTestVal(pkey.getData())); assertEquals(1, TestUtils.getTestVal(data.getData())); /* Put {2, 0} */ txn = txnBegin(); key = entry(2); data = entry(0); try { priDb.put(txn, key, data); /* Expect exception because secondary key must be unique. */ fail(); } catch (DatabaseException e) { txnAbort(txn); /* Ensure that primary record was not inserted. */ assertEquals(OperationStatus.NOTFOUND, secDb.get(null, key, data, null)); /* Ensure that secondary record has not changed. */ assertEquals( OperationStatus.SUCCESS, secDb.get(null, entry(0 + KEY_OFFSET), pkey, data, null)); assertEquals(0, TestUtils.getTestVal(pkey.getData())); assertEquals(0, TestUtils.getTestVal(data.getData())); } /* Overwrite {1, 1} */ txn = txnBegin(); key = entry(1); data = entry(1); priDb.put(txn, key, data); txnCommit(txn); assertEquals(OperationStatus.SUCCESS, secDb.get(null, entry(1 + KEY_OFFSET), pkey, data, null)); assertEquals(1, TestUtils.getTestVal(pkey.getData())); assertEquals(1, TestUtils.getTestVal(data.getData())); /* Modify secondary key to {1, 3} */ txn = txnBegin(); key = entry(1); data = entry(3); priDb.put(txn, key, data); txnCommit(txn); assertEquals(OperationStatus.SUCCESS, secDb.get(null, entry(3 + KEY_OFFSET), pkey, data, null)); assertEquals(1, TestUtils.getTestVal(pkey.getData())); assertEquals(3, TestUtils.getTestVal(data.getData())); secDb.close(); priDb.close(); }
public void testPutAndDelete() throws DatabaseException { SecondaryDatabase secDb = initDb(); Database priDb = secDb.getPrimaryDatabase(); DatabaseEntry data = new DatabaseEntry(); DatabaseEntry key = new DatabaseEntry(); OperationStatus status; Transaction txn = txnBegin(); /* Database.put() */ status = priDb.put(txn, entry(1), entry(2)); assertSame(OperationStatus.SUCCESS, status); status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(2), data); /* Database.putNoOverwrite() */ status = priDb.putNoOverwrite(txn, entry(1), entry(1)); assertSame(OperationStatus.KEYEXIST, status); status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(2), data); /* Database.put() overwrite */ status = priDb.put(txn, entry(1), entry(3)); assertSame(OperationStatus.SUCCESS, status); status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = secDb.get(txn, entry(103), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(3), data); /* Database.delete() */ status = priDb.delete(txn, entry(1)); assertSame(OperationStatus.SUCCESS, status); status = priDb.delete(txn, entry(1)); assertSame(OperationStatus.NOTFOUND, status); status = secDb.get(txn, entry(103), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* SecondaryDatabase.delete() */ status = priDb.put(txn, entry(1), entry(1)); assertSame(OperationStatus.SUCCESS, status); status = priDb.put(txn, entry(2), entry(1)); assertSame(OperationStatus.SUCCESS, status); status = secDb.get(txn, entry(101), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(1), data); status = secDb.delete(txn, entry(101)); assertSame(OperationStatus.SUCCESS, status); status = secDb.delete(txn, entry(101)); assertSame(OperationStatus.NOTFOUND, status); status = secDb.get(txn, entry(101), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = priDb.get(txn, entry(1), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = priDb.get(txn, entry(2), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* * Database.putNoDupData() cannot be called since the primary cannot be * configured for duplicates. */ /* Primary and secondary are empty now. */ /* Get a txn for a cursor. */ txnCommit(txn); txn = txnBeginCursor(); Cursor priCursor = null; SecondaryCursor secCursor = null; try { priCursor = priDb.openCursor(txn, null); secCursor = secDb.openSecondaryCursor(txn, null); /* Cursor.putNoOverwrite() */ status = priCursor.putNoOverwrite(entry(1), entry(2)); assertSame(OperationStatus.SUCCESS, status); status = secCursor.getSearchKey(entry(102), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(2), data); /* Cursor.putCurrent() */ status = priCursor.putCurrent(entry(3)); assertSame(OperationStatus.SUCCESS, status); status = secCursor.getSearchKey(entry(102), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = secCursor.getSearchKey(entry(103), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(3), data); /* Cursor.delete() */ status = priCursor.delete(); assertSame(OperationStatus.SUCCESS, status); status = priCursor.delete(); assertSame(OperationStatus.KEYEMPTY, status); status = secCursor.getSearchKey(entry(103), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = priCursor.getSearchKey(entry(1), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* Cursor.put() */ status = priCursor.put(entry(1), entry(4)); assertSame(OperationStatus.SUCCESS, status); status = secCursor.getSearchKey(entry(104), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), key); assertDataEquals(entry(4), data); /* SecondaryCursor.delete() */ status = secCursor.delete(); assertSame(OperationStatus.SUCCESS, status); status = secCursor.delete(); assertSame(OperationStatus.KEYEMPTY, status); status = secCursor.getCurrent(new DatabaseEntry(), key, data, LockMode.DEFAULT); assertSame(OperationStatus.KEYEMPTY, status); status = secCursor.getSearchKey(entry(104), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); status = priCursor.getSearchKey(entry(1), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* * Cursor.putNoDupData() cannot be called since the primary cannot * be configured for duplicates. */ /* Primary and secondary are empty now. */ } finally { if (secCursor != null) { secCursor.close(); } if (priCursor != null) { priCursor.close(); } } txnCommit(txn); secDb.close(); priDb.close(); }
public void testGet() throws DatabaseException { SecondaryDatabase secDb = initDb(); Database priDb = secDb.getPrimaryDatabase(); DatabaseEntry data = new DatabaseEntry(); DatabaseEntry key = new DatabaseEntry(); DatabaseEntry secKey = new DatabaseEntry(); OperationStatus status; Transaction txn = txnBegin(); /* * For parameters that do not require initialization with a non-null * data array, we set them to null to make sure this works. [#12121] */ /* Add one record for each key with one data/duplicate. */ for (int i = 0; i < NUM_RECS; i += 1) { status = priDb.put(txn, entry(i), entry(i)); assertSame(OperationStatus.SUCCESS, status); } /* SecondaryDatabase.get() */ for (int i = 0; i < NUM_RECS; i += 1) { data.setData(null); status = secDb.get(txn, entry(i + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); } data.setData(null); status = secDb.get(txn, entry(NUM_RECS + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* SecondaryDatabase.getSearchBoth() */ for (int i = 0; i < NUM_RECS; i += 1) { data.setData(null); status = secDb.getSearchBoth(txn, entry(i + KEY_OFFSET), entry(i), data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), data); } data.setData(null); status = secDb.getSearchBoth( txn, entry(NUM_RECS + KEY_OFFSET), entry(NUM_RECS), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* Get a cursor txn. */ txnCommit(txn); txn = txnBeginCursor(); SecondaryCursor cursor = secDb.openSecondaryCursor(txn, null); try { /* SecondaryCursor.getFirst()/getNext() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); for (int i = 0; i < NUM_RECS; i += 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getNext(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getCurrent() (last) */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getCurrent(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(NUM_RECS - 1 + KEY_OFFSET), secKey); assertDataEquals(entry(NUM_RECS - 1), key); assertDataEquals(entry(NUM_RECS - 1), data); assertPriLocked(priDb, key); /* SecondaryCursor.getLast()/getPrev() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); for (int i = NUM_RECS - 1; i >= 0; i -= 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getPrev(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getCurrent() (first) */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getCurrent(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(0 + KEY_OFFSET), secKey); assertDataEquals(entry(0), key); assertDataEquals(entry(0), data); assertPriLocked(priDb, key); /* SecondaryCursor.getSearchKey() */ key.setData(null); data.setData(null); status = cursor.getSearchKey(entry(KEY_OFFSET - 1), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); for (int i = 0; i < NUM_RECS; i += 1) { key.setData(null); data.setData(null); status = cursor.getSearchKey(entry(i + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key); } key.setData(null); data.setData(null); status = cursor.getSearchKey(entry(NUM_RECS + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getSearchBoth() */ data.setData(null); status = cursor.getSearchKey(entry(KEY_OFFSET - 1), entry(0), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); for (int i = 0; i < NUM_RECS; i += 1) { data.setData(null); status = cursor.getSearchBoth(entry(i + KEY_OFFSET), entry(i), data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), data); assertPriLocked(priDb, entry(i)); } data.setData(null); status = cursor.getSearchBoth( entry(NUM_RECS + KEY_OFFSET), entry(NUM_RECS), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getSearchKeyRange() */ key.setData(null); data.setData(null); status = cursor.getSearchKeyRange(entry(KEY_OFFSET - 1), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(0), key); assertDataEquals(entry(0), data); assertPriLocked(priDb, key); for (int i = 0; i < NUM_RECS; i += 1) { key.setData(null); data.setData(null); status = cursor.getSearchKeyRange(entry(i + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key); } key.setData(null); data.setData(null); status = cursor.getSearchKeyRange(entry(NUM_RECS + KEY_OFFSET), key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getSearchBothRange() */ data.setData(null); status = cursor.getSearchBothRange(entry(1 + KEY_OFFSET), entry(1), data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(1), data); assertPriLocked(priDb, entry(1)); for (int i = 0; i < NUM_RECS; i += 1) { data.setData(null); status = cursor.getSearchBothRange(entry(i + KEY_OFFSET), entry(i), data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i), data); assertPriLocked(priDb, entry(i)); } data.setData(null); status = cursor.getSearchBothRange( entry(NUM_RECS + KEY_OFFSET), entry(NUM_RECS), data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); /* Add one duplicate for each key. */ Cursor priCursor = priDb.openCursor(txn, null); try { for (int i = 0; i < NUM_RECS; i += 1) { status = priCursor.put(entry(i + KEY_OFFSET), entry(i)); assertSame(OperationStatus.SUCCESS, status); } } finally { priCursor.close(); } /* SecondaryCursor.getNextDup() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); for (int i = 0; i < NUM_RECS; i += 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getNextDup(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i + KEY_OFFSET), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getNextDup(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getNext(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getNextNoDup() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); for (int i = 0; i < NUM_RECS; i += 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getNextNoDup(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getPrevDup() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); for (int i = NUM_RECS - 1; i >= 0; i -= 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i + KEY_OFFSET), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getPrevDup(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getPrevDup(secKey, key, data, LockMode.DEFAULT); assertSame(OperationStatus.NOTFOUND, status); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getPrev(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); /* SecondaryCursor.getPrevNoDup() */ secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); for (int i = NUM_RECS - 1; i >= 0; i -= 1) { assertSame(OperationStatus.SUCCESS, status); assertDataEquals(entry(i + KEY_OFFSET), secKey); assertDataEquals(entry(i + KEY_OFFSET), key); assertDataEquals(entry(i), data); assertPriLocked(priDb, key, data); secKey.setData(null); key.setData(null); data.setData(null); status = cursor.getPrevNoDup(secKey, key, data, LockMode.DEFAULT); } assertSame(OperationStatus.NOTFOUND, status); } finally { cursor.close(); } txnCommit(txn); secDb.close(); priDb.close(); }