monarch-0.9.0.0: src/Database/Monarch/Mock/Types.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module : Database.Monarch.Mock.Types
-- Copyright : 2013 Noriyuki OHKAWA
-- License : BSD3
--
-- Maintainer : n.ohkawa@gmail.com
-- Stability : experimental
-- Portability : unknown
--
-- Type definitions.
--
module Database.Monarch.Mock.Types
(
MockT
, MockDB, mockDB
, newMockDB, emptyMockDB
, runMock
, TTValue(..)
) where
import Control.Concurrent.STM.TVar
import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.Base
import Control.Applicative
import Control.Monad.Trans.Control
import qualified Data.ByteString as BS
import qualified Data.Map as M
import Database.Monarch.Types ( Code )
-- | KVS Value type
data TTValue = TTString BS.ByteString
| TTInt Int
| TTDouble Double
-- | Connection with TokyoTyrant
data MockDB = MockDB { mockDB :: M.Map BS.ByteString TTValue -- ^ DB
}
-- | The Mock monad transformer to provide TokyoTyrant access.
newtype MockT m a =
MockT { unMockT :: ErrorT Code (ReaderT (TVar MockDB) m) a }
deriving ( Functor, Applicative, Monad, MonadIO
, MonadReader (TVar MockDB), MonadError Code, MonadBase base )
instance MonadTrans MockT where
lift = MockT . lift . lift
instance MonadTransControl MockT where
newtype StT MockT a = StMock { unStMock :: Either Code a }
liftWith f = MockT . ErrorT . ReaderT $ (\r -> liftM Right (f $ \t -> liftM StMock (runReaderT (runErrorT (unMockT t)) r)))
restoreT = MockT . ErrorT . ReaderT . const . liftM unStMock
instance MonadBaseControl base m => MonadBaseControl base (MockT m) where
newtype StM (MockT m) a = StMMockT { unStMMockT :: ComposeSt MockT m a }
liftBaseWith = defaultLiftBaseWith StMMockT
restoreM = defaultRestoreM unStMMockT
-- | Empty mock DB
emptyMockDB :: MockDB
emptyMockDB = MockDB { mockDB = M.empty }
-- | Create mock DB
newMockDB :: IO (TVar MockDB)
newMockDB = newTVarIO emptyMockDB
-- | Run Mock with TokyoTyrant at target host and port.
runMock :: MonadIO m =>
MockT m a
-> TVar MockDB
-> m (Either Code a)
runMock action =
runReaderT (runErrorT $ unMockT action)