001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2004,2008 Oracle. All rights reserved.
005: *
006: * $Id: EventExampleDPL.java,v 1.1.2.2 2008/01/07 15:14:04 cwl Exp $
007: */
008:
009: package persist;
010:
011: import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
012:
013: import java.io.File;
014: import java.util.Calendar;
015: import java.util.Date;
016: import java.util.HashSet;
017: import java.util.Random;
018: import java.util.Set;
019:
020: import com.sleepycat.je.DatabaseException;
021: import com.sleepycat.je.Environment;
022: import com.sleepycat.je.EnvironmentConfig;
023: import com.sleepycat.je.Transaction;
024: import com.sleepycat.persist.EntityCursor;
025: import com.sleepycat.persist.EntityStore;
026: import com.sleepycat.persist.PrimaryIndex;
027: import com.sleepycat.persist.SecondaryIndex;
028: import com.sleepycat.persist.StoreConfig;
029: import com.sleepycat.persist.model.Entity;
030: import com.sleepycat.persist.model.PrimaryKey;
031: import com.sleepycat.persist.model.SecondaryKey;
032:
033: /**
034: * EventExampleDPL is a trivial example which stores Java objects that
035: * represent an event. Events are primarily indexed by a timestamp, but have
036: * other attributes, such as price, account reps, customer name and
037: * quantity. Some of those other attributes are indexed.
038: * <p>
039: * The example simply shows the creation of a JE environment and database,
040: * inserting some events, and retrieving the events using the Direct
041: * Persistence layer.
042: * <p>
043: * This example is meant to be paired with its twin, EventExample.java.
044: * EventExample.java and EventExampleDPL.java perform the same functionality,
045: * but use the Base API and the Direct Persistence Layer api, respectively.
046: * This may be a useful way to compare the two apis.
047: * <p>
048: * To run the example:
049: * <pre>
050: * javac EventExampleDPL.java
051: * java -cp je.jar EventExampleDPL -h <environmentDirectory>
052: * </pre>
053: */
054: public class EventExampleDPL {
055:
056: /*
057: * The Event class embodies our example event and is the application
058: * data. The @Entity annotation indicates that this class defines the
059: * objects stored in a JE database.
060: */
061: @Entity
062: static class Event {
063:
064: @PrimaryKey
065: private Date time;
066:
067: @SecondaryKey(relate=MANY_TO_ONE)
068: private int price;
069:
070: private Set<String> accountReps;
071:
072: private String customerName;
073: private int quantity;
074:
075: Event(Date time, int price, String customerName) {
076:
077: this .time = time;
078: this .price = price;
079: this .customerName = customerName;
080: this .accountReps = new HashSet<String>();
081: }
082:
083: private Event() {
084: } // For deserialization
085:
086: void addRep(String rep) {
087: accountReps.add(rep);
088: }
089:
090: @Override
091: public String toString() {
092: StringBuilder sb = new StringBuilder();
093: sb.append("time=").append(time);
094: sb.append(" price=").append(price);
095: sb.append(" customerName=").append(customerName);
096: sb.append(" reps=");
097: if (accountReps.size() == 0) {
098: sb.append("none");
099: } else {
100: for (String rep : accountReps) {
101: sb.append(rep).append(" ");
102: }
103: }
104: return sb.toString();
105: }
106: }
107:
108: /* A JE environment is roughly equivalent to a relational database. */
109: private Environment env;
110: private EntityStore store;
111:
112: /*
113: * Event accessors let us access events by the primary index (time)
114: * as well as by the rep and price fields
115: */
116: PrimaryIndex<Date, Event> eventByTime;
117: SecondaryIndex<Integer, Date, Event> eventByPrice;
118:
119: /* Used for generating example data. */
120: private Calendar cal;
121:
122: /*
123: * First manually make a directory to house the JE environment.
124: * Usage: java -cp je.jar EventExampleDPL -h <envHome>
125: * All JE on-disk storage is held within envHome.
126: */
127: public static void main(String[] args) throws DatabaseException {
128:
129: if (args.length != 2 || !"-h".equals(args[0])) {
130: System.err
131: .println("Usage: java "
132: + EventExampleDPL.class.getName()
133: + " -h <envHome>");
134: System.exit(2);
135: }
136: EventExampleDPL example = new EventExampleDPL(new File(args[1]));
137: example.run();
138: example.close();
139: }
140:
141: private EventExampleDPL(File envHome) throws DatabaseException {
142:
143: /* Open a transactional Berkeley DB engine environment. */
144: System.out.println("-> Creating a JE environment");
145: EnvironmentConfig envConfig = new EnvironmentConfig();
146: envConfig.setAllowCreate(true);
147: envConfig.setTransactional(true);
148: env = new Environment(envHome, envConfig);
149:
150: /* Initialize the data access object. */
151: init();
152: cal = Calendar.getInstance();
153: }
154:
155: /**
156: * Create all primary and secondary indices.
157: */
158: private void init() throws DatabaseException {
159:
160: /* Open a transactional entity store. */
161: System.out.println("-> Creating a JE database");
162: StoreConfig storeConfig = new StoreConfig();
163: storeConfig.setAllowCreate(true);
164: storeConfig.setTransactional(true);
165: store = new EntityStore(env, "ExampleStore", storeConfig);
166:
167: eventByTime = store.getPrimaryIndex(Date.class, Event.class);
168: eventByPrice = store.getSecondaryIndex(eventByTime,
169: Integer.class, "price");
170: }
171:
172: private void run() throws DatabaseException {
173:
174: Random rand = new Random();
175:
176: /*
177: * Create a set of events. Each insertion is a separate, auto-commit
178: * transaction.
179: */
180: System.out.println("-> Inserting 4 events");
181: eventByTime.put(new Event(makeDate(1), 100, "Company_A"));
182: eventByTime.put(new Event(makeDate(2), 2, "Company_B"));
183: eventByTime.put(new Event(makeDate(3), 20, "Company_C"));
184: eventByTime.put(new Event(makeDate(4), 40, "CompanyD"));
185:
186: /* Load a whole set of events transactionally. */
187: Transaction txn = env.beginTransaction(null, null);
188: int maxPrice = 50;
189: System.out
190: .println("-> Inserting some randomly generated events");
191: for (int i = 0; i < 25; i++) {
192: Event e = new Event(makeDate(rand.nextInt(365)), rand
193: .nextInt(maxPrice), "Company_X");
194: if ((i % 2) == 0) {
195: e.addRep("Bob");
196: e.addRep("Nikunj");
197: } else {
198: e.addRep("Yongmin");
199: }
200: eventByTime.put(e);
201: }
202: txn.commitWriteNoSync();
203:
204: /*
205: * Windows of events - display the events between June 1 and Aug 31
206: */
207: System.out
208: .println("\n-> Display the events between June 1 and Aug 31");
209: Date startDate = makeDate(Calendar.JUNE, 1);
210: Date endDate = makeDate(Calendar.AUGUST, 31);
211:
212: EntityCursor<Event> eventWindow = eventByTime.entities(
213: startDate, true, endDate, true);
214: printEvents(eventWindow);
215:
216: /*
217: * Display all events, ordered by a secondary index on price.
218: */
219: System.out.println("\n-> Display all events, ordered by price");
220: EntityCursor<Event> byPriceEvents = eventByPrice.entities();
221: printEvents(byPriceEvents);
222: }
223:
224: private void close() throws DatabaseException {
225:
226: store.close();
227: env.close();
228: }
229:
230: /**
231: * Print all events covered by this cursor.
232: */
233: private void printEvents(EntityCursor<Event> eCursor)
234: throws DatabaseException {
235: try {
236: for (Event e : eCursor) {
237: System.out.println(e);
238: }
239: } finally {
240: /* Be sure to close the cursor. */
241: eCursor.close();
242: }
243: }
244:
245: /**
246: * Little utility for making up java.util.Dates for different days, just
247: * to generate test data.
248: */
249: private Date makeDate(int day) {
250:
251: cal.set((Calendar.DAY_OF_YEAR), day);
252: return cal.getTime();
253: }
254:
255: /**
256: * Little utility for making up java.util.Dates for different days, just
257: * to make the test data easier to read.
258: */
259: private Date makeDate(int month, int day) {
260:
261: cal.set((Calendar.MONTH), month);
262: cal.set((Calendar.DAY_OF_MONTH), day);
263: return cal.getTime();
264: }
265: }
|