Example #1
0
  /**
   * Same as testPutEntitySubclassWithGetSubclassIndex2 but store the first instance of the subclass
   * after closing and reopening the store, *without* calling getSubclassIndex. This ensures that a
   * single call to getSubclassIndex is sufficient and subsequent use of the store does not require
   * it. [#16399]
   */
  public void testPutEntitySubclassWithGetSubclassIndex2() throws DatabaseException {

    open();

    PrimaryIndex<Long, Statement> pri = store.getPrimaryIndex(Long.class, Statement.class);

    SecondaryIndex<String, Long, ExtendedStatement> sec =
        store.getSubclassIndex(pri, ExtendedStatement.class, String.class, "name");

    Transaction txn = txnBegin();
    pri.put(txn, new Statement(1));
    txnCommit(txn);

    close();
    open();

    pri = store.getPrimaryIndex(Long.class, Statement.class);

    txn = txnBegin();
    pri.put(txn, new ExtendedStatement(2, "abc"));
    txnCommit(txn);

    sec = store.getSubclassIndex(pri, ExtendedStatement.class, String.class, "name");

    ExtendedStatement o = sec.get("abc");
    assertNotNull(o);
    assertEquals(2, o.id);

    close();
  }
Example #2
0
  public void testSeparateSequence() throws DatabaseException {

    open();

    PrimaryIndex<Integer, SeparateSequenceEntity1> priIndex1 =
        store.getPrimaryIndex(Integer.class, SeparateSequenceEntity1.class);

    PrimaryIndex<Integer, SeparateSequenceEntity2> priIndex2 =
        store.getPrimaryIndex(Integer.class, SeparateSequenceEntity2.class);

    Transaction txn = txnBegin();
    SeparateSequenceEntity1 e1 = new SeparateSequenceEntity1();
    SeparateSequenceEntity2 e2 = new SeparateSequenceEntity2();
    priIndex1.put(txn, e1);
    assertEquals(1, e1.key);
    priIndex2.putNoOverwrite(txn, e2);
    assertEquals(Integer.valueOf(1), e2.key);
    e1.key = 0;
    priIndex1.putNoOverwrite(txn, e1);
    assertEquals(2, e1.key);
    e2.key = null;
    priIndex2.put(txn, e2);
    assertEquals(Integer.valueOf(2), e2.key);
    txnCommit(txn);

    close();
  }
