예제 #1
0
  /**
   * Inserts an entity and returns null, or updates it if the primary key already exists and returns
   * the existing entity.
   *
   * <p>If a {@link PrimaryKey#sequence} is used and the primary key field of the given entity is
   * null or zero, this method will assign the next value from the sequence to the primary key field
   * of the given entity.
   *
   * @param txn the transaction used to protect this operation, null to use auto-commit, or null if
   *     the store is non-transactional.
   * @param entity the entity to be inserted or updated.
   * @return the existing entity that was updated, or null if the entity was inserted.
   * @throws DatabaseException the base class for all BDB exceptions.
   */
  public E put(Transaction txn, E entity) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    assignKey(entity, keyEntry);

    boolean autoCommit = false;
    Environment env = db.getEnvironment();
    if (transactional && txn == null && DbCompat.getThreadTransaction(env) == null) {
      txn = env.beginTransaction(null, getAutoCommitTransactionConfig());
      autoCommit = true;
    }

    CursorConfig cursorConfig = null;
    if (concurrentDB) {
      cursorConfig = new CursorConfig();
      DbCompat.setWriteCursor(cursorConfig, true);
    }
    boolean failed = true;
    Cursor cursor = db.openCursor(txn, cursorConfig);
    LockMode lockMode = locking ? LockMode.RMW : null;
    try {
      while (true) {
        OperationStatus status = cursor.getSearchKey(keyEntry, dataEntry, lockMode);
        if (status == OperationStatus.SUCCESS) {
          E existing = entityBinding.entryToObject(keyEntry, dataEntry);
          entityBinding.objectToData(entity, dataEntry);
          cursor.put(keyEntry, dataEntry);
          failed = false;
          return existing;
        } else {
          entityBinding.objectToData(entity, dataEntry);
          status = cursor.putNoOverwrite(keyEntry, dataEntry);
          if (status != OperationStatus.KEYEXIST) {
            failed = false;
            return null;
          }
        }
      }
    } finally {
      cursor.close();
      if (autoCommit) {
        if (failed) {
          txn.abort();
        } else {
          txn.commit();
        }
      }
    }
  }
예제 #2
0
파일: Store.java 프로젝트: nologic/nabs
 /**
  * Checks whether the given data is in the current format by translating it to/from an object. If
  * true is returned, data is updated.
  */
 private boolean evolveNeeded(DatabaseEntry key, DatabaseEntry data, EntityBinding binding) {
   Object entity = binding.entryToObject(key, data);
   DatabaseEntry newData = new DatabaseEntry();
   binding.objectToData(entity, newData);
   if (data.equals(newData)) {
     return false;
   } else {
     byte[] bytes = newData.getData();
     int off = newData.getOffset();
     int size = newData.getSize();
     data.setData(bytes, off, size);
     return true;
   }
 }
예제 #3
0
  public E get(Transaction txn, SK key, LockMode lockMode) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry pkeyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    keyBinding.objectToEntry(key, keyEntry);

    OperationStatus status = secDb.get(txn, keyEntry, pkeyEntry, dataEntry, lockMode);

    if (status == OperationStatus.SUCCESS) {
      return (E) entityBinding.entryToObject(pkeyEntry, dataEntry);
    } else {
      return null;
    }
  }
예제 #4
0
  public E get(Transaction txn, PK key, LockMode lockMode) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    keyBinding.objectToEntry(key, keyEntry);

    OperationStatus status = db.get(txn, keyEntry, dataEntry, lockMode);

    if (status == OperationStatus.SUCCESS) {
      if (entityBinding instanceof PersistEntityBinding) {
        return (E) ((PersistEntityBinding) entityBinding).entryToObjectWithPriKey(key, dataEntry);
      } else {
        return entityBinding.entryToObject(keyEntry, dataEntry);
      }
    } else {
      return null;
    }
  }
예제 #5
0
 public V entryToValue(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) {
   return (V) entityBinding.entryToObject(isSecondary ? pkey : key, data);
 }