001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: SampleDatabase.java,v 1.24.2.2 2008/01/07 15:14:00 cwl Exp $
007: */
008:
009: package collections.ship.entity;
010:
011: import java.io.File;
012: import java.io.FileNotFoundException;
013:
014: import com.sleepycat.bind.serial.ClassCatalog;
015: import com.sleepycat.bind.serial.SerialSerialKeyCreator;
016: import com.sleepycat.bind.serial.StoredClassCatalog;
017: import com.sleepycat.je.Database;
018: import com.sleepycat.je.DatabaseConfig;
019: import com.sleepycat.je.DatabaseException;
020: import com.sleepycat.je.Environment;
021: import com.sleepycat.je.EnvironmentConfig;
022: import com.sleepycat.je.ForeignKeyDeleteAction;
023: import com.sleepycat.je.SecondaryConfig;
024: import com.sleepycat.je.SecondaryDatabase;
025:
026: /**
027: * SampleDatabase defines the storage containers, indices and foreign keys
028: * for the sample database.
029: *
030: * @author Mark Hayes
031: */
032: public class SampleDatabase {
033:
034: private static final String CLASS_CATALOG = "java_class_catalog";
035: private static final String SUPPLIER_STORE = "supplier_store";
036: private static final String PART_STORE = "part_store";
037: private static final String SHIPMENT_STORE = "shipment_store";
038: private static final String SHIPMENT_PART_INDEX = "shipment_part_index";
039: private static final String SHIPMENT_SUPPLIER_INDEX = "shipment_supplier_index";
040: private static final String SUPPLIER_CITY_INDEX = "supplier_city_index";
041:
042: private Environment env;
043: private Database partDb;
044: private Database supplierDb;
045: private Database shipmentDb;
046: private SecondaryDatabase supplierByCityDb;
047: private SecondaryDatabase shipmentByPartDb;
048: private SecondaryDatabase shipmentBySupplierDb;
049: private StoredClassCatalog javaCatalog;
050:
051: /**
052: * Open all storage containers, indices, and catalogs.
053: */
054: public SampleDatabase(String homeDirectory)
055: throws DatabaseException, FileNotFoundException {
056:
057: // Open the Berkeley DB environment in transactional mode.
058: //
059: System.out.println("Opening environment in: " + homeDirectory);
060: EnvironmentConfig envConfig = new EnvironmentConfig();
061: envConfig.setTransactional(true);
062: envConfig.setAllowCreate(true);
063: env = new Environment(new File(homeDirectory), envConfig);
064:
065: // Set the Berkeley DB config for opening all stores.
066: //
067: DatabaseConfig dbConfig = new DatabaseConfig();
068: dbConfig.setTransactional(true);
069: dbConfig.setAllowCreate(true);
070:
071: // Create the Serial class catalog. This holds the serialized class
072: // format for all database records of serial format.
073: //
074: Database catalogDb = env.openDatabase(null, CLASS_CATALOG,
075: dbConfig);
076: javaCatalog = new StoredClassCatalog(catalogDb);
077:
078: // Open the Berkeley DB database for the part, supplier and shipment
079: // stores. The stores are opened with no duplicate keys allowed.
080: //
081: partDb = env.openDatabase(null, PART_STORE, dbConfig);
082:
083: supplierDb = env.openDatabase(null, SUPPLIER_STORE, dbConfig);
084:
085: shipmentDb = env.openDatabase(null, SHIPMENT_STORE, dbConfig);
086:
087: // Open the SecondaryDatabase for the city index of the supplier store,
088: // and for the part and supplier indices of the shipment store.
089: // Duplicate keys are allowed since more than one supplier may be in
090: // the same city, and more than one shipment may exist for the same
091: // supplier or part. A foreign key constraint is defined for the
092: // supplier and part indices to ensure that a shipment only refers to
093: // existing part and supplier keys. The CASCADE delete action means
094: // that shipments will be deleted if their associated part or supplier
095: // is deleted.
096: //
097: SecondaryConfig secConfig = new SecondaryConfig();
098: secConfig.setTransactional(true);
099: secConfig.setAllowCreate(true);
100: secConfig.setSortedDuplicates(true);
101:
102: secConfig.setKeyCreator(new SupplierByCityKeyCreator(
103: javaCatalog, SupplierKey.class, SupplierData.class,
104: String.class));
105: supplierByCityDb = env.openSecondaryDatabase(null,
106: SUPPLIER_CITY_INDEX, supplierDb, secConfig);
107:
108: secConfig.setForeignKeyDatabase(partDb);
109: secConfig
110: .setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
111: secConfig.setKeyCreator(new ShipmentByPartKeyCreator(
112: javaCatalog, ShipmentKey.class, ShipmentData.class,
113: PartKey.class));
114: shipmentByPartDb = env.openSecondaryDatabase(null,
115: SHIPMENT_PART_INDEX, shipmentDb, secConfig);
116:
117: secConfig.setForeignKeyDatabase(supplierDb);
118: secConfig
119: .setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
120: secConfig.setKeyCreator(new ShipmentBySupplierKeyCreator(
121: javaCatalog, ShipmentKey.class, ShipmentData.class,
122: SupplierKey.class));
123: shipmentBySupplierDb = env.openSecondaryDatabase(null,
124: SHIPMENT_SUPPLIER_INDEX, shipmentDb, secConfig);
125: }
126:
127: /**
128: * Return the storage environment for the database.
129: */
130: public final Environment getEnvironment() {
131:
132: return env;
133: }
134:
135: /**
136: * Return the class catalog.
137: */
138: public final StoredClassCatalog getClassCatalog() {
139:
140: return javaCatalog;
141: }
142:
143: /**
144: * Return the part storage container.
145: */
146: public final Database getPartDatabase() {
147:
148: return partDb;
149: }
150:
151: /**
152: * Return the supplier storage container.
153: */
154: public final Database getSupplierDatabase() {
155:
156: return supplierDb;
157: }
158:
159: /**
160: * Return the shipment storage container.
161: */
162: public final Database getShipmentDatabase() {
163:
164: return shipmentDb;
165: }
166:
167: /**
168: * Return the shipment-by-part index.
169: */
170: public final SecondaryDatabase getShipmentByPartDatabase() {
171:
172: return shipmentByPartDb;
173: }
174:
175: /**
176: * Return the shipment-by-supplier index.
177: */
178: public final SecondaryDatabase getShipmentBySupplierDatabase() {
179:
180: return shipmentBySupplierDb;
181: }
182:
183: /**
184: * Return the supplier-by-city index.
185: */
186: public final SecondaryDatabase getSupplierByCityDatabase() {
187:
188: return supplierByCityDb;
189: }
190:
191: /**
192: * Close all stores (closing a store automatically closes its indices).
193: */
194: public void close() throws DatabaseException {
195:
196: // Close secondary databases, then primary databases.
197: supplierByCityDb.close();
198: shipmentByPartDb.close();
199: shipmentBySupplierDb.close();
200: partDb.close();
201: supplierDb.close();
202: shipmentDb.close();
203: // And don't forget to close the catalog and the environment.
204: javaCatalog.close();
205: env.close();
206: }
207:
208: /**
209: * The SecondaryKeyCreator for the SupplierByCity index. This is an
210: * extension of the abstract class SerialSerialKeyCreator, which implements
211: * SecondaryKeyCreator for the case where the data keys and value are all
212: * of the serial format.
213: */
214: private static class SupplierByCityKeyCreator extends
215: SerialSerialKeyCreator {
216:
217: /**
218: * Construct the city key extractor.
219: * @param catalog is the class catalog.
220: * @param primaryKeyClass is the supplier key class.
221: * @param valueClass is the supplier value class.
222: * @param indexKeyClass is the city key class.
223: */
224: private SupplierByCityKeyCreator(ClassCatalog catalog,
225: Class primaryKeyClass, Class valueClass,
226: Class indexKeyClass) {
227:
228: super (catalog, primaryKeyClass, valueClass, indexKeyClass);
229: }
230:
231: /**
232: * Extract the city key from a supplier key/value pair. The city key
233: * is stored in the supplier value, so the supplier key is not used.
234: */
235: public Object createSecondaryKey(Object primaryKeyInput,
236: Object valueInput) {
237:
238: SupplierData supplierData = (SupplierData) valueInput;
239: return supplierData.getCity();
240: }
241: }
242:
243: /**
244: * The SecondaryKeyCreator for the ShipmentByPart index. This is an
245: * extension of the abstract class SerialSerialKeyCreator, which implements
246: * SecondaryKeyCreator for the case where the data keys and value are all
247: * of the serial format.
248: */
249: private static class ShipmentByPartKeyCreator extends
250: SerialSerialKeyCreator {
251:
252: /**
253: * Construct the part key extractor.
254: * @param catalog is the class catalog.
255: * @param primaryKeyClass is the shipment key class.
256: * @param valueClass is the shipment value class.
257: * @param indexKeyClass is the part key class.
258: */
259: private ShipmentByPartKeyCreator(ClassCatalog catalog,
260: Class primaryKeyClass, Class valueClass,
261: Class indexKeyClass) {
262:
263: super (catalog, primaryKeyClass, valueClass, indexKeyClass);
264: }
265:
266: /**
267: * Extract the part key from a shipment key/value pair. The part key
268: * is stored in the shipment key, so the shipment value is not used.
269: */
270: public Object createSecondaryKey(Object primaryKeyInput,
271: Object valueInput) {
272:
273: ShipmentKey shipmentKey = (ShipmentKey) primaryKeyInput;
274: return new PartKey(shipmentKey.getPartNumber());
275: }
276: }
277:
278: /**
279: * The SecondaryKeyCreator for the ShipmentBySupplier index. This is an
280: * extension of the abstract class SerialSerialKeyCreator, which implements
281: * SecondaryKeyCreator for the case where the data keys and value are all
282: * of the serial format.
283: */
284: private static class ShipmentBySupplierKeyCreator extends
285: SerialSerialKeyCreator {
286:
287: /**
288: * Construct the supplier key extractor.
289: * @param catalog is the class catalog.
290: * @param primaryKeyClass is the shipment key class.
291: * @param valueClass is the shipment value class.
292: * @param indexKeyClass is the supplier key class.
293: */
294: private ShipmentBySupplierKeyCreator(ClassCatalog catalog,
295: Class primaryKeyClass, Class valueClass,
296: Class indexKeyClass) {
297:
298: super (catalog, primaryKeyClass, valueClass, indexKeyClass);
299: }
300:
301: /**
302: * Extract the supplier key from a shipment key/value pair. The part
303: * key is stored in the shipment key, so the shipment value is not
304: * used.
305: */
306: public Object createSecondaryKey(Object primaryKeyInput,
307: Object valueInput) {
308:
309: ShipmentKey shipmentKey = (ShipmentKey) primaryKeyInput;
310: return new SupplierKey(shipmentKey.getSupplierNumber());
311: }
312: }
313: }
|