Example #3
0
  public void testBadSequenceKeys() throws DatabaseException {

    open();
    try {
      PrimaryIndex<Boolean, BadSequenceKeyEntity1> index =
          store.getPrimaryIndex(Boolean.class, BadSequenceKeyEntity1.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(expected.getMessage().indexOf("Type not allowed for sequence") >= 0);
    }
    try {
      PrimaryIndex<BadSequenceKeyEntity2.Key, BadSequenceKeyEntity2> index =
          store.getPrimaryIndex(BadSequenceKeyEntity2.Key.class, BadSequenceKeyEntity2.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(expected.getMessage().indexOf("Type not allowed for sequence") >= 0);
    }
    try {
      PrimaryIndex<BadSequenceKeyEntity3.Key, BadSequenceKeyEntity3> index =
          store.getPrimaryIndex(BadSequenceKeyEntity3.Key.class, BadSequenceKeyEntity3.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(
          expected
                  .getMessage()
                  .indexOf(
                      "A composite key class used with a sequence may contain "
                          + "only a single integer key field")
              >= 0);
    }
    close();
  }
Example #4
0
  /**
   * Test a fix for a bug where opening a TO_MANY secondary index would fail fail with
   * "IllegalArgumentException: Wrong secondary key class: ..." when the store was opened read-only.
   * [#15156]
   */
  public void testToManyReadOnly() throws DatabaseException {

    open();
    PrimaryIndex<Integer, ToManyKeyEntity> priIndex =
        store.getPrimaryIndex(Integer.class, ToManyKeyEntity.class);
    priIndex.put(new ToManyKeyEntity());
    close();

    openReadOnly();
    priIndex = store.getPrimaryIndex(Integer.class, ToManyKeyEntity.class);
    SecondaryIndex<ToManyKey, Integer, ToManyKeyEntity> secIndex =
        store.getSecondaryIndex(priIndex, ToManyKey.class, "key2");
    secIndex.get(new ToManyKey());
    close();
  }
    public boolean setup(boolean readOnly) {
      boolean open = false;
      try {
        EnvironmentConfig envConfig = new EnvironmentConfig();
        envConfig.setReadOnly(readOnly);
        envConfig.setAllowCreate(!readOnly);

        env = new Environment(envHome, envConfig);

        StoreConfig storeConfig = new StoreConfig();
        storeConfig.setReadOnly(readOnly);
        storeConfig.setAllowCreate(!readOnly);

        store = new EntityStore(env, "EntityStore", storeConfig);

        objectBySid = store.getPrimaryIndex(String.class, TestObject.class);

        open = true;
      } catch (EnvironmentLockedException e) {
      } catch (Exception e) {
        e.printStackTrace();
        System.exit(-1);
      }

      return open;
    }
Example #6
0
  /**
   * Checks that we get an appropriate exception when storing an entity subclass instance, which
   * contains a secondary key, without registering the subclass up front. [#16399]
   */
  public void testPutEntitySubclassWithoutRegisterClass() throws DatabaseException {

    open();

    final PrimaryIndex<Long, Statement> pri = store.getPrimaryIndex(Long.class, Statement.class);

    final Transaction txn = txnBegin();
    pri.put(txn, new Statement(1));
    try {
      pri.put(txn, new ExtendedStatement(2, null));
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(
          expected.toString(),
          expected
              .getMessage()
              .contains(
                  "Entity subclasses defining a secondary key must be "
                      + "registered by calling EntityModel.registerClass or "
                      + "EntityStore.getSubclassIndex before storing an instance "
                      + "of the subclass: "
                      + ExtendedStatement.class.getName()));
    }
    txnAbort(txn);

    close();
  }
Example #7
0
  public void testCursorCount() throws DatabaseException {

    open();

    PrimaryIndex<Integer, MyEntity> priIndex = store.getPrimaryIndex(Integer.class, MyEntity.class);

    SecondaryIndex<Integer, Integer, MyEntity> secIndex =
        store.getSecondaryIndex(priIndex, Integer.class, "secKey");

    Transaction txn = txnBeginCursor();

    MyEntity e = new MyEntity();
    e.priKey = 1;
    e.secKey = 1;
    priIndex.put(txn, e);

    EntityCursor<MyEntity> cursor = secIndex.entities(txn, null);
    cursor.next();
    assertEquals(1, cursor.count());
    cursor.close();

    e.priKey = 2;
    priIndex.put(txn, e);
    cursor = secIndex.entities(txn, null);
    cursor.next();
    assertEquals(2, cursor.count());
    cursor.close();

    txnCommit(txn);
    close();
  }
Example #8
0
  public void testCompositeSequence() throws DatabaseException {

    open();

    PrimaryIndex<CompositeSequenceEntity1.Key, CompositeSequenceEntity1> priIndex1 =
        store.getPrimaryIndex(CompositeSequenceEntity1.Key.class, CompositeSequenceEntity1.class);

    PrimaryIndex<CompositeSequenceEntity2.Key, CompositeSequenceEntity2> priIndex2 =
        store.getPrimaryIndex(CompositeSequenceEntity2.Key.class, CompositeSequenceEntity2.class);

    Transaction txn = txnBegin();
    CompositeSequenceEntity1 e1 = new CompositeSequenceEntity1();
    CompositeSequenceEntity2 e2 = new CompositeSequenceEntity2();
    priIndex1.put(txn, e1);
    assertEquals(1, e1.key.key);
    priIndex2.putNoOverwrite(txn, e2);
    assertEquals(Integer.valueOf(1), e2.key.key);
    e1.key = null;
    priIndex1.putNoOverwrite(txn, e1);
    assertEquals(2, e1.key.key);
    e2.key = null;
    priIndex2.put(txn, e2);
    assertEquals(Integer.valueOf(2), e2.key.key);
    txnCommit(txn);

    EntityCursor<CompositeSequenceEntity1> c1 = priIndex1.entities();
    e1 = c1.next();
    assertEquals(2, e1.key.key);
    e1 = c1.next();
    assertEquals(1, e1.key.key);
    e1 = c1.next();
    assertNull(e1);
    c1.close();

    EntityCursor<CompositeSequenceEntity2> c2 = priIndex2.entities();
    e2 = c2.next();
    assertEquals(Integer.valueOf(2), e2.key.key);
    e2 = c2.next();
    assertEquals(Integer.valueOf(1), e2.key.key);
    e2 = c2.next();
    assertNull(e2);
    c2.close();

    close();
  }
  /** Create all primary and secondary indices. */
  private void init() throws DatabaseException {

    /* Open a transactional entity store. */
    System.out.println("-> Creating a BDB database");
    StoreConfig storeConfig = new StoreConfig();
    storeConfig.setAllowCreate(true);
    storeConfig.setTransactional(true);
    store = new EntityStore(env, "ExampleStore", storeConfig);

    eventByTime = store.getPrimaryIndex(Date.class, Event.class);
    eventByPrice = store.getSecondaryIndex(eventByTime, Integer.class, "price");
  }
Example #10
0
  public void testBadKeyClass1() throws DatabaseException {

    open();
    try {
      PrimaryIndex<BadKeyClass1, UseBadKeyClass1> index =
          store.getPrimaryIndex(BadKeyClass1.class, UseBadKeyClass1.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(expected.getMessage().indexOf("@KeyField") >= 0);
    }
    close();
  }
Example #11
0
  public void testCustomCompare() throws DatabaseException {

    open();

    PrimaryIndex<ReverseIntKey, CustomCompareEntity> priIndex =
        store.getPrimaryIndex(ReverseIntKey.class, CustomCompareEntity.class);

    SecondaryIndex<ReverseIntKey, ReverseIntKey, CustomCompareEntity> secIndex1 =
        store.getSecondaryIndex(priIndex, ReverseIntKey.class, "secKey1");

    SecondaryIndex<ReverseIntKey, ReverseIntKey, CustomCompareEntity> secIndex2 =
        store.getSecondaryIndex(priIndex, ReverseIntKey.class, "secKey2");

    Transaction txn = txnBegin();
    for (int i = 1; i <= 5; i += 1) {
      assertTrue(priIndex.putNoOverwrite(txn, new CustomCompareEntity(i)));
    }
    txnCommit(txn);

    txn = txnBeginCursor();
    EntityCursor<CustomCompareEntity> c = priIndex.entities(txn, null);
    for (int i = 5; i >= 1; i -= 1) {
      CustomCompareEntity e = c.next();
      assertNotNull(e);
      assertEquals(new ReverseIntKey(i), e.key);
    }
    c.close();
    txnCommit(txn);

    txn = txnBeginCursor();
    c = secIndex1.entities(txn, null);
    for (int i = -1; i >= -5; i -= 1) {
      CustomCompareEntity e = c.next();
      assertNotNull(e);
      assertEquals(new ReverseIntKey(-i), e.key);
      assertEquals(new ReverseIntKey(i), e.secKey1);
    }
    c.close();
    txnCommit(txn);

    txn = txnBeginCursor();
    c = secIndex2.entities(txn, null);
    for (int i = -1; i >= -5; i -= 1) {
      CustomCompareEntity e = c.next();
      assertNotNull(e);
      assertEquals(new ReverseIntKey(-i), e.key);
      assertTrue(e.secKey2.contains(new ReverseIntKey(i)));
    }
    c.close();
    txnCommit(txn);

    close();
  }
Example #12
0
  public void testReadOnly() throws DatabaseException {

    open();
    PrimaryIndex<Integer, SharedSequenceEntity1> priIndex =
        store.getPrimaryIndex(Integer.class, SharedSequenceEntity1.class);
    Transaction txn = txnBegin();
    SharedSequenceEntity1 e = new SharedSequenceEntity1();
    priIndex.put(txn, e);
    assertEquals(1, e.key);
    txnCommit(txn);
    close();

    /*
     * Check that we can open the store read-only and read the records
     * written above.
     */
    openReadOnly();
    priIndex = store.getPrimaryIndex(Integer.class, SharedSequenceEntity1.class);
    e = priIndex.get(1);
    assertNotNull(e);
    close();
  }
Example #13
0
  // Open the indices
  public SimpleDA(EntityStore store) throws DatabaseException {

    // Primary key for SimpleEntityClass classes
    pIdx = store.getPrimaryIndex(String.class, SimpleEntityClass.class);

    // Secondary key for SimpleEntityClass classes
    // Last field in the getSecondaryIndex() method must be
    // the name of a class member; in this case, an
    // SimpleEntityClass.class data member.
    sIdx = store.getSecondaryIndex(pIdx, String.class, "sKey");

    sec_pcursor = pIdx.entities();
    sec_scursor = sIdx.subIndex("skeyone").entities();
  }
Example #14
0
  public void testUninitializedCursor() throws DatabaseException {

    open();

    PrimaryIndex<Integer, MyEntity> priIndex = store.getPrimaryIndex(Integer.class, MyEntity.class);

    Transaction txn = txnBeginCursor();

    MyEntity e = new MyEntity();
    e.priKey = 1;
    e.secKey = 1;
    priIndex.put(txn, e);

    EntityCursor<MyEntity> entities = priIndex.entities(txn, null);
    try {
      entities.nextDup();
      fail();
    } catch (IllegalStateException expected) {
    }
    try {
      entities.prevDup();
      fail();
    } catch (IllegalStateException expected) {
    }
    try {
      entities.current();
      fail();
    } catch (IllegalStateException expected) {
    }
    try {
      entities.delete();
      fail();
    } catch (IllegalStateException expected) {
    }
    try {
      entities.update(e);
      fail();
    } catch (IllegalStateException expected) {
    }
    try {
      entities.count();
      fail();
    } catch (IllegalStateException expected) {
    }

    entities.close();
    txnCommit(txn);
    close();
  }
Example #15
0
  /**
   * When Y is opened and X has a key with relatedEntity=Y.class, X should be opened automatically.
   * If X is not opened, foreign key constraints will not be enforced. [#15358]
   */
  public void testAutoOpenRelatedEntity() throws DatabaseException {

    PrimaryIndex<Integer, RelatedY> priY;
    PrimaryIndex<Integer, RelatedX> priX;

    /* Opening X should create (and open) Y and enforce constraints. */
    open();
    priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
    PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedY.class.getName(), null);
    if (isTransactional) {
      /* Constraint enforcement requires transactions. */
      try {
        priX.put(new RelatedX());
        fail();
      } catch (DatabaseException e) {
        assertTrue(
            "" + e.getMessage(),
            (e.getMessage().indexOf("foreign key not allowed: it is not present") >= 0)
                || (e.getMessage().indexOf("DB_FOREIGN_CONFLICT") >= 0));
      }
    }
    priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
    priY.put(new RelatedY());
    priX.put(new RelatedX());
    close();

    /* Delete should cascade even when X is not opened explicitly. */
    open();
    priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
    assertEquals(1, priY.count());
    priY.delete(88);
    assertEquals(0, priY.count());
    priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
    assertEquals(0, priX.count()); /* Failed prior to [#15358] fix. */
    close();
  }
Example #16
0
  public void testKeyName() throws DatabaseException {

    open();

    PrimaryIndex<Long, BookEntity> pri1 = store.getPrimaryIndex(Long.class, BookEntity.class);
    PrimaryIndex<Long, AuthorEntity> pri2 = store.getPrimaryIndex(Long.class, AuthorEntity.class);

    BookEntity book = new BookEntity();
    pri1.put(book);
    AuthorEntity author = new AuthorEntity();
    author.bookIds.add(book.bookId);
    pri2.put(author);

    close();

    open();
    pri1 = store.getPrimaryIndex(Long.class, BookEntity.class);
    pri2 = store.getPrimaryIndex(Long.class, AuthorEntity.class);
    book = pri1.get(1L);
    assertNotNull(book);
    author = pri2.get(1L);
    assertNotNull(author);
    close();
  }
Example #17
0
  /** A proxied object may not current contain a field that references the parent proxy. [#15815] */
  public void testProxyNestedRef() throws DatabaseException {

    open();
    PrimaryIndex<Integer, ProxyNestedRef> index =
        store.getPrimaryIndex(Integer.class, ProxyNestedRef.class);
    ProxyNestedRef entity = new ProxyNestedRef();
    entity.list.add(entity.list);
    try {
      index.put(entity);
      fail();
    } catch (IllegalArgumentException expected) {
      assertTrue(
          expected.getMessage().indexOf("Cannot embed a reference to a proxied object") >= 0);
    }
    close();
  }
Example #18
0
  /**
   * When opening read-only, secondaries are not opened when the primary is opened, causing a
   * different code path to be used for opening secondaries. For a RawStore in particular, this
   * caused an unreported NullPointerException in JE 3.0.12. No SR was created because the use case
   * is very obscure and was discovered by code inspection.
   */
  public void testOpenRawStoreReadOnly() throws DatabaseException {

    open();
    store.getPrimaryIndex(Integer.class, MyEntity.class);
    close();

    StoreConfig config = new StoreConfig();
    config.setReadOnly(true);
    config.setTransactional(envConfig.getTransactional());
    RawStore rawStore = new RawStore(env, "test", config);

    String clsName = MyEntity.class.getName();
    rawStore.getSecondaryIndex(clsName, "secKey");

    rawStore.close();
  }
Example #19
0
  public void testPersistentFields() throws DatabaseException {

    open();
    PrimaryIndex<Integer, PersistentFields> pri =
        store.getPrimaryIndex(Integer.class, PersistentFields.class);
    PersistentFields o1 = new PersistentFields(-1, 1, 2, 3, 4, 5, 6);
    assertNull(pri.put(o1));
    PersistentFields o2 = pri.get(-1);
    assertNotNull(o2);
    assertEquals(0, o2.transient1);
    assertEquals(0, o2.transient2);
    assertEquals(0, o2.transient3);
    assertEquals(4, o2.persistent1);
    assertEquals(5, o2.persistent2);
    assertEquals(6, o2.persistent3);
    close();
  }
Example #20
0
  /** Disallow primary keys on entity subclasses. [#15757] */
  public void testEntitySubclassWithPrimaryKey() throws DatabaseException {

    open();
    PrimaryIndex<Integer, EntitySuperClass> index =
        store.getPrimaryIndex(Integer.class, EntitySuperClass.class);
    EntitySuperClass e1 = new EntitySuperClass(1, "one");
    index.put(e1);
    assertEquals(e1, index.get(1));
    EntitySubClass e2 = new EntitySubClass(2, "two", "foo", 9);
    try {
      index.put(e2);
    } catch (IllegalArgumentException e) {
      assertTrue(e.getMessage().contains("PrimaryKey may not appear on an Entity subclass"));
    }
    assertEquals(e1, index.get(1));
    close();
  }
  private void openGroup() throws IOException {

    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);

    ReplicationConfig repConfig = new ReplicationConfig();
    repConfig.setConfigParam(RepParams.VLSN_LOG_CACHE_SIZE.getName(), "2");

    repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, nNodes, envConfig, repConfig);
    master = RepTestUtils.joinGroup(repEnvInfo);

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setTransactional(true);
    store = new EntityStore(master, "test", config);
    primaryIndex = store.getPrimaryIndex(Integer.class, AppData.class);
  }
  /** Opens the store. */
  private void open() throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(envConfig.getAllowCreate());
    config.setTransactional(envConfig.getTransactional());

    store = new EntityStore(env, "test", config);

    primary = store.getPrimaryIndex(Integer.class, MyEntity.class);
    oneToOne = store.getSecondaryIndex(primary, Integer.class, "oneToOne");
    manyToOne = store.getSecondaryIndex(primary, Integer.class, "manyToOne");
    oneToMany = store.getSecondaryIndex(primary, Integer.class, "oneToMany");
    manyToMany = store.getSecondaryIndex(primary, Integer.class, "manyToMany");

    assertNotNull(primary);
    assertNotNull(oneToOne);
    assertNotNull(manyToOne);
    assertNotNull(oneToMany);
    assertNotNull(manyToMany);

    rawStore = new RawStore(env, "test", config);
    String clsName = MyEntity.class.getName();
    entityType = rawStore.getModel().getRawType(clsName);
    assertNotNull(entityType);

    primaryRaw = rawStore.getPrimaryIndex(clsName);
    oneToOneRaw = rawStore.getSecondaryIndex(clsName, "oneToOne");
    manyToOneRaw = rawStore.getSecondaryIndex(clsName, "manyToOne");
    oneToManyRaw = rawStore.getSecondaryIndex(clsName, "oneToMany");
    manyToManyRaw = rawStore.getSecondaryIndex(clsName, "manyToMany");

    assertNotNull(primaryRaw);
    assertNotNull(oneToOneRaw);
    assertNotNull(manyToOneRaw);
    assertNotNull(oneToManyRaw);
    assertNotNull(manyToManyRaw);
  }
  /**
   * Load the index data from the input file and transfer it to the persistent hash table
   *
   * @param dbDir
   */
  public void setup(File dbDir) {
    try {
      // Setup needed classes for interacting with Berkeley DNB Java Edition
      EnvironmentConfig envConfig = new EnvironmentConfig();
      StoreConfig storeConfig = new StoreConfig();
      envConfig.setAllowCreate(true);
      // Try to keep a high amount of data in the cache.
      envConfig.setCachePercent(80);
      storeConfig.setAllowCreate(true);
      this.myDbEnvironment = new Environment(dbDir, envConfig);
      this.dictStore = new EntityStore(myDbEnvironment, "EntityStore", storeConfig);
      this.pidx = dictStore.getPrimaryIndex(String.class, KeyValueEntry.class);

      if (this.pidx.count() == 0) {
        // prep the index
        try {
          BufferedReader reader = new BufferedReader(new FileReader(this.indexFile));
          String line = null;
          while ((line = reader.readLine()) != null) {
            // de-serialize object from input file
            KeyValueEntry kvp = KeyValueEntry.fromString(line);
            // store in persistent hash table
            this.pidx.put(kvp);
          }
          reader.close();
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
      }

    } catch (DatabaseException dbe) {
      this.myDbEnvironment = null;
      this.dictStore = null;
      this.pidx = null;
    }
  }
Example #24
0
  public void testSubclassIndex() throws DatabaseException {

    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setAllowCreate(true);
    env = new Environment(envHome, envConfig);

    StoreConfig storeConfig = new StoreConfig();
    storeConfig.setAllowCreate(true);
    EntityStore store = new EntityStore(env, "foo", storeConfig);

    PrimaryIndex<String, Employee> employeesById =
        store.getPrimaryIndex(String.class, Employee.class);

    employeesById.put(new Employee("1"));
    employeesById.put(new Manager("2", "a"));
    employeesById.put(new Manager("3", "a"));
    employeesById.put(new Manager("4", "b"));

    Employee e;
    Manager m;

    e = employeesById.get("1");
    assertNotNull(e);
    assertTrue(!(e instanceof Manager));

    /* Ensure DB exists BEFORE calling getSubclassIndex. [#15247] */
    PersistTestUtils.assertDbExists(true, env, "foo", Employee.class.getName(), "dept");

    /* Normal use: Subclass index for a key in the subclass. */
    SecondaryIndex<String, String, Manager> managersByDept =
        store.getSubclassIndex(employeesById, Manager.class, String.class, "dept");

    m = managersByDept.get("a");
    assertNotNull(m);
    assertEquals("2", m.id);

    m = managersByDept.get("b");
    assertNotNull(m);
    assertEquals("4", m.id);

    EntityCursor<Manager> managers = managersByDept.entities();
    try {
      m = managers.next();
      assertNotNull(m);
      assertEquals("2", m.id);
      m = managers.next();
      assertNotNull(m);
      assertEquals("3", m.id);
      m = managers.next();
      assertNotNull(m);
      assertEquals("4", m.id);
      m = managers.next();
      assertNull(m);
    } finally {
      managers.close();
    }

    /* Getting a subclass index for the entity class is also allowed. */
    store.getSubclassIndex(employeesById, Employee.class, String.class, "other");

    /* Getting a subclass index for a base class key is not allowed. */
    try {
      store.getSubclassIndex(employeesById, Manager.class, String.class, "other");
      fail();
    } catch (IllegalArgumentException expected) {
    }

    store.close();
    env.close();
    env = null;
  }
Example #25
0
  /**
   * Ensures that custom comparators are persisted and work correctly during recovery. JE recovery
   * uses comparators, so they are serialized and stored in the DatabaseImpl. They are deserialized
   * during recovery prior to opening the EntityStore and its format catalog. But the formats are
   * needed by the comparator, so they are specially created when needed.
   *
   * <p>In particular we need to ensure that enum key fields work correctly, since their formats are
   * not static (like simple type formats are). [#17140]
   *
   * <p>Note that we don't need to actually cause a recovery in order to test the deserialization
   * and subsequent use of comparators. The JE DatabaseConfig.setBtreeComparator method serializes
   * and deserializes the comparator. The comparator is initialized on its first use, just as if
   * recovery were run.
   */
  public void testStoredComparators() throws DatabaseException {

    open();

    PrimaryIndex<StoredComparatorEntity.Key, StoredComparatorEntity> priIndex =
        store.getPrimaryIndex(StoredComparatorEntity.Key.class, StoredComparatorEntity.class);

    SecondaryIndex<
            StoredComparatorEntity.MyEnum, StoredComparatorEntity.Key, StoredComparatorEntity>
        secIndex = store.getSecondaryIndex(priIndex, StoredComparatorEntity.MyEnum.class, "secKey");

    final StoredComparatorEntity.Key[] priKeys =
        new StoredComparatorEntity.Key[] {
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.A, 1, StoredComparatorEntity.MyEnum.A),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.A, 1, StoredComparatorEntity.MyEnum.B),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.A, 2, StoredComparatorEntity.MyEnum.A),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.A, 2, StoredComparatorEntity.MyEnum.B),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.B, 1, StoredComparatorEntity.MyEnum.A),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.B, 1, StoredComparatorEntity.MyEnum.B),
          new StoredComparatorEntity.Key(
              StoredComparatorEntity.MyEnum.C, 0, StoredComparatorEntity.MyEnum.C),
        };

    final StoredComparatorEntity.MyEnum[] secKeys =
        new StoredComparatorEntity.MyEnum[] {
          StoredComparatorEntity.MyEnum.C,
          StoredComparatorEntity.MyEnum.B,
          StoredComparatorEntity.MyEnum.A,
          null,
          StoredComparatorEntity.MyEnum.A,
          StoredComparatorEntity.MyEnum.B,
          StoredComparatorEntity.MyEnum.C,
        };

    assertEquals(priKeys.length, secKeys.length);
    final int nEntities = priKeys.length;

    Transaction txn = txnBegin();
    for (int i = 0; i < nEntities; i += 1) {
      priIndex.put(txn, new StoredComparatorEntity(priKeys[i], secKeys[i]));
    }
    txnCommit(txn);

    txn = txnBeginCursor();
    EntityCursor<StoredComparatorEntity> entities = priIndex.entities(txn, null);
    for (int i = nEntities - 1; i >= 0; i -= 1) {
      StoredComparatorEntity e = entities.next();
      assertNotNull(e);
      assertEquals(priKeys[i], e.key);
      assertEquals(secKeys[i], e.secKey);
    }
    assertNull(entities.next());
    entities.close();
    txnCommit(txn);

    txn = txnBeginCursor();
    entities = secIndex.entities(txn, null);
    for (StoredComparatorEntity.MyEnum myEnum :
        EnumSet.allOf(StoredComparatorEntity.MyEnum.class)) {
      for (int i = 0; i < nEntities; i += 1) {
        if (secKeys[i] == myEnum) {
          StoredComparatorEntity e = entities.next();
          assertNotNull(e);
          assertEquals(priKeys[i], e.key);
          assertEquals(secKeys[i], e.secKey);
        }
      }
    }
    assertNull(entities.next());
    entities.close();
    txnCommit(txn);

    close();
  }
