This package realises a binding to Berkeley DB, originally by Sleepycat Software, now managed by Oracle. The DB library implements modular support for the bottom layers of a database. In can be configured for single-threaded access to a file, multi-threaded access with transactions, remote access as well as database replication.
Berkeley DB is an embedded database. This implies the library provides access to a file containing one or more database tables. The Berkeley DB database tables are always binary, mapping a key to a value. The SWI-Prolog interface to Berkeley DB allows for fast storage of arbitrary Prolog terms including cycles and constraints in the database.
Accessing a database consists of four steps:
Errors reported by the underlying database are mapped to an exception
of the form error(bdb(Code,Message,Object), _)
, where Code is an atom
for well known errors and an integer for less known ones. Message is
the return from the db_strerror()
function and Object is the most
related Prolog object, typically a database or database environment
handle. If Code is an atom, it is the lowercase version of the
associated C macro after string the DB_
prefix. Currently the
following atom-typed codes are defined: lock_deadlock
, runrecovery
,
notfound
, keyempty
, keyexist
, lock_notgranted
and
secondary_bad
.
environment(+Environment)
option. If bdb_init/1 is called,
it must be called before the first call to bdb_open/4 that uses
the default environment. If bdb_init/1 is not called, the
default environment can only handle plain files and does not
support multiple threads, locking, crash recovery, etc.
Initializing a BDB environment always requires the home(+Dir)
option. If the environment contains no databases, the argument
create(true)
must be supplied as well.
The currently supported options are listed below. The name of
the boolean options are derived from the DB flags by dropping
the =DB_= prefix and using lowercase, e.g. DB_INIT_LOCK
becomes init_lock
. For details, please refer to the DB manual.
true
, create any underlying file as required. By
default, no new files are created. This option should be
set for prograns that create new databases.DB_INIT_LOCK
). Implied if transactions
are used.DB_INIT_LOG
). Logging
enables recovery of databases in case of system failure.
Normally it is used in combination with transactions.mp_size(+Size)
or
mp_mmapsize(+Size)
is specified.init_log(true)
.DB_INIT_MPOOL
). The
mp_size
option sets the memory-pool used for
caching, while the mp_mmapsize
controls the maximum size
of a DB file mapped entirely into memory.berkeley_db_svc
. Optionally additional options may be
specified:
DB_ENV->set_thread_count()
.read
, providing
read-only access or update
, providing read/write access.
Options is a list of options. Supported options are below. The
boolean options are passed as flags to DB->open()
. The
option name is derived from the flag name by stripping the
DB_
prefix and converting to lower case. Consult the
Berkeley DB documentation for details.
create(true)
, fail if the database already
exists.bdb_put(DB, f(X), 42)
, we get the following query results:
bdb_get(DB, f(Y), V)
binds Value to 42
, while Y is left
unbound.bdb_get(DB, f(a), V)
fails.bdb_enum(DB, f(a), V)
succeeds, but does not perform any
indexing, i.e., it enumerates all key-value pairs and
performs the unification.error(package(db, deadlock), _)
This exception indicates a deadlock was raised by one of the DB predicates. Deadlocks may arise if multiple processes or threads access the same keys in a different order. The DB infra-structure causes one of the processes involved in the deadlock to abort its transaction. This process may choose to restart the transaction.
For example, a DB application may define {Goal}
to realise
transactions and restart these automatically is a deadlock is
raised:
{Goal} :- catch(bdb_transaction(Goal), E, true), ( var(E) -> true ; E = error(package(db, deadlock), _) -> {Goal} ; throw(E) ).
DB_VERSION_MAJOR*10000 + DB_VERSION_MINOR*100 + DB_VERSION_PATCH
The following predicates are exported from this file while their implementation is defined in imported modules or non-module files loaded by this module.
environment(+Environment)
option. If bdb_init/1 is called,
it must be called before the first call to bdb_open/4 that uses
the default environment. If bdb_init/1 is not called, the
default environment can only handle plain files and does not
support multiple threads, locking, crash recovery, etc.
Initializing a BDB environment always requires the home(+Dir)
option. If the environment contains no databases, the argument
create(true)
must be supplied as well.
The currently supported options are listed below. The name of
the boolean options are derived from the DB flags by dropping
the =DB_= prefix and using lowercase, e.g. DB_INIT_LOCK
becomes init_lock
. For details, please refer to the DB manual.
true
, create any underlying file as required. By
default, no new files are created. This option should be
set for prograns that create new databases.DB_INIT_LOCK
). Implied if transactions
are used.DB_INIT_LOG
). Logging
enables recovery of databases in case of system failure.
Normally it is used in combination with transactions.mp_size(+Size)
or
mp_mmapsize(+Size)
is specified.init_log(true)
.DB_INIT_MPOOL
). The
mp_size
option sets the memory-pool used for
caching, while the mp_mmapsize
controls the maximum size
of a DB file mapped entirely into memory.berkeley_db_svc
. Optionally additional options may be
specified:
DB_ENV->set_thread_count()
.error(package(db, deadlock), _)
This exception indicates a deadlock was raised by one of the DB predicates. Deadlocks may arise if multiple processes or threads access the same keys in a different order. The DB infra-structure causes one of the processes involved in the deadlock to abort its transaction. This process may choose to restart the transaction.
For example, a DB application may define {Goal}
to realise
transactions and restart these automatically is a deadlock is
raised:
{Goal} :- catch(bdb_transaction(Goal), E, true), ( var(E) -> true ; E = error(package(db, deadlock), _) -> {Goal} ; throw(E) ).