Beispiel #1
0
  public static Database setupDatabase(boolean readOnly, String dbName, Bdb bdb)
      throws IOException, DatabaseException {
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setReadOnly(readOnly);
    dbConfig.setAllowCreate(!readOnly);
    dbConfig.setDeferredWrite(!readOnly);

    return bdb.bdbEnv.openDatabase(null, dbName, dbConfig);
  }
  /*
   * This method will:
   * 1. apply the modified DatabaseConfig to the database.
   * 2. close the database and do a sync to make sure the new configuration
   *    is written to the log.
   * 3. open the database with a useExisting config and return the current
   *    DatabaseConfig.
   */
  private DatabaseConfig setAndGetDbConfig(Environment env, DatabaseConfig dbConfig, String dbName)
      throws Exception {

    Database db = env.openDatabase(null, "foo", dbConfig);
    db.close();

    env.sync();

    /*
     * Open with the useExisting config to see what attributes have been
     * persisted.
     */
    DatabaseConfig newConfig = new DatabaseConfig();
    newConfig.setReadOnly(true);
    newConfig.setTransactional(true);
    newConfig.setUseExistingConfig(true);

    db = env.openDatabase(null, dbName, newConfig);
    newConfig = db.getConfig();
    db.close();

    return newConfig;
  }
  @Test
  public void testConfigMatching() throws Throwable {

    try {
      /* DatabaseConfig matching. */

      DatabaseConfig confA = new DatabaseConfig();
      DatabaseConfig confB = new DatabaseConfig();

      try {
        confA.validate(confB);
      } catch (Exception E) {
        fail("expected valid match");
      }

      try {
        confB.validate(confA);
      } catch (Exception E) {
        fail("expected valid match");
      }

      try {
        confA.validate(null); // uses the DEFAULT config
      } catch (Exception E) {
        fail("expected valid match");
      }

      confA.setReadOnly(true);
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }

      confA.setReadOnly(false);
      confA.setSortedDuplicates(true);
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confA.setSortedDuplicates(false);

      confA.setOverrideBtreeComparator(true);
      confA.setBtreeComparator(TestComparator.class);
      confB.setOverrideBtreeComparator(true);
      confB.setBtreeComparator(TestComparator2.class);
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confA.setBtreeComparator((Class) null);
      confA.setOverrideBtreeComparator(false);
      confB.setBtreeComparator((Class) null);
      confB.setOverrideBtreeComparator(false);

      confA.setOverrideDuplicateComparator(true);
      confA.setDuplicateComparator(TestComparator.class);
      confB.setOverrideDuplicateComparator(true);
      confB.setDuplicateComparator(TestComparator2.class);
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }

      /* Same tests as above but for serialized comparators. */

      confA.setOverrideBtreeComparator(true);
      confA.setBtreeComparator(new TestSerialComparator());
      confB.setOverrideBtreeComparator(true);
      confB.setBtreeComparator(new TestSerialComparator2());
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confA.setBtreeComparator((Comparator) null);
      confA.setOverrideBtreeComparator(false);
      confB.setBtreeComparator((Comparator) null);
      confB.setOverrideBtreeComparator(false);

      confA.setOverrideDuplicateComparator(true);
      confA.setDuplicateComparator(new TestSerialComparator());
      confB.setOverrideDuplicateComparator(true);
      confB.setDuplicateComparator(new TestSerialComparator2());
      try {
        confA.validate(confB);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }

      /* SecondaryConfig matching. */

      SecondaryConfig confC = new SecondaryConfig();
      SecondaryConfig confD = new SecondaryConfig();
      confC.setKeyCreator(new SecKeyCreator1());
      confD.setKeyCreator(new SecKeyCreator1());

      try {
        confC.validate(confD);
      } catch (Exception E) {
        E.printStackTrace();
        fail("expected valid match");
      }

      try {
        confD.validate(confC);
      } catch (Exception E) {
        fail("expected valid match");
      }

      try {
        confC.validate(null);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }

      confD.setKeyCreator(new SecKeyCreator2());
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confD.setKeyCreator(new SecKeyCreator1());

      confD.setMultiKeyCreator(new SecMultiKeyCreator1());
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confD.setMultiKeyCreator(null);

      confC.setForeignKeyDeleteAction(ForeignKeyDeleteAction.NULLIFY);
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confC.setForeignKeyDeleteAction(ForeignKeyDeleteAction.ABORT);

      confC.setForeignKeyNullifier(new ForeignKeyNullifier1());
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confC.setForeignKeyNullifier(null);

      confC.setForeignMultiKeyNullifier(new ForeignMultiKeyNullifier1());
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confC.setForeignMultiKeyNullifier(null);

      confC.setImmutableSecondaryKey(true);
      try {
        confC.validate(confD);
        fail("expected exception");
      } catch (IllegalArgumentException E) {
        // ok
      }
      confC.setImmutableSecondaryKey(false);
    } catch (Throwable t) {
      t.printStackTrace();
      throw t;
    }
  }
  @Test
  public void testOpenReadOnly() throws Throwable {

    try {
      EnvironmentConfig envConfig = TestUtils.initEnvConfig();
      envConfig.setTransactional(true);
      envConfig.setAllowCreate(true);
      env = create(envHome, envConfig);

      DatabaseEntry key = new DatabaseEntry();
      DatabaseEntry data = new DatabaseEntry();

      Transaction txn = env.beginTransaction(null, null);
      DatabaseConfig dbConfig = new DatabaseConfig();
      dbConfig.setTransactional(true);
      dbConfig.setAllowCreate(true);
      Database myDb = env.openDatabase(txn, "testDB2", dbConfig);

      key.setData(TestUtils.getTestArray(0));
      data.setData(TestUtils.getTestArray(0));
      try {
        myDb.put(txn, key, data);
      } catch (DatabaseException DBE) {
        fail("unexpected DatabaseException during put");
      }

      txn.commit();
      myDb.close();

      dbConfig = new DatabaseConfig();
      dbConfig.setTransactional(true);
      dbConfig.setReadOnly(true);
      txn = env.beginTransaction(null, null);
      myDb = env.openDatabase(txn, "testDB2", dbConfig);
      assertTrue(myDb.isTransactional());
      assertTrue(myDb.getConfig().getTransactional());

      key.setData(TestUtils.getTestArray(0));
      data.setData(TestUtils.getTestArray(0));
      try {
        myDb.put(txn, key, data);
        fail("expected UnsupportedOperationException " + "because open RDONLY");
      } catch (UnsupportedOperationException expected) {
      }

      key.setData(TestUtils.getTestArray(0));
      data.setData(TestUtils.getTestArray(0));
      assertEquals(OperationStatus.SUCCESS, myDb.get(txn, key, data, LockMode.DEFAULT));

      Cursor cursor = myDb.openCursor(txn, null);

      assertEquals(OperationStatus.SUCCESS, cursor.getFirst(key, data, LockMode.DEFAULT));

      try {
        cursor.delete();
        fail("expected Exception from delete on RD_ONLY db");
      } catch (UnsupportedOperationException e) {
      }

      key.setData(TestUtils.getTestArray(1));
      data.setData(TestUtils.getTestArray(1));
      try {
        myDb.put(txn, key, data);
        fail("expected UnsupportedOperationException because open RDONLY");
      } catch (UnsupportedOperationException expected) {
      }

      cursor.close();
      txn.commit();
      myDb.close();

      close(env);
    } catch (Throwable t) {
      t.printStackTrace();
      throw t;
    }
  }
  /**
   * Test that any conflicts between configuration object settings and the underlying impl object
   * are detected.
   */
  @Test
  public void testConfigConflict() throws Throwable {

    try {
      EnvironmentConfig envConfig = TestUtils.initEnvConfig();
      envConfig.setAllowCreate(true);
      env = create(envHome, envConfig);

      /*
       * Test conflicts of duplicate allowed configuration.
       */

      /* 1a. Create allowing duplicates. */
      DatabaseConfig firstConfig = new DatabaseConfig();
      firstConfig.setAllowCreate(true);
      firstConfig.setSortedDuplicates(true);
      Database firstHandle = env.openDatabase(null, "fooDups", firstConfig);
      /* 1b. Try to open w/no duplicates. */
      DatabaseConfig secondConfig = new DatabaseConfig();
      secondConfig.setSortedDuplicates(false);
      try {
        env.openDatabase(null, "fooDups", secondConfig);
        fail("Conflict in duplicates allowed should be detected.");
      } catch (IllegalArgumentException expected) {
      }

      firstHandle.close();
      env.removeDatabase(null, "fooDups");

      /* 2a. Create dis-allowing duplicates. */
      firstConfig.setSortedDuplicates(false);
      firstConfig.setKeyPrefixing(false);
      firstHandle = env.openDatabase(null, "fooDups", firstConfig);
      /* 2b. Try to open w/duplicates. */
      secondConfig.setSortedDuplicates(true);
      try {
        env.openDatabase(null, "fooDups", secondConfig);
        fail("Conflict in duplicates allowed should be detected.");
      } catch (IllegalArgumentException expected) {
      }
      firstHandle.close();

      /*
       * Test conflicts of read only. If the environment is read/write
       * we should be able to open handles in read only or read/write
       * mode. If the environment is readonly, the database handles
       * must also be read only.
       */
      DatabaseConfig readOnlyConfig = new DatabaseConfig();
      readOnlyConfig.setReadOnly(true);
      Database roHandle = env.openDatabase(null, "fooDups", readOnlyConfig);
      roHandle.close();

      /* Open the environment in read only mode. */
      close(env);
      envConfig = TestUtils.initEnvConfig();
      envConfig.setReadOnly(true);
      env = create(envHome, envConfig);

      /* Open a readOnly database handle, should succeed */
      roHandle = env.openDatabase(null, "fooDups", readOnlyConfig);
      roHandle.close();

      /* Open a read/write database handle, should not succeed. */
      try {
        env.openDatabase(null, "fooDups", null);
        fail("Should not be able to open read/write");
      } catch (IllegalArgumentException expected) {
      }
      close(env);

      /*
       * Check comparator changes.
       */
      /* 1a. Open w/a null comparator */
      env = create(envHome, null);
      firstConfig = new DatabaseConfig();
      firstConfig.setAllowCreate(true);
      firstHandle = env.openDatabase(null, "fooComparator", firstConfig);
      DatabaseConfig firstRetrievedConfig = firstHandle.getConfig();
      assertEquals(null, firstRetrievedConfig.getBtreeComparator());
      assertEquals(null, firstRetrievedConfig.getDuplicateComparator());

      /*
       * 1b. Open a db w/a different comparator, shouldn't take effect
       * because override is not set.
       */
      secondConfig = new DatabaseConfig();
      Comparator btreeComparator = new TestComparator();
      Comparator dupComparator = new TestComparator();
      secondConfig.setBtreeComparator((Class<Comparator<byte[]>>) btreeComparator.getClass());
      secondConfig.setDuplicateComparator((Class<Comparator<byte[]>>) dupComparator.getClass());
      Database secondHandle = env.openDatabase(null, "fooComparator", secondConfig);
      DatabaseConfig retrievedConfig = secondHandle.getConfig();
      assertEquals(null, retrievedConfig.getBtreeComparator());
      assertEquals(null, retrievedConfig.getDuplicateComparator());
      secondHandle.close();

      /* Same as above but with a serialized comparator. */
      secondConfig = new DatabaseConfig();
      btreeComparator = new TestSerialComparator();
      dupComparator = new TestSerialComparator();
      secondConfig.setBtreeComparator(btreeComparator);
      secondConfig.setDuplicateComparator(dupComparator);
      secondHandle = env.openDatabase(null, "fooComparator", secondConfig);
      retrievedConfig = secondHandle.getConfig();
      assertEquals(null, retrievedConfig.getBtreeComparator());
      assertEquals(null, retrievedConfig.getDuplicateComparator());
      secondHandle.close();

      /*
       * Test that update DatabaseConfig while there are open handles
       * should throw exceptions.
       */
      secondConfig.setOverrideBtreeComparator(true);
      secondConfig.setOverrideDuplicateComparator(true);
      btreeComparator = new TestComparator();
      dupComparator = new TestComparator();
      secondConfig.setBtreeComparator((Class<Comparator<byte[]>>) btreeComparator.getClass());
      secondConfig.setDuplicateComparator((Class<Comparator<byte[]>>) dupComparator.getClass());
      try {
        secondHandle = env.openDatabase(null, "fooComparator", secondConfig);
        fail("Expect exceptions here");
      } catch (IllegalStateException e) {
        /* Expected exception. */
      } catch (Exception e) {
        fail("Unexpected exception: " + e.getMessage());
      }
      secondHandle.close();

      /*
       * Open a new database handle without DatabaseConfig changes should
       * be valid.
       */
      try {
        secondHandle = env.openDatabase(null, "fooComparator", firstConfig);
      } catch (Exception e) {
        fail("Unexpected exception: " + e.getMessage());
      }

      secondHandle.close();
      firstHandle.close();
      close(env);
    } catch (Throwable t) {
      t.printStackTrace();
      close(env);
      throw t;
    }
  }