/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using BerkeleyDB.Internal;
namespace BerkeleyDB {
///
/// The base class from which all database classes inherit
///
public class BaseDatabase : IDisposable {
internal DB db;
///
/// The environment that the database lies in.
///
protected internal DatabaseEnvironment env;
///
/// Whether the database is opened.
///
protected internal bool isOpen;
private DBTCopyDelegate CopyDelegate;
private EntryComparisonDelegate dupCompareHandler;
private DatabaseFeedbackDelegate feedbackHandler;
private BDB_CompareDelegate doDupCompareRef;
private BDB_DbFeedbackDelegate doFeedbackRef;
#region Constructors
///
/// Protected constructor
///
///
/// The environment in which to create this database
///
/// Flags to pass to the DB->create() method
protected BaseDatabase(DatabaseEnvironment envp, uint flags) {
db = new DB(envp == null ? null : envp.dbenv, flags);
db.api_internal = this;
if (envp == null) {
env = new DatabaseEnvironment(db.env());
} else
env = envp;
}
///
/// Create a new database object with the same underlying DB handle as
/// . Used during Database.Open to get an
/// object of the correct DBTYPE.
///
/// Database to clone
protected BaseDatabase(BaseDatabase clone) {
db = clone.db;
clone.db = null;
db.api_internal = this;
env = clone.env;
clone.env = null;
}
internal void Config(DatabaseConfig cfg) {
// The cache size cannot change.
if (cfg.CacheSize != null)
db.set_cachesize(cfg.CacheSize.Gigabytes,
cfg.CacheSize.Bytes, cfg.CacheSize.NCaches);
if (cfg.encryptionIsSet)
db.set_encrypt(
cfg.EncryptionPassword, (uint)cfg.EncryptAlgorithm);
if (cfg.ErrorPrefix != null)
ErrorPrefix = cfg.ErrorPrefix;
if (cfg.ErrorFeedback != null)
ErrorFeedback = cfg.ErrorFeedback;
if (cfg.Feedback != null)
Feedback = cfg.Feedback;
db.set_flags(cfg.flags);
if (cfg.ByteOrder != ByteOrder.MACHINE)
db.set_lorder(cfg.ByteOrder.lorder);
if (cfg.NoWaitDbExclusiveLock == true)
db.set_lk_exclusive(1);
else if (cfg.NoWaitDbExclusiveLock == false)
db.set_lk_exclusive(0);
if (cfg.pagesizeIsSet)
db.set_pagesize(cfg.PageSize);
if (cfg.Priority != CachePriority.DEFAULT)
db.set_priority(cfg.Priority.priority);
}
///
/// Protected factory method to create and open a new database object.
///
/// The database's filename
/// The subdatabase's name
/// The database's configuration
///
/// The transaction in which to open the database
///
/// A new, open database object
protected static BaseDatabase Open(string Filename,
string DatabaseName, DatabaseConfig cfg, Transaction txn) {
BaseDatabase ret = new BaseDatabase(cfg.Env, 0);
ret.Config(cfg);
ret.db.open(Transaction.getDB_TXN(txn),
Filename, DatabaseName, DBTYPE.DB_UNKNOWN, cfg.openFlags, 0);
return ret;
}
#endregion Constructor
#region Callbacks
private static void doFeedback(IntPtr dbp, int opcode, int percent) {
DB db = new DB(dbp, false);
db.api_internal.Feedback((DatabaseFeedbackEvent)opcode, percent);
}
#endregion Callbacks
#region Properties
// Sorted alpha by property name
///
/// If true, all database modification operations based on this object
/// will be transactionally protected.
///
public bool AutoCommit {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_AUTO_COMMIT) != 0;
}
}
///
/// The size of the shared memory buffer pool -- that is, the cache.
///
public CacheInfo CacheSize {
get {
uint gb = 0;
uint b = 0;
int n = 0;
db.get_cachesize(ref gb, ref b, ref n);
return new CacheInfo(gb, b, n);
}
}
///
/// The CreatePolicy with which this database was opened.
///
public CreatePolicy Creation {
get {
uint flags = 0;
db.get_open_flags(ref flags);
if ((flags & DbConstants.DB_EXCL) != 0)
return CreatePolicy.ALWAYS;
else if ((flags & DbConstants.DB_CREATE) != 0)
return CreatePolicy.IF_NEEDED;
else
return CreatePolicy.NEVER;
}
}
///
/// The name of this database, if it has one.
///
public string DatabaseName {
get {
string tmp = null;
string ret = null;
db.get_dbname(out tmp, out ret);
return ret;
}
}
///
/// If true, do checksum verification of pages read into the cache from
/// the backing filestore.
///
///
/// Berkeley DB uses the SHA1 Secure Hash Algorithm if encryption is
/// configured and a general hash algorithm if it is not.
///
public bool DoChecksum {
get {
uint flags = 0;
db.get_flags(ref flags);
return (flags & DbConstants.DB_CHKSUM) != 0;
}
}
///
/// The algorithm used by the Berkeley DB library to perform encryption
/// and decryption.
///
public EncryptionAlgorithm EncryptAlgorithm {
get {
uint flags = 0;
db.get_encrypt_flags(ref flags);
return (EncryptionAlgorithm)Enum.ToObject(
typeof(EncryptionAlgorithm), flags);
}
}
///
/// If true, encrypt all data stored in the database.
///
public bool Encrypted {
get {
uint flags = 0;
db.get_flags(ref flags);
return (flags & DbConstants.DB_ENCRYPT) != 0;
}
}
///
/// The database byte order.
///
public ByteOrder Endianness {
get {
int lorder = 0;
db.get_lorder(ref lorder);
return ByteOrder.FromConst(lorder);
}
}
///
/// The mechanism for reporting detailed error messages to the
/// application.
///
///
///
/// When an error occurs in the Berkeley DB library, a
/// , or subclass of DatabaseException,
/// is thrown. In some cases, however, the exception may be insufficient
/// to completely describe the cause of the error, especially during
/// initial application debugging.
///
///
/// In some cases, when an error occurs, Berkeley DB will call the given
/// delegate with additional error information. It is up to the delegate
/// to display the error message in an appropriate manner.
///
///
/// Setting ErrorFeedback to NULL unconfigures the callback interface.
///
///
/// This error-logging enhancement does not slow performance or
/// significantly increase application size, and may be run during
/// normal operation as well as during application debugging.
///
///
/// For databases opened inside of a DatabaseEnvironment, setting
/// ErrorFeedback affects the entire environment and is equivalent to
/// setting DatabaseEnvironment.ErrorFeedback.
///
///
/// For databases not opened in an environment, setting ErrorFeedback
/// configures operations performed using the specified object, not all
/// operations performed on the underlying database.
///
///
public ErrorFeedbackDelegate ErrorFeedback {
get { return env.ErrorFeedback; }
set { env.ErrorFeedback = value; }
}
///
/// The prefix string that appears before error messages issued by
/// Berkeley DB.
///
///
///
/// For databases opened inside of a DatabaseEnvironment, setting
/// ErrorPrefix affects the entire environment and is equivalent to
/// setting .
///
///
/// Setting ErrorPrefix configures operations performed using the
/// specified object, not all operations performed on the underlying
/// database.
///
///
public string ErrorPrefix {
get { return env.ErrorPrefix; }
set { env.ErrorPrefix = value; }
}
///
/// Monitor progress within long running operations.
///
///
///
/// Some operations performed by the Berkeley DB library can take
/// non-trivial amounts of time. The Feedback delegate can be used by
/// applications to monitor progress within these operations. When an
/// operation is likely to take a long time, Berkeley DB will call the
/// specified delegate with progress information.
///
///
/// It is up to the delegate to display this information in an
/// appropriate manner.
///
///
public DatabaseFeedbackDelegate Feedback {
get { return feedbackHandler; }
set {
if (value == null)
db.set_feedback(null);
else if (feedbackHandler == null) {
if (doFeedbackRef == null)
doFeedbackRef = new BDB_DbFeedbackDelegate(doFeedback);
db.set_feedback(doFeedbackRef);
}
feedbackHandler = value;
}
}
///
/// The filename of this database, if it has one.
///
public string FileName {
get {
string ret = "";
string tmp = "";
db.get_dbname(out ret, out tmp);
return ret;
}
}
///
/// If true, the object is free-threaded; that is, concurrently usable
/// by multiple threads in the address space.
///
public bool FreeThreaded {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_THREAD) != 0;
}
}
///
/// If true, the object references a physical file supporting multiple
/// databases.
///
///
/// If true, the object is a handle on a database whose key values are
/// the names of the databases stored in the physical file and whose
/// data values are opaque objects. No keys or data values may be
/// modified or stored using the database handle.
///
public bool HasMultiple { get { return (db.get_multiple() != 0); } }
///
/// If true, the underlying database files were created on an
/// architecture of the same byte order as the current one. This
/// information may be used to determine whether application data needs
/// to be adjusted for this architecture or not.
///
public bool InHostOrder {
get {
int isswapped = 0;
db.get_byteswapped(ref isswapped);
return (isswapped == 0);
}
}
///
///
/// If true, this database is not mapped into process memory.
///
///
/// See for further
/// information.
///
///
public bool NoMMap {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_NOMMAP) == 0;
}
}
///
/// If true, Berkeley DB will not write log records for this database.
///
public bool NonDurableTxns {
get {
uint flags = 0;
db.get_flags(ref flags);
return (flags & DbConstants.DB_TXN_NOT_DURABLE) != 0;
}
}
///
/// If true, configure the database handle to obtain a write lock on the
/// entire database. When the database is opened it will immediately
/// throw if it cannot obtain the
/// exclusive lock immediately. If False, configure the database handle
/// to obtain a write lock on the entire database. When the database is
/// opened, it will block until it can obtain the exclusive lock. If
/// null, do not configure the database handle to obtain a write lock on
/// the entire database.
///
public bool? NoWaitDbExclusiveLock {
get {
int onoff = 0;
int nowait = 0;
bool? result = null;
db.get_lk_exclusive(ref onoff, ref nowait);
if (onoff > 0) {
if (nowait > 0) result = true;
else result = false;
}
return result;
}
}
///
/// The database's current page size.
///
/// If was not set by
/// your application, then the default pagesize is selected based on the
/// underlying filesystem I/O block size.
///
public uint Pagesize {
get {
uint pgsz = 0;
db.get_pagesize(ref pgsz);
return pgsz;
}
}
///
/// The cache priority for pages referenced by this object.
///
public CachePriority Priority {
get {
uint pri = 0;
db.get_priority(ref pri);
return CachePriority.fromUInt(pri);
}
}
///
/// If true, this database has been opened for reading only. Any attempt
/// to modify items in the database will fail, regardless of the actual
/// permissions of any underlying files.
///
public bool ReadOnly {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_RDONLY) != 0;
}
}
///
/// If true, this database supports transactional read operations with
/// degree 1 isolation. Read operations on the database may request the
/// return of modified but not yet committed data.
///
public bool ReadUncommitted {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_READ_UNCOMMITTED) != 0;
}
}
///
/// If true, this database has been opened in a transactional mode.
///
public bool Transactional {
get { return (db.get_transactional() != 0); }
}
///
/// If true, the underlying file was physically truncated upon open,
/// discarding all previous databases it might have held.
///
public bool Truncated {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_TRUNCATE) != 0;
}
}
///
/// The type of the underlying access method (and file format). This
/// value may be used to determine the type of the database after an
/// .
///
public DatabaseType Type {
get {
DBTYPE mytype = DBTYPE.DB_UNKNOWN;
db.get_type(ref mytype);
switch (mytype) {
case DBTYPE.DB_BTREE:
return DatabaseType.BTREE;
case DBTYPE.DB_HASH:
return DatabaseType.HASH;
case DBTYPE.DB_HEAP:
return DatabaseType.HEAP;
case DBTYPE.DB_QUEUE:
return DatabaseType.QUEUE;
case DBTYPE.DB_RECNO:
return DatabaseType.RECNO;
default:
return DatabaseType.UNKNOWN;
}
}
}
///
/// If true, the database was opened with support for multiversion
/// concurrency control.
///
public bool UseMVCC {
get {
uint flags = 0;
db.get_open_flags(ref flags);
return (flags & DbConstants.DB_MULTIVERSION) != 0;
}
}
#endregion Properties
#region Methods
//Sorted alpha by method name
///
/// Flush any cached database information to disk, close any open
/// objects, free any
/// allocated resources, and close any underlying files.
///
///
///
/// Although closing a database will close any open cursors, it is
/// recommended that applications explicitly close all their Cursor
/// objects before closing the database. The reason why is that when the
/// cursor is explicitly closed, the memory allocated for it is
/// reclaimed; however, this will not happen if you close a database
/// while cursors are still opened.
///
///
/// The same rule, for the same reasons, hold true for
/// objects. Simply make sure you resolve
/// all your transaction objects before closing your database handle.
///
///
/// Because key/data pairs are cached in memory, applications should
/// make a point to always either close database handles or sync their
/// data to disk (using before exiting, to
/// ensure that any data cached in main memory are reflected in the
/// underlying file system.
///
///
/// When called on a database that is the primary database for a
/// secondary index, the primary database should be closed only after
/// all secondary indices referencing it have been closed.
///
///
/// When multiple threads are using the object concurrently, only a
/// single thread may call the Close method.
///
///
/// The object may not be accessed again after Close is called,
/// regardless of its outcome.
///
///
public void Close() {
Close(true);
}
///
/// Optionally flush any cached database information to disk, close any
/// open objects, free
/// any allocated resources, and close any underlying files.
///
///
/// If false, do not flush cached information to disk.
///
///
///
/// The sync parameter is a dangerous option. It should be set to false
/// only if the application is doing logging (with transactions) so that
/// the database is recoverable after a system or application crash, or
/// if the database is always generated from scratch after any system or
/// application crash.
///
///
/// It is important to understand that flushing cached information to
/// disk only minimizes the window of opportunity for corrupted data.
/// Although unlikely, it is possible for database corruption to happen
/// if a system or application crash occurs while writing data to the
/// database. To ensure that database corruption never occurs,
/// applications must either use transactions and logging with automatic
/// recovery or edit a copy of the database, and once all applications
/// using the database have successfully called Close, atomically
/// replace the original database with the updated copy.
///
///
/// Note that this parameter only works when the database has been
/// opened using an environment.
///
///
public void Close(bool sync) {
db.close(sync ? 0 : DbConstants.DB_NOSYNC);
isOpen = false;
}
///
/// Create a database cursor.
///
/// A newly created cursor
public Cursor Cursor() { return Cursor(new CursorConfig(), null); }
///
/// Create a database cursor with the given configuration.
///
///
/// The configuration properties for the cursor.
///
/// A newly created cursor
public Cursor Cursor(CursorConfig cfg) { return Cursor(cfg, null); }
///
/// Create a transactionally protected database cursor.
///
///
/// The transaction context in which the cursor may be used.
///
/// A newly created cursor
public Cursor Cursor(Transaction txn) {
return Cursor(new CursorConfig(), txn);
}
///
/// Create a transactionally protected database cursor with the given
/// configuration.
///
///
/// The configuration properties for the cursor.
///
///
/// The transaction context in which the cursor may be used.
///
/// A newly created cursor
public Cursor Cursor(CursorConfig cfg, Transaction txn) {
if (cfg.Priority == CachePriority.DEFAULT)
return new Cursor(db.cursor(
Transaction.getDB_TXN(txn), cfg.flags), Type, Pagesize);
else
return new Cursor(db.cursor(Transaction.getDB_TXN(txn),
cfg.flags), Type, Pagesize, cfg.Priority);
}
///
/// Remove key/data pairs from the database. If
/// is DatabaseEntry, the key/data pair associated with
/// is discarded from the database. In the
/// presence of duplicate key values, all records associated with the
/// designated key will be discarded. If is
/// MultipleDatabaseEntry, delete multiple data items using keys from
/// the buffer to which the key parameter refers. If
/// is MultipleKeyDatabaseEntry, delete multiple
/// data items using keys and data from the buffer to which the key
/// parameter refers.
///
///
///
/// When called on a secondary database, remove the key/data pair from
/// the primary database and all secondary indices.
///
///
/// If the operation occurs in a transactional database, the operation
/// will be implicitly transaction protected.
///
///
///
/// Discard the key/data pair associated with .
///
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
public void Delete(DatabaseEntry key) {
Delete(key, null);
}
///
/// Remove key/data pairs from the database. If
/// is DatabaseEntry, the key/data pair associated with
/// is discarded from the database. In the
/// presence of duplicate key values, all records associated with the
/// designated key will be discarded. If is
/// MultipleDatabaseEntry, delete multiple data items using keys from
/// the buffer to which the key parameter refers. If
/// is MultipleKeyDatabaseEntry, delete multiple
/// data items using keys and data from the buffer to which the key
/// parameter refers.
///
///
///
/// When called on a secondary database, remove the key/data pairs from
/// the primary database and all secondary indices.
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
///
///
/// Discard the key/data pairs associated with .
///
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
public void Delete(DatabaseEntry key, Transaction txn) {
uint flags = 0;
System.Type type = key.GetType();
if (type == typeof(MultipleDatabaseEntry))
flags |= DbConstants.DB_MULTIPLE;
else if (type == typeof(MultipleKeyDatabaseEntry))
flags |= DbConstants.DB_MULTIPLE_KEY;
db.del(Transaction.getDB_TXN(txn), key, flags);
}
///
/// Check whether appears in the database.
///
///
/// If the operation occurs in a transactional database, the operation
/// will be implicitly transaction protected.
///
/// The key to search for.
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// True if appears in the database, false
/// otherwise.
///
public bool Exists(DatabaseEntry key) {
return Exists(key, null, null);
}
///
/// Check whether appears in the database.
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for.
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// True if appears in the database, false
/// otherwise.
///
public bool Exists(DatabaseEntry key, Transaction txn) {
return Exists(key, txn, null);
}
///
/// Check whether appears in the database.
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for.
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// The locking behavior to use.
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// True if appears in the database, false
/// otherwise.
///
public bool Exists(
DatabaseEntry key, Transaction txn, LockingInfo info) {
/*
* If the library call does not throw an exception the key exists.
* If the exception is NotFound the key does not exist and we
* should return false. Any other exception should get passed
* along.
*/
try {
db.exists(Transaction.getDB_TXN(txn),
key, (info == null) ? 0 : info.flags);
return true;
} catch (NotFoundException) {
return false;
}
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// .
///
///
/// If the operation occurs in a transactional database, the operation
/// will be implicitly transaction protected.
///
/// The key to search for
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is the
/// retrieved data.
///
public
KeyValuePair Get(DatabaseEntry key) {
return Get(key, (Transaction)null, (LockingInfo)null);
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// .
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is the
/// retrieved data.
///
public KeyValuePair Get(
DatabaseEntry key, Transaction txn) {
return Get(key, txn, null);
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// .
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// The locking behavior to use.
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is the
/// retrieved data.
///
public KeyValuePair Get(
DatabaseEntry key, Transaction txn, LockingInfo info) {
return Get(key, null, txn, info, 0);
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// . If the data is a partial
/// ,
/// bytes starting bytes
/// from the beginning of the retrieved data record are returned as
/// if they comprise the entire record. If any or all of the specified
/// bytes do not exist in the record, Get is successful, and any
/// existing bytes are returned.
///
/// The key to search for
/// The retrieved data
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never
/// explicitly created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// the partially retrieved bytes in the data.
///
public KeyValuePair Get(
DatabaseEntry key, DatabaseEntry data) {
return Get(key, data, null, null);
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// . If the data is a partial
/// ,
/// bytes starting bytes
/// from the beginning of the retrieved data record are returned as
/// if they comprise the entire record. If any or all of the specified
/// bytes do not exist in the record, Get is successful, and any
/// existing bytes are returned.
///
///
/// If is null and the operation occurs in
/// a transactional database, the operation will be implicitly
/// transaction protected.
///
/// The key to search for
/// The retrieved data
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store
/// group, is a handle returned from
/// ; otherwise null.
///
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never
/// explicitly created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// the partially retrieved bytes in the data.
///
public KeyValuePair Get(
DatabaseEntry key, DatabaseEntry data, Transaction txn) {
return Get(key, data, txn, null);
}
///
/// Retrieve a key/data pair from the database. In the presence of
/// duplicate key values, Get will return the first data item for
/// . If the data is a partial
/// ,
/// bytes starting bytes
/// from the beginning of the retrieved data record are returned as
/// if they comprise the entire record. If any or all of the specified
/// bytes do not exist in the record, Get is successful, and any
/// existing bytes are returned.
///
///
/// If is null and the operation occurs in
/// a transactional database, the operation will be implicitly
/// transaction protected.
///
/// The key to search for
/// The retrieved data
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store
/// group, is a handle returned from
/// ; otherwise null.
///
/// The locking behavior to use.
///
/// A NotFoundException is thrown if is not in
/// the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never
/// explicitly created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// the partially retrieved bytes in the data.
///
public KeyValuePair Get(
DatabaseEntry key, DatabaseEntry data, Transaction txn,
LockingInfo info) {
return Get(key, data, txn, info, 0);
}
///
/// Protected method to retrieve data from the underlying DB handle.
///
///
/// The key to search for. If null a new DatabaseEntry is created.
///
///
/// The data to search for. If null a new DatabaseEntry is created.
///
/// The txn for this operation.
/// Locking info for this operation.
///
/// Flags value specifying which type of get to perform. Passed
/// directly to DB->get().
///
///
/// A whose Key
/// parameter is and whose Value parameter is the
/// retrieved data.
///
protected KeyValuePair Get(
DatabaseEntry key,
DatabaseEntry data, Transaction txn, LockingInfo info, uint flags) {
if (key == null)
key = new DatabaseEntry();
if (data == null)
data = new DatabaseEntry();
flags |= info == null ? 0 : info.flags;
db.get(Transaction.getDB_TXN(txn), key, data, flags);
return new KeyValuePair(key, data);
}
///
/// Retrieve a key/data pair from the database which matches
/// and .
///
///
/// If the operation occurs in a transactional database, the operation
/// will be implicitly transaction protected.
///
/// The key to search for
/// The data to search for
///
/// A NotFoundException is thrown if and
/// are not in the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// .
///
public KeyValuePair GetBoth(
DatabaseEntry key, DatabaseEntry data) {
return GetBoth(key, data, null, null);
}
///
/// Retrieve a key/data pair from the database which matches
/// and .
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for
/// The data to search for
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// A NotFoundException is thrown if and
/// are not in the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// .
///
public KeyValuePair GetBoth(
DatabaseEntry key, DatabaseEntry data, Transaction txn) {
return GetBoth(key, data, txn, null);
}
///
/// Retrieve a key/data pair from the database which matches
/// and .
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
/// The key to search for
/// The data to search for
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// The locking behavior to use.
///
/// A NotFoundException is thrown if and
/// are not in the database.
///
///
/// A KeyEmptyException is thrown if the database is a
/// or
/// database and exists, but was never explicitly
/// created by the application or was later deleted.
///
///
/// A whose Key
/// parameter is and whose Value parameter is
/// .
///
public KeyValuePair GetBoth(
DatabaseEntry key,
DatabaseEntry data, Transaction txn, LockingInfo info) {
return Get(key, data, txn, info, DbConstants.DB_GET_BOTH);
}
///
/// Display the database statistical information which does not require
/// traversal of the database.
///
///
/// Among other things, this method makes it possible for applications
/// to request key and record counts without incurring the performance
/// penalty of traversing the entire database.
///
///
/// The statistical information is described by the
/// , ,
/// , , and
/// classes.
///
public void PrintFastStats() {
PrintStats(false, true);
}
///
/// Display the database statistical information which does not require
/// traversal of the database.
///
///
/// Among other things, this method makes it possible for applications
/// to request key and record counts without incurring the performance
/// penalty of traversing the entire database.
///
///
/// If true, display all available information.
///
public void PrintFastStats(bool PrintAll) {
PrintStats(PrintAll, true);
}
///
/// Display the database statistical information.
///
///
/// The statistical information is described by the
/// , ,
/// , , and
/// classes.
///
public void PrintStats() {
PrintStats(false, false);
}
///
/// Display the database statistical information.
///
///
/// If true, display all available information.
///
public void PrintStats(bool PrintAll) {
PrintStats(PrintAll, false);
}
private void PrintStats(bool all, bool fast) {
uint flags = 0;
flags |= all ? DbConstants.DB_STAT_ALL : 0;
flags |= fast ? DbConstants.DB_FAST_STAT : 0;
db.stat_print(flags);
}
///
/// Remove the underlying file represented by
/// , incidentally removing all of the
/// databases it contained.
///
/// The file to remove
public static void Remove(string Filename) {
Remove(Filename, null, null);
}
///
/// Remove the underlying file represented by
/// , incidentally removing all of the
/// databases it contained.
///
/// The file to remove
///
/// The DatabaseEnvironment the database belongs to
///
public static void Remove(string Filename, DatabaseEnvironment DbEnv) {
Remove(Filename, null, DbEnv);
}
///
/// Remove the database specified by and
/// .
///
/// The file to remove
/// The database to remove
public static void Remove(string Filename, string DatabaseName) {
Remove(Filename, DatabaseName, null);
}
///
/// Remove the database specified by and
/// .
///
///
///
/// Applications should never remove databases with open DB handles, or
/// in the case of removing a file, when any database in the file has an
/// open handle. For example, some architectures do not permit the
/// removal of files with open system handles. On these architectures,
/// attempts to remove databases currently in use by any thread of
/// control in the system may fail.
///
///
/// Remove should not be called if the remove is intended to be
/// transactionally safe;
/// should be
/// used instead.
///
///
/// The file to remove
/// The database to remove
///
/// The DatabaseEnvironment the database belongs to
///
public static void Remove(
string Filename, string DatabaseName, DatabaseEnvironment DbEnv) {
BaseDatabase db = new BaseDatabase(DbEnv, 0);
db.db.remove(Filename, DatabaseName, 0);
}
///
/// Rename the underlying file represented by
/// , incidentally renaming all of the
/// databases it contained.
///
/// The file to rename
/// The new filename
public static void Rename(string Filename, string NewName) {
Rename(Filename, null, NewName, null);
}
///
/// Rename the underlying file represented by
/// , incidentally renaming all of the
/// databases it contained.
///
/// The file to rename
/// The new filename
///
/// The DatabaseEnvironment the database belongs to
///
public static void Rename(
string Filename, string NewName, DatabaseEnvironment DbEnv) {
Rename(Filename, null, NewName, DbEnv);
}
///
/// Rename the database specified by and
/// .
///
/// The file to rename
/// The database to rename
/// The new database name
public static void Rename(
string Filename, string DatabaseName, string NewName) {
Rename(Filename, DatabaseName, NewName, null);
}
///
/// Rename the database specified by and
/// .
///
///
///
/// Applications should not rename databases that are currently in use.
/// If an underlying file is being renamed and logging is currently
/// enabled in the database environment, no database in the file may be
/// open when Rename is called. In particular, some architectures do not
/// permit renaming files with open handles. On these architectures,
/// attempts to rename databases that are currently in use by any thread
/// of control in the system may fail.
///
///
/// Rename should not be called if the rename is intended to be
/// transactionally safe;
/// should be
/// used instead.
///
///
/// The file to rename
/// The database to rename
/// The new database name
///
/// The DatabaseEnvironment the database belongs to
///
public static void Rename(string Filename,
string DatabaseName, string NewName, DatabaseEnvironment DbEnv) {
BaseDatabase db = new BaseDatabase(DbEnv, 0);
db.db.rename(Filename, DatabaseName, NewName, 0);
}
///
/// Flush any cached information to disk.
///
///
///
/// If the database is in memory only, Sync has no effect and will
/// always succeed.
///
///
/// It is important to understand that flushing cached information to
/// disk only minimizes the window of opportunity for corrupted data.
/// Although unlikely, it is possible for database corruption to happen
/// if a system or application crash occurs while writing data to the
/// database. To ensure that database corruption never occurs,
/// applications must either: use transactions and logging with
/// automatic recovery or edit a copy of the database, and once all
/// applications using the database have successfully called
/// , atomically replace
/// the original database with the updated copy.
///
///
public void Sync() {
db.sync(0);
}
///
/// Empty the database, discarding all records it contains.
///
///
/// If the operation occurs in a transactional database, the operation
/// will be implicitly transaction protected.
///
///
/// When called on a database configured with secondary indices,
/// Truncate will truncate the primary database and all secondary
/// indices. A count of the records discarded from the primary database
/// is returned.
///
///
/// The number of records discarded from the database.
///
public uint Truncate() {
return Truncate(null);
}
///
/// Empty the database, discarding all records it contains.
///
///
/// If is null and the operation occurs in a
/// transactional database, the operation will be implicitly transaction
/// protected.
///
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// The number of records discarded from the database.
///
public uint Truncate(Transaction txn) {
uint countp = 0;
db.truncate(Transaction.getDB_TXN(txn), ref countp, 0);
return countp;
}
#endregion Methods
///
/// Release the resources held by this object, and close the database if
/// it's still open.
///
public void Dispose() {
if (isOpen)
this.Close();
if (db != null)
this.db.Dispose();
GC.SuppressFinalize(this);
}
}
}