Exemple #1
0
  public synchronized void closeClass(Class entityClass) throws DatabaseException {

    checkOpen();
    String clsName = entityClass.getName();
    EntityMetadata entityMeta = checkEntityClass(clsName);

    PrimaryIndex priIndex = priIndexMap.get(clsName);
    if (priIndex != null) {
      /* Close the secondaries first. */
      DatabaseException firstException = null;
      for (SecondaryKeyMetadata keyMeta : entityMeta.getSecondaryKeys().values()) {

        String secName = makeSecName(clsName, keyMeta.getKeyName());
        SecondaryIndex secIndex = secIndexMap.get(secName);
        if (secIndex != null) {
          Database db = secIndex.getDatabase();
          firstException = closeDb(db, firstException);
          firstException = closeDb(secIndex.getKeysDatabase(), firstException);
          secIndexMap.remove(secName);
          deferredWriteDatabases.remove(db);
        }
      }
      /* Close the primary last. */
      Database db = priIndex.getDatabase();
      firstException = closeDb(db, firstException);
      priIndexMap.remove(clsName);
      deferredWriteDatabases.remove(db);

      /* Throw the first exception encountered. */
      if (firstException != null) {
        throw firstException;
      }
    }
  }
Exemple #2
0
  public synchronized void close() throws DatabaseException {

    checkOpen();
    DatabaseException firstException = null;
    try {
      if (rawAccess) {
        boolean allClosed = catalog.close();
        assert allClosed;
      } else {
        synchronized (catalogPool) {
          Map<String, PersistCatalog> catalogMap = catalogPool.get(env);
          assert catalogMap != null;
          if (catalog.close()) {
            /* Remove when the reference count goes to zero. */
            catalogMap.remove(storeName);
          }
        }
      }
      catalog = null;
    } catch (DatabaseException e) {
      if (firstException == null) {
        firstException = e;
      }
    }
    firstException = closeDb(sequenceDb, firstException);
    for (SecondaryIndex index : secIndexMap.values()) {
      firstException = closeDb(index.getDatabase(), firstException);
      firstException = closeDb(index.getKeysDatabase(), firstException);
    }
    for (PrimaryIndex index : priIndexMap.values()) {
      firstException = closeDb(index.getDatabase(), firstException);
    }
    if (firstException != null) {
      throw firstException;
    }
  }
Exemple #3
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;
  }
Exemple #4
0
  private void evolveIndex(Format format, EvolveEvent event, EvolveListener listener)
      throws DatabaseException {

    Class entityClass = format.getType();
    String entityClassName = format.getClassName();
    EntityMetadata meta = model.getEntityMetadata(entityClassName);
    String keyClassName = meta.getPrimaryKey().getClassName();
    keyClassName = SimpleCatalog.keyClassName(keyClassName);
    DatabaseConfig dbConfig = getPrimaryConfig(meta);

    PrimaryIndex<Object, Object> index =
        getPrimaryIndex(Object.class, keyClassName, entityClass, entityClassName);
    Database db = index.getDatabase();

    EntityBinding binding = index.getEntityBinding();
    DatabaseEntry key = new DatabaseEntry();
    DatabaseEntry data = new DatabaseEntry();

    Cursor readCursor = db.openCursor(null, CursorConfig.READ_UNCOMMITTED);
    try {
      while (readCursor.getNext(key, data, null) == OperationStatus.SUCCESS) {
        if (evolveNeeded(key, data, binding)) {
          Transaction txn = null;
          if (dbConfig.getTransactional()) {
            boolean success = false;
            txn = env.beginTransaction(null, null);
          }
          boolean doCommit = false;
          Cursor writeCursor = null;
          try {
            writeCursor = db.openCursor(txn, null);
            if (writeCursor.getSearchKey(key, data, LockMode.RMW) == OperationStatus.SUCCESS) {
              boolean written = false;
              if (evolveNeeded(key, data, binding)) {
                writeCursor.putCurrent(data);
                written = true;
              }
              if (listener != null) {
                EvolveInternal.updateEvent(event, entityClassName, 1, written ? 1 : 0);
                if (!listener.evolveProgress(event)) {
                  break;
                }
              }
            }
          } finally {
            if (writeCursor != null) {
              writeCursor.close();
            }
            if (txn != null) {
              if (doCommit) {
                txn.commit();
              } else {
                txn.abort();
              }
            }
          }
        }
      }
    } finally {
      readCursor.close();
    }
  }