package persist;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
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.bind.tuple.LongBinding;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.db.SecondaryConfig;
import com.sleepycat.db.SecondaryCursor;
import com.sleepycat.db.SecondaryDatabase;
import com.sleepycat.db.SecondaryKeyCreator;
import com.sleepycat.db.Transaction;
public class EventExample {
static class Event implements Serializable {
private int price;
private Set<String> accountReps;
private String customerName;
private int quantity;
Event(int price,
String customerName) {
this.price = price;
this.customerName = customerName;
this.accountReps = new HashSet<String>();
}
void addRep(String rep) {
accountReps.add(rep);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(" price=").append(price);
sb.append(" customerName=").append(customerName);
sb.append(" reps=");
if (accountReps.size() == 0) {
sb.append("none");
} else {
for (String rep: accountReps) {
sb.append(rep).append(" ");
}
}
return sb.toString();
}
int getPrice() {
return price;
}
}
private Environment env;
private Database eventDb;
private SecondaryDatabase eventByPriceDb;
private Database catalogDb;
private EntryBinding eventBinding;
private Calendar cal;
public static void main(String[] args)
throws DatabaseException, FileNotFoundException {
if (args.length != 2 || !"-h".equals(args[0])) {
System.err.println
("Usage: java " + EventExample.class.getName() +
" -h <envHome>");
System.exit(2);
}
EventExample example = new EventExample(new File(args[1]));
example.run();
example.close();
}
private EventExample(File envHome)
throws DatabaseException, FileNotFoundException {
System.out.println("-> Creating a BDB environment");
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
envConfig.setTransactional(true);
envConfig.setInitializeCache(true);
envConfig.setInitializeLocking(true);
env = new Environment(envHome, envConfig);
init();
cal = Calendar.getInstance();
}
private void init()
throws DatabaseException, FileNotFoundException {
System.out.println("-> Creating a BDB database");
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
dbConfig.setType(DatabaseType.BTREE);
eventDb = env.openDatabase(null, "eventDb", null, dbConfig);
DatabaseConfig catalogConfig = new DatabaseConfig();
catalogConfig.setTransactional(true);
catalogConfig.setAllowCreate(true);
catalogConfig.setType(DatabaseType.BTREE);
catalogDb = env.openDatabase(null, "catalogDb", null, catalogConfig);
StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);
eventBinding = new SerialBinding(catalog, Event.class);
SecondaryConfig secConfig = new SecondaryConfig();
secConfig.setTransactional(true);
secConfig.setAllowCreate(true);
secConfig.setType(DatabaseType.BTREE);
secConfig.setSortedDuplicates(true);
secConfig.setKeyCreator(new PriceKeyCreator(eventBinding));
eventByPriceDb = env.openSecondaryDatabase(null,
"priceDb",
null,
eventDb,
secConfig);
}
private void run()
throws DatabaseException {
Random rand = new Random();
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
System.out.println("-> Inserting 4 events");
LongBinding.longToEntry(makeDate(1), key);
eventBinding.objectToEntry(new Event(100, "Company_A"),
data);
eventDb.put(null, key, data);
LongBinding.longToEntry(makeDate(2), key);
eventBinding.objectToEntry(new Event(2, "Company_B"),
data);
eventDb.put(null, key, data);
LongBinding.longToEntry(makeDate(3), key);
eventBinding.objectToEntry(new Event(20, "Company_C"),
data);
eventDb.put(null, key, data);
LongBinding.longToEntry(makeDate(4), key);
eventBinding.objectToEntry(new Event(40, "CompanyD"),
data);
eventDb.put(null, key, data);
Transaction txn = env.beginTransaction(null, null);
int maxPrice = 50;
System.out.println("-> Inserting some randomly generated events");
for (int i = 0; i < 25; i++) {
long time = makeDate(rand.nextInt(365));
Event e = new Event(rand.nextInt(maxPrice),"Company_X");
if ((i%2) ==0) {
e.addRep("Jane");
e.addRep("Nikunj");
} else {
e.addRep("Yongmin");
}
LongBinding.longToEntry(time, key);
eventBinding.objectToEntry(e, data);
eventDb.put(txn, key, data);
}
txn.commitWriteNoSync();
System.out.println("\n-> Display the events between June 1 and Aug 31");
long endDate = makeDate(Calendar.AUGUST, 31);
Cursor eventWindow = eventDb.openCursor(null, null);
LongBinding.longToEntry(makeDate(Calendar.JUNE, 1), key);
if ((eventWindow.getSearchKeyRange(key, data, null)) !=
OperationStatus.SUCCESS) {
System.out.println("No events found!");
eventWindow.close();
return;
}
try {
printEvents(key, data, eventWindow, endDate);
} finally {
eventWindow.close();
}
System.out.println("\n-> Display all events, ordered by price");
SecondaryCursor priceCursor =
eventByPriceDb.openSecondaryCursor(null, null);
try {
printEvents(priceCursor);
} finally {
priceCursor.close();
}
}
private void close()
throws DatabaseException {
eventByPriceDb.close();
eventDb.close();
catalogDb.close();
env.close();
}
private void printEvents(DatabaseEntry firstKey,
DatabaseEntry firstData,
Cursor cursor,
long endDate)
throws DatabaseException {
System.out.println("time=" +
new Date(LongBinding.entryToLong(firstKey)) +
eventBinding.entryToObject(firstData));
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
while (cursor.getNext(key, data, null) ==
OperationStatus.SUCCESS) {
if (LongBinding.entryToLong(key) > endDate) {
break;
}
System.out.println("time=" +
new Date(LongBinding.entryToLong(key)) +
eventBinding.entryToObject(data));
}
}
private void printEvents(SecondaryCursor cursor)
throws DatabaseException {
DatabaseEntry timeKey = new DatabaseEntry();
DatabaseEntry priceKey = new DatabaseEntry();
DatabaseEntry eventData = new DatabaseEntry();
while (cursor.getNext(priceKey, timeKey, eventData, null) ==
OperationStatus.SUCCESS) {
System.out.println("time=" +
new Date(LongBinding.entryToLong(timeKey)) +
eventBinding.entryToObject(eventData));
}
}
private long makeDate(int day) {
cal.set((Calendar.DAY_OF_YEAR), day);
return cal.getTime().getTime();
}
private long makeDate(int month, int day) {
cal.set((Calendar.MONTH), month);
cal.set((Calendar.DAY_OF_MONTH), day);
return cal.getTime().getTime();
}
private static class PriceKeyCreator implements SecondaryKeyCreator {
private EntryBinding dataBinding;
PriceKeyCreator(EntryBinding eventBinding) {
this.dataBinding = eventBinding;
}
public boolean createSecondaryKey(SecondaryDatabase secondaryDb,
DatabaseEntry keyEntry,
DatabaseEntry dataEntry,
DatabaseEntry resultEntry)
throws DatabaseException {
Event e = (Event) dataBinding.entryToObject(dataEntry);
int price = e.getPrice();
IntegerBinding.intToEntry(price, resultEntry);
return true;
}
}
}