/*
* Create a tuple binding for Integer key objects. Tuples,
* unlike serialized Java objects, have a well defined sort
* order.
*/
EntryBinding keyBinding =
TupleBinding.getPrimitiveBinding(Integer.class);
/*
* Create a serial binding for MyData data objects. Serial
* bindings can be used to store any Serializable object.
*/
EntryBinding dataBinding = new SerialBinding(catalog, MyData.class);
/*
* Further below we'll use a tuple binding (IntegerBinding
* specifically) for integer keys. Tuples, unlike serialized
* Java objects, have a well defined sort order.
*/
/*
* Define a String tuple binding for a secondary key. The
* secondary key is the msg field of the MyData object.
*/
EntryBinding secKeyBinding =
TupleBinding.getPrimitiveBinding(String.class);
/*
* Open a secondary database to allow accessing the primary
* database by the secondary key value.
*/
SecondaryConfig secConfig = new SecondaryConfig();
secConfig.setTransactional(true);
secConfig.setAllowCreate(true);
secConfig.setSortedDuplicates(true);
secConfig.setKeyCreator(new MyKeyCreator(secKeyBinding, dataBinding));
SecondaryDatabase exampleSecDb =
exampleEnv.openSecondaryDatabase(txn, "bindingsSecDb",
exampleDb, secConfig);
txn.commit();
/* DatabaseEntry represents the key and data of each record. */
DatabaseEntry keyEntry = new DatabaseEntry();
DatabaseEntry dataEntry = new DatabaseEntry();
if (doInsert) {
/*
* Put some data in. Note that the primary database is always used
* to add data. Adding or changing data in the secondary database
* is not allowed; however, deleting through the secondary database
* is allowed.
*/
for (int i = offset; i < numRecords + offset; i++) {
txn = exampleEnv.beginTransaction(null, null);
StringBuffer stars = new StringBuffer();
for (int j = 0; j < i; j++) {
stars.append('*');
}
MyData data = new MyData(i, stars.toString());
IntegerBinding.intToEntry(i, keyEntry);
dataBinding.objectToEntry(data, dataEntry);
OperationStatus status =
exampleDb.put(txn, keyEntry, dataEntry);
/*
* Note that put will throw a DatabaseException when error
* conditions are found such as deadlock. However, the status
* return conveys a variety of information. For example, the
* put might succeed, or it might not succeed if the record
* exists and duplicates were not
*/
if (status != OperationStatus.SUCCESS) {
throw new DatabaseException
("Data insertion got status " + status);
}
txn.commit();
}
} else {
/*
* Retrieve the data by secondary key by opening a cursor on the
* secondary database. The key parameter for a secondary cursor is
* always the secondary key, but the data parameter is always the
* data of the primary database. You can cast the cursor to a
* SecondaryCursor and use additional method signatures for
* retrieving the primary key also. Or you can call
* openSecondaryCursor() to avoid casting.
*/
txn = exampleEnv.beginTransaction(null, null);
Cursor cursor = exampleSecDb.openCursor(txn, null);
while (cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
String key = (String) secKeyBinding.entryToObject(keyEntry);
MyData data = (MyData) dataBinding.entryToObject(dataEntry);
System.out.println("key=" + key + " data=" + data);
}
cursor.close();