ppad-lmdb-0.1.0: Minimal bindings to LMDB.
Copyright(c) 2026 Jared Tobin
LicenseMIT
MaintainerJared Tobin <jared@ppad.tech>
Safe HaskellNone
LanguageHaskell2010

Database.LMDB

Description

Minimal bindings to LMDB, an embedded ACID key-value store. The upstream LMDB C source is vendored under cbits/ at release LMDB_0.9.33; no external liblmdb is needed.

LMDB has a single-writer, many-reader transaction model and uses memory mapping for zero-copy reads. This module presents that as a bracketed IO-only interface.

Read-only and read-write transactions are distinguished at the type level via a phantom parameter on Txn, so using a write primitive (e.g. put) on a read transaction is a compile-time error.

Most operations throw LMDBException on error. get and del are the exceptions: they map a missing key onto Nothing and False respectively, since absence is normal control flow.

Synopsis

Environments

data Env Source #

An LMDB environment. Roughly, an open database file (or, with envNoSubdir off, a directory containing one).

data EnvFlags Source #

Configuration for open.

Constructors

EnvFlags 

Fields

  • envMapSize :: !Int

    map size in bytes; LMDB will refuse writes beyond this. The default of 10 MiB is intentionally small — set it to something appropriate for your workload before opening.

  • envMaxDbs :: !Int

    maximum number of named sub-databases. Default 1.

  • envNoSubdir :: !Bool

    if True, treat the path as a regular file rather than a directory containing data.mdb and lock.mdb.

  • envReadOnly :: !Bool

    open the environment read-only.

  • envNoSync :: !Bool

    skip fsync at commit time. Faster, but a crash may lose the last transaction. The database remains internally consistent.

Instances

Instances details
Show EnvFlags Source # 
Instance details

Defined in Database.LMDB

defaultEnvFlags :: EnvFlags Source #

Default EnvFlags: 10 MiB map, one database, directory layout, read-write, syncing at commit.

>>> envMapSize defaultEnvFlags
10485760

open :: FilePath -> EnvFlags -> IO Env Source #

Open an LMDB environment at the given path. The path must already exist (as a directory unless envNoSubdir is set, in which case the file's parent directory must exist).

Throws LMDBException on failure.

>>> env <- open "/tmp/mydb" defaultEnvFlags { envNoSubdir = True }

close :: Env -> IO () Source #

Close an environment. Must not be called while transactions are live.

withEnv :: FilePath -> EnvFlags -> (Env -> IO a) -> IO a Source #

Bracketed environment lifecycle: open the environment, run the action, close on exit (including async exceptions).

>>> withEnv "/tmp/mydb" defaultEnvFlags $ \env -> ...

Transactions

data Txn s Source #

A transaction. The phantom s distinguishes RO from RW so that write operations refuse to type-check against read-only transactions.

data RO Source #

Phantom tag for read-only transactions.

data RW Source #

Phantom tag for read-write transactions.

withReadTxn :: Env -> (Txn RO -> IO a) -> IO a Source #

Run an action in a read-only transaction. The transaction is aborted on exit; read transactions have no work to commit.

>>> withReadTxn env $ \txn -> ...

withWriteTxn :: Env -> (Txn RW -> IO a) -> IO a Source #

Run an action in a read-write transaction. Commits if the action returns normally; aborts on exception.

>>> withWriteTxn env $ \txn -> ...

Databases

data Dbi Source #

A database identifier within an Env.

openDbi Source #

Arguments

:: Txn s 
-> Maybe ByteString

database name; Nothing for the default

-> Bool

create if not present

-> IO Dbi 

Open a database within a transaction. Pass Nothing for the unnamed default database. If the create flag is True, the database is created if it does not already exist — and the transaction must be a read-write transaction.

>>> dbi <- openDbi txn Nothing True

Key-value operations

get Source #

Arguments

:: Txn s 
-> Dbi 
-> ByteString

key

-> IO (Maybe ByteString)

value, if present

Look up a key. Returns Nothing if not found. Other LMDB errors throw LMDBException.

The returned ByteString is a copy of the data; LMDB's memory-mapped buffer is not aliased into Haskell.

>>> get txn dbi "hello"
Just "world"

put Source #

Arguments

:: Txn RW 
-> Dbi 
-> ByteString

key

-> ByteString

value

-> IO () 

Insert or replace a key. Throws LMDBException on failure.

>>> put txn dbi "hello" "world"

del Source #

Arguments

:: Txn RW 
-> Dbi 
-> ByteString

key

-> IO Bool

True if the key was present and removed

Delete a key. Returns True if the key existed and was removed, False if it was already absent.

>>> del txn dbi "hello"
True

Cursors

data Cursor s Source #

A cursor for range-scanning a Dbi.

withCursor :: Txn s -> Dbi -> (Cursor s -> IO a) -> IO a Source #

Bracketed cursor lifecycle: open a cursor over the given Dbi, run the action, close the cursor on exit (including async exceptions).

>>> withCursor txn dbi $ \cur -> ...

cursorFirst :: Cursor s -> IO (Maybe (ByteString, ByteString)) Source #

Position at the first key/value pair, or Nothing on an empty database.

>>> cursorFirst cur
Just ("a","alpha")

cursorLast :: Cursor s -> IO (Maybe (ByteString, ByteString)) Source #

Position at the last key/value pair, or Nothing on an empty database.

cursorNext :: Cursor s -> IO (Maybe (ByteString, ByteString)) Source #

Advance to the next key/value pair, or Nothing if already at the end.

cursorPrev :: Cursor s -> IO (Maybe (ByteString, ByteString)) Source #

Step back to the previous key/value pair, or Nothing if already at the start.

cursorSeek :: Cursor s -> ByteString -> IO (Maybe (ByteString, ByteString)) Source #

Position at the first key greater than or equal to the given key, or Nothing if no such key exists.

>>> cursorSeek cur "m"
Just ("n","november")

Errors

data LMDBException Source #

A typed wrapper around LMDB error codes. LMDBOther carries the raw error code plus the message from mdb_strerror.

Constructors

LMDBKeyExist 
LMDBNotFound

Only seen via Database.LMDB.Internal; the safe layer maps this to Nothing or False instead of throwing.

LMDBMapFull 
LMDBCorrupted 
LMDBPanic 
LMDBVersionMismatch 
LMDBOther !Int !String