lmdb

Minimal LMDB bindings for Haskell.
git clone git://git.ppad.tech/lmdb.git
Log | Files | Refs | README | LICENSE

Internal.hs (6863B)


      1 {-# OPTIONS_HADDOCK not-home #-}
      2 {-# LANGUAGE CApiFFI #-}
      3 
      4 -- |
      5 -- Module: Database.LMDB.Internal
      6 -- Copyright: (c) 2026 Jared Tobin
      7 -- License: MIT
      8 -- Maintainer: Jared Tobin <jared@ppad.tech>
      9 --
     10 -- Raw FFI declarations and constants for the LMDB C API. This module
     11 -- is exposed for power users; prefer "Database.LMDB" for the safe,
     12 -- bracketed interface.
     13 
     14 module Database.LMDB.Internal (
     15   -- * Opaque handles
     16     MDB_env
     17   , MDB_txn
     18   , MDB_dbi
     19   , MDB_cursor
     20 
     21   -- * Value pair
     22   , MDB_val(..)
     23 
     24   -- * Environment flags
     25   , _MDB_NOSUBDIR
     26   , _MDB_NOSYNC
     27   , _MDB_RDONLY
     28   , _MDB_NOMETASYNC
     29   , _MDB_NOTLS
     30 
     31   -- * Database open flags
     32   , _MDB_CREATE
     33 
     34   -- * Put flags
     35   , _MDB_NOOVERWRITE
     36   , _MDB_APPEND
     37 
     38   -- * Cursor operations
     39   , _MDB_FIRST
     40   , _MDB_LAST
     41   , _MDB_NEXT
     42   , _MDB_PREV
     43   , _MDB_SET
     44   , _MDB_SET_RANGE
     45   , _MDB_GET_CURRENT
     46 
     47   -- * Error codes
     48   , _MDB_SUCCESS
     49   , _MDB_KEYEXIST
     50   , _MDB_NOTFOUND
     51   , _MDB_MAP_FULL
     52   , _MDB_CORRUPTED
     53   , _MDB_PANIC
     54   , _MDB_VERSION_MISMATCH
     55   , _MDB_INVALID
     56   , _MDB_BAD_TXN
     57   , _MDB_BAD_VALSIZE
     58   , _MDB_BAD_DBI
     59 
     60   -- * Environment lifecycle
     61   , mdb_env_create
     62   , mdb_env_open
     63   , mdb_env_close
     64   , mdb_env_set_mapsize
     65   , mdb_env_set_maxdbs
     66   , mdb_env_sync
     67 
     68   -- * Transactions
     69   , mdb_txn_begin
     70   , mdb_txn_commit
     71   , mdb_txn_abort
     72 
     73   -- * Databases
     74   , mdb_dbi_open
     75   , mdb_dbi_close
     76 
     77   -- * Key-value operations
     78   , mdb_get
     79   , mdb_put
     80   , mdb_del
     81 
     82   -- * Cursors
     83   , mdb_cursor_open
     84   , mdb_cursor_close
     85   , mdb_cursor_get
     86 
     87   -- * Diagnostics
     88   , mdb_strerror
     89   ) where
     90 
     91 import Foreign.C.String (CString)
     92 import Foreign.C.Types
     93   (CInt(..), CUInt(..), CSize(..), CChar(..))
     94 import Foreign.Ptr (Ptr)
     95 import Foreign.Storable (Storable(..))
     96 import System.Posix.Types (CMode(..))
     97 
     98 -- opaque handles -------------------------------------------------------------
     99 
    100 data MDB_env
    101 data MDB_txn
    102 data MDB_cursor
    103 
    104 -- | LMDB's database identifier is a plain @unsigned int@ value type,
    105 --   not a pointer.
    106 type MDB_dbi = CUInt
    107 
    108 -- value pair -----------------------------------------------------------------
    109 
    110 -- | The key-or-value pair LMDB passes across the FFI boundary.
    111 data MDB_val = MDB_val
    112   { mvSize :: !CSize
    113   , mvData :: !(Ptr CChar)
    114   }
    115 
    116 instance Storable MDB_val where
    117   sizeOf    _ = 2 * sizeOf (undefined :: Ptr ())
    118   {-# INLINE sizeOf #-}
    119   alignment _ = alignment   (undefined :: Ptr ())
    120   {-# INLINE alignment #-}
    121   peek p = do
    122     sz <- peekByteOff p 0
    123     pd <- peekByteOff p (sizeOf (undefined :: Ptr ()))
    124     pure (MDB_val sz pd)
    125   {-# INLINE peek #-}
    126   poke p (MDB_val sz pd) = do
    127     pokeByteOff p 0 sz
    128     pokeByteOff p (sizeOf (undefined :: Ptr ())) pd
    129   {-# INLINE poke #-}
    130 
    131 -- environment flags ----------------------------------------------------------
    132 
    133 _MDB_NOSUBDIR, _MDB_NOSYNC, _MDB_RDONLY, _MDB_NOMETASYNC, _MDB_NOTLS
    134   :: CUInt
    135 _MDB_NOSUBDIR    = 0x4000
    136 _MDB_NOSYNC      = 0x10000
    137 _MDB_RDONLY      = 0x20000
    138 _MDB_NOMETASYNC  = 0x40000
    139 _MDB_NOTLS       = 0x200000
    140 
    141 -- database open flags --------------------------------------------------------
    142 
    143 _MDB_CREATE :: CUInt
    144 _MDB_CREATE = 0x40000
    145 
    146 -- put flags ------------------------------------------------------------------
    147 
    148 _MDB_NOOVERWRITE, _MDB_APPEND :: CUInt
    149 _MDB_NOOVERWRITE = 0x10
    150 _MDB_APPEND      = 0x20000
    151 
    152 -- cursor ops -----------------------------------------------------------------
    153 
    154 -- These mirror the enum MDB_cursor_op declared in lmdb.h. We only
    155 -- bind the operations the safe wrapper currently uses; add more as
    156 -- needed.
    157 
    158 _MDB_FIRST, _MDB_LAST, _MDB_NEXT, _MDB_PREV
    159   , _MDB_SET, _MDB_SET_RANGE, _MDB_GET_CURRENT :: CInt
    160 _MDB_FIRST       = 0
    161 _MDB_LAST        = 6
    162 _MDB_NEXT        = 8
    163 _MDB_PREV        = 12
    164 _MDB_SET         = 15
    165 _MDB_SET_RANGE   = 17  -- index per MDB_cursor_op enum (post-DUP entries)
    166 _MDB_GET_CURRENT = 4
    167 
    168 -- error codes ----------------------------------------------------------------
    169 
    170 _MDB_SUCCESS, _MDB_KEYEXIST, _MDB_NOTFOUND, _MDB_MAP_FULL
    171   , _MDB_CORRUPTED, _MDB_PANIC, _MDB_VERSION_MISMATCH, _MDB_INVALID
    172   , _MDB_BAD_TXN, _MDB_BAD_VALSIZE, _MDB_BAD_DBI :: CInt
    173 _MDB_SUCCESS          = 0
    174 _MDB_KEYEXIST         = -30799
    175 _MDB_NOTFOUND         = -30798
    176 _MDB_CORRUPTED        = -30796
    177 _MDB_PANIC            = -30795
    178 _MDB_VERSION_MISMATCH = -30794
    179 _MDB_INVALID          = -30793
    180 _MDB_MAP_FULL         = -30792
    181 _MDB_BAD_TXN          = -30782
    182 _MDB_BAD_VALSIZE      = -30781
    183 _MDB_BAD_DBI          = -30780
    184 
    185 -- foreign imports ------------------------------------------------------------
    186 
    187 -- environment lifecycle
    188 
    189 foreign import capi "lmdb.h mdb_env_create"
    190   mdb_env_create :: Ptr (Ptr MDB_env) -> IO CInt
    191 
    192 foreign import capi "lmdb.h mdb_env_open"
    193   mdb_env_open
    194     :: Ptr MDB_env -> CString -> CUInt -> CMode -> IO CInt
    195 
    196 foreign import capi "lmdb.h mdb_env_close"
    197   mdb_env_close :: Ptr MDB_env -> IO ()
    198 
    199 foreign import capi "lmdb.h mdb_env_set_mapsize"
    200   mdb_env_set_mapsize :: Ptr MDB_env -> CSize -> IO CInt
    201 
    202 foreign import capi "lmdb.h mdb_env_set_maxdbs"
    203   mdb_env_set_maxdbs :: Ptr MDB_env -> MDB_dbi -> IO CInt
    204 
    205 foreign import capi "lmdb.h mdb_env_sync"
    206   mdb_env_sync :: Ptr MDB_env -> CInt -> IO CInt
    207 
    208 -- transactions
    209 
    210 foreign import capi "lmdb.h mdb_txn_begin"
    211   mdb_txn_begin
    212     :: Ptr MDB_env
    213     -> Ptr MDB_txn      -- parent (NULL for top-level)
    214     -> CUInt            -- flags
    215     -> Ptr (Ptr MDB_txn)
    216     -> IO CInt
    217 
    218 foreign import capi "lmdb.h mdb_txn_commit"
    219   mdb_txn_commit :: Ptr MDB_txn -> IO CInt
    220 
    221 foreign import capi "lmdb.h mdb_txn_abort"
    222   mdb_txn_abort :: Ptr MDB_txn -> IO ()
    223 
    224 -- databases
    225 
    226 foreign import capi "lmdb.h mdb_dbi_open"
    227   mdb_dbi_open
    228     :: Ptr MDB_txn
    229     -> CString          -- name; NULL for the default unnamed db
    230     -> CUInt            -- flags
    231     -> Ptr MDB_dbi
    232     -> IO CInt
    233 
    234 foreign import capi "lmdb.h mdb_dbi_close"
    235   mdb_dbi_close :: Ptr MDB_env -> MDB_dbi -> IO ()
    236 
    237 -- key-value ops
    238 
    239 foreign import capi "lmdb.h mdb_get"
    240   mdb_get
    241     :: Ptr MDB_txn -> MDB_dbi -> Ptr MDB_val -> Ptr MDB_val -> IO CInt
    242 
    243 foreign import capi "lmdb.h mdb_put"
    244   mdb_put
    245     :: Ptr MDB_txn
    246     -> MDB_dbi
    247     -> Ptr MDB_val      -- key
    248     -> Ptr MDB_val      -- data
    249     -> CUInt            -- flags
    250     -> IO CInt
    251 
    252 foreign import capi "lmdb.h mdb_del"
    253   mdb_del
    254     :: Ptr MDB_txn
    255     -> MDB_dbi
    256     -> Ptr MDB_val      -- key
    257     -> Ptr MDB_val      -- data; NULL except for MDB_DUPSORT
    258     -> IO CInt
    259 
    260 -- cursors
    261 
    262 foreign import capi "lmdb.h mdb_cursor_open"
    263   mdb_cursor_open
    264     :: Ptr MDB_txn -> MDB_dbi -> Ptr (Ptr MDB_cursor) -> IO CInt
    265 
    266 foreign import capi "lmdb.h mdb_cursor_close"
    267   mdb_cursor_close :: Ptr MDB_cursor -> IO ()
    268 
    269 foreign import capi "lmdb.h mdb_cursor_get"
    270   mdb_cursor_get
    271     :: Ptr MDB_cursor
    272     -> Ptr MDB_val      -- key (in/out)
    273     -> Ptr MDB_val      -- data (out)
    274     -> CInt             -- MDB_cursor_op
    275     -> IO CInt
    276 
    277 -- diagnostics
    278 
    279 foreign import capi "lmdb.h mdb_strerror"
    280   mdb_strerror :: CInt -> IO CString