/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2004-2005
* Sleepycat Software. All rights reserved.
*
* $Id: BindingExample.java,v 1.14 2005/06/09 17:20:51 mark Exp $
*/
package je;
import java.io.File;
import java.io.Serializable;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.tuple.IntegerBinding;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
/**
* BindingExample operates in the same way as SimpleExample, but uses a
* IntegerBinding and a SerialBinding to map between Java objects and stored
* DatabaseEntry objects.
*/
class BindingExample {
private static final int EXIT_SUCCESS = 0;
private static final int EXIT_FAILURE = 1;
private int numRecords; // num records to insert or retrieve
private int offset; // where we want to start inserting
private boolean doInsert; // if true, insert, else retrieve
private File envDir;
public BindingExample(int numRecords,
boolean doInsert,
File envDir,
int offset) {
this.numRecords = numRecords;
this.doInsert = doInsert;
this.envDir = envDir;
this.offset = offset;
}
/**
* Usage string
*/
public static void usage() {
System.out.println("usage: java " +
"je.BindingExample " +
"<envHomeDirectory> " +
"<insert|retrieve> <numRecords> [offset]");
System.exit(EXIT_FAILURE);
}
/**
* Main
*/
public static void main(String argv[]) {
if (argv.length < 2) {
usage();
return;
}
File envHomeDirectory = new File(argv[0]);
boolean doInsertArg = false;
if (argv[1].equalsIgnoreCase("insert")) {
doInsertArg = true;
} else if (argv[1].equalsIgnoreCase("retrieve")) {
doInsertArg = false;
} else {
usage();
}
int startOffset = 0;
int numRecordsVal = 0;
if (doInsertArg) {
if (argv.length > 2) {
numRecordsVal = Integer.parseInt(argv[2]);
} else {
usage();
return;
}
if (argv.length > 3) {
startOffset = Integer.parseInt(argv[3]);
}
}
try {
BindingExample app = new BindingExample(numRecordsVal,
doInsertArg,
envHomeDirectory,
startOffset);
app.run();
} catch (DatabaseException e) {
e.printStackTrace();
System.exit(EXIT_FAILURE);
}
System.exit(EXIT_SUCCESS);
}
/**
* Insert or retrieve data
*/
public void run() throws DatabaseException {
/* Create a new, transactional database environment */
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
Environment exampleEnv = new Environment(envDir, envConfig);
/* Make a database within that environment */
Transaction txn = exampleEnv.beginTransaction(null, null);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
dbConfig.setSortedDuplicates(true);
Database exampleDb = exampleEnv.openDatabase(txn,
"bindingsDb",
dbConfig);
/*
* In our example, the database record is composed of an integer
* key and and instance of the MyData class as data.
*
* A class catalog database is needed for storing class descriptions
* for the serial binding used below. This avoids storing class
* descriptions redundantly in each record.
*/
DatabaseConfig catalogConfig = new DatabaseConfig();
catalogConfig.setTransactional(true);
catalogConfig.setAllowCreate(true);
Database catalogDb = exampleEnv.openDatabase(txn,
"catalogDb",
catalogConfig);
StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);
/*
* 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);
txn.commit();
/*
* Further below we'll use a tuple binding (IntegerBinding
* specifically) for integer keys. Tuples, unlike serialized Java
* objects, have a well defined sort order.
*/
/* DatabaseEntry represents the key and data of each record */
DatabaseEntry keyEntry = new DatabaseEntry();
DatabaseEntry dataEntry = new DatabaseEntry();
if (doInsert) {
/* put some data in */
for (int i = offset; i < numRecords + offset; i++) {
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);
txn = exampleEnv.beginTransaction(null, null);
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 */
Cursor cursor = exampleDb.openCursor(null, null);
while (cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
int key = IntegerBinding.entryToInt(keyEntry);
MyData data = (MyData) dataBinding.entryToObject(dataEntry);
System.out.println("key=" + key + " data=" + data);
}
cursor.close();
}
catalogDb.close();
exampleDb.close();
exampleEnv.close();
}
private static class MyData implements Serializable {
private int num;
private String msg;
MyData(int number, String message) {
this.num = number;
this.msg = message;
}
public String toString() {
return String.valueOf(num) + ' ' + msg;
}
}
}