Example #26
0
  public void testCursorUpdate() throws DatabaseException {

    open();

    PrimaryIndex<Integer, MyEntity> priIndex = store.getPrimaryIndex(Integer.class, MyEntity.class);

    SecondaryIndex<Integer, Integer, MyEntity> secIndex =
        store.getSecondaryIndex(priIndex, Integer.class, "secKey");

    Transaction txn = txnBeginCursor();

    Integer k;
    MyEntity e = new MyEntity();
    e.priKey = 1;
    e.secKey = 2;
    priIndex.put(txn, e);

    /* update() with primary entity cursor. */
    EntityCursor<MyEntity> entities = priIndex.entities(txn, null);
    e = entities.next();
    assertNotNull(e);
    assertEquals(1, e.priKey);
    assertEquals(Integer.valueOf(2), e.secKey);
    e.secKey = null;
    assertTrue(entities.update(e));
    e = entities.current();
    assertNotNull(e);
    assertEquals(1, e.priKey);
    assertEquals(null, e.secKey);
    e.secKey = 3;
    assertTrue(entities.update(e));
    e = entities.current();
    assertNotNull(e);
    assertEquals(1, e.priKey);
    assertEquals(Integer.valueOf(3), e.secKey);
    entities.close();

    /* update() with primary keys cursor. */
    EntityCursor<Integer> keys = priIndex.keys(txn, null);
    k = keys.next();
    assertNotNull(k);
    assertEquals(Integer.valueOf(1), k);
    try {
      keys.update(2);
      fail();
    } catch (UnsupportedOperationException expected) {
    }
    keys.close();

    /* update() with secondary entity cursor. */
    entities = secIndex.entities(txn, null);
    e = entities.next();
    assertNotNull(e);
    assertEquals(1, e.priKey);
    assertEquals(Integer.valueOf(3), e.secKey);
    try {
      entities.update(e);
      fail();
    } catch (UnsupportedOperationException expected) {
    } catch (IllegalArgumentException expectedForDbCore) {
    }
    entities.close();

    /* update() with secondary keys cursor. */
    keys = secIndex.keys(txn, null);
    k = keys.next();
    assertNotNull(k);
    assertEquals(Integer.valueOf(3), k);
    try {
      keys.update(k);
      fail();
    } catch (UnsupportedOperationException expected) {
    }
    keys.close();

    txnCommit(txn);
    close();
  }
