Skip to content

Commit

Permalink
fix createJobTable failure when table name contains dot
Browse files Browse the repository at this point in the history
`createJobTable` fails when the table name contains a dot
for example `myschema.jobs`.
  • Loading branch information
kanagarajkm committed Oct 13, 2020
1 parent b269ce4 commit 76a1fd0
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions src/OddJobs/Migrations.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ module OddJobs.Migrations
)
where

import Database.PostgreSQL.Simple as PGS
import Data.Functor (void)
import OddJobs.Types
import Control.Monad
import Data.Functor (void)
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8)
import Database.PostgreSQL.Simple as PGS
import Database.PostgreSQL.Simple.Types as PGS
import OddJobs.Types

createJobTableQuery :: TableName -> Query
createJobTableQuery tname = "CREATE TABLE " <> tname <>
Expand All @@ -21,28 +25,34 @@ createJobTableQuery tname = "CREATE TABLE " <> tname <>
", locked_at timestamp with time zone null" <>
", locked_by text null" <>
", constraint incorrect_locking_info CHECK ((status <> 'locked' and locked_at is null and locked_by is null) or (status = 'locked' and locked_at is not null and locked_by is not null))" <>
");" <>
"create index idx_" <> tname <> "_created_at on " <> tname <> "(created_at);" <>
"create index idx_" <> tname <> "_updated_at on " <> tname <> "(updated_at);" <>
"create index idx_" <> tname <> "_locked_at on " <> tname <> "(locked_at);" <>
"create index idx_" <> tname <> "_locked_by on " <> tname <> "(locked_by);" <>
"create index idx_" <> tname <> "_status on " <> tname <> "(status);" <>
"create index idx_" <> tname <> "_run_at on " <> tname <> "(run_at);"
");"

createNotificationTrigger :: TableName -> Query
createNotificationTrigger tname = "create or replace function " <> fnName <> "() returns trigger as $$" <>
"begin \n" <>
" perform pg_notify('" <> pgEventName tname <> "', row_to_json(new)::text); \n" <>
" return new; \n" <>
"end; \n" <>
"$$ language plpgsql;" <>
"create trigger " <> trgName <> " after insert on " <> tname <> " for each row execute procedure " <> fnName <> "();"
createJobTableIndex :: Connection -> TableName -> Text -> IO ()
createJobTableIndex conn tname cname = do
let q = "create index ? on " <> tname <> "(?)"
void $ PGS.execute conn q (idxName, cName)
where
fnName = "notify_job_monitor_for_" <> tname
trgName = "trg_notify_job_monitor_for_" <> tname
idxName = PGS.Identifier $ "idx_" <> (decodeUtf8 $ fromQuery tname) <> "_" <> cname
cName = PGS.Identifier cname

createNotificationTrigger :: Connection -> TableName -> IO ()
createNotificationTrigger conn tname = do
let q = "create or replace function ?() returns trigger as $$" <>
"begin \n" <>
" perform pg_notify('" <> pgEventName tname <> "', row_to_json(new)::text); \n" <>
" return new; \n" <>
"end; \n" <>
"$$ language plpgsql;" <>
"create trigger ? after insert on " <> tname <> " for each row execute procedure ?();"
void $ PGS.execute conn q (fnName, trgName, fnName)
where
fnName = PGS.Identifier $ "notify_job_monitor_for_" <> (decodeUtf8 $ fromQuery tname)
trgName = PGS.Identifier $ "trg_notify_job_monitor_for_" <> (decodeUtf8 $ fromQuery tname)

createJobTable :: Connection -> TableName -> IO ()
createJobTable conn tname = void $ do
PGS.execute_ conn (createJobTableQuery tname)
PGS.execute_ conn (createNotificationTrigger tname)
forM_ jobTableIndexes $ \col -> createJobTableIndex conn tname col
createNotificationTrigger conn tname
where
jobTableIndexes = ["created_at", "updated_at", "locked_at", "locked_by", "status", "run_at"]

0 comments on commit 76a1fd0

Please sign in to comment.