/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2003
* Sleepycat Software. All rights reserved.
*
* $Id: SampleDatabase.java,v 1.14 2003/10/18 19:50:32 mhayes Exp $
*/
package com.sleepycat.examples.bdb.shipment.marshal;
import com.sleepycat.bdb.bind.KeyExtractor;
import com.sleepycat.bdb.bind.serial.SerialFormat;
import com.sleepycat.bdb.bind.serial.TupleSerialKeyExtractor;
import com.sleepycat.bdb.bind.tuple.TupleFormat;
import com.sleepycat.bdb.bind.tuple.TupleInput;
import com.sleepycat.bdb.bind.tuple.TupleOutput;
import com.sleepycat.bdb.ForeignKeyIndex;
import com.sleepycat.bdb.DataIndex;
import com.sleepycat.bdb.DataStore;
import com.sleepycat.bdb.StoredClassCatalog;
import com.sleepycat.db.Db;
import com.sleepycat.db.DbEnv;
import com.sleepycat.db.DbException;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* SampleDatabase defines the storage containers, indices and foreign keys
* for the sample database.
*
* @author Mark Hayes
*/
public class SampleDatabase {
private static final String CLASS_CATALOG = "java_class_catalog";
private static final String SUPPLIER_STORE = "supplier_store";
private static final String PART_STORE = "part_store";
private static final String SHIPMENT_STORE = "shipment_store";
private static final String SHIPMENT_PART_INDEX = "shipment_part_index";
private static final String SHIPMENT_SUPPLIER_INDEX =
"shipment_supplier_index";
private static final String SUPPLIER_CITY_INDEX = "supplier_city_index";
private DbEnv env;
private DataStore supplierStore;
private DataStore partStore;
private DataStore shipmentStore;
private DataIndex supplierByCityIndex;
private ForeignKeyIndex shipmentByPartIndex;
private ForeignKeyIndex shipmentBySupplierIndex;
private StoredClassCatalog javaCatalog;
private TupleFormat partKeyFormat;
private SerialFormat partValueFormat;
private TupleFormat supplierKeyFormat;
private SerialFormat supplierValueFormat;
private TupleFormat shipmentKeyFormat;
private SerialFormat shipmentValueFormat;
private TupleFormat cityKeyFormat;
/**
* Open all storage containers, indices, and catalogs.
*/
public SampleDatabase(String homeDirectory, boolean runRecovery)
throws DbException, FileNotFoundException {
// Open the Berkeley DB environment in transactional mode.
//
int envFlags = Db.DB_INIT_TXN | Db.DB_INIT_LOCK | Db.DB_INIT_MPOOL |
Db.DB_CREATE;
if (runRecovery) envFlags |= Db.DB_RECOVER;
env = new DbEnv(0);
System.out.println("Opening environment in: " + homeDirectory);
env.open(homeDirectory, envFlags, 0);
// Set the flags for opening all stores and indices.
//
int flags = Db.DB_CREATE | Db.DB_AUTO_COMMIT;
// Create the Serial class catalog. This holds the serialized class
// format for all database records of format SerialFormat.
//
javaCatalog = new StoredClassCatalog(env, CLASS_CATALOG, null, flags);
// Create the data formats. In this example, all key formats are
// TupleFormat and all value formats are SerialFormat. Note that
// entity (combined key/value) classes are used for the value
// formats--for details see the bindings in the SampleViews class.
//
partKeyFormat = new TupleFormat();
partValueFormat = new SerialFormat(javaCatalog, Part.class);
supplierKeyFormat = new TupleFormat();
supplierValueFormat = new SerialFormat(javaCatalog, Supplier.class);
shipmentKeyFormat = new TupleFormat();
shipmentValueFormat = new SerialFormat(javaCatalog, Shipment.class);
cityKeyFormat = new TupleFormat();
// Open the Berkeley DB database, along with the associated
// DataStore, for the part, supplier and shipment stores.
// In this sample, the stores are opened with the DB_BTREE access
// method and no duplicate keys allowed. The DB_BTREE method is used
// to provide ordered keys, since ordering is meaningful when the tuple
// data format is used. Duplicate keys are not allowed for any entity
// with indexes or foreign key relationships.
//
Db partDb = new Db(env, 0);
partDb.open(null, PART_STORE, null, Db.DB_BTREE, flags, 0);
partStore = new DataStore(partDb, partKeyFormat,
partValueFormat, null);
Db supplierDb = new Db(env, 0);
supplierDb.open(null, SUPPLIER_STORE, null, Db.DB_BTREE, flags, 0);
supplierStore = new DataStore(supplierDb, supplierKeyFormat,
supplierValueFormat, null);
Db shipmentDb = new Db(env, 0);
shipmentDb.open(null, SHIPMENT_STORE, null, Db.DB_BTREE, flags, 0);
shipmentStore = new DataStore(shipmentDb, shipmentKeyFormat,
shipmentValueFormat, null);
// Create the KeyExtractor objects for the part and supplier
// indices of the shipment store. Each key extractor object defines
// its associated index, since it is responsible for mapping between
// the indexed value and the index key.
//
KeyExtractor cityExtractor = new MarshalledKeyExtractor(
supplierKeyFormat,
supplierValueFormat,
cityKeyFormat,
Supplier.CITY_KEY);
KeyExtractor partExtractor = new MarshalledKeyExtractor(
shipmentKeyFormat,
shipmentValueFormat,
partKeyFormat,
Shipment.PART_KEY);
KeyExtractor supplierExtractor = new MarshalledKeyExtractor(
shipmentKeyFormat,
shipmentValueFormat,
supplierKeyFormat,
Shipment.SUPPLIER_KEY);
// Open the Berkeley DB database, along with the associated
// ForeignKeyIndex, for the part and supplier indices of the shipment
// store.
// In this sample, the indices are opened with the DB_BTREE access
// method and sorted duplicate keys. The DB_BTREE method is used to
// provide ordered keys, since ordering is meaningful when the tuple
// data format is used. Duplicate keys are allowed since more than one
// shipment may exist for the same supplier or part. For indices, if
// duplicates are allowed they should always be sorted to allow for
// efficient joins.
//
Db cityIndexDb = new Db(env, 0);
cityIndexDb.setFlags(Db.DB_DUPSORT);
cityIndexDb.open(null, SUPPLIER_CITY_INDEX, null, Db.DB_BTREE,
flags, 0);
supplierByCityIndex = new DataIndex(supplierStore, cityIndexDb,
cityKeyFormat, cityExtractor);
Db partIndexDb = new Db(env, 0);
partIndexDb.setFlags(Db.DB_DUPSORT);
partIndexDb.open(null, SHIPMENT_PART_INDEX, null, Db.DB_BTREE,
flags, 0);
shipmentByPartIndex = new ForeignKeyIndex(shipmentStore, partIndexDb,
partExtractor, partStore,
ForeignKeyIndex.ON_DELETE_CASCADE);
Db supplierIndexDb = new Db(env, 0);
supplierIndexDb.setFlags(Db.DB_DUPSORT);
supplierIndexDb.open(null, SHIPMENT_SUPPLIER_INDEX, null, Db.DB_BTREE,
flags, 0);
shipmentBySupplierIndex = new ForeignKeyIndex(shipmentStore,
supplierIndexDb,
supplierExtractor, supplierStore,
ForeignKeyIndex.ON_DELETE_CASCADE);
}
/**
* Return the storage environment for the database.
*/
public final DbEnv getEnvironment() {
return env;
}
/**
* Return the DataFormat of the part key.
*/
public final TupleFormat getPartKeyFormat() {
return partKeyFormat;
}
/**
* Return the DataFormat of the part value.
*/
public final SerialFormat getPartValueFormat() {
return partValueFormat;
}
/**
* Return the DataFormat of the supplier key.
*/
public final TupleFormat getSupplierKeyFormat() {
return supplierKeyFormat;
}
/**
* Return the DataFormat of the supplier value.
*/
public final SerialFormat getSupplierValueFormat() {
return supplierValueFormat;
}
/**
* Return the DataFormat of the shipment key.
*/
public final TupleFormat getShipmentKeyFormat() {
return shipmentKeyFormat;
}
/**
* Return the DataFormat of the shipment value.
*/
public final SerialFormat getShipmentValueFormat() {
return shipmentValueFormat;
}
/**
* Return the DataFormat of the city key.
*/
public final TupleFormat getCityKeyFormat() {
return cityKeyFormat;
}
/**
* Return the part storage container.
*/
public final DataStore getPartStore() {
return partStore;
}
/**
* Return the supplier storage container.
*/
public final DataStore getSupplierStore() {
return supplierStore;
}
/**
* Return the shipment storage container.
*/
public final DataStore getShipmentStore() {
return shipmentStore;
}
/**
* Return the shipment-by-part index.
*/
public final ForeignKeyIndex getShipmentByPartIndex() {
return shipmentByPartIndex;
}
/**
* Return the shipment-by-supplier index.
*/
public final ForeignKeyIndex getShipmentBySupplierIndex() {
return shipmentBySupplierIndex;
}
/**
* Return the supplier-by-city index.
*/
public final DataIndex getSupplierByCityIndex() {
return supplierByCityIndex;
}
/**
* Close all stores (closing a store automatically closes its indices).
*/
public void close()
throws DbException, IOException {
partStore.close();
supplierStore.close();
shipmentStore.close();
// And don't forget to close the catalog and the environment.
javaCatalog.close();
env.close(0);
}
/**
* The KeyExtractor for MarshalledEntity objects. This is an
* extension of the abstract class TupleSerialKeyExtractor, which
* implements KeyExtractor for the case where the data keys are of the
* format TupleFormat and the data values are of the format
* SerialFormat.
*/
private static class MarshalledKeyExtractor
extends TupleSerialKeyExtractor {
private String keyName;
/**
* Construct the part key extractor.
* @param primaryKeyFormat is the shipment key format.
* @param valueFormat is the shipment value format.
* @param indexKeyFormat is the part key format.
*/
private MarshalledKeyExtractor(TupleFormat primaryKeyFormat,
SerialFormat valueFormat,
TupleFormat indexKeyFormat,
String keyName) {
super(primaryKeyFormat, valueFormat, indexKeyFormat);
this.keyName = keyName;
}
/**
* Extract the city key from a supplier key/value pair. The city key
* is stored in the supplier value, so the supplier key is not used.
*/
public void extractIndexKey(TupleInput primaryKeyInput,
Object valueInput,
TupleOutput indexKeyOutput)
throws IOException {
// the primary key is unmarshalled before marshalling the index
// key, to account for cases where the index key is composed of
// data elements from the primary key
MarshalledEntity entity = (MarshalledEntity) valueInput;
entity.unmarshalPrimaryKey(primaryKeyInput);
entity.marshalIndexKey(keyName, indexKeyOutput);
}
/**
* This method will never be called since ON_DELETE_CLEAR was not
* specified when creating the index.
*/
public void clearIndexKey(Object valueInputOutput)
throws IOException {
MarshalledEntity entity = (MarshalledEntity) valueInputOutput;
entity.clearIndexKey(keyName);
}
}
}