Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / examples / java / src / persist / EventExampleDPL.java
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2004, 2012 Oracle and/or its affiliates.  All rights reserved.
5  *
6  * $Id$
7  */
8
9 package persist;
10
11 import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
12
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.util.Calendar;
16 import java.util.Date;
17 import java.util.HashSet;
18 import java.util.Random;
19 import java.util.Set;
20
21 import com.sleepycat.db.DatabaseException;
22 import com.sleepycat.db.Environment;
23 import com.sleepycat.db.EnvironmentConfig;
24 import com.sleepycat.db.Transaction;
25 import com.sleepycat.persist.EntityCursor;
26 import com.sleepycat.persist.EntityStore;
27 import com.sleepycat.persist.PrimaryIndex;
28 import com.sleepycat.persist.SecondaryIndex;
29 import com.sleepycat.persist.StoreConfig;
30 import com.sleepycat.persist.model.Entity;
31 import com.sleepycat.persist.model.PrimaryKey;
32 import 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  */
55 public 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 }