{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE QuasiQuotes #-} module Simplex.Messaging.Server.QueueStore.Postgres.Migrations where import Data.List (sortOn) import Data.Text (Text) import qualified Data.Text as T import Simplex.Messaging.Agent.Store.Shared import Text.RawString.QQ (r) serverSchemaMigrations :: [(String, Text, Maybe Text)] serverSchemaMigrations = [ ("20250207_initial", m20250207_initial, Nothing), ("20250319_updated_index", m20250319_updated_index, Just down_m20250319_updated_index), ("20250320_short_links", m20250320_short_links, Just down_m20250320_short_links) ] -- | The list of migrations in ascending order by date serverMigrations :: [Migration] serverMigrations = sortOn name $ map migration serverSchemaMigrations where migration (name, up, down) = Migration {name, up, down = down} m20250207_initial :: Text m20250207_initial = T.pack [r| CREATE TABLE msg_queues( recipient_id BYTEA NOT NULL, recipient_key BYTEA NOT NULL, rcv_dh_secret BYTEA NOT NULL, sender_id BYTEA NOT NULL, sender_key BYTEA, snd_secure BOOLEAN NOT NULL, notifier_id BYTEA, notifier_key BYTEA, rcv_ntf_dh_secret BYTEA, status TEXT NOT NULL, updated_at BIGINT, deleted_at BIGINT, PRIMARY KEY (recipient_id) ); CREATE UNIQUE INDEX idx_msg_queues_sender_id ON msg_queues(sender_id); CREATE UNIQUE INDEX idx_msg_queues_notifier_id ON msg_queues(notifier_id); CREATE INDEX idx_msg_queues_deleted_at ON msg_queues (deleted_at); |] m20250319_updated_index :: Text m20250319_updated_index = T.pack [r| DROP INDEX idx_msg_queues_deleted_at; CREATE INDEX idx_msg_queues_updated_at ON msg_queues (deleted_at, updated_at); |] down_m20250319_updated_index :: Text down_m20250319_updated_index = T.pack [r| DROP INDEX idx_msg_queues_updated_at; CREATE INDEX idx_msg_queues_deleted_at ON msg_queues (deleted_at); |] m20250320_short_links :: Text m20250320_short_links = T.pack [r| ALTER TABLE msg_queues ADD COLUMN queue_mode TEXT, ADD COLUMN link_id BYTEA, ADD COLUMN fixed_data BYTEA, ADD COLUMN user_data BYTEA; UPDATE msg_queues SET queue_mode = 'M' WHERE snd_secure IS TRUE; ALTER TABLE msg_queues DROP COLUMN snd_secure; UPDATE msg_queues SET recipient_key = ('\x01'::BYTEA || chr(length(recipient_key))::BYTEA || recipient_key); ALTER TABLE msg_queues RENAME COLUMN recipient_key TO recipient_keys; CREATE UNIQUE INDEX idx_msg_queues_link_id ON msg_queues(link_id); |] down_m20250320_short_links :: Text down_m20250320_short_links = T.pack [r| ALTER TABLE msg_queues ADD COLUMN snd_secure BOOLEAN NOT NULL DEFAULT FALSE; UPDATE msg_queues SET snd_secure = TRUE WHERE queue_mode = 'M'; DROP INDEX idx_msg_queues_link_id; ALTER TABLE msg_queues DROP COLUMN queue_mode, DROP COLUMN link_id, DROP COLUMN fixed_data, DROP COLUMN user_data; DO $$ DECLARE bad_id BYTEA; BEGIN SELECT recipient_id INTO bad_id FROM msg_queues WHERE get_byte(recipient_keys, 0) != 1 OR get_byte(recipient_keys, 1) != length(recipient_keys) - 2 LIMIT 1; IF bad_id IS NOT NULL THEN RAISE EXCEPTION 'Cannot downgrade: many keys or incorrect length in recipient_keys for %', encode(bad_id, 'base64'); END IF; END; $$; UPDATE msg_queues SET recipient_keys = substring(recipient_keys from 3); ALTER TABLE msg_queues RENAME COLUMN recipient_keys TO recipient_key; |]