{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {- | Module : Hindsight.Projection.Schema Description : PostgreSQL schema for async projections Copyright : (c) 2024 License : BSD3 Maintainer : maintainer@example.com Stability : experimental This module provides the schema initialization for async projections. The schema is compatible with (and can coexist with) the sync projection schema from hindsight-postgresql-store. Both use the same 'projections' table, but async projections additionally create a NOTIFY trigger for efficient event waiting. = Idempotency All schema operations use 'CREATE IF NOT EXISTS' and 'CREATE OR REPLACE', making them safe to run multiple times and alongside other projection systems. = Migration Path - Sync → Async: NOTIFY trigger gets added automatically - Async → Sync: Trigger remains (harmless), or can be dropped manually - Both: They share the table harmoniously -} module Hindsight.Projection.Schema ( createProjectionSchema, ) where import Data.FileEmbed (embedFileRelative) import Hasql.Session (Session) import Hasql.Session qualified as Session {- | Creates the projection state schema This creates the 'projections' table and the LISTEN/NOTIFY trigger for async projection progress notifications. Safe to call multiple times (idempotent). Safe to call alongside hindsight-postgresql-store schema (compatible). -} createProjectionSchema :: Session () createProjectionSchema :: Session () createProjectionSchema = ByteString -> Session () Session.sql (ByteString -> Session ()) -> ByteString -> Session () forall a b. (a -> b) -> a -> b $ $(embedFileRelative "sql/projection-schema.sql")