{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | This module makes tokyotyrant-haskell monadic. module Database.Monarch ( -- * Basic Types Key, Value, Host, Port -- * TokyoTyrant DB action monad and its runner , Monarch, runMonarch -- * Fetch/store single key/value , get, put, putKeep -- * Fetch/store multiple key/value , mget, mput -- * Delete key/value , delete, vanish -- * Search key prefix , fwmkeys ) where import qualified Database.TokyoTyrant.FFI as TT import Data.ByteString import Control.Applicative import Control.Monad.Reader import Control.Monad.Error import Control.Exception type Key = ByteString type Value = ByteString type Host = ByteString type Port = Int -- | A monad supporting TokyoTyrant access. newtype Monarch a = Monarch { unMonarch :: ErrorT String (ReaderT TT.Connection IO) a} deriving ( Functor, Applicative, Monad, MonadIO , MonadReader TT.Connection, MonadError String ) -- | Run Monarch with TokyoTyrant at target host and port. runMonarch :: MonadIO m => Host -- ^ host -> Port -- ^ port -> Monarch a -- ^ action -> m (Either String a) runMonarch host port monarch = liftIO $ bracket open' close' action where action = (return . Left) `either` (runReaderT . runErrorT . unMonarch $ monarch) open' = TT.open host port close' = (const $ return ()) `either` TT.close liftMonarch :: (MonadIO m, MonadError a m) => IO (Either a b) -> m b liftMonarch action = liftIO action >>= either throwError return -- | Get a value. If not found, return Nothing. get :: Key -- ^ key -> Monarch (Maybe Value) get key = do conn <- ask liftMonarch $ TT.get conn key -- | Destructive store a value. put :: Key -- ^ key -> Value -- ^ value -> Monarch () put key value = do conn <- ask liftMonarch $ TT.put conn key value -- | Non-Destructive store a value. putKeep :: Key -- ^ key -> Value -- ^ value -> Monarch () putKeep key value = do conn <- ask liftMonarch $ TT.putKeep conn key value -- | Get values. mget :: [Key] -- ^ keys to get -> Monarch [(Key, Value)] mget keys = do conn <- ask liftMonarch $ TT.mget conn keys -- | Put values. mput :: [(Key, Value)] -- ^ key/value pairs to put -> Monarch () mput kvs = do conn <- ask liftMonarch $ TT.mput conn kvs -- | Delete a value. delete :: Key -- ^ key to delete -> Monarch () delete key = do conn <- ask liftMonarch $ TT.delete conn key -- | Delete all value. vanish :: Monarch () vanish = do conn <- ask liftMonarch $ TT.vanish conn -- | Search keys by prefix. fwmkeys :: ByteString -- ^ key prefix -> Maybe Int -- ^ max # of returned keys; -- Nothing means no limit -> Monarch [Key] fwmkeys key n = do conn <- ask liftMonarch $ TT.fwmkeys conn key (maybe (-1) id n)