module Hasql.Private.Session.UnliftIO where
import Control.Monad.Reader.Class (ask)
import Control.Monad.Error.Class (throwError)
import Control.Monad.IO.Unlift
import Control.Exception.Safe
import Hasql.Session
instance MonadUnliftIO Session where
withRunInIO :: ((forall a. Session a -> IO a) -> IO b) -> Session b
withRunInIO (forall a. Session a -> IO a) -> IO b
inner = do
Connection
conn <- Session Connection
forall r (m :: * -> *). MonadReader r m => m r
ask
Either QueryError b
res <- IO (Either QueryError b) -> Session (Either QueryError b)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either QueryError b) -> Session (Either QueryError b))
-> IO (Either QueryError b) -> Session (Either QueryError b)
forall a b. (a -> b) -> a -> b
$ IO b -> IO (Either QueryError b)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (IO b -> IO (Either QueryError b))
-> IO b -> IO (Either QueryError b)
forall a b. (a -> b) -> a -> b
$ (forall a. Session a -> IO a) -> IO b
inner ((forall a. Session a -> IO a) -> IO b)
-> (forall a. Session a -> IO a) -> IO b
forall a b. (a -> b) -> a -> b
$ \Session a
sess -> do
Session a -> Connection -> IO (Either QueryError a)
forall a. Session a -> Connection -> IO (Either QueryError a)
run Session a
sess Connection
conn IO (Either QueryError a) -> (Either QueryError a -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (QueryError -> IO a) -> (a -> IO a) -> Either QueryError a -> IO a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either QueryError -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
case Either QueryError b
res of
Left QueryError
e -> QueryError -> Session b
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError QueryError
e
Right b
a -> b -> Session b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
a