packages feed

tokyocabinet-haskell 0.0.5 → 0.0.6

raw patch · 21 files changed

+2197/−59 lines, 21 filesdep +HUnitdep +directorydep ~basenew-uploader

Dependencies added: HUnit, directory

Dependency ranges changed: base

Files

Changes view
@@ -1,5 +1,8 @@ Revision history for tokyocabinet-haskell package. +0.0.6  Thu May 07 02:44:59 UTC 2020+  - Fixed build for newer GHC+ 0.0.5  Sat May 09 06:00:00 UTC 2009   - added ADB interface. 
Database/TokyoCabinet.hs view
@@ -27,7 +27,6 @@ import qualified Database.TokyoCabinet.BDB.Cursor as C import qualified Database.TokyoCabinet.Error as E -import Data.Int import Data.Word  -- $doc@@ -68,7 +67,7 @@ newtype TCM a =     TCM { -- | Unwrap TCM.           runTCM :: IO a-    } deriving (Monad, MonadIO)+    } deriving (Functor, Applicative, Monad, MonadIO)  -- | Represent open mode for `open' function. data OpenMode = OREADER |
Database/TokyoCabinet/ADB.hs view
@@ -4,7 +4,6 @@     (     -- $doc       ADB-    , ECODE(..)     , new     , delete     , open@@ -39,7 +38,7 @@ import Foreign.ForeignPtr  import Database.TokyoCabinet.ADB.C-import Database.TokyoCabinet.Error+import Database.TokyoCabinet.Error (cINT_MIN) import Database.TokyoCabinet.Internal import Database.TokyoCabinet.Storable import Database.TokyoCabinet.Sequence
Database/TokyoCabinet/Associative.hs view
@@ -1,7 +1,5 @@ module Database.TokyoCabinet.Associative where -import Data.Maybe- import Foreign.Ptr import Foreign.ForeignPtr 
Database/TokyoCabinet/Error.hsc view
@@ -11,7 +11,7 @@     , cINT_MIN     ) where -import Foreign+import System.IO.Unsafe (unsafePerformIO) import Foreign.C.Types import Foreign.C.String 
Database/TokyoCabinet/FDB/Key.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-} module Database.TokyoCabinet.FDB.Key (Key(..), ID(..)) where  import Database.TokyoCabinet.FDB.C (ID(..), unID)
Database/TokyoCabinet/List/C.hs view
@@ -1,4 +1,3 @@-{-# INCLUDE <tcutil.h> #-} {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} module Database.TokyoCabinet.List.C where 
Database/TokyoCabinet/Map/C.hs view
@@ -1,4 +1,3 @@-{-# INCLUDE <tcutil.h> #-} {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} module Database.TokyoCabinet.Map.C where 
+ TestUtil.hs view
@@ -0,0 +1,18 @@+module TestUtil where+import Test.HUnit+import System.Directory+import Control.Monad+import Control.Exception++setupFile :: FilePath -> IO String+setupFile fn =+  doesFileExist fn >>=+  flip when (assertFailure ("setupFile: (" ++ fn ++ ") already exists!")) >>+  return fn++teardownFile :: String -> IO ()+teardownFile fn = doesFileExist fn >>= flip when (removeFile fn)++withoutFile :: String -> (String -> IO a) -> IO a+withoutFile fn = bracket (setupFile fn) teardownFile+
− examples/tctdb.hs
@@ -1,38 +0,0 @@-import Control.Monad (unless)-import Database.TokyoCabinet.TDB-import Database.TokyoCabinet.TDB.Query hiding (new)-import qualified Database.TokyoCabinet.Map as M-import qualified Database.TokyoCabinet.TDB.Query as Q (new)--data Profile = Profile { name :: String-                       , age  :: Int } deriving Show--insertProfile :: TDB -> Profile -> IO Bool-insertProfile tdb profile =-    do m <- M.new-       M.put m "name" (name profile)-       M.put m "age" (show . age $ profile)-       Just pk <- genuid tdb-       put tdb (show pk) m--main :: IO ()-main = do t <- new-          open t "foo.tct" [OWRITER, OCREAT] >>= err t--          mapM_ (insertProfile t) [ Profile "tom" 23-                                  , Profile "bob" 24-                                  , Profile "alice" 20 ]--          q <- Q.new t-          addcond q "age" QCNUMGE "23"-          setorder q "name" QOSTRASC-          proc q $ \pk cols -> do-            Just name <- M.get cols "name"-            putStrLn name-            M.put cols "name" (name ++ "!")-            return (QPPUT cols)--          close t >>= err t-          return ()-    where-      err tdb = flip unless $ ecode tdb >>= error . show
+ tests/ADBTest.hs view
@@ -0,0 +1,181 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import Database.TokyoCabinet.ADB++import Data.Maybe (catMaybes)+import Data.List (sort)+import Control.Monad++dbname :: String+dbname = "+"++withOpenedADB :: String -> (ADB -> IO a) -> IO a+withOpenedADB name action = do+  a <- new+  open a name+  res <- action a+  close a+  return res++test_new_delete = new >>= delete++test_open_close =+    do adb <- new+       not `fmap` open adb "foo.tch#mode=r" @? "file does not exist"+       open adb "+" @? "open"+       close adb @? "close"+       not `fmap` close adb @? "cannot close closed file"++test_putxx =+    do withOpenedADB dbname $ \adb -> do+         put adb "foo" "bar"+         get adb "foo" >>= (Just "bar" @=?)+         putkeep adb "foo" "baz"+         get adb "foo" >>= (Just "bar" @=?)+         putcat adb "foo" "baz"+         get adb "foo" >>= (Just "barbaz" @=?)++test_out =+    do withOpenedADB dbname $ \adb -> do+         put adb "foo" "bar"+         get adb "foo" >>= (Just "bar" @=?)+         out adb "foo" @? "out succeeded"+         get adb "foo" >>= ((Nothing :: Maybe String) @=?)++test_put_get =+    do withOpenedADB dbname $ \adb -> do+         put adb "1" "foo"+         put adb "2" "bar"+         put adb "3" "baz"+         get adb "1" >>= (Just "foo" @=?)+         get adb "2" >>= (Just "bar" @=?)+         get adb "3" >>= (Just "baz" @=?)++test_vsiz =+    do withOpenedADB dbname $ \adb -> do+         put adb "foo" "bar"+         vsiz adb "foo" >>= (Just 3 @=?)+         vsiz adb "bar" >>= ((Nothing :: Maybe Int) @=?)++test_iterate =+    do withOpenedADB dbname $ \adb -> do+         let keys = [1, 2, 3] :: [Int]+             vals = ["foo", "bar", "baz"]+         zipWithM_ (put adb) keys vals+         iterinit adb+         keys' <- sequence $ replicate (length keys) (iternext adb)+         (sort $ catMaybes keys') @?= (sort keys)++test_fwmkeys =+    do withOpenedADB dbname $ \adb -> do+         mapM_ (uncurry (put adb)) ([ ("foo", 100)+                                    , ("bar", 200)+                                    , ("baz", 201)+                                    , ("jkl", 300)] :: [(String, Int)])+         fwmkeys adb "ba" 10 >>= (["bar", "baz"] @=?) . sort+         fwmkeys adb "ba" 1 >>= (["bar"] @=?)+         fwmkeys adb "" 10 >>= (["bar", "baz", "foo", "jkl"] @=?) . sort++test_addint =+    do withOpenedADB dbname $ \adb -> do+         let ini = 32 :: Int+         put adb "foo" ini+         get adb "foo" >>= (Just ini @=?)+         addint adb "foo" 3+         get adb "foo" >>= (Just (ini+3) @=?)+         addint adb "bar" 1 >>= (Just 1 @=?)+         put adb "bar" "foo"+         addint adb "bar" 1 >>= (Nothing @=?)++test_adddouble =+    do withOpenedADB dbname $ \adb -> do+         let ini = 0.003 :: Double+         put adb "foo" ini+         get adb "foo" >>= (Just ini @=?)+         adddouble adb "foo" 0.3+         (get adb "foo" >>= (isIn (ini+0.3))) @? "isIn"+         adddouble adb "bar" 0.5 >>= (Just 0.5 @=?)+         put adb "bar" "foo"+         adddouble adb "bar" 1.2 >>= (Nothing @=?)+    where+      margin = 1e-30+      isIn :: Double -> (Maybe Double) -> IO Bool+      isIn expected (Just actual) =+          let diff = expected - actual+          in return $ abs diff <= margin++test_vanish =+    withOpenedADB dbname $ \adb -> do+      put adb "foo" "111"+      put adb "bar" "222"+      put adb "baz" "333"+      rnum adb >>= (3 @=?)+      vanish adb+      rnum adb >>= (0 @=?)++test_copy =+   withoutFile "bar.tch" $ \fnd ->+        withOpenedADB dbname $ \adb -> do+          put adb "foo" "bar"+          copy adb fnd+          close adb+          open adb fnd+          get adb "foo" >>= (Just "bar" @=?)++test_txn =+    withoutFile "foo.tcb" $ \fn ->+        withOpenedADB fn $ \adb -> do+          tranbegin adb @? "tranbegin"+          put adb "foo" "bar"+          get adb "foo" >>= (Just "bar" @=?)+          tranabort adb @? "tranabort"+          get adb "foo" >>= ((Nothing :: Maybe String) @=?)+          tranbegin adb @? "tranbegin2"+          put adb "foo" "baz"+          get adb "foo" >>= (Just "baz" @=?)+          trancommit adb @? "trancommit"+          get adb "foo" >>= (Just "baz" @=?)++test_path =+    withOpenedADB dbname $ \adb ->+        path adb >>= (Just dbname @=?)++test_util =+    do adb <- new+       open adb dbname+       put adb "foo" "bar"+       path adb >>= (Just dbname @=?)+       rnum adb >>= (1 @=?)+       ((> 0) `fmap` size adb) @? "size"+       sync adb @? "sync"+       optimize adb "capnum=1000" @? "optimize"+       close adb++test_misc =+    withoutFile "foo.tct" $ \fn ->+        withOpenedADB fn $ \adb -> do+          misc adb "put" ["1", "foo", "100", "bar", "200"] >>= (([] :: String) @=?)+          misc adb "get" ["1"] >>= (["foo", "100", "bar", "200"] @=?)++tests = test [+          "new delete" ~: test_new_delete+        , "open close"  ~: test_open_close+        , "put get" ~: test_put_get+        , "out" ~: test_out+        , "putxx" ~: test_putxx+        , "copy" ~: test_copy+        , "transaction" ~: test_txn+        , "fwmkeys" ~: test_fwmkeys+        , "path" ~: test_path+        , "addint" ~: test_addint+        , "adddouble" ~: test_adddouble+        , "util" ~: test_util+        , "vsiz" ~: test_vsiz+        , "vanish" ~: test_vanish+        , "iterate" ~: test_iterate+        , "misc" ~: test_misc+        ]++main = runTestTT tests
+ tests/BDBTest.hs view
@@ -0,0 +1,258 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import Database.TokyoCabinet.BDB+import qualified Database.TokyoCabinet.BDB.Cursor as C++import Data.Maybe (catMaybes, fromJust)+import Data.List (sort)+import Control.Monad++dbname :: String+dbname = "foo.tcb"++withOpenedBDB :: String -> (BDB -> IO a) -> IO ()+withOpenedBDB name action = do+  h <- new+  open h name [OREADER, OWRITER, OCREAT]+  res <- action h+  close h+  return ()++test_ecode =+    withoutFile dbname $ \fn -> do+        h <- new+        open h fn [OREADER]+        ecode h >>= (ENOFILE @=?)++test_new_delete = do+  bdb <- new+  delete bdb++test_open_close =+    withoutFile dbname $ \fn -> do+      bdb <- new+      not `fmap` open bdb fn [OREADER] @? "file does not exist"+      open bdb fn [OREADER, OWRITER, OCREAT] @? "open"+      close bdb @? "close"+      not `fmap` close bdb @? "cannot close closed file"++test_putxx =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          put bdb "foo" "bar"+          get bdb "foo" >>= (Just "bar" @=?)+          putkeep bdb "foo" "baz"+          get bdb "foo" >>= (Just "bar" @=?)+          putcat bdb "foo" "baz"+          get bdb "foo" >>= (Just "barbaz" @=?)+          putdup bdb "foo" "bar2" @? "putdup"+          getlist bdb "foo" >>= (["barbaz", "bar2"] @=?)+          putlist bdb "bar" ["hoge", "fuga", "abc"] @? "putlist"+          getlist bdb "bar" >>= (["hoge", "fuga", "abc"] @=?)++test_out =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          put bdb "foo" "bar"+          get bdb "foo" >>= (Just "bar" @=?)+          out bdb "foo" @? "out succeeded"+          get bdb "foo" >>= ((Nothing :: Maybe String) @=?)+          putlist bdb "bar" ([1, 2, 3] :: [Int])+          out bdb "bar" -- first one is removed+          get bdb "bar" >>= ((Just 2 :: Maybe Int) @=?)+          outlist bdb "bar"+          get bdb "bar" >>= ((Nothing :: Maybe Int) @=?)++test_put_get =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          put bdb "1" "foo"+          put bdb "2" "bar"+          put bdb "3" "baz"+          get bdb "1" >>= (Just "foo" @=?)+          get bdb "2" >>= (Just "bar" @=?)+          get bdb "3" >>= (Just "baz" @=?)+          putdup bdb "1" "foo2"+          get bdb "4" >>= ((Nothing :: Maybe String) @=?)+          getlist bdb "1" >>= (["foo", "foo2"] @=?)+          getlist bdb "4" >>= (([] :: [String]) @=?)++test_vnum =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          putlist bdb "foo" ["bar", "baz", "hoge", "fuga"]+          vnum bdb "foo" >>= (Just 4 @=?)+          vnum bdb "bar" >>= (Nothing @=?)++test_vsiz =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          put bdb "foo" "bar"+          vsiz bdb "foo" >>= (Just 3 @=?)+          vsiz bdb "bar" >>= ((Nothing :: Maybe Int) @=?)++test_iterate =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          let keys  = ["foo", "bar", "baz", "jkl"]+              vals  = [100, 200 ..] :: [Int]+              kvs = sort $ zip keys vals+              destkey = "baz"+              destval = fromJust $ lookup destkey kvs+          zipWithM (put bdb) keys vals+          cur <- C.new bdb+          C.first cur+          C.key cur >>= (Just (fst . head $ kvs) @=?)+          C.val cur >>= (Just (snd . head $ kvs) @=?)+          C.out cur @? "cursor out"+          get bdb (fst . head $ kvs) >>= ((Nothing :: Maybe String) @=?)+          C.key cur >>= (Just (fst . (!! 1) $ kvs) @=?)+          C.val cur >>= (Just (snd . (!! 1) $ kvs) @=?)+          C.next cur @? "cursor next"+          C.key cur >>= (Just (fst . (!! 2) $ kvs) @=?)+          C.val cur >>= (Just (snd . (!! 2) $ kvs) @=?)+          C.prev cur @? "cursor prev"+          C.key cur >>= (Just (fst . (!! 1) $ kvs) @=?)+          C.val cur >>= (Just (snd . (!! 1) $ kvs) @=?)+          C.jump cur "b" @? "cursor jump"+          C.key cur >>= (Just destkey @=?)+          C.put cur (100 :: Int) C.CPAFTER @? "cursor put"+          getlist bdb destkey >>= (([destval, 100] :: [Int]) @=?)+          C.last cur @? "cursor last"+          C.key cur >>= (Just (fst . last $ kvs) @=?)+          C.delete cur++test_range =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          let keys = ["abc", "abd", "bcd", "bcz", "fgh", "ghjc", "ziji"]+          zipWithM (put bdb) keys ([1..] :: [Int])+          range bdb (Just "a") True (Just "abz") True 10+                    >>= (["abc", "abd"] @=?)+          range bdb (Just "a") True (Just "abd") False 10+                    >>= (["abc"] @=?)+          range bdb (Just "abc") False (Just "fgh") False 3+                    >>= (["abd", "bcd", "bcz"] @=?)+          range bdb (Just "a") False (Just "ab") False 10+                    >>= (([] :: [String]) @=?)+          range bdb Nothing False Nothing False (-1) >>= (keys @=?)+++test_fwmkeys =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          mapM_ (uncurry (put bdb)) ([ ("foo", 100)+                                     , ("bar", 200)+                                     , ("baz", 201)+                                     , ("jkl", 300)] :: [(String, Int)])+          fwmkeys bdb "ba" 10 >>= (["bar", "baz"] @=?) . sort+          fwmkeys bdb "ba" 1 >>= (["bar"] @=?)+          fwmkeys bdb "" 10 >>= (["bar", "baz", "foo", "jkl"] @=?) . sort++test_addint =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          let ini = 32 :: Int+          put bdb "foo" ini+          get bdb "foo" >>= (Just ini @=?)+          addint bdb "foo" 3+          get bdb "foo" >>= (Just (ini+3) @=?)+          addint bdb "bar" 1 >>= (Just 1 @=?)+          put bdb "bar" "foo"+          addint bdb "bar" 1 >>= (Nothing @=?)++test_adddouble =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          let ini = 0.003 :: Double+          put bdb "foo" ini+          get bdb "foo" >>= (Just ini @=?)+          adddouble bdb "foo" 0.3+          (get bdb "foo" >>= (isIn (ini+0.3))) @? "isIn"+          adddouble bdb "bar" 0.5 >>= (Just 0.5 @=?)+          put bdb "bar" "foo"+          adddouble bdb "bar" 1.2 >>= (Nothing @=?)+    where+      margin = 1e-30+      isIn :: Double -> (Maybe Double) -> IO Bool+      isIn expected (Just actual) =+          let diff = expected - actual+          in return $ abs diff <= margin++test_vanish =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+            put bdb "foo" "111"+            put bdb "bar" "222"+            put bdb "baz" "333"+            rnum bdb >>= (3 @=?)+            vanish bdb+            rnum bdb >>= (0 @=?)++test_copy =+    withoutFile dbname $ \fns ->+        withoutFile "bar.tcb" $ \fnd ->+            withOpenedBDB fns $ \bdb -> do+                put bdb "foo" "bar"+                copy bdb fnd+                close bdb+                open bdb fnd [OREADER]+                get bdb "foo" >>= (Just "bar" @=?)++test_txn =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb -> do+          tranbegin bdb+          put bdb "foo" "bar"+          get bdb "foo" >>= (Just "bar" @=?)+          tranabort bdb+          get bdb "foo" >>= ((Nothing :: Maybe String) @=?)+          tranbegin bdb+          put bdb "foo" "baz"+          get bdb "foo" >>= (Just "baz" @=?)+          trancommit bdb+          get bdb "foo" >>= (Just "baz" @=?)++test_path =+    withoutFile dbname $ \fn ->+        withOpenedBDB fn $ \bdb ->+            path bdb >>= (Just dbname @=?)++test_util =+    withoutFile dbname $ \fn -> do+      bdb <- new+      setcache bdb 1000000 0 @? "setcache"+      setxmsiz bdb 1000000 @? "setxmsiz"+      tune bdb 0 0 0 (-1) (-1) [TLARGE, TBZIP] @? "tune"+      open bdb fn [OREADER, OWRITER, OCREAT]+      path bdb >>= (Just fn @=?)+      rnum bdb >>= (0 @=?)+      ((> 0) `fmap` fsiz bdb) @? "fsiz"+      sync bdb @? "sync"+      optimize bdb 0 0 0 (-1) (-1) [] @? "optimize"+      close bdb++tests = test [+          "new delete" ~: test_new_delete+        , "ecode" ~: test_ecode+        , "open close"  ~: test_open_close+        , "put get" ~: test_put_get+        , "vnum" ~: test_vnum+        , "out" ~: test_out+        , "putxx" ~: test_putxx+        , "copy" ~: test_copy+        , "transaction" ~: test_txn+        , "range" ~: test_range+        , "fwmkeys" ~: test_fwmkeys+        , "path" ~: test_path+        , "addint" ~: test_addint+        , "adddouble" ~: test_adddouble+        , "util" ~: test_util+        , "vsiz" ~: test_vsiz+        , "vanish" ~: test_vanish+        , "iterate" ~: test_iterate+        ]++main = runTestTT tests
+ tests/FDBTest.hs view
@@ -0,0 +1,198 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import Database.TokyoCabinet.FDB++import Data.Maybe (catMaybes, fromJust)+import Data.List (sort)+import Control.Monad++dbname :: String+dbname = "foo.tcf"++withOpenedFDB :: String -> (FDB -> IO a) -> IO ()+withOpenedFDB name action = do+  h <- new+  open h name [OREADER, OWRITER, OCREAT]+  res <- action h+  close h+  return ()++test_ecode =+    withoutFile dbname $ \fn -> do+        h <- new+        open h fn [OREADER]+        ecode h >>= (ENOFILE @=?)++test_new_delete = do+  fdb <- new+  delete fdb++test_open_close =+    withoutFile dbname $ \fn -> do+      fdb <- new+      not `fmap` open fdb fn [OREADER] @? "file does not exist"+      open fdb fn [OREADER, OWRITER, OCREAT] @? "open"+      close fdb @? "close"+      not `fmap` close fdb @? "cannot close closed file"++test_putxx =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          put fdb "1" "bar"+          get fdb "1" >>= (Just "bar" @=?)+          putkeep fdb "1" "baz"+          get fdb "1" >>= (Just "bar" @=?)+          putcat fdb "1" "baz"+          get fdb "1" >>= (Just "barbaz" @=?)++test_out =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          put fdb "1" "bar"+          get fdb "1" >>= (Just "bar" @=?)+          out fdb "1" @? "out succeeded"+          get fdb "1" >>= ((Nothing :: Maybe String) @=?)++test_put_get =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          put fdb "2" "foo"+          put fdb "3" "bar"+          put fdb "4" "baz"+          put fdb IDNEXT "hoge"+          put fdb IDPREV "fuga"+          get fdb "2" >>= (Just "foo" @=?)+          get fdb "3" >>= (Just "bar" @=?)+          get fdb "4" >>= (Just "baz" @=?)+          get fdb (5 :: Int) >>= (Just "hoge" @=?)+          get fdb (1 :: Int) >>= (Just "fuga" @=?)+          put fdb IDMAX "max"+          put fdb IDMIN "min"+          get fdb (5 :: Int) >>= (Just "max" @=?)+          get fdb (1 :: Int) >>= (Just "min" @=?)++test_iterate =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          let keys = [1, 2, 3] :: [Int]+              vals = ["foo", "bar", "baz"]+          zipWithM_ (put fdb) keys vals+          iterinit fdb+          keys' <- sequence $ replicate (length keys) (iternext fdb)+          (sort $ catMaybes keys') @?= (sort keys)+          iternext fdb >>= ((Nothing :: Maybe String) @=?)++test_vsiz =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          put fdb "123" "bar"+          vsiz fdb "123" >>= (Just 3 @=?)+          vsiz fdb "234" >>= ((Nothing :: Maybe Int) @=?)++test_range =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          zipWithM_ (put fdb) ([1..10] :: [Int]) ([100, 200..1000] :: [Int])+          range fdb (2 :: Int) (5 :: Int) (-1)+                    >>= (([2..5] :: [Int]) @=?)+          range fdb IDMIN IDMAX (-1)+                    >>= (([1..10] :: [Int]) @=?)+          range fdb IDMIN IDMAX 2+                    >>= (([1..2] :: [Int]) @=?)++test_fwmkeys =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          zipWithM_ (put fdb) ([1..10] :: [Int]) ([100, 200..1000] :: [Int])+          fwmkeys fdb "[min,max]" 10 >>= ((map show [1..10]) @=?)++test_addint =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          let ini = 32 :: Int+          put fdb "10" ini+          get fdb "10" >>= (Just ini @=?)+          addint fdb "10" 3+          get fdb "10" >>= (Just (ini+3) @=?)+          addint fdb "20" 1 >>= (Just 1 @=?)+          put fdb "20" "foo"+          addint fdb "20" 1 >>= (Nothing @=?)++test_adddouble =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+          let ini = 0.003 :: Double+          put fdb "1" ini+          get fdb "1" >>= (Just ini @=?)+          adddouble fdb "1" 0.3+          (get fdb "1" >>= (isIn (ini+0.3))) @? "isIn"+          adddouble fdb "2" 0.5 >>= (Just 0.5 @=?)+          put fdb "2" "foo"+          adddouble fdb "2" 1.2 >>= (Nothing @=?)+    where+      margin = 1e-30+      isIn :: Double -> (Maybe Double) -> IO Bool+      isIn expected (Just actual) =+          let diff = expected - actual+          in return $ abs diff <= margin++test_vanish =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb -> do+            put fdb "1" "111"+            put fdb "2" "222"+            put fdb "3" "333"+            rnum fdb >>= (3 @=?)+            vanish fdb+            rnum fdb >>= (0 @=?)++test_copy =+    withoutFile dbname $ \fns ->+        withoutFile "bar.tcf" $ \fnd ->+            withOpenedFDB fns $ \fdb -> do+                put fdb "1" "bar"+                copy fdb fnd+                close fdb+                open fdb fnd [OREADER]+                get fdb "1" >>= (Just "bar" @=?)++test_path =+    withoutFile dbname $ \fn ->+        withOpenedFDB fn $ \fdb ->+            path fdb >>= (Just dbname @=?)++test_util =+    withoutFile dbname $ \fn -> do+      fdb <- new+      tune fdb 0 100000000 @? "tune"+      open fdb fn [OREADER, OWRITER, OCREAT]+      path fdb >>= (Just fn @=?)+      rnum fdb >>= (0 @=?)+      ((> 0) `fmap` fsiz fdb) @? "fsiz"+      sync fdb @? "sync"+      put fdb (1 :: Int) "dummy record"+      optimize fdb 0 0 @? "optimize"+      close fdb++tests = test [+          "new delete" ~: test_new_delete+        , "ecode" ~: test_ecode+        , "open close"  ~: test_open_close+        , "put get" ~: test_put_get+        , "out" ~: test_out+        , "putxx" ~: test_putxx+        , "copy" ~: test_copy+        , "range" ~: test_range+        , "fwmkeys" ~: test_fwmkeys+        , "path" ~: test_path+        , "addint" ~: test_addint+        , "adddouble" ~: test_adddouble+        , "util" ~: test_util+        , "vsiz" ~: test_vsiz+        , "vanish" ~: test_vanish+        , "iterate" ~: test_iterate+        ]++main = runTestTT tests
+ tests/HDBTest.hs view
@@ -0,0 +1,201 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import Database.TokyoCabinet.HDB++import Data.Maybe (catMaybes)+import Data.List (sort)+import Control.Monad++dbname :: String+dbname = "foo.tch"++withOpenedHDB :: String -> (HDB -> IO a) -> IO a+withOpenedHDB name action = do+  h <- new+  open h name [OREADER, OWRITER, OCREAT]+  res <- action h+  close h+  return res++test_ecode =+    withoutFile dbname $ \fn -> do+        h <- new+        open h fn [OREADER]+        ecode h >>= (ENOFILE @=?)++test_new_delete = do+  hdb <- new+  delete hdb++test_open_close =+    withoutFile dbname $ \fn -> do+      hdb <- new+      not `fmap` open hdb fn [OREADER] @? "file does not exist"+      open hdb fn [OREADER, OWRITER, OCREAT] @? "open"+      close hdb @? "close"+      not `fmap` close hdb @? "cannot close closed file"++test_putxx =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          put hdb "foo" "bar"+          get hdb "foo" >>= (Just "bar" @=?)+          putkeep hdb "foo" "baz"+          get hdb "foo" >>= (Just "bar" @=?)+          putcat hdb "foo" "baz"+          get hdb "foo" >>= (Just "barbaz" @=?)+          putasync hdb "bar" "baz"+          sync hdb+          get hdb "bar" >>= (Just "baz" @=?)++test_out =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          put hdb "foo" "bar"+          get hdb "foo" >>= (Just "bar" @=?)+          out hdb "foo" @? "out succeeded"+          get hdb "foo" >>= ((Nothing :: Maybe String) @=?)++test_put_get =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          put hdb "1" "foo"+          put hdb "2" "bar"+          put hdb "3" "baz"+          get hdb "1" >>= (Just "foo" @=?)+          get hdb "2" >>= (Just "bar" @=?)+          get hdb "3" >>= (Just "baz" @=?)++test_vsiz =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          put hdb "foo" "bar"+          vsiz hdb "foo" >>= (Just 3 @=?)+          vsiz hdb "bar" >>= ((Nothing :: Maybe Int) @=?)++test_iterate =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          let keys = [1, 2, 3] :: [Int]+              vals = ["foo", "bar", "baz"]+          zipWithM_ (put hdb) keys vals+          iterinit hdb+          keys' <- sequence $ replicate (length keys) (iternext hdb)+          (sort $ catMaybes keys') @?= (sort keys)++test_fwmkeys =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          mapM_ (uncurry (put hdb)) ([ ("foo", 100)+                                     , ("bar", 200)+                                     , ("baz", 201)+                                     , ("jkl", 300)] :: [(String, Int)])+          fwmkeys hdb "ba" 10 >>= (["bar", "baz"] @=?) . sort+          fwmkeys hdb "ba" 1 >>= (["bar"] @=?)+          fwmkeys hdb "" 10 >>= (["bar", "baz", "foo", "jkl"] @=?) . sort++test_addint =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          let ini = 32 :: Int+          put hdb "foo" ini+          get hdb "foo" >>= (Just ini @=?)+          addint hdb "foo" 3+          get hdb "foo" >>= (Just (ini+3) @=?)+          addint hdb "bar" 1 >>= (Just 1 @=?)+          put hdb "bar" "foo"+          addint hdb "bar" 1 >>= (Nothing @=?)++test_adddouble =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          let ini = 0.003 :: Double+          put hdb "foo" ini+          get hdb "foo" >>= (Just ini @=?)+          adddouble hdb "foo" 0.3+          (get hdb "foo" >>= (isIn (ini+0.3))) @? "isIn"+          adddouble hdb "bar" 0.5 >>= (Just 0.5 @=?)+          put hdb "bar" "foo"+          adddouble hdb "bar" 1.2 >>= (Nothing @=?)+    where+      margin = 1e-30+      isIn :: Double -> (Maybe Double) -> IO Bool+      isIn expected (Just actual) =+          let diff = expected - actual+          in return $ abs diff <= margin++test_vanish =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+            put hdb "foo" "111"+            put hdb "bar" "222"+            put hdb "baz" "333"+            rnum hdb >>= (3 @=?)+            vanish hdb+            rnum hdb >>= (0 @=?)++test_copy =+    withoutFile dbname $ \fns ->+        withoutFile "bar.tch" $ \fnd ->+            withOpenedHDB fns $ \hdb -> do+                put hdb "foo" "bar"+                copy hdb fnd+                close hdb+                open hdb fnd [OREADER]+                get hdb "foo" >>= (Just "bar" @=?)++test_txn =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb -> do+          tranbegin hdb+          put hdb "foo" "bar"+          get hdb "foo" >>= (Just "bar" @=?)+          tranabort hdb+          get hdb "foo" >>= ((Nothing :: Maybe String) @=?)+          tranbegin hdb+          put hdb "foo" "baz"+          get hdb "foo" >>= (Just "baz" @=?)+          trancommit hdb+          get hdb "foo" >>= (Just "baz" @=?)++test_path =+    withoutFile dbname $ \fn ->+        withOpenedHDB fn $ \hdb ->+            path hdb >>= (Just dbname @=?)++test_util =+    withoutFile dbname $ \fn -> do+      hdb <- new+      setcache hdb 1000000 @? "setcache"+      setxmsiz hdb 1000000 @? "setxmsiz"+      tune hdb 150000 5 11 [TLARGE, TBZIP] @? "tune"+      open hdb fn [OREADER, OWRITER, OCREAT]+      path hdb >>= (Just fn @=?)+      rnum hdb >>= (0 @=?)+      ((> 0) `fmap` fsiz hdb) @? "fsiz"+      sync hdb @? "sync"+      optimize hdb 0 (-1) (-1) [] @? "optimize"+      close hdb++tests = test [+          "new delete" ~: test_new_delete+        , "ecode" ~: test_ecode+        , "open close"  ~: test_open_close+        , "put get" ~: test_put_get+        , "out" ~: test_out+        , "putxx" ~: test_putxx+        , "copy" ~: test_copy+        , "transaction" ~: test_txn+        , "fwmkeys" ~: test_fwmkeys+        , "path" ~: test_path+        , "addint" ~: test_addint+        , "adddouble" ~: test_adddouble+        , "util" ~: test_util+        , "vsiz" ~: test_vsiz+        , "vanish" ~: test_vanish+        , "iterate" ~: test_iterate+        ]++main = runTestTT tests
+ tests/ListTest.hs view
@@ -0,0 +1,221 @@+module Main where+import Test.HUnit++import Control.Monad+import Data.Int+import Data.Word+import qualified Data.ByteString.Char8 as S+import qualified Data.ByteString.Lazy.Char8 as L++import Database.TokyoCabinet.List++len_test = do+  xs <- new+  (==0) `fmap` len xs @? "empty"+  push xs "foo"+  (==1) `fmap` len xs @? "1 element"+  push xs "baz"+  (==2) `fmap` len xs @? "2 elements"+  pop xs :: IO (Maybe String)+  (==1) `fmap` len xs @? "1 element again"+  pop xs :: IO (Maybe String)+  (==0) `fmap` len xs @? "empty again"+  delete xs++push_pop_test = do+  xs <- new+  push xs "foo"+  push xs "bar"+  push xs "baz"+  (@?= (Just "baz")) =<< pop xs+  (@?= (Just "bar")) =<< pop xs+  (@?= (Just "foo")) =<< pop xs+  (@?= (Nothing :: Maybe String)) =<< pop xs+  delete xs++unshift_shift_test = do+  xs <- new+  unshift xs "foo"+  unshift xs "bar"+  unshift xs "baz"+  (@?= (Just "baz")) =<< shift xs+  (@?= (Just "bar")) =<< shift xs+  (@?= (Just "foo")) =<< shift xs+  (@?= (Nothing :: Maybe String)) =<< shift xs+  delete xs++clear_test = do+  xs <- new+  push xs ""+  push xs ""+  push xs ""+  (@?= 3) =<< len xs+  clear xs+  (@?= 0) =<< len xs+  delete xs++insert_remove_test = do+  xs <- new+  (@?= (Nothing :: Maybe String)) =<< remove xs 0+  insert xs 0 "foo"+  insert xs 0 "bar"+  insert xs 1 "baz"+  (@?= 3)            =<< len xs+  (@?= (Just "bar")) =<< get xs 0+  (@?= (Just "baz")) =<< get xs 1+  (@?= (Just "foo")) =<< get xs 2+  (@?= (Nothing :: Maybe String)) =<< get xs 3+  remove xs 0 :: IO (Maybe String)+  (@?= 2) =<< len xs+  (@?= (Just "foo")) =<< get xs 1+  remove xs 1 :: IO (Maybe String)+  (@?= 1)                         =<< len xs+  (@?= (Just "baz"))              =<< get xs 0+  (@?= (Nothing :: Maybe String)) =<< get xs 1+  (@?= (Nothing :: Maybe String)) =<< remove xs 1+  delete xs++sort_test = do+  xs <- new+  let x = 12 :: Int+      y = 49 :: Int+      z = 5  :: Int+  push xs x+  push xs y+  push xs z+  sort xs+  (@?= 3)        =<< len xs+  (@?= (Just z)) =<< get xs 0+  (@?= (Just x)) =<< get xs 1+  (@?= (Just y)) =<< get xs 2+  delete xs++lsearch_test = do+  xs <- new+  let x = 12 :: Int+      y = 49 :: Int+      z = 5  :: Int+  push xs x+  push xs y+  push xs z+  (@?= 2) =<< lsearch xs z+  (@?= 0) =<< lsearch xs x+  (@?= 1) =<< lsearch xs y+  delete xs++bsearch_test = do+  xs <- new+  let x = 12 :: Int+      y = 49 :: Int+      z = 5  :: Int+  push xs z+  push xs x+  push xs y+  (@?= 0) =<< bsearch xs z+  (@?= 1) =<< bsearch xs x+  (@?= 2) =<< bsearch xs y+  delete xs++int_test = do+  xs   <- new :: IO (List Int)+  xs8  <- new :: IO (List Int8)+  xs16 <- new :: IO (List Int16)+  xs32 <- new :: IO (List Int32)+  xs64 <- new :: IO (List Int64)+  let num_int   = [ 1..10]+      num_int8  = [11..20]+      num_int16 = [21..30]+      num_int32 = [31..40]+      num_int64 = [41..50]+  pushlist xs   num_int+  pushlist xs8  num_int8+  pushlist xs16 num_int16+  pushlist xs32 num_int32+  pushlist xs64 num_int64+  get xs   0 >>= (@?= (Just (num_int   !! 0)))+  get xs   9 >>= (@?= (Just (num_int   !! 9)))+  get xs8  0 >>= (@?= (Just (num_int8  !! 0)))+  get xs8  9 >>= (@?= (Just (num_int8  !! 9)))+  get xs16 0 >>= (@?= (Just (num_int16 !! 0)))+  get xs16 9 >>= (@?= (Just (num_int16 !! 9)))+  get xs32 0 >>= (@?= (Just (num_int32 !! 0)))+  get xs32 9 >>= (@?= (Just (num_int32 !! 9)))+  get xs64 0 >>= (@?= (Just (num_int64 !! 0)))+  get xs64 9 >>= (@?= (Just (num_int64 !! 9)))+    where+      pushlist xs ys = mapM_ (push xs) ys++word_test = do+  xs8  <- new :: IO (List Word8)+  xs16 <- new :: IO (List Word16)+  xs32 <- new :: IO (List Word32)+  xs64 <- new :: IO (List Word64)+  let num_word8   = [ 1..10]+      num_word16  = [11..20]+      num_word32  = [21..30]+      num_word64  = [31..40]+  pushlist xs8  num_word8+  pushlist xs16 num_word16+  pushlist xs32 num_word32+  pushlist xs64 num_word64+  get xs8  0 >>= (@?= (Just (num_word8  !! 0)))+  get xs8  9 >>= (@?= (Just (num_word8  !! 9)))+  get xs16 0 >>= (@?= (Just (num_word16 !! 0)))+  get xs16 9 >>= (@?= (Just (num_word16 !! 9)))+  get xs32 0 >>= (@?= (Just (num_word32 !! 0)))+  get xs32 9 >>= (@?= (Just (num_word32 !! 9)))+  get xs64 0 >>= (@?= (Just (num_word64 !! 0)))+  get xs64 9 >>= (@?= (Just (num_word64 !! 9)))+    where+      pushlist xs ys = mapM_ (push xs) ys++strict_bytestring_test = do+  xs <- new+  let vals = map S.pack ["foo", "bar", "baz"]+  mapM_ (push xs) vals+  get xs 0 >>= (@?= (Just (vals  !! 0)))+  get xs 1 >>= (@?= (Just (vals  !! 1)))+  get xs 2 >>= (@?= (Just (vals  !! 2)))++lazy_bytestring_test = do+  xs <- new+  let vals = map L.pack ["foo", "bar", "baz"]+  mapM_ (push xs) vals+  get xs 0 >>= (@?= (Just (vals  !! 0)))+  get xs 1 >>= (@?= (Just (vals  !! 1)))+  get xs 2 >>= (@?= (Just (vals  !! 2)))++dump_load_test = do+  xs <- new+  mapM_ (push xs) ["foo", "bar", "baz"]+  bytes <- dump xs+  ys <- load bytes+  xsiz <- len xs+  ysiz <- len ys+  xsiz @?= ysiz+  tclist_equal xs ys 0 xsiz+  where+    tclist_equal xs ys ix num =+        do if ix == num+             then return ()+             else do liftM2 (@?=) (get xs ix :: IO (Maybe String))+                                  (get ys ix :: IO (Maybe String))+                     tclist_equal xs ys (1 + ix) num++tests = test [+          "len test" ~: len_test+        , "push pop test" ~: push_pop_test+        , "unshift shift test" ~: unshift_shift_test+        , "clear test" ~: clear_test+        , "insert remove test" ~: insert_remove_test+        , "sort test" ~: sort_test+        , "lsearch test" ~: lsearch_test+        , "bsearch test" ~: bsearch_test+        , "int_test" ~: int_test+        , "word_test" ~: word_test+        , "strict_bytestring_test" ~: strict_bytestring_test+        , "lazy_bytestring_test" ~: lazy_bytestring_test+        , "dump_load_test" ~: dump_load_test+        ]++main = runTestTT tests
+ tests/MapTest.hs view
@@ -0,0 +1,126 @@+module Main where+import Test.HUnit++import Control.Monad+import Database.TokyoCabinet.Map++new_delete_test = do+  m <- new+  delete m+  m' <- new2 10+  delete m'++dup_test = do+  m1 <- new+  put m1 "foo" "bar"+  m2 <- dup m1+  get m2 "foo" >>= (Just "bar" @=?)++putxx_test = do+  m <- new+  put m "foo" "bar"+  get m "foo" >>= (Just "bar" @=?)+  putkeep m "foo" "baz"+  get m "foo" >>= (Just "bar" @=?)+  putcat m "foo" "baz"+  get m "foo" >>= (Just "barbaz" @=?)+  get m "hoge" >>= (Nothing @=?)++out_test = do+  m <- new+  put m "foo" "bar"+  get m "foo" >>= (Just "bar" @=?)+  out m "foo"+  get m "foo" >>= (Nothing @=?)++move_test = do+  m <- new+  put m "foo" "100"+  put m "bar" "200"+  put m "baz" "300"+  keys m >>= ("foo" @=?) . head+  move m "bar" True+  keys m >>= ("bar" @=?) . head+  move m "foo" False+  keys m >>= ("foo" @=?) . last++iter_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  iterinit m+  iternext m >>= (Just "foo" @=?)+  iternext m >>= (Just "bar" @=?)+  iternext m >>= (Just "baz" @=?)++util_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  rnum m >>= (3 @=?)+  siz <- msiz m+  (siz > 0) @? "msiz returns positive int value"+  m' <- new+  rnum m' >>= (0 @=?)++keys_vals_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  keys m >>= (["foo", "bar", "baz"] @=?)+  vals m >>= ([1..3] @=?)+  m' <- new :: IO (Map String String)+  keys m' >>= ([] @=?)+  vals m' >>= ([] @=?)++add_test = do+  mi <- new+  put mi "foo" (1 :: Int)+  addint mi "foo" 23 >>= (Just 24 @=?)+  addint mi "bar" 23 >>= (Just 23 @=?)+  md <- new+  put md "foo" (1 :: Double)+  adddouble md "foo" 2.0 >>= (Just 3.0 @=?)+  adddouble md "bar" 2.0 >>= (Just 2.0 @=?)++clear_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  rnum m >>= (3 @=?)+  get m "foo" >>= (Just 1 @=?)+  clear m+  rnum m >>= (0 @=?)+  get m "foo" >>= (Nothing @=?)++cutfront_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  keys m >>= ("foo" @=?) . head+  cutfront m 2+  keys m >>= ("baz" @=?) . head+  m' <- new :: IO (Map Int Int)+  cutfront m' 10+  keys m' >>= ([] @=?)++dump_load_test = do+  m <- new+  zipWithM_ (put m) ["foo", "bar", "baz"] ([1..] :: [Int])+  bytes <- dump m+  m' <- load bytes+  liftM2 (==) (keys m) (keys m') @? "original and dumped have the same keys"+  liftM2 (==) (vals m) (vals m') @? "original and dumped have the same vals"+  delete m++tests = test [+          "new delete test" ~: new_delete_test+        , "dup test" ~: dup_test+        , "putxx test" ~: putxx_test+        , "out test" ~: out_test+        , "move test" ~: move_test+        , "iter test" ~: iter_test+        , "util test" ~: util_test+        , "keys vals test" ~: keys_vals_test+        , "add test" ~: add_test+        , "clear test" ~: clear_test+        , "cutfront test" ~: cutfront_test+        , "dump load test" ~: dump_load_test+        ]++main = runTestTT tests
+ tests/StorableTest.hs view
@@ -0,0 +1,145 @@+module Main where++import TestUtil+import Test.HUnit hiding (path)++import Database.TokyoCabinet+import Database.TokyoCabinet.Storable+import qualified Data.ByteString.Char8 as S+import qualified Data.ByteString.Lazy.Char8 as L++import Data.Int+import Data.Word++import Control.Monad.Trans (liftIO)++e @=?: a = liftIO $ e @=? a++check :: (TCDB tc, Eq a, Storable a) => tc -> a -> a -> TCM ()+check tc k v = do put tc k v+                  get tc k >>= (Just v @=?:)+                  iterinit tc+                  iternext tc >>= (Just k @=?:)++bdb :: TCM BDB+bdb = new++hdb :: TCM HDB+hdb = new++fdb :: TCM FDB+fdb = new++string = "100"+bstring = S.pack "100"+lstring = L.pack "100000"++int = 100 :: Int+int8 = 100 :: Int8+int16 = 100 :: Int16+int32 = 100 :: Int32+int64 = 100 :: Int64++word8 = 100 :: Word8+word16 = 100 :: Word16+word32 = 100 :: Word32+word64 = 100 :: Word64++double = 100 :: Double+float = 100 :: Float++char = '1'++dbname tc = "foo" ++ (defaultExtension tc)++make_check :: (TCDB tc, Eq a, Storable a) => TCM tc -> a -> IO Bool+make_check tcm k = runTCM $ do+                     tc <- tcm+                     liftIO $ withoutFile (dbname tc) $ \fn ->+                         runTCM $ do+                              open tc fn [OWRITER, OCREAT]+                              check tc k k+                              close tc++tests = test [+          make_check bdb string+        , make_check hdb string+        , make_check fdb string+        , make_check bdb bstring+        , make_check hdb bstring+        , make_check fdb bstring+        , make_check bdb lstring+        , make_check hdb lstring+        , make_check fdb lstring+        , make_check bdb int+        , make_check hdb int+        , make_check fdb int+        , make_check bdb [int]+        , make_check hdb [int]+        , make_check fdb [int]+        , make_check bdb int8+        , make_check hdb int8+        , make_check fdb int8+        , make_check bdb [int8]+        , make_check hdb [int8]+        , make_check fdb [int8]+        , make_check bdb int16+        , make_check hdb int16+        , make_check fdb int16+        , make_check bdb [int16]+        , make_check hdb [int16]+        , make_check fdb [int16]+        , make_check bdb int32+        , make_check hdb int32+        , make_check fdb int32+        , make_check bdb [int32]+        , make_check hdb [int32]+        , make_check fdb [int32]+        , make_check bdb int64+        , make_check hdb int64+        , make_check fdb int64+        , make_check bdb [int64]+        , make_check hdb [int64]+        , make_check fdb [int64]+        , make_check bdb word8+        , make_check hdb word8+        , make_check fdb word8+        , make_check bdb [word8]+        , make_check hdb [word8]+        , make_check fdb [word8]+        , make_check bdb word16+        , make_check hdb word16+        , make_check fdb word16+        , make_check bdb [word16]+        , make_check hdb [word16]+        , make_check fdb [word16]+        , make_check bdb word32+        , make_check hdb word32+        , make_check fdb word32+        , make_check bdb [word32]+        , make_check hdb [word32]+        , make_check fdb [word32]+        , make_check bdb word64+        , make_check hdb word64+        , make_check fdb word64+        , make_check bdb [word64]+        , make_check hdb [word64]+        , make_check fdb [word64]+        , make_check bdb double+        , make_check hdb double+        , make_check bdb [double]+        , make_check hdb [double]+        , make_check bdb float+        , make_check hdb float+        , make_check bdb [float]+        , make_check hdb [float]+        , make_check bdb char+        , make_check hdb char+        , make_check fdb char+        , make_check bdb [char]+        , make_check hdb [char]+        , make_check fdb [char]+        ]+                          ++main = runTestTT tests
+ tests/TCDBTest.hs view
@@ -0,0 +1,260 @@+module Main where++import TestUtil+import Test.HUnit hiding (path)+import Database.TokyoCabinet+import qualified Database.TokyoCabinet.BDB as B++import Data.Maybe (catMaybes)+import Data.List (sort)++import Control.Monad+import Control.Exception+import Control.Monad.Trans (liftIO)++withoutFileM :: String -> (String -> TCM a) -> TCM a+withoutFileM fn action = liftIO $ bracket (setupFile fn) teardownFile+                         (runTCM . action)++withOpenedTC :: (TCDB tc) => String -> tc -> (tc -> TCM a) -> TCM a+withOpenedTC name tc action = do+  open tc name [OREADER, OWRITER, OCREAT]+  res <- action tc+  close tc+  return res++tcdb :: (TCDB tc) => (tc -> TCM a) -> TCM a+tcdb = (new >>=)++bdb :: (BDB -> TCM a) -> TCM a+bdb = tcdb++hdb :: (HDB -> TCM a) -> TCM a+hdb = tcdb++fdb :: (FDB -> TCM a) -> TCM a+fdb = tcdb++tdb :: (TDB -> TCM a) -> TCM a+tdb = tcdb++bbdb :: (B.BDB -> TCM a) -> TCM a+bbdb = tcdb++dbname tc = "foo" ++ (defaultExtension tc)++test_new_delete tc = delete tc++e @=?: a = liftIO $ e @=? a+e @?=: a = liftIO $ e @?= a+e @?: msg = liftIO $ runTCM e @? msg++test_ecode tc =+    withoutFileM (dbname tc) $ \fn -> do+        open tc fn [OREADER]+        ecode tc >>= (ENOFILE @=?:)++test_open_close tc =+    withoutFileM (dbname tc) $ \fn -> do+      not `liftM` open tc fn [OREADER] @?: "file does not exist"+      open tc fn [OREADER, OWRITER, OCREAT] @?: "open"+      close tc @?: "close"+      not `liftM` close tc @?: "cannot close closed file"++test_putxx tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          put tc' "1" "bar"+          get tc' "1" >>= (Just "bar" @=?:)+          putkeep tc' "1" "baz"+          get tc' "1" >>= (Just "bar" @=?:)+          putcat tc' "1" "baz"+          get tc' "1" >>= (Just "barbaz" @=?:)++test_out tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          put tc' "1" "bar"+          get tc' "1" >>= (Just "bar" @=?:)+          out tc' "1" @?: "out succeeded"+          get tc' "1" >>= ((Nothing :: Maybe String) @=?:)++test_put_get tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          put tc' "1" "foo"+          put tc' "2" "bar"+          put tc' "3" "baz"+          get tc' "1" >>= (Just "foo" @=?:)+          get tc' "2" >>= (Just "bar" @=?:)+          get tc' "3" >>= (Just "baz" @=?:)++test_vsiz tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          put tc' "1" "bar"+          vsiz tc' "1" >>= (Just 3 @=?:)+          vsiz tc' "2" >>= ((Nothing :: Maybe Int) @=?:)++test_iterate tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          let keys = [1..3] :: [Int]+              vals = ["foo", "bar", "baz"]+          zipWithM_ (put tc') keys vals+          iterinit tc'+          keys' <- sequence $ replicate (length keys) (iternext tc')+          (sort $ catMaybes keys') @?=: (sort keys)++test_fwmkeys tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          mapM_ (uncurry (put tc')) ([ ("foo", 100)+                                     , ("bar", 200)+                                     , ("baz", 201)+                                     , ("jkl", 300)] :: [(String, Int)])+          fwmkeys tc' "ba" 10 >>= (["bar", "baz"] @=?:) . sort+          fwmkeys tc' "ba" 1 >>= (["bar"] @=?:)+          fwmkeys tc' "" 10 >>= (["bar", "baz", "foo", "jkl"] @=?:) . sort++test_fwmkeys_fdb tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          zipWithM_ (put tc') ([1..10] :: [Int]) ([100, 200..1000] :: [Int])+          fwmkeys tc' "[min,max]" 10 >>= (([1..10] :: [Int]) @=?:)++test_addint tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          let ini = 32 :: Int+          put tc' "100" ini+          get tc' "100" >>= (Just ini @=?:)+          addint tc' "100" 3+          get tc' "100" >>= (Just (ini+3) @=?:)+          addint tc' "200" 1 >>= (Just 1 @=?:)+          put tc' "200" "foo"+          addint tc' "200" 1 >>= (Nothing @=?:)++test_adddouble tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+          let ini = 0.003 :: Double+          put tc' "100" ini+          get tc' "100" >>= (Just ini @=?:)+          adddouble tc' "100" 0.3+          (get tc' "100" >>= (return . isIn (ini+0.3))) @?: "isIn"+          adddouble tc' "200" 0.5 >>= (Just 0.5 @=?:)+          put tc' "200" "foo"+          adddouble tc' "200" 1.2 >>= (Nothing @=?:)+    where+      margin = 1e-30+      isIn :: Double -> (Maybe Double) -> Bool+      isIn expected (Just actual) =+          let diff = expected - actual+          in abs diff <= margin++test_vanish tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' -> do+            put tc' "100" "111"+            put tc' "200" "222"+            put tc' "300" "333"+            rnum tc' >>= (3 @=?:)+            vanish tc'+            rnum tc' >>= (0 @=?:)++test_copy tc =+    withoutFileM (dbname tc) $ \fns ->    +        withoutFileM ("bar" ++ defaultExtension tc) $ \fnd ->+            withOpenedTC fns tc $ \tc' -> do+                put tc' "100" "bar"+                copy tc' fnd+                close tc'+                open tc' fnd [OREADER]+                get tc' "100" >>= (Just "bar" @=?:)++test_path tc =+    withoutFileM (dbname tc) $ \fn ->+        withOpenedTC fn tc $ \tc' ->+            path tc' >>= (Just (dbname tc) @=?:)++test_util tc =+    withoutFileM (dbname tc) $ \fn -> do+      open tc fn [OWRITER, OCREAT]+      path tc >>= (Just fn @=?:)+      rnum tc >>= (0 @=?:)+      ((> 0) `liftM` size tc) @?: "fsiz"+      sync tc @?: "sync"+      close tc++tests = test [+          "new delete BDB" ~: (runTCM $ bdb test_new_delete)+        , "new delete HDB" ~: (runTCM $ hdb test_new_delete)+        , "new delete FDB" ~: (runTCM $ fdb test_new_delete)+        , "new delete B.BDB" ~: (runTCM $ bbdb test_new_delete)+        , "ecode BDB" ~: (runTCM $ bdb test_ecode)+        , "ecode HDB" ~: (runTCM $ hdb test_ecode)+        , "ecode FDB" ~: (runTCM $ fdb test_ecode)+        , "ecode B.BDB" ~: (runTCM $ bbdb test_ecode)+        , "open close BDB" ~: (runTCM $ bdb test_open_close)+        , "open close HDB" ~: (runTCM $ hdb test_open_close)+        , "open close FDB" ~: (runTCM $ fdb test_open_close)+        , "open close B.BDB" ~: (runTCM $ bbdb test_open_close)+        , "putxxx BDB" ~: (runTCM $ bdb test_putxx)+        , "putxxx HDB" ~: (runTCM $ hdb test_putxx)+        , "putxxx FDB" ~: (runTCM $ fdb test_putxx)+        , "putxxx B.BDB" ~: (runTCM $ bbdb test_putxx)+        , "out BDB" ~: (runTCM $ bdb test_out)+        , "out HDB" ~: (runTCM $ hdb test_out)+        , "out FDB" ~: (runTCM $ fdb test_out)+        , "out B.BDB" ~: (runTCM $ bbdb test_out)+        , "put get BDB" ~: (runTCM $ bdb test_put_get)+        , "put get HDB" ~: (runTCM $ hdb test_put_get)+        , "put get FDB" ~: (runTCM $ fdb test_put_get)+        , "put get B.BDB" ~: (runTCM $ bbdb test_put_get)+        , "vsiz BDB" ~: (runTCM $ bdb test_vsiz)+        , "vsiz HDB" ~: (runTCM $ hdb test_vsiz)+        , "vsiz FDB" ~: (runTCM $ fdb test_vsiz)+        , "vsiz B.BDB" ~: (runTCM $ bbdb test_vsiz)+        , "iterate BDB" ~: (runTCM $ bdb test_iterate)+        , "iterate HDB" ~: (runTCM $ hdb test_iterate)+        , "iterate FDB" ~: (runTCM $ fdb test_iterate)+        , "fwmkeys BDB" ~: (runTCM $ bdb test_fwmkeys)+        , "fwmkeys HDB" ~: (runTCM $ hdb test_fwmkeys)+        , "fwmkeys FDB" ~: (runTCM $ fdb test_fwmkeys_fdb)+        , "fwmkeys B.BDB" ~: (runTCM $ bbdb test_fwmkeys)+        , "addint BDB" ~: (runTCM $ bdb test_addint)+        , "addint HDB" ~: (runTCM $ hdb test_addint)+        , "addint FDB" ~: (runTCM $ fdb test_addint)+        , "addint B.BDB" ~: (runTCM $ bbdb test_addint)+        , "adddouble BDB" ~: (runTCM $ bdb test_adddouble)+        , "adddouble HDB" ~: (runTCM $ hdb test_adddouble)+        , "adddouble FDB" ~: (runTCM $ fdb test_adddouble)+        , "adddouble B.BDB" ~: (runTCM $ bbdb test_adddouble)+        , "vanish BDB" ~: (runTCM $ bdb test_vanish)+        , "vanish HDB" ~: (runTCM $ hdb test_vanish)+        , "vanish FDB" ~: (runTCM $ fdb test_vanish)+        , "vanish B.BDB" ~: (runTCM $ bbdb test_vanish)+        , "copy BDB" ~: (runTCM $ bdb test_copy)+        , "copy HDB" ~: (runTCM $ hdb test_copy)+        , "copy FDB" ~: (runTCM $ fdb test_copy)+        , "copy B.BDB" ~: (runTCM $ bbdb test_copy)+        , "path BDB" ~: (runTCM $ bdb test_path)+        , "path HDB" ~: (runTCM $ hdb test_path)+        , "path FDB" ~: (runTCM $ fdb test_path)+        , "path B.BDB" ~: (runTCM $ bbdb test_path)+        , "util BDB" ~: (runTCM $ bdb test_util)+        , "util HDB" ~: (runTCM $ hdb test_util)+        , "util FDB" ~: (runTCM $ fdb test_util)+        , "util B.BDB" ~: (runTCM $ bbdb test_util)+        , "new delete TDB" ~: (runTCM $ tdb test_new_delete)+        , "ecode TDB" ~: (runTCM $ tdb test_ecode)+        , "open close TDB" ~: (runTCM $ tdb test_open_close)+        , "iterate TDB" ~: (runTCM $ tdb test_iterate)+        , "fwmkeys B.BDB" ~: (runTCM $ bbdb test_fwmkeys)+        , "vanish TDB" ~: (runTCM $ tdb test_vanish)+        , "path TDB" ~: (runTCM $ tdb test_path)+        , "util TDB" ~: (runTCM $ tdb test_util)+        ]++main = runTestTT tests
+ tests/TDBQRYTest.hs view
@@ -0,0 +1,150 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import Data.IORef+import Data.List (isPrefixOf)+import Database.TokyoCabinet.TDB+import Database.TokyoCabinet.TDB.Query hiding (new, delete)+import qualified Database.TokyoCabinet.TDB.Query as Q (new, delete)++dbname :: String+dbname = "foo.tct"++withOpenedTDB :: String -> (TDB -> IO a) -> IO ()+withOpenedTDB name action = do+  h <- new+  open h name [OWRITER, OCREAT]+  action h+  close h+  return ()++test_new_delete = do+  tdb <- new+  qry <- Q.new tdb+  Q.delete qry+  delete tdb++samples :: [ (String, AssocList String String) ]+samples = [ ("hop" , AssocList [("foo", "1"), ("bar", "abc")])+          , ("step", AssocList [("foo", "2"), ("bar", "def")])+          , ("jump", AssocList [("foo", "3"), ("bar", "deg")]) ]+++test_addcond =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "1"+               search qry >>= (["step", "jump"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" QCSTRBW "de"+               search qry >>= (["step", "jump"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" QCSTRBW "de"+               search qry >>= (["step", "jump"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" (QCNEGATE QCSTRBW) "de"+               search qry >>= (["hop"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" QCSTRRX ".e."+               search qry >>= (["step", "jump"] @=?)++test_setorder =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "0"+               setorder qry "bar" QOSTRDESC+               search qry >>= (["jump", "step", "hop"] @=?)+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "0"+               setorder qry "bar" QOSTRASC+               search qry >>= (["hop", "step", "jump"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" QCSTRBW ""+               setorder qry "foo" QONUMDESC+               search qry >>= (["jump", "step", "hop"] @=?)+               qry <- Q.new tdb+               addcond qry "bar" QCSTRBW ""+               setorder qry "foo" QONUMASC+               search qry >>= (["hop", "step", "jump"] @=?)++test_setlimit =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "0"+               setlimit qry 1 0+               search qry >>= (["hop"] @=?)+               setlimit qry 1 1+               search qry >>= (["step"] @=?)+               setlimit qry 2 2+               search qry >>= (["jump"] @=?)+               setlimit qry 2 1+               search qry >>= (["step", "jump"] @=?)++test_searchout =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "2"+               searchout qry @? "searchout"+               fwmkeys tdb "" (-1) >>= (["hop", "step"] @=?)++test_hint =+    withoutFile dbname $ \fn ->+    withoutFile (dbname ++ ".idx.foo.dec") $ \_ ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGT "2"+               search qry :: IO [String]+               ("scanning the whole table" `isPrefixOf`) `fmap` hint qry @? "whole"+               setindex tdb "foo" ITDECIMAL+               search qry :: IO [String]+               ("using an index: \"foo\"" `isPrefixOf`) `fmap` hint qry @? "index"++test_proc1 =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGE "2"+               (proc qry $ \pkey (AssocList cols) -> do+                 let val = [(k, v ++ "!") | (k, v) <- cols] :: [(String, String)]+                 return $ QPPUT (AssocList val)) @? "proc"+               (AssocList res) <- get tdb "step"+               lookup "foo" res @?= Just "2!"+               (AssocList res) <- get tdb "jump"+               lookup "foo" res @?= Just "3!"++test_proc2 =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               acc <- newIORef [] :: IO (IORef [String])+               qry <- Q.new tdb+               addcond qry "foo" QCNUMGE "1"+               proc qry $ \pkey (AssocList cols) -> do+                 let Just foo = lookup "foo" cols+                 writeIORef acc . (foo:) =<< readIORef acc+                 return $ if foo == "2" then QPSTOP else QPNOP+               readIORef acc >>= (["2", "1"] @=?)++tests = test [+          "new delete" ~: test_new_delete+        , "addcond" ~: test_addcond+        , "setorder" ~: test_setorder+        , "setlimit" ~: test_setlimit+        , "searchout" ~: test_searchout+        , "hint" ~: test_hint+        , "proc1" ~: test_proc1+        , "proc2" ~: test_proc2+        ]++main = runTestTT tests
+ tests/TDBTest.hs view
@@ -0,0 +1,203 @@+module Main where++import Test.HUnit hiding (path)+import TestUtil+import System.Directory+import Database.TokyoCabinet.TDB++dbname :: String+dbname = "foo.tct"++withOpenedTDB :: String -> (TDB -> IO a) -> IO ()+withOpenedTDB name action = do+  h <- new+  open h name [OWRITER, OCREAT]+  action h+  close h+  return ()++test_ecode =+    withoutFile dbname $ \fn -> do+        h <- new+        open h fn [OREADER]+        ecode h >>= (ENOFILE @=?)++test_new_delete = do+  tdb <- new+  delete tdb++test_open_close =+    withoutFile dbname $ \fn -> do+      tdb <- new+      not `fmap` open tdb fn [OREADER] @? "file does not exist"+      open tdb fn [OWRITER, OCREAT] @? "open"+      close tdb @? "close"+      not `fmap` close tdb @? "cannot close closed file"++test_util =+    withoutFile dbname $ \fn -> do+      tdb <- new+      setcache tdb 10000 4096 512 @? "setcache"+      setxmsiz tdb 67108864 @? "setxmsiz"+      tune tdb 100000 (-1) (-1) [TLARGE, TBZIP] @? "tune"+      open tdb fn [OWRITER, OCREAT] @? "open"+      path tdb >>= (Just fn @=?)+      rnum tdb >>= (0 @=?)+      ((> 0) `fmap` fsiz tdb) @? "fsiz"+      sync tdb @? "sync"+      optimize tdb 0 0 0 [] @? "optimize"+      close tdb++samples :: [ (String, AssocList String String) ]+samples = [ ("1", AssocList [("foo", "1"), ("bar", "2")])+          , ("2", AssocList [("foo", "1"), ("bar", "3")])+          , ("3", AssocList [("foo", "2"), ("bar", "1")]) ]++samples' :: [(String, String)]+samples' = [ ("1", "foo\0" ++ "1\0bar\0" ++ "2")+           , ("2", "foo\0" ++ "1\0bar\0" ++ "3")+           , ("3", "foo\0" ++ "2\0bar\0" ++ "1") ]++test_put =+    withoutFile dbname $ \fn -> do+      withOpenedTDB fn $ \tdb ->+          do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+             get tdb "1" >>= (hd @=?)+             putkeep tdb "4" (AssocList [("foo", "10"), ("bar", "20")]) @? "putkeep"+             putkeep tdb "1" (AssocList [("foo", "10"), ("bar", "20")])+             get tdb "1" >>= (hd @=?)+             putcat tdb "1" (AssocList [("baz", "3")]) @? "putcat"+             get tdb "1" >>= (AssocList [("foo", "1"), ("bar", "2"), ("baz", "3")] @=?)+          where+            hd = snd (head samples)++test_put' =+    withoutFile dbname $ \fn -> do+      withOpenedTDB fn $ \tdb ->+          do all id `fmap` mapM (uncurry $ put' tdb) samples' @? "put'"+             get' tdb "1" >>= (Just hd @=?)+             putkeep' tdb "4" ("foo\0" ++ "10\0bar\0" ++ "20") @? "putkeep'"+             putkeep' tdb "1" ("foo\0" ++ "10\0bar\0" ++ "20")+             get' tdb "1" >>= (Just hd @=?)+             putcat' tdb "1" ("baz\0" ++ "3") @? "putcat'"+             get' tdb "1" >>= (Just ("foo\0" ++ "1\0bar\0" ++ "2\0baz\0" ++ "3") @=?)+          where+            hd = snd (head samples')+test_out =+    withoutFile dbname $ \fn -> do+      withOpenedTDB fn $ \tdb ->+          do put tdb "1" (AssocList [("foo", "100"), ("bar", "200")]) @? "put"+             get tdb "1" >>= (AssocList [("foo", "100"), ("bar", "200")] @=?)+             out tdb "1" @? "out"+             get tdb "1" >>= (AssocList ([] :: [(String, String)]) @=?)++test_txn =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb -> do+          let sample = AssocList [("foo", "100"), ("bar", "200")]+              empty = AssocList [] :: AssocList String String+          tranbegin tdb+          put tdb "1" sample+          get tdb "1" >>= (sample @=?)+          tranabort tdb+          get tdb "1" >>= (empty @=?)+          tranbegin tdb+          put tdb "1" sample+          get tdb "1" >>= (sample @=?)+          trancommit tdb+          get tdb "1" >>= (sample @=?)++test_iter =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               iterinit tdb @? "iterinit"+               iternext tdb >>= (Just "1" @=?)+               iternext tdb >>= (Just "2" @=?)+               iternext tdb >>= (Just "3" @=?)+               iternext tdb >>= ((Nothing :: Maybe String) @=?)++test_vanish =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               get tdb "1" >>= (snd (head samples) @=?)+               vanish tdb+               get tdb "1" >>= ((AssocList [] :: AssocList String String) @=?)++test_copy =+    withoutFile dbname $ \fns ->+        withoutFile "bar.tcb" $ \fnd ->+            withOpenedTDB fns $ \tdb ->+                do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+                   copy tdb fnd @? "copy"+                   close tdb+                   open tdb fnd [OREADER]+                   get tdb "1" >>= (snd (head samples) @=?)++test_vsiz =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               vsiz tdb "1" >>= (Just 12 @=?)+               vsiz tdb "10" >>= (Nothing @=?)++test_add =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               addint tdb "1" 1 >>= (Just 1 @=?)+               addint tdb "1" 1 >>= (Just 2 @=?)+               v <- get tdb "1"+               lookup "_num" (unAssocList v) @?= Just "2"+               adddouble tdb "2" 1.2 >>= (Just 1.2 @=?)+               adddouble tdb "2" 1.2 >>= (Just 2.4 @=?)+               v <- get tdb "2"+               lookup "_num" (unAssocList v) @?= Just "2.4"++test_fwmkeys =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do put tdb "foo" (AssocList [("foo", "100")])+               put tdb "bar" (AssocList [("foo", "100")])+               put tdb "baz" (AssocList [("foo", "100")])+               fwmkeys tdb "ba" 10 >>= (["bar", "baz"] @=?)+               fwmkeys tdb "bak" 10 >>= (([] :: [String]) @=?)+               fwmkeys tdb "" 2 >>= (["foo", "bar"] @=?)++test_genuid =+    withoutFile dbname $ \fn -> do+      tdb <- new+      genuid tdb >>= (Nothing @=?)+      open tdb fn [OWRITER, OCREAT]+      genuid tdb >>= (Just 1 @=?)+      close tdb++test_setindex =+    withoutFile dbname $ \fn ->+        withOpenedTDB fn $ \tdb ->+            do all id `fmap` mapM (uncurry $ put tdb) samples @? "put"+               withoutFile (dbname ++ ".idx.foo.dec") $ \ifn -> do+                   setindex tdb "foo" ITDECIMAL+                   doesFileExist ifn @? "index"++tests = test [+          "new delete" ~: test_new_delete+        , "ecode" ~: test_ecode+        , "open close"  ~: test_open_close+        , "util" ~: test_util+        , "put" ~: test_put+        , "put'" ~: test_put'+        , "out" ~: test_out+        , "transaction" ~: test_txn+        , "iterate" ~: test_iter+        , "vanish" ~: test_vanish+        , "copy" ~: test_copy+        , "vsiz" ~: test_vsiz+        , "add" ~: test_add+        , "fwmkeys" ~: test_fwmkeys+        , "genuid" ~: test_genuid+        , "setindex" ~: test_setindex+        ]++main = runTestTT tests
tokyocabinet-haskell.cabal view
@@ -1,11 +1,11 @@ Name:           tokyocabinet-haskell-Version:        0.0.5-Cabal-Version:  >= 1.6+Version:        0.0.6+Cabal-Version:  >= 1.10 License:        BSD3 License-File:   LICENSE Author:         Tom Tsuruhara-Maintainer:     tom.lpsd@gmail.com-Homepage:       http://tom-lpsd.github.com/tokyocabinet-haskell/+Maintainer:     Stephen Paul Weber <singpolyma@singpolyma.net>+Homepage:       https://git.singpolyma.net/tokyocabinet-haskell Stability:      experimental Category:       Database Synopsis:       Haskell binding of Tokyo Cabinet@@ -23,14 +23,11 @@  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+  location: https://git.singpolyma.net/tokyocabinet-haskell  Library-  Build-Depends:        base >= 4.0, bytestring >= 0.9, mtl >= 1.1+  Default-Language:     Haskell2010+  Build-Depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, mtl >= 1.1   Exposed-modules:     Database.TokyoCabinet     Database.TokyoCabinet.HDB@@ -59,10 +56,231 @@    Other-modules:     Database.TokyoCabinet.Internal-  Extensions:           CPP, ForeignFunctionInterface,+  Default-Extensions:   CPP, ForeignFunctionInterface,                         EmptyDataDecls, TypeSynonymInstances,                         GeneralizedNewtypeDeriving   Extra-libraries:      tokyocabinet   Extra-lib-dirs:       /usr/local/lib   Include-dirs:         /usr/local/include   GHC-Options:          -Wall++test-suite ListTest+  Default-Language:     Haskell2010+  Main-Is:              tests/ListTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Storable++test-suite MapTest+  Default-Language:     Haskell2010+  Main-Is:              tests/MapTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Map+    Database.TokyoCabinet.Map.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable++test-suite HDBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/HDBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.HDB+    Database.TokyoCabinet.HDB.C+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable++test-suite BDBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/BDBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.BDB+    Database.TokyoCabinet.BDB.C+    Database.TokyoCabinet.BDB.Cursor+    Database.TokyoCabinet.BDB.Cursor.C+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable++test-suite FDBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/FDBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.FDB+    Database.TokyoCabinet.FDB.C+    Database.TokyoCabinet.FDB.Key+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable++test-suite TDBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/TDBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.Associative+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Map+    Database.TokyoCabinet.Map.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable+    Database.TokyoCabinet.TDB+    Database.TokyoCabinet.TDB.C++test-suite TDBQRYTest+  Default-Language:     Haskell2010+  Main-Is:              tests/TDBQRYTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.Associative+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.FDB.C+    Database.TokyoCabinet.FDB.Key+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Map+    Database.TokyoCabinet.Map.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable+    Database.TokyoCabinet.TDB+    Database.TokyoCabinet.TDB.C+    Database.TokyoCabinet.TDB.Query+    Database.TokyoCabinet.TDB.Query.C++test-suite ADBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/ADBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet.ADB+    Database.TokyoCabinet.ADB.C+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Storable+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Internal++test-suite TCDBTest+  Default-Language:     Haskell2010+  Main-Is:              tests/TCDBTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet+    Database.TokyoCabinet.Associative+    Database.TokyoCabinet.BDB+    Database.TokyoCabinet.BDB.C+    Database.TokyoCabinet.BDB.Cursor+    Database.TokyoCabinet.BDB.Cursor.C+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.FDB+    Database.TokyoCabinet.FDB.C+    Database.TokyoCabinet.FDB.Key+    Database.TokyoCabinet.HDB+    Database.TokyoCabinet.HDB.C+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Map+    Database.TokyoCabinet.Map.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable+    Database.TokyoCabinet.TDB+    Database.TokyoCabinet.TDB.C++test-suite StorableTest+  Default-Language:     Haskell2010+  Main-Is:              tests/StorableTest.hs+  Type:                 exitcode-stdio-1.0+  Extra-libraries:      tokyocabinet+  Build-depends:        base >= 4.0 && < 4.12, bytestring >= 0.9, HUnit >= 1.2, directory >= 1.0, mtl >= 1.1+  Default-Extensions:   CPP, ForeignFunctionInterface,+                        EmptyDataDecls, TypeSynonymInstances+  Other-modules:+    TestUtil+    Database.TokyoCabinet+    Database.TokyoCabinet.Associative+    Database.TokyoCabinet.BDB+    Database.TokyoCabinet.BDB.C+    Database.TokyoCabinet.BDB.Cursor+    Database.TokyoCabinet.BDB.Cursor.C+    Database.TokyoCabinet.Error+    Database.TokyoCabinet.FDB+    Database.TokyoCabinet.FDB.C+    Database.TokyoCabinet.FDB.Key+    Database.TokyoCabinet.HDB+    Database.TokyoCabinet.HDB.C+    Database.TokyoCabinet.Internal+    Database.TokyoCabinet.List+    Database.TokyoCabinet.List.C+    Database.TokyoCabinet.Map+    Database.TokyoCabinet.Map.C+    Database.TokyoCabinet.Sequence+    Database.TokyoCabinet.Storable+    Database.TokyoCabinet.TDB+    Database.TokyoCabinet.TDB.C