Example #27
0
  public void testCursorDelete() throws DatabaseException {

    open();

    PrimaryIndex<Integer, MyEntity> priIndex = store.getPrimaryIndex(Integer.class, MyEntity.class);

    SecondaryIndex<Integer, Integer, MyEntity> secIndex =
        store.getSecondaryIndex(priIndex, Integer.class, "secKey");

    Transaction txn = txnBeginCursor();

    /* delete() with primary and secondary entities cursor. */

    for (EntityIndex index : new EntityIndex[] {priIndex, secIndex}) {

      MyEntity e = new MyEntity();
      e.priKey = 1;
      e.secKey = 1;
      priIndex.put(txn, e);
      e.priKey = 2;
      priIndex.put(txn, e);

      EntityCursor<MyEntity> cursor = index.entities(txn, null);

      e = cursor.next();
      assertNotNull(e);
      assertEquals(1, e.priKey);
      e = cursor.current();
      assertNotNull(e);
      assertEquals(1, e.priKey);
      assertTrue(cursor.delete());
      assertTrue(!cursor.delete());
      assertNull(cursor.current());

      e = cursor.next();
      assertNotNull(e);
      assertEquals(2, e.priKey);
      e = cursor.current();
      assertNotNull(e);
      assertEquals(2, e.priKey);
      assertTrue(cursor.delete());
      assertTrue(!cursor.delete());
      assertNull(cursor.current());

      e = cursor.next();
      assertNull(e);

      if (index == priIndex) {
        e = new MyEntity();
        e.priKey = 2;
        e.secKey = 1;
        assertTrue(!cursor.update(e));
      }

      cursor.close();
    }

    /* delete() with primary and secondary keys cursor. */

    for (EntityIndex index : new EntityIndex[] {priIndex, secIndex}) {

      MyEntity e = new MyEntity();
      e.priKey = 1;
      e.secKey = 1;
      priIndex.put(txn, e);
      e.priKey = 2;
      priIndex.put(txn, e);

      EntityCursor<Integer> cursor = index.keys(txn, null);

      Integer k = cursor.next();
      assertNotNull(k);
      assertEquals(1, k.intValue());
      k = cursor.current();
      assertNotNull(k);
      assertEquals(1, k.intValue());
      assertTrue(cursor.delete());
      assertTrue(!cursor.delete());
      assertNull(cursor.current());

      int expectKey = (index == priIndex) ? 2 : 1;
      k = cursor.next();
      assertNotNull(k);
      assertEquals(expectKey, k.intValue());
      k = cursor.current();
      assertNotNull(k);
      assertEquals(expectKey, k.intValue());
      assertTrue(cursor.delete());
      assertTrue(!cursor.delete());
      assertNull(cursor.current());

      k = cursor.next();
      assertNull(k);

      cursor.close();
    }

    txnCommit(txn);
    close();
  }
