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