module Hasql.Queue.Low.ExactlyOnce ( enqueue , withDequeue , withDequeueWith ) where import qualified Hasql.Queue.High.ExactlyOnce as H import Control.Exception import qualified Hasql.Encoders as E import qualified Hasql.Decoders as D import Hasql.Session import Hasql.Statement import Hasql.Connection import qualified Hasql.Queue.Internal as I import Control.Monad.IO.Class import Data.Text(Text) {-|Enqueue a payload send a notification on the specified channel. -} enqueue :: Text -- ^ Notification channel name. Any valid PostgreSQL identifier -> E.Value a -- ^ Payload encoder -> [a] -- ^ List of payloads to enqueue -> Session () enqueue channel theEncoder values = do H.enqueue theEncoder values statement channel $ Statement "SELECT notify_on($1)" (E.param $ E.nonNullable E.text) D.noResult True dequeueOrRollbackAndThrow :: D.Value a -> Int -> Session [a] dequeueOrRollbackAndThrow theDecoder dequeueCount = H.dequeue theDecoder dequeueCount >>= \case [] -> liftIO $ throwIO I.NoRows xs -> pure xs withDequeue :: Text -- ^ Notification channel name. Any valid PostgreSQL identifier -> Connection -- ^ Connection -> D.Value a -- ^ Payload decoder -> Int -- ^ Batch count -> (Session [a] -> Session b) -- ^ Transaction runner -> IO b withDequeue = withDequeueWith mempty withDequeueWith :: I.WithNotifyHandlers -- ^ Event handlers for events that occur as 'withDequeWith' loops -> Text -- ^ Notification channel name. Any valid PostgreSQL identifier -> Connection -- ^ Connection -> D.Value a -- ^ Payload decoder -> Int -- ^ Batch count -> (Session [a] -> Session b) -- ^ Transaction runner -> IO b withDequeueWith withNotifyHandlers channel conn theDecoder dequeueCount runner = I.withNotifyWith withNotifyHandlers channel conn $ runner (dequeueOrRollbackAndThrow theDecoder dequeueCount)