Example #28
0
  public void testDeleteFromSubIndex() throws DatabaseException {

    open();

    PrimaryIndex<Integer, MyEntity> priIndex = store.getPrimaryIndex(Integer.class, MyEntity.class);

    SecondaryIndex<Integer, Integer, MyEntity> secIndex =
        store.getSecondaryIndex(priIndex, Integer.class, "secKey");

    Transaction txn = txnBegin();
    MyEntity e = new MyEntity();
    e.secKey = 1;
    e.priKey = 1;
    priIndex.put(txn, e);
    e.priKey = 2;
    priIndex.put(txn, e);
    e.priKey = 3;
    priIndex.put(txn, e);
    e.priKey = 4;
    priIndex.put(txn, e);
    txnCommit(txn);

    EntityIndex<Integer, MyEntity> subIndex = secIndex.subIndex(1);
    txn = txnBeginCursor();
    e = subIndex.get(txn, 1, null);
    assertEquals(1, e.priKey);
    assertEquals(Integer.valueOf(1), e.secKey);
    e = subIndex.get(txn, 2, null);
    assertEquals(2, e.priKey);
    assertEquals(Integer.valueOf(1), e.secKey);
    e = subIndex.get(txn, 3, null);
    assertEquals(3, e.priKey);
    assertEquals(Integer.valueOf(1), e.secKey);
    e = subIndex.get(txn, 5, null);
    assertNull(e);

    boolean deleted = subIndex.delete(txn, 1);
    assertTrue(deleted);
    assertNull(subIndex.get(txn, 1, null));
    assertNotNull(subIndex.get(txn, 2, null));

    EntityCursor<MyEntity> cursor = subIndex.entities(txn, null);
    boolean saw4 = false;
    for (MyEntity e2 = cursor.first(); e2 != null; e2 = cursor.next()) {
      if (e2.priKey == 3) {
        cursor.delete();
      }
      if (e2.priKey == 4) {
        saw4 = true;
      }
    }
    cursor.close();
    assertTrue(saw4);
    assertNull(subIndex.get(txn, 1, null));
    assertNull(subIndex.get(txn, 3, null));
    assertNotNull(subIndex.get(txn, 2, null));
    assertNotNull(subIndex.get(txn, 4, null));

    txnCommit(txn);
    close();
  }
