{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Arbiter.Core.Job.Schema
(
SchemaName
, TableName
, createSchemaSQL
, defaultSchemaName
, createJobQueueTableSQL
, createJobQueueDLQTableSQL
, createJobQueueArchiveTableSQL
, queueTableNames
, addTraceContextColumnSQL
, addClaimSeqColumnSQL
, addKindColumnSQL
, setMaxAttemptsDefaultSQL
, createJobQueueUngroupedReadyRankingIndexSQL
, createJobQueueUngroupedDueIndexSQL
, migrateUngroupedReadySplitIndexesSQL
, createDLQGroupKeyIndexSQL
, createDLQFailedAtIndexSQL
, createDLQParentIdIndexSQL
, createArchiveCompletedAtIndexSQL
, createArchiveExpiresAtIndexSQL
, createArchiveJobIdIndexSQL
, createArchiveParentIdIndexSQL
, createArchiveGroupKeyIndexSQL
, createDedupKeyIndexSQL
, createParentIdIndexSQL
, createNotifyFunctionSQL
, createNotifyTriggerSQL
, dropNotifyTriggerSQL
, dropNotifyFunctionSQL
, createEventStreamingFunctionSQL
, createEventStreamingTriggersSQL
, dropEventStreamingFunctionSQL
, dropEventStreamingTriggersSQL
, notificationChannelForTable
, eventStreamingChannel
, pauseNotifyChannel
, pauseNotifyChannelPrefix
, cancelNotifyChannel
, cancelNotifyChannelPrefix
, cronRunNotifyChannel
, notifyFunctionName
, notifyTriggerName
, eventStreamingFunctionName
, eventStreamingTriggerName
, eventStreamingDLQTriggerName
, legacyEventStreamingTriggers
, notifyObjectComment
, notifyObjectCommentPrefix
, notifyAdoptedObjectComment
, eventStreamingObjectComment
, eventStreamingObjectCommentPrefix
, eventStreamingAdoptedObjectComment
, qualifiedTable
, jobQueueTable
, jobQueueDLQTable
, jobQueueArchiveTable
, jobQueueResultsTable
, jobQueueGroupsTable
, createResultsTableSQL
, maintenanceFunctionNames
, createMaintenanceTriggersSQL
, statementTriggerSQL
) where
import Data.Bool (bool)
import Data.Text (Text)
import Data.Text qualified as T
import NeatInterpolation (text)
import Arbiter.Core.Job.Types (defaultMaxAttempts)
import Arbiter.Core.SqlLiterals (quoteIdentifier)
type SchemaName = Text
type TableName = Text
defaultSchemaName :: SchemaName
defaultSchemaName :: Text
defaultSchemaName = Text
"arbiter"
notificationChannelForTable :: TableName -> Text
notificationChannelForTable :: Text -> Text
notificationChannelForTable Text
tableName = Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_created"
eventStreamingChannel :: Text
eventStreamingChannel :: Text
eventStreamingChannel = Text
"arbiter_job_events"
pauseNotifyChannelPrefix :: SchemaName -> Text
pauseNotifyChannelPrefix :: Text -> Text
pauseNotifyChannelPrefix Text
schemaName = Text
"arbiter_pause_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_"
pauseNotifyChannel :: SchemaName -> Text -> Text
pauseNotifyChannel :: Text -> Text -> Text
pauseNotifyChannel Text
schemaName Text
queueName =
Int -> Text -> Text
T.take Int
63 (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
pauseNotifyChannelPrefix Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
queueName
cancelNotifyChannelPrefix :: SchemaName -> Text
cancelNotifyChannelPrefix :: Text -> Text
cancelNotifyChannelPrefix Text
schemaName = Text
"arbiter_cancel_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_"
cancelNotifyChannel :: SchemaName -> Text -> Text
cancelNotifyChannel :: Text -> Text -> Text
cancelNotifyChannel Text
schemaName Text
queueName =
Int -> Text -> Text
T.take Int
63 (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
cancelNotifyChannelPrefix Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
queueName
cronRunNotifyChannel :: SchemaName -> Text
cronRunNotifyChannel :: Text -> Text
cronRunNotifyChannel Text
schemaName = Int -> Text -> Text
T.take Int
63 (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text
"arbiter_cron_run_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
schemaName
notifyFunctionName :: TableName -> Text
notifyFunctionName :: Text -> Text
notifyFunctionName Text
tableName = Text
"notify_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_created"
notifyTriggerName :: TableName -> Text
notifyTriggerName :: Text -> Text
notifyTriggerName Text
tableName = Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_notify_trigger"
eventStreamingFunctionName :: Text
eventStreamingFunctionName :: Text
eventStreamingFunctionName = Text
"notify_job_event"
eventStreamingTriggerName :: TableName -> Text
eventStreamingTriggerName :: Text -> Text
eventStreamingTriggerName Text
tableName = Text
"notify_job_event_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName
eventStreamingDLQTriggerName :: TableName -> Text
eventStreamingDLQTriggerName :: Text -> Text
eventStreamingDLQTriggerName Text
tableName = Text
"notify_job_event_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_dlq"
legacyEventStreamingTriggers :: [(Text, Bool)]
legacyEventStreamingTriggers :: [(Text, Bool)]
legacyEventStreamingTriggers =
[ (Text
"notify_job_insert", Bool
False)
, (Text
"notify_job_update", Bool
False)
, (Text
"notify_job_delete", Bool
False)
, (Text
"notify_dlq_insert", Bool
True)
]
notifyObjectComment :: Text
= Text
notifyObjectCommentPrefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"v1"
notifyObjectCommentPrefix :: Text
= Text
"arbiter:notify:"
notifyAdoptedObjectComment :: Text
= Text
notifyObjectCommentPrefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"adopted"
eventStreamingObjectComment :: Text
= Text
eventStreamingObjectCommentPrefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"v1"
eventStreamingObjectCommentPrefix :: Text
= Text
"arbiter:event-stream:"
eventStreamingAdoptedObjectComment :: Text
= Text
eventStreamingObjectCommentPrefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"adopted"
qualifiedTable :: SchemaName -> TableName -> Text
qualifiedTable :: Text -> Text -> Text
qualifiedTable Text
schemaName Text
tableName = 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 -> Text
quoteIdentifier Text
tableName
jobQueueTable :: SchemaName -> TableName -> Text
jobQueueTable :: Text -> Text -> Text
jobQueueTable = Text -> Text -> Text
qualifiedTable
jobQueueDLQTable :: SchemaName -> TableName -> Text
jobQueueDLQTable :: Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName = Text -> Text -> Text
qualifiedTable Text
schemaName (Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
dlqSuffix)
jobQueueArchiveTable :: SchemaName -> TableName -> Text
jobQueueArchiveTable :: Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName = Text -> Text -> Text
qualifiedTable Text
schemaName (Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
archiveSuffix)
setMaxAttemptsDefaultSQL :: SchemaName -> TableName -> Text
setMaxAttemptsDefaultSQL :: Text -> Text -> Text
setMaxAttemptsDefaultSQL Text
schemaName Text
tableName =
let tbl :: Text
tbl = Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
dma :: Text
dma = String -> Text
T.pack (Int32 -> String
forall a. Show a => a -> String
show Int32
defaultMaxAttempts)
in [text|
UPDATE ${tbl} SET max_attempts = ${dma} WHERE max_attempts IS NULL;
ALTER TABLE ${tbl} ALTER COLUMN max_attempts SET DEFAULT ${dma};
|]
jobQueueResultsTable :: Text -> Text -> Text
jobQueueResultsTable :: Text -> Text -> Text
jobQueueResultsTable Text
schemaName Text
tableName = Text -> Text -> Text
qualifiedTable Text
schemaName (Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
resultsSuffix)
jobQueueGroupsTable :: Text -> Text -> Text
jobQueueGroupsTable :: Text -> Text -> Text
jobQueueGroupsTable Text
schemaName Text
tableName = Text -> Text -> Text
qualifiedTable Text
schemaName (Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
groupsSuffix)
dlqSuffix, archiveSuffix, resultsSuffix, groupsSuffix :: Text
dlqSuffix :: Text
dlqSuffix = Text
"_dlq"
archiveSuffix :: Text
archiveSuffix = Text
"_archive"
resultsSuffix :: Text
resultsSuffix = Text
"_results"
groupsSuffix :: Text
groupsSuffix = Text
"_groups"
queueTableNames :: TableName -> [TableName]
queueTableNames :: Text -> [Text]
queueTableNames Text
tableName = Text
tableName Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) [Text
dlqSuffix, Text
archiveSuffix, Text
resultsSuffix, Text
groupsSuffix]
createSchemaSQL :: SchemaName -> Text
createSchemaSQL :: Text -> Text
createSchemaSQL Text
schemaName =
Text
"CREATE SCHEMA IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier Text
schemaName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
jobColumns :: [Text]
jobColumns :: [Text]
jobColumns =
[ Text
" id BIGSERIAL PRIMARY KEY,"
, Text
" payload JSONB NOT NULL,"
, Text
" group_key TEXT,"
, Text
" inserted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),"
, Text
" updated_at TIMESTAMPTZ,"
, Text
" last_attempted_at TIMESTAMPTZ,"
, Text
" not_visible_until TIMESTAMPTZ,"
, Text
" attempts INT NOT NULL DEFAULT 0,"
, Text
" last_error TEXT,"
, Text
" priority INT NOT NULL DEFAULT 0,"
, Text
" dedup_key TEXT,"
, Text
" dedup_strategy TEXT,"
, Text
" max_attempts INT,"
, Text
" parent_id BIGINT,"
, Text
" parent_state JSONB,"
, Text
" suspended BOOLEAN NOT NULL DEFAULT FALSE"
]
addJobColumnsSQL :: Text -> Text -> [Text] -> Text
addJobColumnsSQL :: Text -> Text -> [Text] -> Text
addJobColumnsSQL Text
schemaName Text
tableName [Text]
columns =
[Text] -> Text
T.unlines [Text -> Text
alter (Text -> Text -> Text
tbl Text
schemaName Text
tableName) | Text -> Text -> Text
tbl <- [Text -> Text -> Text
jobQueueTable, Text -> Text -> Text
jobQueueDLQTable, Text -> Text -> Text
jobQueueArchiveTable]]
where
alter :: Text -> Text
alter Text
table = Text
"ALTER TABLE " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
table Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
", " ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
addColumn [Text]
columns) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
addColumn :: a -> a
addColumn a
column = a
"ADD COLUMN IF NOT EXISTS " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
column
addTraceContextColumnSQL :: Text -> Text -> Text
addTraceContextColumnSQL :: Text -> Text -> Text
addTraceContextColumnSQL Text
schemaName Text
tableName =
Text -> Text -> [Text] -> Text
addJobColumnsSQL Text
schemaName Text
tableName [Text
"traceparent TEXT", Text
"tracestate TEXT"]
addClaimSeqColumnSQL :: Text -> Text -> Text
addClaimSeqColumnSQL :: Text -> Text -> Text
addClaimSeqColumnSQL Text
schemaName Text
tableName =
Text -> Text -> [Text] -> Text
addJobColumnsSQL Text
schemaName Text
tableName [Text
"claim_seq BIGINT NOT NULL DEFAULT 0"]
addKindColumnSQL :: Text -> Text -> Text
addKindColumnSQL :: Text -> Text -> Text
addKindColumnSQL Text
schemaName Text
tableName =
Text -> Text -> [Text] -> Text
addJobColumnsSQL Text
schemaName Text
tableName [Text
"kind TEXT"]
jobColumnsForDLQ :: Text
jobColumnsForDLQ :: Text
jobColumnsForDLQ =
[Text] -> Text
T.unlines
[ Text
" id BIGSERIAL PRIMARY KEY,"
, Text
" failed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),"
, Text
" job_id BIGINT NOT NULL,"
]
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.unlines (Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
drop Int
1 [Text]
jobColumns)
createJobQueueTableSQL :: Text -> Text -> Text
createJobQueueTableSQL :: Text -> Text -> Text
createJobQueueTableSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE TABLE IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ("
, [Text] -> Text
T.unlines [Text]
jobColumns
, Text
") WITH (fillfactor = 70);"
]
createJobQueueDLQTableSQL :: Text -> Text -> Text
createJobQueueDLQTableSQL :: Text -> Text -> Text
createJobQueueDLQTableSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE TABLE IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ("
, Text
jobColumnsForDLQ
, Text
");"
]
jobColumnsForArchive :: Text
jobColumnsForArchive :: Text
jobColumnsForArchive =
[Text] -> Text
T.unlines
[ Text
" id BIGSERIAL PRIMARY KEY,"
, Text
" completed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),"
, Text
" archive_expires_at TIMESTAMPTZ NOT NULL,"
, Text
" job_id BIGINT NOT NULL,"
, Text
" claimed_by UUID,"
, Text
" archive_for INT,"
, Text
" rate_limit_key TEXT,"
, Text
" rate_limit_prefix TEXT,"
, Text
" rate_limit_cost DOUBLE PRECISION,"
, Text
" concurrency_key TEXT,"
, Text
" concurrency_prefix TEXT,"
, Text
" result JSONB,"
]
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.unlines (Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
drop Int
1 [Text]
jobColumns)
createJobQueueArchiveTableSQL :: Text -> Text -> Text
createJobQueueArchiveTableSQL :: Text -> Text -> Text
createJobQueueArchiveTableSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE TABLE IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ("
, Text
jobColumnsForArchive
, Text
");"
]
createArchiveCompletedAtIndexSQL :: Text -> Text -> Text
createArchiveCompletedAtIndexSQL :: Text -> Text -> Text
createArchiveCompletedAtIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_archive_completed_at")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (completed_at DESC);"
]
createArchiveExpiresAtIndexSQL :: Text -> Text -> Text
createArchiveExpiresAtIndexSQL :: Text -> Text -> Text
createArchiveExpiresAtIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_archive_expires_at")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (archive_expires_at);"
]
createArchiveJobIdIndexSQL :: Text -> Text -> Text
createArchiveJobIdIndexSQL :: Text -> Text -> Text
createArchiveJobIdIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_archive_job_id")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (job_id);"
]
createArchiveParentIdIndexSQL :: Text -> Text -> Text
createArchiveParentIdIndexSQL :: Text -> Text -> Text
createArchiveParentIdIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_archive_parent_id")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (parent_id)"
, Text
"WHERE parent_id IS NOT NULL;"
]
createArchiveGroupKeyIndexSQL :: Text -> Text -> Text
createArchiveGroupKeyIndexSQL :: Text -> Text -> Text
createArchiveGroupKeyIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_archive_group_key")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueArchiveTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (group_key);"
]
createJobQueueUngroupedReadyRankingIndexSQL :: Text -> Text -> Text
createJobQueueUngroupedReadyRankingIndexSQL :: Text -> Text -> Text
createJobQueueUngroupedReadyRankingIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_ungrouped_ready_ranking")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (priority ASC, id ASC)"
, Text
"WHERE group_key IS NULL AND not_visible_until IS NULL AND NOT suspended;"
]
createJobQueueUngroupedDueIndexSQL :: Text -> Text -> Text
createJobQueueUngroupedDueIndexSQL :: Text -> Text -> Text
createJobQueueUngroupedDueIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_ungrouped_due")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (not_visible_until ASC)"
, Text
"WHERE group_key IS NULL AND not_visible_until IS NOT NULL AND NOT suspended;"
]
migrateUngroupedReadySplitIndexesSQL :: Text -> Text -> Text
migrateUngroupedReadySplitIndexesSQL :: Text -> Text -> Text
migrateUngroupedReadySplitIndexesSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"DROP INDEX IF EXISTS "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_ungrouped_ranking")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
, Text -> Text -> Text
createJobQueueUngroupedReadyRankingIndexSQL Text
schemaName Text
tableName
, Text -> Text -> Text
createJobQueueUngroupedDueIndexSQL Text
schemaName Text
tableName
]
createDLQGroupKeyIndexSQL :: Text -> Text -> Text
createDLQGroupKeyIndexSQL :: Text -> Text -> Text
createDLQGroupKeyIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_dlq_group_key")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (group_key);"
]
createDLQFailedAtIndexSQL :: Text -> Text -> Text
createDLQFailedAtIndexSQL :: Text -> Text -> Text
createDLQFailedAtIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_dlq_failed_at")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (failed_at DESC);"
]
createDLQParentIdIndexSQL :: Text -> Text -> Text
createDLQParentIdIndexSQL :: Text -> Text -> Text
createDLQParentIdIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_dlq_parent_id")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (parent_id)"
, Text
"WHERE parent_id IS NOT NULL;"
]
createDedupKeyIndexSQL :: Text -> Text -> Text
createDedupKeyIndexSQL :: Text -> Text -> Text
createDedupKeyIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE UNIQUE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_dedup_key")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (dedup_key)"
, Text
"WHERE dedup_key IS NOT NULL;"
]
createParentIdIndexSQL :: Text -> Text -> Text
createParentIdIndexSQL :: Text -> Text -> Text
createParentIdIndexSQL Text
schemaName Text
tableName =
[Text] -> Text
T.unlines
[ Text
"CREATE INDEX IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text
"idx_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_parent_id")
, Text
"ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (parent_id)"
, Text
"WHERE parent_id IS NOT NULL;"
]
createResultsTableSQL :: Text -> Text -> Text
createResultsTableSQL :: Text -> Text -> Text
createResultsTableSQL Text
schemaName Text
tableName =
let resultsTbl :: Text
resultsTbl = Text -> Text -> Text
jobQueueResultsTable Text
schemaName Text
tableName
mainTbl :: Text
mainTbl = Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
in [Text] -> Text
T.unlines
[ Text
"CREATE TABLE IF NOT EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
resultsTbl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ("
, Text
" parent_id BIGINT NOT NULL REFERENCES " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
mainTbl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"(id) ON DELETE CASCADE,"
, Text
" child_id BIGINT NOT NULL,"
, Text
" result JSONB NOT NULL,"
, Text
" PRIMARY KEY (parent_id, child_id)"
, Text
");"
]
maintenanceFunctionNames :: Text -> Text -> (Text, Text, Text)
maintenanceFunctionNames :: Text -> Text -> (Text, Text, Text)
maintenanceFunctionNames Text
schemaName Text
baseName =
(Text -> Text
func Text
"_insert", Text -> Text
func Text
"_delete", Text -> Text
func Text
"_update")
where
func :: Text -> Text
func Text
suffix = 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 -> Text
quoteIdentifier (Text
baseName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
suffix)
statementTriggerSQL :: Text -> Text -> Text -> Text -> Text -> Text -> Text
statementTriggerSQL :: Text -> Text -> Text -> Text -> Text -> Text -> Text
statementTriggerSQL Text
schemaName Text
tbl Text
baseName Text
suffix Text
event Text
referencing =
let func :: Text
func = 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 -> Text
quoteIdentifier (Text
baseName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
suffix)
trig :: Text
trig = Text -> Text
quoteIdentifier (Text
baseName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
suffix)
in Text -> [Text] -> Text
T.intercalate
Text
"\n"
[ Text
"DROP TRIGGER IF EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
trig Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
, Text
"CREATE TRIGGER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
trig
, Text
"AFTER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
event Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl
, Text
"REFERENCING " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
referencing
, Text
"FOR EACH STATEMENT EXECUTE FUNCTION " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
func Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"();"
]
createMaintenanceTriggersSQL :: Text -> Text -> Text -> Text
createMaintenanceTriggersSQL :: Text -> Text -> Text -> Text
createMaintenanceTriggersSQL Text
schemaName Text
tbl Text
baseName =
Text -> [Text] -> Text
T.intercalate
Text
"\n\n"
[ Text -> Text -> Text -> Text -> Text -> Text -> Text
statementTriggerSQL Text
schemaName Text
tbl Text
baseName Text
"_insert" Text
"INSERT" Text
"NEW TABLE AS new_table"
, Text -> Text -> Text -> Text -> Text -> Text -> Text
statementTriggerSQL Text
schemaName Text
tbl Text
baseName Text
"_delete" Text
"DELETE" Text
"OLD TABLE AS old_table"
, Text -> Text -> Text -> Text -> Text -> Text -> Text
statementTriggerSQL Text
schemaName Text
tbl Text
baseName Text
"_update" Text
"UPDATE" Text
"OLD TABLE AS old_table NEW TABLE AS new_table"
]
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"
createNotifyFunctionSQL :: Text -> Text -> Text
createNotifyFunctionSQL :: Text -> Text -> Text
createNotifyFunctionSQL Text
schemaName Text
tableName =
let functionName :: Text
functionName = Text -> Text
notifyFunctionName Text
tableName
channelName :: Text
channelName = Text -> Text
notificationChannelForTable Text
tableName
quotedChannel :: Text
quotedChannel = HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"'" Text
"''" Text
channelName
in [Text] -> Text
T.unlines
[ Text
"CREATE OR REPLACE FUNCTION " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier Text
functionName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"()"
, Text
"RETURNS TRIGGER AS $$"
, Text
"BEGIN"
, Text
" IF EXISTS (SELECT 1 FROM new_table) THEN"
, Text
" PERFORM pg_notify('" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
quotedChannel Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"', '');"
, Text
" END IF;"
, Text
" RETURN NULL;"
, Text
"END;"
, Text
"$$ LANGUAGE plpgsql;"
, Text
"COMMENT ON FUNCTION "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier Text
functionName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"() IS '"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
notifyObjectComment
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"';"
]
createNotifyTriggerSQL :: Text -> Text -> Text
createNotifyTriggerSQL :: Text -> Text -> Text
createNotifyTriggerSQL Text
schemaName Text
tableName =
let functionName :: Text
functionName = Text -> Text
notifyFunctionName Text
tableName
trigName :: Text
trigName = Text -> Text
quoteIdentifier (Text -> Text
notifyTriggerName Text
tableName)
tbl :: Text
tbl = Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
in [Text] -> Text
T.unlines
[ Text
"DROP TRIGGER IF EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
trigName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
, Text
"CREATE TRIGGER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
trigName
, Text
"AFTER INSERT ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl
, Text
"REFERENCING NEW TABLE AS new_table"
, Text
"FOR EACH STATEMENT"
, Text
"EXECUTE FUNCTION " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier Text
functionName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"();"
, Text
"COMMENT ON TRIGGER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
trigName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" IS '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
notifyObjectComment Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"';"
]
dropNotifyTriggerSQL :: Text -> Text -> Text
dropNotifyTriggerSQL :: Text -> Text -> Text
dropNotifyTriggerSQL Text
schemaName Text
tableName =
Text
"DROP TRIGGER IF EXISTS "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text -> Text
notifyTriggerName Text
tableName)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
dropNotifyFunctionSQL :: Text -> Text -> Text
dropNotifyFunctionSQL :: Text -> Text -> Text
dropNotifyFunctionSQL Text
schemaName Text
tableName =
let functionName :: Text
functionName = Text -> Text
notifyFunctionName Text
tableName
in Text
"DROP FUNCTION IF EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier Text
functionName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"();"
createEventStreamingFunctionSQL :: SchemaName -> Text
createEventStreamingFunctionSQL :: Text -> Text
createEventStreamingFunctionSQL Text
schemaName =
let funcName :: Text
funcName = 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 -> Text
quoteIdentifier Text
eventStreamingFunctionName
in [Text] -> Text
T.unlines
[ Text
"CREATE OR REPLACE FUNCTION " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
funcName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"() RETURNS trigger AS $$"
, Text
"DECLARE"
, Text
" event_type text;"
, Text
" job_id bigint;"
, Text
" queue_name text := TG_ARGV[0];"
, Text
" is_dlq boolean := TG_ARGV[1]::boolean;"
, Text
"BEGIN"
, Text
" IF TG_OP = 'UPDATE' THEN"
, Text
" IF NEW.claimed_by IS NOT NULL AND NEW.claim_seq = OLD.claim_seq"
, Text
" AND NEW.not_visible_until >= OLD.not_visible_until"
, Text
" AND " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
leaseStripped Text
"OLD" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" = " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
leaseStripped Text
"NEW" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" THEN"
, Text
" RETURN NULL;"
, Text
" END IF;"
, Text
" END IF;"
, Text
" CASE TG_OP"
, Text
" WHEN 'INSERT' THEN"
, Text
" event_type := CASE WHEN is_dlq THEN 'job_dlq' ELSE 'job_inserted' END;"
, Text
" job_id := NEW.id;"
, Text
" WHEN 'UPDATE' THEN"
, Text
" event_type := 'job_updated';"
, Text
" job_id := NEW.id;"
, Text
" WHEN 'DELETE' THEN"
, Text
" event_type := 'job_deleted';"
, Text
" job_id := OLD.id;"
, Text
" END CASE;"
, Text
""
, Text
" PERFORM pg_notify('" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
eventStreamingChannel Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"',"
, Text
" json_build_object("
, Text
" 'event', event_type,"
, Text
" 'table', queue_name,"
, Text
" 'job_id', job_id"
, Text
" )::text);"
, Text
" RETURN NULL;"
, Text
"END;"
, Text
"$$ LANGUAGE plpgsql;"
, Text
"COMMENT ON FUNCTION " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
funcName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"() IS '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
eventStreamingObjectComment Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"';"
]
where
leaseStripped :: a -> a
leaseStripped a
row = a
"(to_jsonb(" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
row a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
") - 'not_visible_until' - 'updated_at')"
createEventStreamingTriggersSQL :: SchemaName -> TableName -> Text
Text
schemaName Text
tableName =
let tbl :: Text
tbl = Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
dlqTbl :: Text
dlqTbl = Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName
funcName :: Text
funcName = 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 -> Text
quoteIdentifier Text
eventStreamingFunctionName
triggerCall :: Text -> Text
triggerCall Text
isDLQ =
Text
"FOR EACH ROW EXECUTE FUNCTION "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
funcName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"("
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteLiteral Text
tableName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteLiteral Text
isDLQ
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
");"
triggerComment :: Text -> Text -> Text
triggerComment Text
trigger Text
tableRef =
Text
"COMMENT ON TRIGGER "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier Text
trigger
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableRef
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" IS "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteLiteral Text
eventStreamingObjectComment
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
in Text -> Text -> Text
dropEventStreamingTriggersSQL Text
schemaName Text
tableName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.unlines
[ Text
"CREATE TRIGGER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text -> Text
eventStreamingTriggerName Text
tableName)
, Text
"AFTER INSERT OR UPDATE OR DELETE ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tbl
, Text -> Text
triggerCall Text
"false"
, Text -> Text -> Text
triggerComment (Text -> Text
eventStreamingTriggerName Text
tableName) Text
tbl
, Text
""
, Text
"CREATE TRIGGER " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier (Text -> Text
eventStreamingDLQTriggerName Text
tableName)
, Text
"AFTER INSERT ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
dlqTbl
, Text -> Text
triggerCall Text
"true"
, Text -> Text -> Text
triggerComment (Text -> Text
eventStreamingDLQTriggerName Text
tableName) Text
dlqTbl
]
where
quoteLiteral :: Text -> Text
quoteLiteral = (Text
"'" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'") (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"'" Text
"''"
dropEventStreamingTriggersSQL :: Text -> Text -> Text
Text
schemaName Text
tableName =
let tbl :: Text
tbl = Text -> Text -> Text
jobQueueTable Text
schemaName Text
tableName
dlqTbl :: Text
dlqTbl = Text -> Text -> Text
jobQueueDLQTable Text
schemaName Text
tableName
dropTrigger :: Text -> Text -> Text
dropTrigger Text
name Text
tableRef = Text
"DROP TRIGGER IF EXISTS " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quoteIdentifier Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ON " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
tableRef Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
";"
in [Text] -> Text
T.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
((Text, Bool) -> Text) -> [(Text, Bool)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (\(Text
name, Bool
isDLQ) -> Text -> Text -> Text
dropTrigger Text
name (Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
tbl Text
dlqTbl Bool
isDLQ)) [(Text, Bool)]
legacyEventStreamingTriggers
[Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> [ Text -> Text -> Text
dropTrigger (Text -> Text
eventStreamingTriggerName Text
tableName) Text
tbl
, Text -> Text -> Text
dropTrigger (Text -> Text
eventStreamingDLQTriggerName Text
tableName) Text
dlqTbl
]
dropEventStreamingFunctionSQL :: SchemaName -> Text
dropEventStreamingFunctionSQL :: Text -> Text
dropEventStreamingFunctionSQL Text
schemaName =
Text
"DROP FUNCTION IF EXISTS "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> 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 -> Text
quoteIdentifier Text
eventStreamingFunctionName
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"();"