-- | Interface to TC's Abstract DataBase. See also, -- for details module Database.TokyoCabinet.ADB ( -- $doc ADB , 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 (cINT_MIN) 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