1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2004,2008 Oracle. All rights reserved. 5 * 6 * $Id: EventExampleDPL.java,v 1.1 2008/02/07 17:12:24 mark Exp $ 7 */ 8 9package persist; 10 11import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE; 12 13import java.io.File; 14import java.io.FileNotFoundException; 15import java.util.Calendar; 16import java.util.Date; 17import java.util.HashSet; 18import java.util.Random; 19import java.util.Set; 20 21import com.sleepycat.db.DatabaseException; 22import com.sleepycat.db.Environment; 23import com.sleepycat.db.EnvironmentConfig; 24import com.sleepycat.db.Transaction; 25import com.sleepycat.persist.EntityCursor; 26import com.sleepycat.persist.EntityStore; 27import com.sleepycat.persist.PrimaryIndex; 28import com.sleepycat.persist.SecondaryIndex; 29import com.sleepycat.persist.StoreConfig; 30import com.sleepycat.persist.model.Entity; 31import com.sleepycat.persist.model.PrimaryKey; 32import com.sleepycat.persist.model.SecondaryKey; 33 34/** 35 * EventExampleDPL is a trivial example which stores Java objects that 36 * represent an event. Events are primarily indexed by a timestamp, but have 37 * other attributes, such as price, account reps, customer name and 38 * quantity. Some of those other attributes are indexed. 39 * <p> 40 * The example simply shows the creation of a BDB environment and database, 41 * inserting some events, and retrieving the events using the Direct 42 * Persistence layer. 43 * <p> 44 * This example is meant to be paired with its twin, EventExample.java. 45 * EventExample.java and EventExampleDPL.java perform the same functionality, 46 * but use the Base API and the Direct Persistence Layer API, respectively. 47 * This may be a useful way to compare the two APIs. 48 * <p> 49 * To run the example: 50 * <pre> 51 * javac EventExampleDPL.java 52 * java EventExampleDPL -h <environmentDirectory> 53 * </pre> 54 */ 55public class EventExampleDPL { 56 57 /* 58 * The Event class embodies our example event and is the application 59 * data. The @Entity annotation indicates that this class defines the 60 * objects stored in a BDB database. 61 */ 62 @Entity 63 static class Event { 64 65 @PrimaryKey 66 private Date time; 67 68 @SecondaryKey(relate=MANY_TO_ONE) 69 private int price; 70 71 private Set<String> accountReps; 72 73 private String customerName; 74 private int quantity; 75 76 Event(Date time, 77 int price, 78 String customerName) { 79 80 this.time = time; 81 this.price = price; 82 this.customerName = customerName; 83 this.accountReps = new HashSet<String>(); 84 } 85 86 private Event() {} // For deserialization 87 88 void addRep(String rep) { 89 accountReps.add(rep); 90 } 91 92 @Override 93 public String toString() { 94 StringBuilder sb = new StringBuilder(); 95 sb.append("time=").append(time); 96 sb.append(" price=").append(price); 97 sb.append(" customerName=").append(customerName); 98 sb.append(" reps="); 99 if (accountReps.size() == 0) { 100 sb.append("none"); 101 } else { 102 for (String rep: accountReps) { 103 sb.append(rep).append(" "); 104 } 105 } 106 return sb.toString(); 107 } 108 } 109 110 /* A BDB environment is roughly equivalent to a relational database. */ 111 private Environment env; 112 private EntityStore store; 113 114 /* 115 * Event accessors let us access events by the primary index (time) 116 * as well as by the rep and price fields 117 */ 118 PrimaryIndex<Date,Event> eventByTime; 119 SecondaryIndex<Integer,Date,Event> eventByPrice; 120 121 /* Used for generating example data. */ 122 private Calendar cal; 123 124 /* 125 * First manually make a directory to house the BDB environment. 126 * Usage: java EventExampleDPL -h <envHome> 127 * All BDB on-disk storage is held within envHome. 128 */ 129 public static void main(String[] args) 130 throws DatabaseException, FileNotFoundException { 131 132 if (args.length != 2 || !"-h".equals(args[0])) { 133 System.err.println 134 ("Usage: java " + EventExampleDPL.class.getName() + 135 " -h <envHome>"); 136 System.exit(2); 137 } 138 EventExampleDPL example = new EventExampleDPL(new File(args[1])); 139 example.run(); 140 example.close(); 141 } 142 143 private EventExampleDPL(File envHome) 144 throws DatabaseException, FileNotFoundException { 145 146 /* Open a transactional Berkeley DB engine environment. */ 147 System.out.println("-> Creating a BDB environment"); 148 EnvironmentConfig envConfig = new EnvironmentConfig(); 149 envConfig.setAllowCreate(true); 150 envConfig.setTransactional(true); 151 envConfig.setInitializeCache(true); 152 envConfig.setInitializeLocking(true); 153 env = new Environment(envHome, envConfig); 154 155 /* Initialize the data access object. */ 156 init(); 157 cal = Calendar.getInstance(); 158 } 159 160 /** 161 * Create all primary and secondary indices. 162 */ 163 private void init() 164 throws DatabaseException { 165 166 /* Open a transactional entity store. */ 167 System.out.println("-> Creating a BDB database"); 168 StoreConfig storeConfig = new StoreConfig(); 169 storeConfig.setAllowCreate(true); 170 storeConfig.setTransactional(true); 171 store = new EntityStore(env, "ExampleStore", storeConfig); 172 173 eventByTime = store.getPrimaryIndex(Date.class, Event.class); 174 eventByPrice = store.getSecondaryIndex(eventByTime, 175 Integer.class, 176 "price"); 177 } 178 179 private void run() 180 throws DatabaseException { 181 182 Random rand = new Random(); 183 184 /* 185 * Create a set of events. Each insertion is a separate, auto-commit 186 * transaction. 187 */ 188 System.out.println("-> Inserting 4 events"); 189 eventByTime.put(new Event(makeDate(1), 100, "Company_A")); 190 eventByTime.put(new Event(makeDate(2), 2, "Company_B")); 191 eventByTime.put(new Event(makeDate(3), 20, "Company_C")); 192 eventByTime.put(new Event(makeDate(4), 40, "CompanyD")); 193 194 /* Load a whole set of events transactionally. */ 195 Transaction txn = env.beginTransaction(null, null); 196 int maxPrice = 50; 197 System.out.println("-> Inserting some randomly generated events"); 198 for (int i = 0; i < 25; i++) { 199 Event e = new Event(makeDate(rand.nextInt(365)), 200 rand.nextInt(maxPrice), 201 "Company_X"); 202 if ((i%2) ==0) { 203 e.addRep("Bob"); 204 e.addRep("Nikunj"); 205 } else { 206 e.addRep("Yongmin"); 207 } 208 eventByTime.put(e); 209 } 210 txn.commitWriteNoSync(); 211 212 /* 213 * Windows of events - display the events between June 1 and Aug 31 214 */ 215 System.out.println("\n-> Display the events between June 1 and Aug 31"); 216 Date startDate = makeDate(Calendar.JUNE, 1); 217 Date endDate = makeDate(Calendar.AUGUST, 31); 218 219 EntityCursor<Event> eventWindow = 220 eventByTime.entities(startDate, true, endDate, true); 221 printEvents(eventWindow); 222 223 /* 224 * Display all events, ordered by a secondary index on price. 225 */ 226 System.out.println("\n-> Display all events, ordered by price"); 227 EntityCursor<Event> byPriceEvents = eventByPrice.entities(); 228 printEvents(byPriceEvents); 229 } 230 231 private void close() 232 throws DatabaseException { 233 234 store.close(); 235 env.close(); 236 } 237 238 /** 239 * Print all events covered by this cursor. 240 */ 241 private void printEvents(EntityCursor<Event> eCursor) 242 throws DatabaseException { 243 try { 244 for (Event e: eCursor) { 245 System.out.println(e); 246 } 247 } finally { 248 /* Be sure to close the cursor. */ 249 eCursor.close(); 250 } 251 } 252 253 /** 254 * Little utility for making up java.util.Dates for different days, just 255 * to generate test data. 256 */ 257 private Date makeDate(int day) { 258 259 cal.set((Calendar.DAY_OF_YEAR), day); 260 return cal.getTime(); 261 } 262 263 /** 264 * Little utility for making up java.util.Dates for different days, just 265 * to make the test data easier to read. 266 */ 267 private Date makeDate(int month, int day) { 268 269 cal.set((Calendar.MONTH), month); 270 cal.set((Calendar.DAY_OF_MONTH), day); 271 return cal.getTime(); 272 } 273} 274