123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- {-# LANGUAGE OverloadedStrings #-}
- {-# LANGUAGE TypeFamilies #-}
- {-# OPTIONS_GHC -Wno-orphans #-}
- module Database.Persist.Redis.Config
- ( RedisAuth (..)
- , RedisConf (..)
- , R.RedisCtx
- , R.Redis
- , R.Connection
- , R.PortID (..)
- , RedisT
- , runRedisPool
- , withRedisConn
- , thisConnection
- , module Database.Persist
- ) where
- import Control.Monad.IO.Class (MonadIO (..))
- import Control.Monad.Reader(ReaderT(..))
- import Control.Monad.Reader.Class
- import Data.Aeson (Value (Object, Number, String), (.:?), (.!=), FromJSON(..))
- import qualified Data.ByteString.Char8 as B
- import Control.Monad (mzero, MonadPlus(..))
- import Data.Scientific() -- we require only RealFrac instance of Scientific
- import Data.Text (Text, unpack, pack)
- import qualified Database.Redis as R
- import Database.Persist
- newtype RedisAuth = RedisAuth Text deriving (Eq, Show)
- -- | Information required to connect to a Redis server
- data RedisConf = RedisConf {
- rdHost :: Text, -- ^ Host
- rdPort :: R.PortID, -- ^ Port
- rdAuth :: Maybe RedisAuth, -- ^ Auth info
- rdMaxConn :: Int -- ^ Maximum number of connections
- } deriving (Show)
- instance FromJSON R.PortID where
- parseJSON (Number x) = (return . R.PortNumber . fromInteger . truncate) x
- parseJSON _ = fail "persistent Redis: couldn't parse port number"
- instance FromJSON RedisAuth where
- parseJSON (String t) = (return . RedisAuth) t
- parseJSON _ = fail "persistent ResisAuth: couldn't parse auth"
- -- | Monad reader transformer keeping Redis connection through out the work
- type RedisT = ReaderT R.Connection
- -- | Extracts connection from RedisT monad transformer
- thisConnection :: Monad m => RedisT m R.Connection
- thisConnection = ask
- -- | Run a connection reader function against a Redis configuration
- withRedisConn :: (MonadIO m) => RedisConf -> (R.Connection -> m a) -> m a
- withRedisConn conf connectionReader = do
- conn <- liftIO $ createPoolConfig conf
- connectionReader conn
- runRedisPool :: RedisT m a -> R.Connection -> m a
- runRedisPool r = runReaderT r
- instance PersistConfig RedisConf where
- type PersistConfigBackend RedisConf = RedisT
- type PersistConfigPool RedisConf = R.Connection
- loadConfig (Object o) = do
- host <- o .:? "host" .!= R.connectHost R.defaultConnectInfo
- port <- o .:? "port" .!= R.connectPort R.defaultConnectInfo
- mPass <- o .:? "password"
- maxConn <- o .:? "maxConn" .!= R.connectMaxConnections R.defaultConnectInfo
- return RedisConf {
- rdHost = pack host,
- rdPort = port,
- rdAuth = mPass,
- rdMaxConn = maxConn
- }
- loadConfig _ = mzero
- createPoolConfig (RedisConf h p Nothing m) =
- R.connect $
- R.defaultConnectInfo {
- R.connectHost = unpack h,
- R.connectPort = p,
- R.connectMaxConnections = m
- }
- createPoolConfig (RedisConf h p (Just (RedisAuth pwd)) m) =
- R.connect $
- R.defaultConnectInfo {
- R.connectHost = unpack h,
- R.connectPort = p,
- R.connectAuth = Just $ B.pack $ unpack pwd,
- R.connectMaxConnections = m
- }
- runPool _ = runRedisPool
|