packages feed

lmdb-simple 0.3.0.0 → 0.3.1.0

raw patch · 7 files changed

+102/−76 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -2,6 +2,29 @@ Simple Haskell API for LMDB =========================== -This is a simple API for the [Lightning Memory-mapped Database][LMDB].+This package allows you to store arbitrary Haskell values in and retrieve them+from a persistent [Lightning Memory-mapped Database][LMDB] on disk.    [LMDB]: https://symas.com/lightning-memory-mapped-database/++LMDB is a high-performance [ACID][]-compliant no-maintenance read-optimized+key-value store. Any Haskell value with a [`Serialise`][Serialise] instance+can be stored in an LMDB database, or used as a key to index one.++  [ACID]: https://en.wikipedia.org/wiki/ACID+  [Serialise]: https://hackage.haskell.org/package/serialise/docs/Codec-Serialise-Tutorial.html#g:3++This package provides a few different APIs for using LMDB:++  * The basic API provides transactional `put` and `get` functions to store+    and retrieve values from an LMDB database.++  * The extended API provides many functions similar to those in `Data.Map`,+    e.g. `lookup`, `insert`, `delete`, `foldr`, and so on.++  * The `View` API provides a read-only snapshot of an LMDB database that can+    be queried from pure code.++  * The `DBRef` API provides a mutable variable similar to `IORef` that is+    tied to a particular key in an LMDB database.+
lmdb-simple.cabal view
@@ -1,6 +1,6 @@  name:                lmdb-simple-version:             0.3.0.0+version:             0.3.1.0  synopsis:            Simple API for LMDB @@ -42,8 +42,8 @@    build-depends:       base >= 4.7 && < 5                      , bytestring >= 0.10 && < 0.11-                     , serialise >= 0.1 && < 0.2                      , lmdb >= 0.2 && < 0.3+                     , serialise >= 0.1 && < 0.2   ghc-options:         -Wall -Wno-name-shadowing -Wno-unused-do-bind   default-language:    Haskell2010   default-extensions:  Trustworthy
src/Database/LMDB/Simple.hs view
@@ -35,7 +35,7 @@ These additional APIs are available:    * "Database.LMDB.Simple.Extra" provides additional functions for querying-    and modifying LMDB databases within the 'Transaction' monad+    and modifying LMDB databases from within the 'Transaction' monad    * "Database.LMDB.Simple.View" provides a read-only snapshot of an LMDB     database that can be accessed from pure code@@ -77,10 +77,6 @@   , SubMode   ) where -import Prelude hiding-  ( lookup-  )- import Control.Concurrent   ( runInBoundThread   )@@ -129,7 +125,6 @@   , isReadOnlyTransaction   , isReadWriteTransaction   )- import qualified Database.LMDB.Simple.Internal as Internal  import Foreign.C
src/Database/LMDB/Simple/DBRef.hs view
@@ -13,32 +13,15 @@   ) where  import Control.Monad-  ( (>=>)-  , void-  )--import Control.Monad.IO.Class-  ( MonadIO (liftIO)+  ( void   )  import Data.ByteString   ( ByteString   ) -import Data.ByteString.Lazy-  ( toStrict-  )--import Data.ByteString.Unsafe-  ( unsafeUseAsCStringLen-  )- import Database.LMDB.Raw   ( MDB_dbi'-  , MDB_val (..)-  , mdb_get'-  , mdb_put'-  , mdb_del'   )  import Database.LMDB.Simple@@ -52,14 +35,10 @@   , ReadWrite   , ReadOnly   , Serialise-  , serialise-  , marshalIn-  , marshalOut-  , defaultWriteFlags-  )--import Foreign-  ( castPtr+  , serialiseBS+  , getBS+  , putBS+  , deleteBS   )  -- | A 'DBRef' is a reference to a particular key within an LMDB database. It@@ -76,32 +55,26 @@ -- environment. newDBRef :: Serialise k          => Environment mode -> Database k a -> k -> IO (DBRef mode a)-newDBRef env (Db _ dbi) = return . Ref env dbi . toStrict . serialise--withVal :: ByteString -> (MDB_val -> IO a) -> IO a-withVal bs f = unsafeUseAsCStringLen bs $ \(ptr, len) ->-  f $ MDB_val (fromIntegral len) (castPtr ptr)+newDBRef env (Db _ dbi) = return . Ref env dbi . serialiseBS  -- | Read the current value of a 'DBRef'. readDBRef :: Serialise a => DBRef mode a -> IO (Maybe a)-readDBRef ref@(Ref env dbi key) = transaction env (tx ref)+readDBRef ref@(Ref env dbi key) = transaction env (tx env ref) -  where tx :: Serialise a => DBRef mode a -> Transaction ReadOnly (Maybe a)-        tx _ = Txn $ \txn -> withVal key $ mdb_get' txn dbi >=>-          maybe (return Nothing) (liftIO . fmap Just . marshalIn)+  where tx :: Serialise a+           => Environment mode -> DBRef mode a -> Transaction ReadOnly (Maybe a)+        tx (Env env) _ = getBS (Db env dbi) key  -- | Write a new value into a 'DBRef'. writeDBRef :: Serialise a => DBRef ReadWrite a -> Maybe a -> IO ()-writeDBRef (Ref env dbi key) = transaction env . maybe delKey putKey+writeDBRef (Ref env dbi key) = transaction env . maybe (delKey env) (putKey env) -  where delKey :: Transaction ReadWrite ()-        delKey = Txn $ \txn -> withVal key $ \kval ->-          void $ mdb_del' txn dbi kval Nothing+  where delKey :: Environment ReadWrite -> Transaction ReadWrite ()+        delKey (Env env) = void $ deleteBS (Db env dbi) key -        putKey :: Serialise a => a -> Transaction ReadWrite ()-        putKey value = Txn $ \txn -> withVal key $ \kval ->-          marshalOut value $ \vval ->  -- FIXME: use mdb_reserve'-          void $ mdb_put' defaultWriteFlags txn dbi kval vval+        putKey :: Serialise a+               => Environment ReadWrite -> a -> Transaction ReadWrite ()+        putKey (Env env) = putBS (Db env dbi) key  -- | Atomically mutate the contents of a 'DBRef'. modifyDBRef_ :: Serialise a => DBRef ReadWrite a -> (Maybe a -> Maybe a) -> IO ()@@ -110,11 +83,12 @@ -- | Atomically mutate the contents of a 'DBRef' and return a value. modifyDBRef :: Serialise a             => DBRef ReadWrite a -> (Maybe a -> (Maybe a, b)) -> IO b-modifyDBRef (Ref env dbi key) = transaction env . tx+modifyDBRef (Ref env dbi key) = transaction env . tx env -  where tx :: Serialise a => (Maybe a -> (Maybe a, b)) -> Transaction ReadWrite b-        tx f = Txn $ \txn -> withVal key $ \kval -> mdb_get' txn dbi kval >>=-          maybe (return Nothing) (fmap Just . marshalIn) >>= \x ->-          let (x', r) = f x in maybe (mdb_del' txn dbi kval Nothing)-            (flip marshalOut $ mdb_put' defaultWriteFlags txn dbi kval) x' >>+  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
src/Database/LMDB/Simple/Internal.hs view
@@ -14,7 +14,7 @@   , isReadOnlyEnvironment   , isReadOnlyTransaction   , isReadWriteTransaction-  , serialise+  , serialiseBS   , marshalOut   , marshalIn   , peekVal@@ -25,8 +25,12 @@   , overwriteFlags   , get   , get'+  , getBS+  , getBS'   , put+  , putBS   , delete+  , deleteBS   ) where  import Codec.Serialise@@ -95,7 +99,9 @@   , copyBytes   ) -import GHC.Exts (Constraint)+import GHC.Exts+  ( Constraint+  )  data ReadWrite data ReadOnly@@ -166,13 +172,22 @@ peekVal :: Serialise v => Ptr MDB_val -> IO v peekVal = peek >=> marshalIn +serialiseLBS :: Serialise v => v -> BSL.ByteString+serialiseLBS = serialise++serialiseBS :: Serialise v => v -> BS.ByteString+serialiseBS = toStrict . serialiseLBS+ marshalIn :: Serialise v => MDB_val -> IO v marshalIn (MDB_val len ptr) =   deserialise . fromStrict <$> packCStringLen (castPtr ptr, fromIntegral len)  marshalOut :: Serialise v => v -> (MDB_val -> IO a) -> IO a-marshalOut value f =-  unsafeUseAsCStringLen (toStrict $ serialise value) $ \(ptr, len) ->+marshalOut = marshalOutBS . serialiseBS++marshalOutBS :: BS.ByteString -> (MDB_val -> IO a) -> IO a+marshalOutBS bs f =+  unsafeUseAsCStringLen bs $ \(ptr, len) ->   f $ MDB_val (fromIntegral len) (castPtr ptr)  copyLazyBS :: BSL.ByteString -> Ptr Word8 -> Int -> IO ()@@ -211,22 +226,36 @@  get :: (Serialise k, Serialise v)     => Database k v -> k -> Transaction mode (Maybe v)-get db key = get' db key >>=-  maybe (return Nothing) (liftIO . fmap Just . marshalIn)+get db = getBS db . serialiseBS  get' :: Serialise k => Database k v -> k -> Transaction mode (Maybe MDB_val)-get' (Db _ dbi) key = Txn $ \txn -> marshalOut key $ mdb_get' txn dbi+get' db = getBS' db . serialiseBS +getBS :: Serialise v+      => Database k v -> BS.ByteString -> Transaction mode (Maybe v)+getBS db keyBS = getBS' db keyBS >>=+  maybe (return Nothing) (liftIO . fmap Just . marshalIn)++getBS' :: Database k v -> BS.ByteString -> Transaction mode (Maybe MDB_val)+getBS' (Db _ dbi) keyBS = Txn $ \txn -> marshalOutBS keyBS $ mdb_get' txn dbi+ put :: (Serialise k, Serialise v)     => Database k v -> k -> v -> Transaction ReadWrite ()-put (Db _ dbi) key value = Txn $ \txn ->-  marshalOut key $ \kval -> do-  let bs = serialise value-      sz = fromIntegral (BSL.length bs)+put db = putBS db . serialiseBS++putBS :: Serialise v+     => Database k v -> BS.ByteString -> v -> Transaction ReadWrite ()+putBS (Db _ dbi) keyBS value = Txn $ \txn ->+  marshalOutBS keyBS $ \kval -> do+  let valueLBS = serialiseLBS value+      sz = fromIntegral (BSL.length valueLBS)   MDB_val len ptr <- mdb_reserve' defaultWriteFlags txn dbi kval sz   let len' = fromIntegral len-  assert (len' == sz) $ copyLazyBS bs ptr len'+  assert (len' == sz) $ copyLazyBS valueLBS ptr len'  delete :: Serialise k => Database k v -> k -> Transaction ReadWrite Bool-delete (Db _ dbi) key = Txn $ \txn ->-  marshalOut key $ \kval -> mdb_del' txn dbi kval Nothing+delete db = deleteBS db . serialiseBS++deleteBS :: Database k v -> BS.ByteString -> Transaction ReadWrite Bool+deleteBS (Db _ dbi) key = Txn $ \txn ->+  marshalOutBS key $ \kval -> mdb_del' txn dbi kval Nothing
test/Database/LMDB/Simple/DBRefSpec.hs view
@@ -22,6 +22,10 @@     (modifyDBRef_ ref (fmap (++ "bar")) >> readDBRef ref)     `shouldReturn` Just "foobar" -  it "can be made empty again" $ \ref ->-    (writeDBRef ref Nothing >> readDBRef ref)+  it "can be emptied with modifyDBRef" $ \ref ->+    (modifyDBRef_ ref (const Nothing) >> readDBRef ref)+    `shouldReturn` Nothing++  it "can be emptied with writeDBRef" $ \ref ->+    (writeDBRef ref (Just "baz") >> writeDBRef ref Nothing >> readDBRef ref)     `shouldReturn` Nothing
test/Database/LMDB/SimpleSpec.hs view
@@ -29,8 +29,9 @@    describe "transactions" $ do     it "aborts" $ \(env, db) ->-      transaction env (put db 0 (Just "zero") >> abort)-      `shouldThrow` (const True :: Selector AbortedTransaction)+      ( do transaction env $ put db 0 Nothing+           transaction env $ put db 0 (Just "zero") >> abort+      ) `shouldThrow` (const True :: Selector AbortedTransaction)      it "rolls back" $ \(env, db) ->       readOnlyTransaction env (get db 0)