tokyocabinet-haskell 0.0.4 → 0.0.5
raw patch · 10 files changed
+508/−191 lines, 10 files
Files
- Changes +10/−0
- Database/TokyoCabinet/ADB.hs +211/−0
- Database/TokyoCabinet/ADB/C.hsc +120/−0
- examples/MyApp1/TokyoCabinet.hs +0/−92
- examples/MyApp2/TokyoCabinet.hs +0/−93
- examples/TCRError.hs +61/−0
- examples/TCReader.hs +53/−0
- examples/tcadb.hs +31/−0
- examples/withTC.hs +13/−0
- tokyocabinet-haskell.cabal +9/−6
+ Changes view
@@ -0,0 +1,10 @@+Revision history for tokyocabinet-haskell package.++0.0.5 Sat May 09 06:00:00 UTC 2009+ - added ADB interface.++0.0.4 Mon Apr 27 14:01:17 UTC 2009+ - added TDB and TDBQRY support.++0.0.1 Tue Mar 31 01:32:18 UTC 2009+ - initial release
+ Database/TokyoCabinet/ADB.hs view
@@ -0,0 +1,211 @@+-- | Interface to TC's Abstract DataBase. See also,+-- <http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi> for details+module Database.TokyoCabinet.ADB+ (+ -- $doc+ ADB+ , ECODE(..)+ , new+ , delete+ , open+ , close+ , put+ , putkeep+ , putcat+ , out+ , get+ , vsiz+ , iterinit+ , iternext+ , fwmkeys+ , addint+ , adddouble+ , sync+ , optimize+ , vanish+ , copy+ , tranbegin+ , trancommit+ , tranabort+ , path+ , rnum+ , size+ , misc+ ) where++import Data.Word++import Foreign.C.String+import Foreign.ForeignPtr++import Database.TokyoCabinet.ADB.C+import Database.TokyoCabinet.Error+import Database.TokyoCabinet.Internal+import Database.TokyoCabinet.Storable+import Database.TokyoCabinet.Sequence++-- $doc+-- Example+--+-- @+-- import Control.Monad+-- import Database.TokyoCabinet.ADB+-- @+--+-- @+-- main = do adb <- new+-- -- open the abstract database object+-- -- \"+\" means that the database will be an on-memory tree database+-- open adb \"+\" >>= err adb \"open failed\"+-- -- store records+-- puts adb [(\"foo\", \"hop\"), (\"bar\", \"step\"), (\"baz\", \"jump\")] >>=+-- err adb \"put failed\" . (all id)+-- -- retrieve records+-- get_print adb \"foo\"+-- -- traverse records+-- iterinit adb+-- iter adb >>= mapM_ (\k -> putStr (k++\":\") >> get_print adb k)+-- -- close the database+-- close adb >>= err adb \"close failed\"+-- where+-- puts :: ADB -> [(String, String)] -> IO [Bool]+-- puts adb = mapM (uncurry $ put adb)+-- @+--+-- @+-- get_print :: ADB -> String -> IO ()+-- get_print adb key = get adb key >>=+-- maybe (error \"something goes wrong\") putStrLn+-- @+--+-- @+-- err :: ADB -> String -> Bool -> IO ()+-- err adb msg = flip unless $ error msg+-- @+--+-- @+-- iter :: ADB -> IO [String]+-- iter adb = iternext adb >>=+-- maybe (return []) (\x -> return . (x:) =<< iter adb)+-- @+--++data ADB = ADB { unTCADB :: !(ForeignPtr ADB') }++-- | Create a Abstract database object. +new :: IO ADB+new = ADB `fmap` (c_tcadbnew >>= newForeignPtr tcadbFinalizer)++-- | Free ADB resource forcibly. +-- ADB is kept by ForeignPtr, so Haskell runtime GC cleans up memory for+-- almost situation. Most always, you don't need to call this. +-- After call this, you must not touch ADB object. Its behavior is undefined.+delete :: ADB -> IO ()+delete adb = finalizeForeignPtr (unTCADB adb)++-- | Open an abstract dataabse.+open :: ADB -> String -> IO Bool+open adb name = withForeignPtr (unTCADB adb) $ (withCString name) . c_tcadbopen++-- | Close an abstract database object.+close :: ADB -> IO Bool+close adb = withForeignPtr (unTCADB adb) c_tcadbclose++-- | Stora a record into an abstract database object. +put :: (Storable k, Storable v) => ADB -> k -> v -> IO Bool+put = putHelper c_tcadbput unTCADB++-- | Store a new record into an abstract database object.+putkeep :: (Storable k, Storable v) => ADB -> k -> v -> IO Bool+putkeep = putHelper c_tcadbputkeep unTCADB++-- | Concatenate a value at the end of the existing record in an+-- abstract database object.+putcat :: (Storable k, Storable v) => ADB -> k -> v -> IO Bool+putcat = putHelper c_tcadbputcat unTCADB++-- | Remove a record of an abstract database object.+out :: (Storable k) => ADB -> k -> IO Bool+out = outHelper c_tcadbout unTCADB++-- | Retrieve a record in an abstract database object.+get :: (Storable k, Storable v) => ADB -> k -> IO (Maybe v)+get = getHelper c_tcadbget unTCADB++-- | Get the size of the value of a record in an abstract database object.+vsiz :: (Storable k) => ADB -> k -> IO (Maybe Int)+vsiz = vsizHelper c_tcadbvsiz unTCADB++-- | Initialize the iterator of an abstract database object.+iterinit :: ADB -> IO Bool+iterinit adb = withForeignPtr (unTCADB adb) c_tcadbiterinit++-- | Get the next key of the iterator of an abstract database object.+iternext :: (Storable k) => ADB -> IO (Maybe k)+iternext = iternextHelper c_tcadbiternext unTCADB++-- | Get forward matching keys in an abstract database object.+fwmkeys :: (Storable k1, Storable k2, Sequence q) =>+ ADB -> k1 -> Int -> IO (q k2)+fwmkeys = fwmHelper c_tcadbfwmkeys unTCADB++-- | Add an integer to a record in an abstract database object.+addint :: (Storable k) => ADB -> k -> Int -> IO (Maybe Int)+addint = addHelper c_tcadbaddint unTCADB fromIntegral fromIntegral (== cINT_MIN)++-- | Add a real number to a record in an abstract database object.+adddouble :: (Storable k) => ADB -> k -> Double -> IO (Maybe Double)+adddouble = addHelper c_tcadbadddouble unTCADB realToFrac realToFrac isNaN++-- | Synchronize updated contents of an abstract database object with+-- the file and the device.+sync :: ADB -> IO Bool+sync adb = withForeignPtr (unTCADB adb) c_tcadbsync++-- | Optimize the storage of an abstract database object.+optimize :: ADB -> String -> IO Bool+optimize adb params =+ withForeignPtr (unTCADB adb) $ (withCString params) . c_tcadboptimize++-- | Remove all records of an abstract database object.+vanish :: ADB -> IO Bool+vanish adb = withForeignPtr (unTCADB adb) c_tcadbvanish++-- | Copy the database file of an abstract database object.+copy :: ADB -> String -> IO Bool+copy = copyHelper c_tcadbcopy unTCADB++-- | Begin the transaction of an abstract database object.+tranbegin :: ADB -> IO Bool+tranbegin adb = withForeignPtr (unTCADB adb) c_tcadbtranbegin++-- | Commit the transaction of an abstract database object.+trancommit :: ADB -> IO Bool+trancommit adb = withForeignPtr (unTCADB adb) c_tcadbtrancommit++-- | Abort the transaction of an abstract database object.+tranabort :: ADB -> IO Bool+tranabort adb = withForeignPtr (unTCADB adb) c_tcadbtranabort++-- | Get the file path of an abstract database object.+path :: ADB -> IO (Maybe String)+path = pathHelper c_tcadbpath unTCADB++-- | Get the number of records of an abstract database object.+rnum :: ADB -> IO Word64+rnum adb = withForeignPtr (unTCADB adb) c_tcadbrnum++-- | Get the size of the database of an abstract database object.+size :: ADB -> IO Word64+size adb = withForeignPtr (unTCADB adb) c_tcadbsize++-- | Call a versatile function for miscellaneous operations of an+-- abstract database object.+misc :: (Storable a, Storable b, Sequence q1, Sequence q2) =>+ ADB -> String -> q1 a -> IO (q2 b)+misc adb name args =+ withForeignPtr (unTCADB adb) $ \adb' ->+ withCString name $ \name' ->+ withList args $ \args' -> do+ ret <- c_tcadbmisc adb' name' args'+ peekList' ret
+ Database/TokyoCabinet/ADB/C.hsc view
@@ -0,0 +1,120 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+module Database.TokyoCabinet.ADB.C where++import Data.Word++import Foreign.Ptr+import Foreign.C.Types+import Foreign.C.String++import Database.TokyoCabinet.List.C (LIST)++#include <tcadb.h>++data ADB'++foreign import ccall safe "tcadbnew"+ c_tcadbnew :: IO (Ptr ADB')++foreign import ccall safe "tcadbdel"+ c_tcadbdel :: Ptr ADB' -> IO ()++foreign import ccall safe "&tcadbdel"+ tcadbFinalizer :: FunPtr (Ptr ADB' -> IO ())++foreign import ccall safe "tcadbopen"+ c_tcadbopen :: Ptr ADB' -> CString -> IO Bool++foreign import ccall safe "tcadbclose"+ c_tcadbclose :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbput"+ c_tcadbput :: Ptr ADB' -> Ptr Word8 -> CInt -> Ptr Word8 -> CInt -> IO Bool++foreign import ccall safe "tcadbput2"+ c_tcadbput2 :: Ptr ADB' -> CString -> CString -> IO Bool++foreign import ccall safe "tcadbputkeep"+ c_tcadbputkeep :: Ptr ADB' -> Ptr Word8 -> CInt -> Ptr Word8 -> CInt -> IO Bool++foreign import ccall safe "tcadbputkeep2"+ c_tcadbputkeep2 :: Ptr ADB' -> CString -> CString -> IO Bool++foreign import ccall safe "tcadbputcat"+ c_tcadbputcat :: Ptr ADB' -> Ptr Word8 -> CInt -> Ptr Word8 -> CInt -> IO Bool++foreign import ccall safe "tcadbputcat2"+ c_tcadbputcat2 :: Ptr ADB' -> CString -> CString -> IO Bool++foreign import ccall safe "tcadbout"+ c_tcadbout :: Ptr ADB' -> Ptr Word8 -> CInt -> IO Bool++foreign import ccall safe "tcadbout2"+ c_tcadbout2 :: Ptr ADB' -> CString -> IO Bool++foreign import ccall safe "tcadbget"+ c_tcadbget :: Ptr ADB' -> Ptr Word8 -> CInt -> Ptr CInt -> IO (Ptr Word8)++foreign import ccall safe "tcadbget2"+ c_tcadbget2 :: Ptr ADB' -> CString -> IO CString++foreign import ccall safe "tcadbvsiz"+ c_tcadbvsiz :: Ptr ADB' -> Ptr Word8 -> CInt -> IO CInt++foreign import ccall safe "tcadbvsiz2"+ c_tcadbvsiz2 :: Ptr ADB' -> CString -> IO CInt++foreign import ccall safe "tcadbiterinit"+ c_tcadbiterinit :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbiternext"+ c_tcadbiternext :: Ptr ADB' -> Ptr CInt -> IO (Ptr Word8)++foreign import ccall safe "tcadbiternext2"+ c_tcadbiternext2 :: Ptr ADB' -> IO CString++foreign import ccall safe "tcadbfwmkeys"+ c_tcadbfwmkeys :: Ptr ADB' -> Ptr Word8 -> CInt -> CInt -> IO (Ptr LIST)++foreign import ccall safe "tcadbfwmkeys2"+ c_tcadbfwmkeys2 :: Ptr ADB' -> CString -> CInt -> IO (Ptr LIST)++foreign import ccall safe "tcadbaddint"+ c_tcadbaddint :: Ptr ADB' -> Ptr Word8 -> CInt -> CInt -> IO CInt++foreign import ccall safe "tcadbadddouble"+ c_tcadbadddouble :: Ptr ADB' -> Ptr Word8 -> CInt -> CDouble -> IO CDouble++foreign import ccall safe "tcadbsync"+ c_tcadbsync :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadboptimize"+ c_tcadboptimize :: Ptr ADB' -> CString -> IO Bool++foreign import ccall safe "tcadbvanish"+ c_tcadbvanish :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbcopy"+ c_tcadbcopy :: Ptr ADB' -> CString -> IO Bool++foreign import ccall safe "tcadbtranbegin"+ c_tcadbtranbegin :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbtrancommit"+ c_tcadbtrancommit :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbtranabort"+ c_tcadbtranabort :: Ptr ADB' -> IO Bool++foreign import ccall safe "tcadbpath"+ c_tcadbpath :: Ptr ADB' -> IO CString++foreign import ccall safe "tcadbrnum"+ c_tcadbrnum :: Ptr ADB' -> IO Word64++foreign import ccall safe "tcadbsize"+ c_tcadbsize :: Ptr ADB' -> IO Word64++foreign import ccall safe "tcadbmisc"+ c_tcadbmisc :: Ptr ADB' -> CString -> Ptr LIST -> IO (Ptr LIST)+
− examples/MyApp1/TokyoCabinet.hs
@@ -1,92 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-module MyApp1.TokyoCabinet- (- TCM- , runTCM- , new- , open- , close- , put- , putcat- , putkeep- , get- , out- , iterinit- , iternext- , fwmkeys- , rnum- , size- , liftT- , TC.defaultExtension- , TCDB- , HDB- , BDB- , FDB- , OpenMode(..)- ) where--import Data.Int--import Control.Monad-import Control.Monad.Reader--import Database.TokyoCabinet.Storable-import Database.TokyoCabinet (TCDB, FDB, BDB, HDB, OpenMode(..))-import qualified Database.TokyoCabinet as TC--newtype TCM tc a =- TCM { unTCM :: ReaderT tc TC.TCM a } deriving (Monad, MonadReader tc)--runTCM :: (TCDB tc) => TCM tc a -> tc -> IO a-runTCM tcm tc = TC.runTCM $ runReaderT (unTCM tcm) tc--new :: (TCDB tc) => IO tc-new = TC.runTCM TC.new--liftT :: (TCDB tc) => TC.TCM a -> TCM tc a-liftT = TCM . lift--open :: (TCDB tc) => String -> [OpenMode] -> TCM tc Bool-open name mode = do tc <- ask- liftT $ TC.open tc name mode--close :: (TCDB tc) => TCM tc Bool-close = ask >>= liftT . TC.close--put :: (TCDB tc, Storable k, Storable v) => k -> v -> TCM tc Bool-put key val = do tc <- ask- liftT $ TC.put tc key val--putcat :: (TCDB tc, Storable k, Storable v) => k -> v -> TCM tc Bool-putcat key val = do tc <- ask- liftT $ TC.putcat tc key val--putkeep :: (TCDB tc, Storable k, Storable v) => k -> v -> TCM tc Bool-putkeep key val = do tc <- ask- liftT $ TC.putkeep tc key val--get :: (TCDB tc, Storable k, Storable v) => k -> TCM tc (Maybe v)-get key = do tc <- ask- liftT $ TC.get tc key--out :: (TCDB tc, Storable k) => k -> TCM tc Bool-out key = do tc <- ask- liftT $ TC.out tc key--iterinit :: (TCDB tc) => TCM tc Bool-iterinit = ask >>= liftT . TC.iterinit--iternext :: (TCDB tc, Storable v) => TCM tc (Maybe v)-iternext = ask >>= liftT . TC.iternext--fwmkeys :: (TCDB tc, Storable k1, Storable k2) => k1 -> Int -> TCM tc [k2]-fwmkeys key maxn = do tc <- ask- liftT $ TC.fwmkeys tc key maxn--rnum :: (TCDB tc) => TCM tc Int64-rnum = do tc <- ask- liftT $ TC.rnum tc--size :: (TCDB tc) => TCM tc Int64-size = do tc <- ask- liftT $ TC.size tc
− examples/MyApp2/TokyoCabinet.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-module MyApp2.TokyoCabinet- (- TCDB- , HDB- , BDB- , FDB- , TCM- , runTCM- , new- , open- , close- , put- , get- , TC.defaultExtension- , ECODE(..)- , OpenMode(..)- ) where--import Control.Monad.Error-import Control.Monad.Reader--import Database.TokyoCabinet- (- OpenMode(..)- , TCDB- , HDB- , BDB- , FDB- )--import Database.TokyoCabinet.Error-import Database.TokyoCabinet.Storable-import qualified Database.TokyoCabinet as TC--instance Error ECODE where- noMsg = ESUCCESS- strMsg "ESUCCESS" = ESUCCESS- strMsg "ETHREAD" = ETHREAD- strMsg "EINVALID" = EINVALID- strMsg "ENOFILE" = ENOFILE- strMsg "ENOPERM" = ENOPERM- strMsg "EMETA" = EMETA- strMsg "ERHEAD" = ERHEAD- strMsg "EOPEN" = EOPEN- strMsg "ECLOSE" = ECLOSE- strMsg "ETRUNC" = ETRUNC- strMsg "ESYNC" = ESYNC- strMsg "ESTAT" = ESTAT- strMsg "ESEEK" = ESEEK- strMsg "EREAD" = EREAD- strMsg "EWRITE" = EWRITE- strMsg "EMMAP" = EMMAP- strMsg "ELOCK" = ELOCK- strMsg "EUNLINK" = EUNLINK- strMsg "ERENAME" = ERENAME- strMsg "EMKDIR" = EMKDIR- strMsg "ERMDIR" = ERMDIR- strMsg "EKEEP" = EKEEP- strMsg "ENOREC" = ENOREC- strMsg _ = EMISC--newtype TCM tc a = TCM { unTCM :: ErrorT ECODE (ReaderT tc TC.TCM) a }- deriving (Monad, MonadIO, MonadReader tc, MonadError ECODE)--runTCM :: (TCDB tc) => TCM tc a -> tc -> IO (Either ECODE a)-runTCM tcm tc = TC.runTCM $ runReaderT (runErrorT $ unTCM tcm) tc--liftT :: (TCDB tc) => TC.TCM a -> TCM tc a-liftT = TCM . lift . lift--throwTCError :: (TCDB tc) => tc -> Bool -> TCM tc ()-throwTCError tc False = (liftT $ TC.ecode tc) >>= throwError-throwTCError _ _ = return ()--new :: (TCDB tc) => IO tc-new = TC.runTCM TC.new--open :: (TCDB tc) => String -> [OpenMode] -> TCM tc ()-open name mode = do tc <- ask- (liftT $ TC.open tc name mode) >>= throwTCError tc--close :: (TCDB tc) => TCM tc ()-close = do tc <- ask- (liftT $ TC.close tc) >>= throwTCError tc--put :: (TCDB tc, Storable k, Storable v) => k -> v -> TCM tc ()-put key val = do tc <- ask- (liftT $ TC.put tc key val) >>= throwTCError tc--get :: (TCDB tc, Storable k, Storable v) => k -> TCM tc (Maybe v)-get key = do tc <- ask- liftT $ TC.get tc key
+ examples/TCRError.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module TCRError where++import Control.Monad.Reader+import Control.Monad.Error++import Database.TokyoCabinet+ (+ TCM+ , runTCM+ , new+ , OpenMode(..)+ , TCDB+ , HDB+ , BDB+ , FDB+ )++import Database.TokyoCabinet.Storable+import qualified Database.TokyoCabinet as TC++newtype TCRError tc e a =+ TCRError { runTCRError :: ErrorT e (ReaderT tc TCM) a}+ deriving (Monad, MonadReader tc, MonadError e)++runTCRE :: TCRError tc e a -> tc -> TCM (Either e a)+runTCRE = runReaderT . runErrorT . runTCRError++liftT :: (Error e) => TCM a -> TCRError tc e a+liftT = TCRError . lift . lift++open :: (TCDB tc) => String -> [OpenMode] -> TCRError tc String ()+open name mode = do tc <- ask+ res <- liftT $ TC.open tc name mode+ if res then return () else throwError "open failed"+++close :: (TCDB tc) => TCRError tc String ()+close = ask >>= liftT . TC.close >>= \res ->+ if res then return () else throwError "close failed"++put :: (TCDB tc) => String -> String -> TCRError tc String ()+put key val = do tc <- ask+ res <- liftT $ TC.put tc key val+ if res then return () else throwError "put failed"++get :: (TCDB tc) => String -> TCRError tc String (Maybe String)+get key = do tc <- ask+ liftT $ TC.get tc key+ ++kvstore :: (TCDB tc) => [(String, String)] -> TCRError tc String ()+kvstore kv = do open "abcd.tch" [OREADER]+ mapM_ (uncurry put) kv+ close++main :: IO ()+main = runTCM $ do h <- new :: TCM BDB+ let kv = [("foo", "100"), ("bar", "200")]+ flip runTCRE h $ catchError (kvstore kv) (\e -> error e)+ >> return ()
+ examples/TCReader.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module TCReader where++import Database.TokyoCabinet.Storable+import Control.Monad+import Control.Monad.Reader++import Database.TokyoCabinet+ (+ TCM+ , TCDB+ , HDB+ , BDB+ , FDB+ , new+ , runTCM+ , OpenMode(..)+ )++import qualified Database.TokyoCabinet as TC++newtype TCReader tc a =+ TCReader { runTCR :: ReaderT tc TCM a } deriving (Monad, MonadReader tc)++runTCReader :: TCReader tc a -> tc -> TCM a+runTCReader = runReaderT . runTCR++open :: (TCDB tc) => String -> [OpenMode] -> TCReader tc Bool+open name mode = do tc <- ask+ TCReader $ lift (TC.open tc name mode)++close :: (TCDB tc) => TCReader tc Bool+close = ask >>= (TCReader . lift . TC.close)++get :: (Storable k, Storable v, TCDB tc) => k -> TCReader tc (Maybe v)+get key = do tc <- ask+ TCReader $ lift (TC.get tc key)++put :: (Storable k, Storable v, TCDB tc) => k -> v -> TCReader tc Bool+put key val = do tc <- ask+ TCReader $ lift (TC.put tc key val)++kvstore :: (Storable k, Storable v, TCDB tc) => [(k, v)] -> TCReader tc Bool+kvstore kv = do open "abcd.tch" [OWRITER, OCREAT]+ mapM_ (uncurry put) kv+ close++main :: IO ()+main = runTCM $ do h <- new :: TCM HDB+ let kv =[ ("foo", 112)+ , ("bar", 200)+ , ("baz", 300) ] :: [(String, Int)]+ runTCReader (kvstore kv) h >> return ()
+ examples/tcadb.hs view
@@ -0,0 +1,31 @@+import Control.Monad+import Database.TokyoCabinet.ADB++main = do adb <- new+ -- open the abstract database object+ -- "+" means that the database will be an on-memory tree database+ open adb "+" >>= err adb "open failed"+ -- store records+ puts adb [("foo", "hop"), ("bar", "step"), ("baz", "jump")]+ >>= err adb "put failed" . (all id)+ -- retrieve records+ get_print adb "foo"+ -- traverse records+ iterinit adb+ iter adb >>= mapM_ (\k -> putStr (k++":") >> get_print adb k)+ -- close the database+ close adb >>= err adb "close failed"+ where+ puts :: ADB -> [(String, String)] -> IO [Bool]+ puts adb = mapM (uncurry $ put adb)++ get_print :: ADB -> String -> IO ()+ get_print adb key = get adb key >>=+ maybe (error "something goes wrong") putStrLn++ err :: ADB -> String -> Bool -> IO ()+ err adb msg = flip unless $ error msg++ iter :: ADB -> IO [String]+ iter adb = iternext adb >>=+ maybe (return []) (\x -> return . (x:) =<< iter adb)
+ examples/withTC.hs view
@@ -0,0 +1,13 @@+module Main where++import Control.Monad.Trans+import Control.Exception+import Database.TokyoCabinet++withTokyoCabinet :: (TCDB a) => String -> (a -> TCM b) -> TCM b+withTokyoCabinet fname action =+ liftIO $ bracket (runTCM open') (runTCM . close') (runTCM . action)+ where open' = do tc <- new+ open tc fname [OREADER, OWRITER, OCREAT]+ return tc+ close' tc = close tc
tokyocabinet-haskell.cabal view
@@ -1,6 +1,6 @@ Name: tokyocabinet-haskell-Version: 0.0.4-Cabal-Version: >= 1.2+Version: 0.0.5+Cabal-Version: >= 1.6 License: BSD3 License-File: LICENSE Author: Tom Tsuruhara@@ -9,10 +9,7 @@ Stability: experimental Category: Database Synopsis: Haskell binding of Tokyo Cabinet-Extra-source-files: examples/tcfdb.hs examples/tcbdb.hs examples/tctdb.hs- examples/tchdb.hs examples/simple.hs examples/myapp1.hs- examples/myapp2.hs examples/MyApp1/TokyoCabinet.hs- examples/MyApp2/TokyoCabinet.hs+Extra-source-files: examples/*.hs Changes Description: Bindings to Tokyo Cabinet library. Tokyo Cabinet is a modern implementation of DBM.@@ -24,6 +21,10 @@ Tested-With: GHC Build-Type: Simple +Source-Repository head+ type: git+ location: git://github.com/tom-lpsd/tokyocabinet-haskell.git+ Flag BuildTest Description: make tests and install it if True Default: False@@ -34,6 +35,8 @@ Database.TokyoCabinet Database.TokyoCabinet.HDB Database.TokyoCabinet.HDB.C+ Database.TokyoCabinet.ADB+ Database.TokyoCabinet.ADB.C Database.TokyoCabinet.BDB Database.TokyoCabinet.BDB.C Database.TokyoCabinet.BDB.Cursor