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