Esempio n. 1
0
  private void createSecDB(SecondaryConfig secConfig) {
    TupleBinding<DataRow> tBinder = new GenericTupleBinder(tMap);
    SecondaryKeyCreator secKeyCreator = new GenericSecKeyCreator(tBinder, secIndexPos, tMap);

    // Get a secondary object and set the key creator on it.
    secConfig.setKeyCreator(secKeyCreator);
    String secDbName = tableName + "-secDB";
    secDB = myDbEnvironment.openSecondaryDatabase(null, secDbName, myDB, secConfig);
  }
Esempio n. 2
0
  public static void main(String[] args) {

    Environment myEnv;
    Database myDatabase;

    try {
      EnvironmentConfig envConfig = new EnvironmentConfig();
      envConfig.setAllowCreate(true);
      myEnv = new Environment(new File("/Users/broso/testDB"), envConfig);

      // Environment open omitted for clarity
      DatabaseConfig myDbConfig = new DatabaseConfig();
      SecondaryConfig mySecConfig = new SecondaryConfig();
      myDbConfig.setAllowCreate(true);
      mySecConfig.setAllowCreate(true);
      // Duplicates are frequently required for secondary databases.
      mySecConfig.setSortedDuplicates(true);

      // Open the primary

      String dbName = "myPrimaryDatabase";
      Database myDb = myEnv.openDatabase(null, dbName, myDbConfig);

      // Open the secondary.
      // Key creators are described in the next section.
      // AKeyCreator akc = new AKeyCreator();

      // Get a secondary object and set the key creator on it.
      // mySecConfig.setKeyCreator(keyCreator);

      // Perform the actual open
      String secDbName = "mySecondaryDatabase";
      SecondaryDatabase mySecDb = myEnv.openSecondaryDatabase(null, secDbName, myDb, mySecConfig);
    } catch (DatabaseException de) {
      // Exception handling goes here
    }
  }
Esempio n. 3
0
 public SecondaryDatabase create2ndDB(Database db, String dbName) {
   return env.openSecondaryDatabase(null, dbName, db, set2ndDbConfig());
 }
  /** Insert or retrieve data. */
  public void run() throws DatabaseException {

    /* Create a new, transactional database environment. */
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);
    Environment exampleEnv = new Environment(envDir, envConfig);

    /*
     * Make a database within that environment. Because this will be used
     * as a primary database, it must not allow duplicates. The primary key
     * of a primary database must be unique.
     */
    Transaction txn = exampleEnv.beginTransaction(null, null);
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setAllowCreate(true);
    Database exampleDb = exampleEnv.openDatabase(txn, "bindingsDb", dbConfig);

    /*
     * In our example, the database record is composed of an integer key
     * and and instance of the MyData class as data.
     *
     * A class catalog database is needed for storing class descriptions
     * for the serial binding used below.  This avoids storing class
     * descriptions redundantly in each record.
     */
    DatabaseConfig catalogConfig = new DatabaseConfig();
    catalogConfig.setTransactional(true);
    catalogConfig.setAllowCreate(true);
    Database catalogDb = exampleEnv.openDatabase(txn, "catalogDb", catalogConfig);
    StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);

    /*
     * Create a serial binding for MyData data objects.  Serial
     * bindings can be used to store any Serializable object.
     */
    EntryBinding<MyData> dataBinding = new SerialBinding<MyData>(catalog, MyData.class);

    /*
     * Further below we'll use a tuple binding (IntegerBinding
     * specifically) for integer keys.  Tuples, unlike serialized
     * Java objects, have a well defined sort order.
     */

    /*
     * Define a String tuple binding for a secondary key.  The
     * secondary key is the msg field of the MyData object.
     */
    EntryBinding<String> secKeyBinding = TupleBinding.getPrimitiveBinding(String.class);

    /*
     * Open a secondary database to allow accessing the primary
     * database by the secondary key value.
     */
    SecondaryConfig secConfig = new SecondaryConfig();
    secConfig.setTransactional(true);
    secConfig.setAllowCreate(true);
    secConfig.setSortedDuplicates(true);
    secConfig.setKeyCreator(new MyKeyCreator(secKeyBinding, dataBinding));
    SecondaryDatabase exampleSecDb =
        exampleEnv.openSecondaryDatabase(txn, "bindingsSecDb", exampleDb, secConfig);
    txn.commit();

    /* DatabaseEntry represents the key and data of each record. */
    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();

    if (doInsert) {

      /*
       * Put some data in.  Note that the primary database is always used
       * to add data.  Adding or changing data in the secondary database
       * is not allowed; however, deleting through the secondary database
       * is allowed.
       */
      for (int i = offset; i < numRecords + offset; i++) {
        txn = exampleEnv.beginTransaction(null, null);
        StringBuffer stars = new StringBuffer();
        for (int j = 0; j < i; j++) {
          stars.append('*');
        }
        MyData data = new MyData(i, stars.toString());

        IntegerBinding.intToEntry(i, keyEntry);
        dataBinding.objectToEntry(data, dataEntry);

        OperationStatus status = exampleDb.put(txn, keyEntry, dataEntry);

        /*
         * Note that put will throw a DatabaseException when error
         * conditions are found such as deadlock.  However, the status
         * return conveys a variety of information. For example, the
         * put might succeed, or it might not succeed if the record
         * exists and duplicates were not
         */
        if (status != OperationStatus.SUCCESS) {
          throw new RuntimeException("Data insertion got status " + status);
        }
        txn.commit();
      }
    } else {

      /*
       * Retrieve the data by secondary key by opening a cursor on the
       * secondary database.  The key parameter for a secondary cursor is
       * always the secondary key, but the data parameter is always the
       * data of the primary database.  You can cast the cursor to a
       * SecondaryCursor and use additional method signatures for
       * retrieving the primary key also.  Or you can call
       * openSecondaryCursor() to avoid casting.
       */
      txn = exampleEnv.beginTransaction(null, null);
      Cursor cursor = exampleSecDb.openCursor(txn, null);

      while (cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) == OperationStatus.SUCCESS) {

        String key = secKeyBinding.entryToObject(keyEntry);
        MyData data = dataBinding.entryToObject(dataEntry);

        System.out.println("key=" + key + " data=" + data);
      }
      cursor.close();
      txn.commit();
    }

    /*
     * Always close secondary databases before closing their associated
     * primary database.
     */
    catalogDb.close();
    exampleSecDb.close();
    exampleDb.close();
    exampleEnv.close();
  }
