<h1>LMDB API</h1>

<h3 id="m:lmdb"><tt><nowiki>
  (import lmdb)
</nowiki></tt></h3>

This [https://www.call-cc.org/|CHICKEN] binding for [https://symas.com/lmdb/|LMDB]
consists of a single module in a shared library of the same name. It
offers a simple, hash-table-like programming interface to key value
databases stored on disk.

<h2>Database Environments</h2>

<h3 id="p:current-database-environment"><tt><nowiki>
  current-database-environment
</nowiki></tt></h3>

A parameter holding the current database environment pointer or
<tt>#f</tt>.

<h3 id="p:database-environment"><tt><nowiki>
  (database-environment? OBJECT) ⇒ BOOLEAN
</nowiki></tt></h3>

Type predicate for database environments.

<h3 id="c:open-database-environment"><tt><nowiki>
  (open-database-environment
   PATH
   [#:mode MODE]
   [#:max-databases MAXDBS]
   [#:max-readers MAXREADERS]
   [#:max-size MAPSIZE]
   [#:fixed-map]
   [#:no-subdirectory]
   [#:read-only]
   [#:write-map]
   [#:no-meta-sync]
   [#:no-sync]
   [#:map-async]
   [#:no-lock]
   [#:no-read-ahead])
  ⇒
  ENVIRONMENT
</nowiki></tt></h3>

Creates a database environment and configures various settings through
setup methods and the open method.

Unless <tt>#:no-subdirectory</tt> is specified or the given
<tt>PATH</tt> already exists, <tt>PATH</tt> is created as a directory
to contain the database environment.

Sets [#p:current-database-environment|<tt>current-database-environment</tt>]
to the newly created environment.

<h3 id="d:close-database-environment"><tt><nowiki>
  (close-database-environment [ENVIRONMENT]) ⇒ VOID
</nowiki></tt></h3>

Closes a database environment and destroys the handle. If no
<tt>ENVIRONMENT</tt> is specified explicitly, closes the current
environment and sets [#p:current-database-environment|<tt>current-database-environment</tt>]
to <tt>#f</tt>.

<h3 id="p:copy-database-environment"><tt><nowiki>
  (copy-database-environment PATH [ENVIRONMENT] [#:compact]) ⇒ VOID
</nowiki></tt></h3>

Copies a database environment to a new <tt>PATH</tt>, optionally
compacting the data. If no <tt>ENVIRONMENT</tt> is specified
explicitly, the current environment is copied.

<h2>Transactions</h2>

<h3 id="p:with-transaction"><tt><nowiki>
  (with-transaction THUNK [ENVIRONMENT] [#:read-only]) ⇒ (values ...)
</nowiki></tt></h3>

Wraps a call to <tt>THUNK</tt> in a transaction. Returns whatever
<tt>(THUNK)</tt> returns. If no <tt>ENVIRONMENT</tt> is specified
explicitly, the current environment is used.

The transaction can optionally be configured as read-only. Read-only
transactions may be nested.

All database operations below have to be executed within a transaction.

The transaction is committed upon normal return from <tt>(THUNK)</tt>
and aborted if <tt>(THUNK)</tt> throws an exception.

<h3 id="p:clear-stale-transactions"><tt><nowiki>
  (clear-stale-transactions [ENVIRONMENT]) ⇒ INTEGER
</nowiki></tt></h3>

Removes stale read-only transactions from the database lockfile (stale
read-write transactions are usually removed automatically). If no
<tt>ENVIRONMENT</tt> is specified explicitly, the current environment is used.

The procedure returns the number of stale lock file entries that were removed.

<h2>Databases</h2>

<h3 id="p:database"><tt><nowiki>
  (database? OBJECT) ⇒ BOOLEAN
</nowiki></tt></h3>

Type predicate for databases.

<h3 id="c:open-database"><tt><nowiki>
  (open-database
   [NAME]
   [#:reverse-key]
   [#:duplicate-sort]
   [#:integer-key]
   [#:duplicate-fixed]
   [#:integer-duplicate]
   [#:reverse-duplicate]
   [#:create])
  ⇒
  DATABASE
</nowiki></tt></h3>

Opens a database and configures various flags.

The name of the database can be omitted if the environment was opened
without <tt>#:max-databases</tt> and consists of only a single default
database.

If a named database does not exist, <tt>#:create</tt> must be specified
when it is first opened.

<h3 id="d:close-database"><tt><nowiki>
  (close-database DATABASE [ENVIRONMENT]) ⇒ VOID
</nowiki></tt></h3>

Closes a database. If the <tt>ENVIRONMENT</tt> containing the database
is not specified explicitly, the current environment is assumed.

<h3 id="p:database-ref"><tt><nowiki>
  (database-ref DATABASE KEY [DEFAULT]) ⇒ VALUE
</nowiki></tt></h3>

Extracts a record with the given <tt>KEY</tt> from the database. If no
record is found and <tt>DEFAULT</tt> is given, it is invoked in case it
is a procedure and returned otherwise. An error is signalled if no
record is found and <tt>DEFAULT</tt> is not given.

Database keys can be strings or blobs. Values extracted from the
database are returned as strings.

<h3 id="p:database-set!"><tt><nowiki>
  (database-set!
   DATABASE KEY VALUE
   [#:no-duplicate]
   [#:no-overwrite]
   [#:append]
   [#:append/duplicate])
  ⇒
  VOID

  (set! (database-ref DATABASE KEY) VALUE) ⇒ VOID
</nowiki></tt></h3>

Stores a record in the database with several optional flags modifying
the behaviour.

For databases configured with support for multiple values per key, new
values are normally added to the set of existing ones. For databases
with one value per key, existing records are replaced.

Database keys and values can be strings or blobs.

<h3 id="p:database-exists"><tt><nowiki>
  (database-exists? DATABASE KEY) ⇒ BOOLEAN
</nowiki></tt></h3>

Checks whether a key exists in the database.

Database keys can be strings or blobs.

<h3 id="p:database-delete!"><tt><nowiki>
  (database-delete! DATABASE KEY [VALUE]) ⇒ VOID
</nowiki></tt></h3>

Deletes a record from the database. An error is signalled if no record
is found.

For databases configured with support for multiple values per key, the
<tt>VALUE</tt> to delete can be specified explicitly. For databases
with one value per key, <tt>VALUE</tt> is ignored.

Database keys and values can be strings or blobs.

<h3 id="p:database-fold"><tt><nowiki>
  (database-fold
   PROC SEED DATABASE
   [#:from START] [#:to< | #:to<= STOP] [#:limit LIMIT])
  ⇒
  (PROC KEY VALUE (... (PROC KEY VALUE SEED)))
</nowiki></tt></h3>

Folds over the records in the database. If <tt>START</tt> is given, only
fold over the records with keys greater than or equal to <tt>START</tt>.
If <tt>STOP</tt> is given, only fold over the records with keys less
than (or equal) to <tt>STOP</tt>. If <tt>LIMIT</tt> is given, process at
most <tt>LIMIT</tt> records before stopping early.

<h3 id="p:database-walk"><tt><nowiki>
  (database-walk
   PROC DATABASE
   [#:from START] [#:to< | #:to<= STOP] [#:limit LIMIT])
  ⇒
  VOID
</nowiki></tt></h3>

Like [#p:database-fold|<tt>database-fold</tt>], but discarding the result.

<h3 id="p:database2alist"><tt><nowiki>
  (database->alist
   DATABASE
   [#:from START] [#:to< | #:to<= STOP] [#:limit LIMIT] [#:duplicate-list])
  ⇒
  ALIST
</nowiki></tt></h3>

Convert the records in the database to an association list. If
<tt>START</tt> is given, only list the records with keys greater than or
equal to <tt>START</tt>. If <tt>STOP</tt> is given, only list the
records with keys less than (or equal) to <tt>STOP</tt>. If
<tt>LIMIT</tt> is given, process at most <tt>LIMIT</tt> records before
stopping early.

Optionally, multiple values for the same key may be folded into lists
rather than producing multiple pairs with the same key in the
association list.

<h3 id="c:alist2database"><tt><nowiki>
  (alist->database
   ALIST [NAME]
   [#:reverse-key]
   [#:duplicate-sort]
   [#:integer-key]
   [#:duplicate-fixed]
   [#:integer-duplicate]
   [#:reverse-duplicate]
   [#:create]
   [#:no-duplicate]
   [#:no-overwrite]
   [#:append]
   [#:append/duplicate])
  ⇒
  DATABASE
</nowiki></tt></h3>

Convert an association list into records in a database. The procedure
accepts the combined flag arguments of [#c:open-database|<tt>open-database</tt>]
and [#p:database-set!|<tt>database-set!</tt>]. The procedure returns a
new handle to the database indicated by the given <tt>NAME</tt> or to
the default database.

<tt>ALIST</tt> must contain pairs of keys and values. Keys can be
strings or blobs. Values can be strings, blobs or lists of strings and
blobs. If a value is a list, all its elements are inserted into the
database with the same key.

If <tt>ALIST</tt> was generated by [#p:database2alist|<tt>database->alist</tt>],
it is safe to pass <tt>#:append</tt> or <tt>#:append/duplicate</tt> to
this procedure.