/** * 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(); } } } }
/** * 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; } }
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; } }
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; } }
public V entryToValue(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { return (V) entityBinding.entryToObject(isSecondary ? pkey : key, data); }