1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: SampleDatabase.java,v 12.8 2008/02/07 17:12:21 mark Exp $
7 */
8
9package collections.ship.factory;
10
11import java.io.File;
12import java.io.FileNotFoundException;
13
14import com.sleepycat.bind.serial.StoredClassCatalog;
15import com.sleepycat.collections.TupleSerialFactory;
16import com.sleepycat.db.Database;
17import com.sleepycat.db.DatabaseConfig;
18import com.sleepycat.db.DatabaseException;
19import com.sleepycat.db.DatabaseType;
20import com.sleepycat.db.Environment;
21import com.sleepycat.db.EnvironmentConfig;
22import com.sleepycat.db.ForeignKeyDeleteAction;
23import com.sleepycat.db.SecondaryConfig;
24import com.sleepycat.db.SecondaryDatabase;
25
26/**
27 * SampleDatabase defines the storage containers, indices and foreign keys
28 * for the sample database.
29 *
30 * @author Mark Hayes
31 */
32public class SampleDatabase {
33
34    private static final String CLASS_CATALOG = "java_class_catalog";
35    private static final String SUPPLIER_STORE = "supplier_store";
36    private static final String PART_STORE = "part_store";
37    private static final String SHIPMENT_STORE = "shipment_store";
38    private static final String SHIPMENT_PART_INDEX = "shipment_part_index";
39    private static final String SHIPMENT_SUPPLIER_INDEX =
40                                    "shipment_supplier_index";
41    private static final String SUPPLIER_CITY_INDEX = "supplier_city_index";
42
43    private Environment env;
44    private Database partDb;
45    private Database supplierDb;
46    private Database shipmentDb;
47    private SecondaryDatabase supplierByCityDb;
48    private SecondaryDatabase shipmentByPartDb;
49    private SecondaryDatabase shipmentBySupplierDb;
50    private StoredClassCatalog javaCatalog;
51    private TupleSerialFactory factory;
52
53    /**
54     * Open all storage containers, indices, and catalogs.
55     */
56    public SampleDatabase(String homeDirectory)
57        throws DatabaseException, FileNotFoundException {
58
59        // Open the Berkeley DB environment in transactional mode.
60        //
61        System.out.println("Opening environment in: " + homeDirectory);
62        EnvironmentConfig envConfig = new EnvironmentConfig();
63        envConfig.setTransactional(true);
64        envConfig.setAllowCreate(true);
65        envConfig.setInitializeCache(true);
66        envConfig.setInitializeLocking(true);
67        env = new Environment(new File(homeDirectory), envConfig);
68
69        // Set the Berkeley DB config for opening all stores.
70        //
71        DatabaseConfig dbConfig = new DatabaseConfig();
72        dbConfig.setTransactional(true);
73        dbConfig.setAllowCreate(true);
74        dbConfig.setType(DatabaseType.BTREE);
75
76        // Create the Serial class catalog.  This holds the serialized class
77        // format for all database records of serial format.
78        //
79        Database catalogDb = env.openDatabase(null, CLASS_CATALOG, null,
80                                              dbConfig);
81        javaCatalog = new StoredClassCatalog(catalogDb);
82
83        // Use the TupleSerialDbFactory for a Serial/Tuple-based database
84        // where marshalling interfaces are used.
85        //
86        factory = new TupleSerialFactory(javaCatalog);
87
88        // Open the Berkeley DB database for the part, supplier and shipment
89        // stores.  The stores are opened with no duplicate keys allowed.
90        //
91        partDb = env.openDatabase(null, PART_STORE, null, dbConfig);
92
93        supplierDb = env.openDatabase(null, SUPPLIER_STORE, null, dbConfig);
94
95        shipmentDb = env.openDatabase(null, SHIPMENT_STORE, null, dbConfig);
96
97        // Open the SecondaryDatabase for the city index of the supplier store,
98        // and for the part and supplier indices of the shipment store.
99        // Duplicate keys are allowed since more than one supplier may be in
100        // the same city, and more than one shipment may exist for the same
101        // supplier or part.  A foreign key constraint is defined for the
102        // supplier and part indices to ensure that a shipment only refers to
103        // existing part and supplier keys.  The CASCADE delete action means
104        // that shipments will be deleted if their associated part or supplier
105        // is deleted.
106        //
107        SecondaryConfig secConfig = new SecondaryConfig();
108        secConfig.setTransactional(true);
109        secConfig.setAllowCreate(true);
110        secConfig.setType(DatabaseType.BTREE);
111        secConfig.setSortedDuplicates(true);
112
113        secConfig.setKeyCreator(factory.getKeyCreator(Supplier.class,
114                                                      Supplier.CITY_KEY));
115        supplierByCityDb = env.openSecondaryDatabase(null, SUPPLIER_CITY_INDEX,
116                                                     null, supplierDb,
117                                                     secConfig);
118
119        secConfig.setForeignKeyDatabase(partDb);
120        secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
121        secConfig.setKeyCreator(factory.getKeyCreator(Shipment.class,
122                                                      Shipment.PART_KEY));
123        shipmentByPartDb = env.openSecondaryDatabase(null, SHIPMENT_PART_INDEX,
124                                                     null, shipmentDb,
125                                                     secConfig);
126
127        secConfig.setForeignKeyDatabase(supplierDb);
128        secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
129        secConfig.setKeyCreator(factory.getKeyCreator(Shipment.class,
130                                                      Shipment.SUPPLIER_KEY));
131        shipmentBySupplierDb = env.openSecondaryDatabase(null,
132                                                     SHIPMENT_SUPPLIER_INDEX,
133                                                     null, shipmentDb,
134                                                     secConfig);
135    }
136
137    /**
138     * Return the tuple-serial factory.
139     */
140    public final TupleSerialFactory getFactory() {
141
142        return factory;
143    }
144
145    /**
146     * Return the storage environment for the database.
147     */
148    public final Environment getEnvironment() {
149
150        return env;
151    }
152
153    /**
154     * Return the class catalog.
155     */
156    public final StoredClassCatalog getClassCatalog() {
157
158        return javaCatalog;
159    }
160
161    /**
162     * Return the part storage container.
163     */
164    public final Database getPartDatabase() {
165
166        return partDb;
167    }
168
169    /**
170     * Return the supplier storage container.
171     */
172    public final Database getSupplierDatabase() {
173
174        return supplierDb;
175    }
176
177    /**
178     * Return the shipment storage container.
179     */
180    public final Database getShipmentDatabase() {
181
182        return shipmentDb;
183    }
184
185    /**
186     * Return the shipment-by-part index.
187     */
188    public final SecondaryDatabase getShipmentByPartDatabase() {
189
190        return shipmentByPartDb;
191    }
192
193    /**
194     * Return the shipment-by-supplier index.
195     */
196    public final SecondaryDatabase getShipmentBySupplierDatabase() {
197
198        return shipmentBySupplierDb;
199    }
200
201    /**
202     * Return the supplier-by-city index.
203     */
204    public final SecondaryDatabase getSupplierByCityDatabase() {
205
206        return supplierByCityDb;
207    }
208
209    /**
210     * Close all databases and the environment.
211     */
212    public void close()
213        throws DatabaseException {
214
215        // Close secondary databases, then primary databases.
216        supplierByCityDb.close();
217        shipmentByPartDb.close();
218        shipmentBySupplierDb.close();
219        partDb.close();
220        supplierDb.close();
221        shipmentDb.close();
222        // And don't forget to close the catalog and the environment.
223        javaCatalog.close();
224        env.close();
225    }
226}
227