{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Types and DDL for the @arbiter_queues@ table. One row per queue, scoped to
-- the schema. Holds operator-facing per-queue state (pause flag, metadata).
module Arbiter.Core.Queues
  ( QueueRow (..)
  , arbiterQueuesTable
  , arbiterQueuesTableName
  , createQueuesTableSQL
  ) where

import Data.Aeson (FromJSON, ToJSON, Value)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Time (UTCTime)
import GHC.Generics (Generic)

import Arbiter.Core.Job.Schema (SchemaName)
import Arbiter.Core.SqlLiterals (quoteIdentifier)

-- | A row of the @arbiter_queues@ pause/resume table.
data QueueRow = QueueRow
  { QueueRow -> Text
queueName :: Text
  , QueueRow -> Bool
paused :: Bool
  , QueueRow -> Maybe UTCTime
pausedAt :: Maybe UTCTime
  , QueueRow -> Maybe Value
metadata :: Maybe Value
  , QueueRow -> UTCTime
createdAt :: UTCTime
  , QueueRow -> UTCTime
updatedAt :: UTCTime
  }
  deriving stock (QueueRow -> QueueRow -> Bool
(QueueRow -> QueueRow -> Bool)
-> (QueueRow -> QueueRow -> Bool) -> Eq QueueRow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: QueueRow -> QueueRow -> Bool
== :: QueueRow -> QueueRow -> Bool
$c/= :: QueueRow -> QueueRow -> Bool
/= :: QueueRow -> QueueRow -> Bool
Eq, (forall x. QueueRow -> Rep QueueRow x)
-> (forall x. Rep QueueRow x -> QueueRow) -> Generic QueueRow
forall x. Rep QueueRow x -> QueueRow
forall x. QueueRow -> Rep QueueRow x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. QueueRow -> Rep QueueRow x
from :: forall x. QueueRow -> Rep QueueRow x
$cto :: forall x. Rep QueueRow x -> QueueRow
to :: forall x. Rep QueueRow x -> QueueRow
Generic, Int -> QueueRow -> ShowS
[QueueRow] -> ShowS
QueueRow -> String
(Int -> QueueRow -> ShowS)
-> (QueueRow -> String) -> ([QueueRow] -> ShowS) -> Show QueueRow
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> QueueRow -> ShowS
showsPrec :: Int -> QueueRow -> ShowS
$cshow :: QueueRow -> String
show :: QueueRow -> String
$cshowList :: [QueueRow] -> ShowS
showList :: [QueueRow] -> ShowS
Show)
  deriving anyclass (Maybe QueueRow
Value -> Parser [QueueRow]
Value -> Parser QueueRow
(Value -> Parser QueueRow)
-> (Value -> Parser [QueueRow])
-> Maybe QueueRow
-> FromJSON QueueRow
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser QueueRow
parseJSON :: Value -> Parser QueueRow
$cparseJSONList :: Value -> Parser [QueueRow]
parseJSONList :: Value -> Parser [QueueRow]
$comittedField :: Maybe QueueRow
omittedField :: Maybe QueueRow
FromJSON, [QueueRow] -> Value
[QueueRow] -> Encoding
QueueRow -> Bool
QueueRow -> Value
QueueRow -> Encoding
(QueueRow -> Value)
-> (QueueRow -> Encoding)
-> ([QueueRow] -> Value)
-> ([QueueRow] -> Encoding)
-> (QueueRow -> Bool)
-> ToJSON QueueRow
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: QueueRow -> Value
toJSON :: QueueRow -> Value
$ctoEncoding :: QueueRow -> Encoding
toEncoding :: QueueRow -> Encoding
$ctoJSONList :: [QueueRow] -> Value
toJSONList :: [QueueRow] -> Value
$ctoEncodingList :: [QueueRow] -> Encoding
toEncodingList :: [QueueRow] -> Encoding
$comitField :: QueueRow -> Bool
omitField :: QueueRow -> Bool
ToJSON)

-- | Qualified table name for the arbiter_queues table.
arbiterQueuesTable :: SchemaName -> Text
arbiterQueuesTable :: Text -> Text
arbiterQueuesTable Text
schemaName = Text -> Text
quoteIdentifier Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
arbiterQueuesTableName

-- | Bare name of the queues table, for catalog lookups by relname.
arbiterQueuesTableName :: Text
arbiterQueuesTableName :: Text
arbiterQueuesTableName = Text
"arbiter_queues"

-- | DDL for the @arbiter_queues@ table.
createQueuesTableSQL :: SchemaName -> Text
createQueuesTableSQL :: Text -> Text
createQueuesTableSQL Text
schemaName =
  [Text] -> Text
T.unlines
    [ Text
"CREATE TABLE IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
arbiterQueuesTable Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ("
    , Text
"  queue_name TEXT PRIMARY KEY,"
    , Text
"  paused BOOLEAN NOT NULL DEFAULT FALSE,"
    , Text
"  paused_at TIMESTAMPTZ,"
    , Text
"  metadata JSONB,"
    , Text
"  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),"
    , Text
"  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()"
    , Text
");"
    ]