module Database.Persist.Zookeeper.Store
( ZookeeperBackend
, execZookeeperT
)where
import Database.Persist
import Control.Exception
import Control.Applicative
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Trans.Control (MonadBaseControl)
import qualified Database.Zookeeper as Z
import Data.Monoid
import qualified Data.Text as T
import Database.Persist.Zookeeper.Config (ZookeeperT(..), thisConnection)
import Database.Persist.Zookeeper.Internal
import Database.Persist.Zookeeper.ZooUtil
import Data.Pool
data ZookeeperBackend
execZookeeperT :: (Read a,Show a,Monad m, MonadIO m) => (Z.Zookeeper -> IO (Either Z.ZKError a)) -> ZookeeperT m a
execZookeeperT action = do
conn <- thisConnection
r <- liftIO $ withResource conn $ \s ->
zExec s action
case r of
(Right x) -> return x
(Left x) -> liftIO $ throwIO $ userError $ "Zookeeper error: code" ++ show x
instance (Applicative m, Functor m, MonadIO m, MonadBaseControl IO m) => PersistStore (ZookeeperT m) where
type PersistMonadBackend (ZookeeperT m) = ZookeeperBackend
insert val = do
let dir = entity2path val
let path = dir <> "/"
str <- execZookeeperT $ \zk -> do
zCreate zk dir path (Just (entity2bin val)) [Z.Sequence]
return $ txtToKey $ T.pack $ str
insertKey (Key (PersistText key)) val = do
_ <- execZookeeperT $ \zk -> do
let dir = entity2path val
zCreate zk dir (T.unpack key) (Just (entity2bin val)) []
return ()
insertKey _ _ = fail "Wrong key type in insertKey"
repsert (Key (PersistText key)) val = do
_ <- execZookeeperT $ \zk -> do
let dir = entity2path val
zRepSert zk dir (T.unpack key) (Just (entity2bin val))
return ()
repsert _ _ = fail "Wrong key type in repsert"
replace (Key (PersistText key)) val = do
execZookeeperT $ \zk -> do
_ <- zReplace zk (T.unpack key) (Just (entity2bin val))
return $ Right ()
return ()
replace _ _ = fail "Wrong key type in replace"
delete (Key (PersistText key)) = do
execZookeeperT $ \zk -> do
_ <- Z.delete zk (T.unpack key) Nothing
return $ Right ()
return ()
delete _ = fail "Wrong key type in delete"
get (Key (PersistText key)) = do
r <- execZookeeperT $ \zk -> do
val <- Z.get zk (T.unpack key) Nothing
return $ Right val
case r of
(Left Z.NoNodeError) ->
return Nothing
(Left v) ->
fail $ show v
(Right (Just str,_sta)) -> do
return (bin2entity str)
(Right (Nothing,_stat)) -> do
fail $ "data is nothing"
get _ = fail "Wrong key type in get"