{-# LANGUAGE OverloadedStrings #-}

import           Control.Concurrent
import           Control.Exception (bracket)
import qualified Database.PostgreSQL.LibPQ as PQ  -- from postgresql-libpq
import           Control.Concurrent

withConn connstr = bracket (PQ.connectdb connstr) (PQ.finish)

connstr = "dbname=postgres"

main = withConn connstr $ \conn -> do 
  stat <- PQ.status conn
  case stat of
    PQ.ConnectionOk -> return ()
    _ -> fail (show stat)

  Just res <- PQ.exec conn "LISTEN test_channel"
  stat <- PQ.resultStatus res
  case stat of
    PQ.CommandOk -> return ()
    _ -> fail (show stat)

  monitor conn

monitor conn = st_wait
  where
    st_wait = do
      mfd <- PQ.socket conn
      case mfd of
        Just fd -> do
          threadWaitRead fd
          _bool <- PQ.consumeInput conn
          st_notices
        Nothing -> putStrLn "exiting..." 

    st_notices = do
      x <- PQ.notifies conn
      case x of
        Nothing -> st_wait
        Just notify -> do
          putStr ("notifyRelname:  ")
          print  (PQ.notifyRelname  notify)
          putStr ("notifyBePid:    ")
          print  (PQ.notifyBePid    notify)
          putStr ("notifyExtra:    ")
          print  (PQ.notifyExtra    notify)
          putStrLn ""
          st_notices