Example #29
0
  private void doSecondaryBulkLoad(boolean closeAndOpenNormally) throws DatabaseException {

    PrimaryIndex<Integer, RelatedX> priX;
    PrimaryIndex<Integer, RelatedY> priY;
    SecondaryIndex<Integer, Integer, RelatedX> secX;

    /* Open priX with SecondaryBulkLoad=true. */
    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setSecondaryBulkLoad(true);
    open(config);

    /* Getting priX should not create the secondary index. */
    priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
    PersistTestUtils.assertDbExists(false, env, STORE_NAME, RelatedX.class.getName(), "key2");

    /* We can put records that violate the secondary key constraint. */
    priX.put(new RelatedX());

    if (closeAndOpenNormally) {
      /* Open normally and attempt to populate the secondary. */
      close();
      open();
      if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) {
        /* Constraint enforcement requires transactions. */
        try {
          /* Before adding the foreign key, constraint is violated. */
          priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
          fail();
        } catch (DatabaseException e) {
          assertTrue(e.toString(), e.toString().contains("foreign key not allowed"));
        }
      }
      /* Open priX with SecondaryBulkLoad=true. */
      close();
      open(config);
      /* Add the foreign key to avoid the constraint error. */
      priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
      priY.put(new RelatedY());
      /* Open normally and the secondary will be populated. */
      close();
      open();
      priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
      PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2");
      secX = store.getSecondaryIndex(priX, Integer.class, "key2");
    } else {
      /* Get secondary index explicitly and it will be populated. */
      if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) {
        /* Constraint enforcement requires transactions. */
        try {
          /* Before adding the foreign key, constraint is violated. */
          secX = store.getSecondaryIndex(priX, Integer.class, "key2");
          fail();
        } catch (DatabaseException e) {
          assertTrue(e.toString(), e.toString().contains("foreign key not allowed"));
        }
      }
      /* Add the foreign key. */
      priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
      priY.put(new RelatedY());
      secX = store.getSecondaryIndex(priX, Integer.class, "key2");
      PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2");
    }

    RelatedX x = secX.get(88);
    assertNotNull(x);
    close();
  }