Ejemplo n.º 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();
        }
      }
    }
  }
Ejemplo n.º 2
0
  /**
   * Inserts an entity, or updates it if the primary key already exists (does not return the
   * existing entity). This method may be used instead of {@link #put(Transaction,Object)} to save
   * the overhead of returning 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.
   * @throws DatabaseException the base class for all BDB exceptions.
   */
  public void putNoReturn(Transaction txn, E entity) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    assignKey(entity, keyEntry);
    entityBinding.objectToData(entity, dataEntry);

    db.put(txn, keyEntry, dataEntry);
  }
Ejemplo n.º 3
0
  /**
   * Inserts an entity and returns true, or returns false if the primary key already exists.
   *
   * <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.
   * @return true if the entity was inserted, or false if an entity with the same primary key is
   *     already present.
   * @throws DatabaseException the base class for all BDB exceptions.
   */
  public boolean putNoOverwrite(Transaction txn, E entity) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    assignKey(entity, keyEntry);
    entityBinding.objectToData(entity, dataEntry);

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

    return (status == OperationStatus.SUCCESS);
  }
Ejemplo n.º 4
0
 /**
  * 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;
   }
 }
Ejemplo n.º 5
0
 public void valueToData(V value, DatabaseEntry data) {
   entityBinding.objectToData(value, data);
 }