{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

module PGExtras.Queries.Locks (locksSQL, displayLocks) where

import PGExtras.Helpers (maybeText, maybeInt, maybeBool, maybeZonedTime)
import Database.PostgreSQL.Simple
import Text.RawString.QQ
import qualified Data.Text as Text
import Data.Time (ZonedTime)
import Control.Monad (forM_)
import Data.List (intercalate)

locksSQL :: Query
locksSQL :: Query
locksSQL = [r|SELECT
  pg_stat_activity.pid,
  pg_class.relname,
  pg_locks.transactionid,
  pg_locks.granted,
  pg_locks.mode,
  pg_stat_activity.query AS query_snippet,
  pg_stat_activity.query_start
FROM pg_stat_activity,pg_locks left
OUTER JOIN pg_class
  ON (pg_locks.relation = pg_class.oid)
WHERE pg_stat_activity.query <> '<insufficient privilege>'
  AND pg_locks.pid = pg_stat_activity.pid
  AND pg_locks.mode IN ('ExclusiveLock', 'AccessExclusiveLock', 'RowExclusiveLock')
  AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;|]

displayLocks :: [(Maybe Int, Maybe Text.Text, Maybe Text.Text, Maybe Bool, Maybe Text.Text, Maybe Text.Text, Maybe ZonedTime)] -> IO ()
displayLocks :: [(Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
  Maybe Text, Maybe ZonedTime)]
-> IO ()
displayLocks rows :: [(Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
  Maybe Text, Maybe ZonedTime)]
rows = do
  String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
description
  String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate " | " [String]
tableHeaders
  [(Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
  Maybe Text, Maybe ZonedTime)]
-> ((Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
     Maybe Text, Maybe ZonedTime)
    -> IO ())
-> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
  Maybe Text, Maybe ZonedTime)]
rows (((Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
   Maybe Text, Maybe ZonedTime)
  -> IO ())
 -> IO ())
-> ((Maybe Int, Maybe Text, Maybe Text, Maybe Bool, Maybe Text,
     Maybe Text, Maybe ZonedTime)
    -> IO ())
-> IO ()
forall a b. (a -> b) -> a -> b
$ \(arg1 :: Maybe Int
arg1, arg2 :: Maybe Text
arg2, arg3 :: Maybe Text
arg3, arg4 :: Maybe Bool
arg4, arg5 :: Maybe Text
arg5, arg6 :: Maybe Text
arg6, arg7 :: Maybe ZonedTime
arg7) ->
    String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe Int -> String
maybeInt(Maybe Int
arg1) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Text -> String
maybeText(Maybe Text
arg2) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Text -> String
maybeText(Maybe Text
arg3) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Bool -> String
maybeBool(Maybe Bool
arg4) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Text -> String
maybeText(Maybe Text
arg5) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe Text -> String
maybeText(Maybe Text
arg6) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe ZonedTime -> String
maybeZonedTime(Maybe ZonedTime
arg7)

description :: [Char]
description :: String
description = "Queries with active exclusive locks"

tableHeaders :: [[Char]]
tableHeaders :: [String]
tableHeaders = ["procpid", "relname", "transactionid", "granted", "query_snippet", "mode", "query_start"]