module Database.PostgreSQL.PQTypes.Notification (
    Channel(..)
  , Notification(..)
  , listen
  , unlisten
  , unlistenAll
  , notify
  ) where

import Data.Text (Text)

import Data.Monoid.Utils
import Database.PostgreSQL.PQTypes.Class
import Database.PostgreSQL.PQTypes.Internal.Notification
import Database.PostgreSQL.PQTypes.SQL.Raw
import Database.PostgreSQL.PQTypes.Utils

-- | Start listening for notifications on a given channel.
{-# INLINABLE listen #-}
listen :: MonadDB m => Channel -> m ()
listen :: Channel -> m ()
listen (Channel RawSQL ()
chan) = RawSQL () -> m ()
forall sql (m :: * -> *). (IsSQL sql, MonadDB m) => sql -> m ()
runQuery_ (RawSQL () -> m ()) -> RawSQL () -> m ()
forall a b. (a -> b) -> a -> b
$ RawSQL ()
"LISTEN" RawSQL () -> RawSQL () -> RawSQL ()
forall m. (IsString m, Monoid m) => m -> m -> m
<+> RawSQL ()
chan

-- | Stop listening for notifications on a given channel.
{-# INLINABLE unlisten #-}
unlisten :: MonadDB m => Channel -> m ()
unlisten :: Channel -> m ()
unlisten (Channel RawSQL ()
chan) = RawSQL () -> m ()
forall sql (m :: * -> *). (IsSQL sql, MonadDB m) => sql -> m ()
runQuery_ (RawSQL () -> m ()) -> RawSQL () -> m ()
forall a b. (a -> b) -> a -> b
$ RawSQL ()
"UNLISTEN" RawSQL () -> RawSQL () -> RawSQL ()
forall m. (IsString m, Monoid m) => m -> m -> m
<+> RawSQL ()
chan

-- | Cancel all listener registrations for the current session.
{-# INLINABLE unlistenAll #-}
unlistenAll :: MonadDB m => m ()
unlistenAll :: m ()
unlistenAll = SQL -> m ()
forall (m :: * -> *). MonadDB m => SQL -> m ()
runSQL_ SQL
"UNLISTEN *"

-- | Generate a notification on a given channel.
{-# INLINABLE notify #-}
notify :: MonadDB m => Channel -> Text -> m ()
notify :: Channel -> Text -> m ()
notify (Channel RawSQL ()
chan) Text
payload = RawSQL (Text, Text) -> m ()
forall sql (m :: * -> *). (IsSQL sql, MonadDB m) => sql -> m ()
runQuery_
  (RawSQL (Text, Text) -> m ()) -> RawSQL (Text, Text) -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> (Text, Text) -> RawSQL (Text, Text)
forall row. (Show row, ToRow row) => Text -> row -> RawSQL row
rawSQL Text
"SELECT pg_notify($1, $2)" (RawSQL () -> Text
unRawSQL RawSQL ()
chan, Text
payload)