Esempio n. 5
0
  /**
   * Opens a secondary index with a given transaction and adds it to the secIndexMap. We assume that
   * the index is not already open.
   */
  private <SK, PK, E1, E2 extends E1> SecondaryIndex<SK, PK, E2> openSecondaryIndex(
      Transaction txn,
      PrimaryIndex<PK, E1> primaryIndex,
      Class<E2> entityClass,
      EntityMetadata entityMeta,
      Class<SK> keyClass,
      String keyClassName,
      SecondaryKeyMetadata secKeyMeta,
      String secName,
      boolean doNotCreate,
      PrimaryOpenState priOpenState)
      throws DatabaseException {

    assert !secIndexMap.containsKey(secName);
    String dbName = storePrefix + secName;
    SecondaryConfig config = getSecondaryConfig(secName, entityMeta, keyClassName, secKeyMeta);
    Database priDb = primaryIndex.getDatabase();
    DatabaseConfig priConfig = priDb.getConfig();

    String relatedClsName = secKeyMeta.getRelatedEntity();
    if (relatedClsName != null) {
      PrimaryIndex relatedIndex = getRelatedIndex(relatedClsName);
      config.setForeignKeyDatabase(relatedIndex.getDatabase());
    }

    if (config.getTransactional() != priConfig.getTransactional()
        || DbCompat.getDeferredWrite(config) != DbCompat.getDeferredWrite(priConfig)
        || config.getReadOnly() != priConfig.getReadOnly()) {
      throw new IllegalArgumentException(
          "One of these properties was changed to be inconsistent"
              + " with the associated primary database: "
              + " Transactional, DeferredWrite, ReadOnly");
    }

    PersistKeyBinding keyBinding = getKeyBinding(keyClassName);

    /*
     * doNotCreate is true when StoreConfig.getSecondaryBulkLoad is true
     * and we are opening a secondary as a side effect of opening a
     * primary, i.e., getSecondaryIndex is not being called.  If
     * doNotCreate is true and the database does not exist, we silently
     * ignore the DatabaseNotFoundException and return null.  When
     * getSecondaryIndex is subsequently called, the secondary database
     * will be created and populated from the primary -- a bulk load.
     */
    SecondaryDatabase db;
    boolean saveAllowCreate = config.getAllowCreate();
    try {
      if (doNotCreate) {
        config.setAllowCreate(false);
      }
      db = env.openSecondaryDatabase(txn, dbName, priDb, config);
    } catch (DatabaseNotFoundException e) {
      if (doNotCreate) {
        return null;
      } else {
        throw e;
      }
    } finally {
      if (doNotCreate) {
        config.setAllowCreate(saveAllowCreate);
      }
    }
    SecondaryIndex<SK, PK, E2> secIndex =
        new SecondaryIndex(db, null, primaryIndex, keyClass, keyBinding);

    /* Update index and database maps. */
    secIndexMap.put(secName, secIndex);
    if (DbCompat.getDeferredWrite(config)) {
      deferredWriteDatabases.put(db, null);
    }
    if (priOpenState != null) {
      priOpenState.addDatabase(db);
      priOpenState.addSecondaryName(secName);
    }
    return secIndex;
  }