module Database.LMDB.Simple.DBRef
( DBRef
, newDBRef
, readDBRef
, writeDBRef
, modifyDBRef_
, modifyDBRef
) where
import Control.Monad
( void
)
import Data.ByteString
( ByteString
)
import Database.LMDB.Raw
( MDB_dbi'
)
import Database.LMDB.Simple
( transaction
)
import Database.LMDB.Simple.Internal
( Environment (..)
, Transaction (..)
, Database (..)
, ReadWrite
, ReadOnly
, Serialise
, serialiseBS
, getBS
, putBS
, deleteBS
)
data DBRef mode a = Ref (Environment mode) MDB_dbi' ByteString
newDBRef :: Serialise k
=> Environment mode -> Database k a -> k -> IO (DBRef mode a)
newDBRef env (Db _ dbi) = return . Ref env dbi . serialiseBS
readDBRef :: Serialise a => DBRef mode a -> IO (Maybe a)
readDBRef ref@(Ref env dbi key) = transaction env (tx env ref)
where tx :: Serialise a
=> Environment mode -> DBRef mode a -> Transaction ReadOnly (Maybe a)
tx (Env env) _ = getBS (Db env dbi) key
writeDBRef :: Serialise a => DBRef ReadWrite a -> Maybe a -> IO ()
writeDBRef (Ref env dbi key) = transaction env . maybe (delKey env) (putKey env)
where delKey :: Environment ReadWrite -> Transaction ReadWrite ()
delKey (Env env) = void $ deleteBS (Db env dbi) key
putKey :: Serialise a
=> Environment ReadWrite -> a -> Transaction ReadWrite ()
putKey (Env env) = putBS (Db env dbi) key
modifyDBRef_ :: Serialise a => DBRef ReadWrite a -> (Maybe a -> Maybe a) -> IO ()
modifyDBRef_ ref f = modifyDBRef ref $ \x -> (f x, ())
modifyDBRef :: Serialise a
=> DBRef ReadWrite a -> (Maybe a -> (Maybe a, b)) -> IO b
modifyDBRef (Ref env dbi key) = transaction env . tx env
where tx :: Serialise a
=> Environment mode -> (Maybe a -> (Maybe a, b))
-> Transaction ReadWrite b
tx (Env env) f = let db = Db env dbi in
getBS db key >>= \x -> let (x', r) = f x in
maybe (void $ deleteBS db key) (putBS db key) x' >>
return r