191 lines
8.1 KiB
SQL
191 lines
8.1 KiB
SQL
-- A user-owned upgraded gift has one stable protocol identity: the original
|
|
-- gift service-message id. The unique service message points back to it via
|
|
-- saved_id, while the original message points forward to the box-local unique
|
|
-- service message via upgrade_msg_id. Both projections must be durable pts
|
|
-- edits so history, live delivery and updates.getDifference agree.
|
|
|
|
ALTER TABLE public.star_gift_upgrade_commands
|
|
ADD COLUMN source_edit_pts integer DEFAULT 0 NOT NULL,
|
|
ADD CONSTRAINT star_gift_upgrade_command_source_edit_pts_check CHECK (source_edit_pts >= 0);
|
|
|
|
DO $$
|
|
DECLARE
|
|
gift record;
|
|
source_root record;
|
|
upgrade_root record;
|
|
pair record;
|
|
next_pts integer;
|
|
event_date integer := EXTRACT(EPOCH FROM clock_timestamp())::integer;
|
|
repaired_source_media jsonb;
|
|
repaired_unique_media jsonb;
|
|
private_media jsonb;
|
|
BEGIN
|
|
FOR gift IN
|
|
SELECT id, owner_peer_id, msg_id, upgrade_msg_id
|
|
FROM public.peer_star_gifts
|
|
WHERE owner_peer_type = 'user'
|
|
AND unique_gift_id IS NOT NULL
|
|
AND lifecycle_status = 'active'
|
|
AND msg_id > 0
|
|
AND upgrade_msg_id > 0
|
|
ORDER BY id
|
|
LOOP
|
|
SELECT private_message_id, message_sender_id
|
|
INTO STRICT source_root
|
|
FROM public.message_boxes
|
|
WHERE owner_user_id = gift.owner_peer_id
|
|
AND box_id = gift.msg_id
|
|
AND NOT deleted;
|
|
|
|
SELECT private_message_id, message_sender_id
|
|
INTO STRICT upgrade_root
|
|
FROM public.message_boxes
|
|
WHERE owner_user_id = gift.owner_peer_id
|
|
AND box_id = gift.upgrade_msg_id
|
|
AND NOT deleted;
|
|
|
|
FOR pair IN
|
|
SELECT source_box.owner_user_id,
|
|
source_box.box_id AS source_box_id,
|
|
source_box.peer_type AS source_peer_type,
|
|
source_box.peer_id AS source_peer_id,
|
|
source_box.media AS source_media,
|
|
unique_box.box_id AS unique_box_id,
|
|
unique_box.peer_type AS unique_peer_type,
|
|
unique_box.peer_id AS unique_peer_id,
|
|
unique_box.media AS unique_media
|
|
FROM public.message_boxes source_box
|
|
JOIN public.message_boxes unique_box
|
|
ON unique_box.owner_user_id = source_box.owner_user_id
|
|
AND unique_box.message_sender_id = upgrade_root.message_sender_id
|
|
AND unique_box.private_message_id = upgrade_root.private_message_id
|
|
AND NOT unique_box.deleted
|
|
WHERE source_box.message_sender_id = source_root.message_sender_id
|
|
AND source_box.private_message_id = source_root.private_message_id
|
|
AND NOT source_box.deleted
|
|
ORDER BY source_box.owner_user_id
|
|
LOOP
|
|
IF pair.source_media #>> '{service_action,kind}' <> 'star_gift' THEN
|
|
RAISE EXCEPTION 'saved gift % source box % has invalid service action', gift.id, pair.source_box_id;
|
|
END IF;
|
|
IF pair.unique_media #>> '{service_action,kind}' <> 'star_gift_unique' THEN
|
|
RAISE EXCEPTION 'saved gift % unique box % has invalid service action', gift.id, pair.unique_box_id;
|
|
END IF;
|
|
|
|
repaired_source_media := jsonb_set(
|
|
pair.source_media,
|
|
'{service_action,star_gift,upgrade_msg_id}',
|
|
to_jsonb(pair.unique_box_id::bigint),
|
|
true
|
|
) #- '{service_action,star_gift,can_upgrade}';
|
|
repaired_unique_media := jsonb_set(
|
|
pair.unique_media,
|
|
'{service_action,star_gift_unique,saved_id}',
|
|
to_jsonb(pair.source_box_id::bigint),
|
|
true
|
|
);
|
|
|
|
IF pair.source_media IS DISTINCT FROM repaired_source_media THEN
|
|
INSERT INTO public.user_update_watermarks (user_id, contiguous_pts)
|
|
VALUES (pair.owner_user_id, 0)
|
|
ON CONFLICT (user_id) DO NOTHING;
|
|
|
|
UPDATE public.user_update_watermarks
|
|
SET contiguous_pts = contiguous_pts + 1,
|
|
updated_at = now()
|
|
WHERE user_id = pair.owner_user_id
|
|
RETURNING contiguous_pts INTO next_pts;
|
|
|
|
UPDATE public.message_boxes
|
|
SET media = repaired_source_media,
|
|
pts = next_pts
|
|
WHERE owner_user_id = pair.owner_user_id
|
|
AND box_id = pair.source_box_id
|
|
AND NOT deleted;
|
|
|
|
INSERT INTO public.user_update_events (
|
|
user_id, pts, pts_count, date, event_type,
|
|
message_box_id, peer_type, peer_id
|
|
) VALUES (
|
|
pair.owner_user_id, next_pts, 1, event_date, 'edit_message',
|
|
pair.source_box_id, pair.source_peer_type, pair.source_peer_id
|
|
);
|
|
|
|
INSERT INTO public.dispatch_outbox (
|
|
target_user_id, pts, event_type,
|
|
exclude_auth_key_id, exclude_session_id
|
|
) VALUES (pair.owner_user_id, next_pts, 'edit_message', 0, 0);
|
|
|
|
IF pair.owner_user_id = gift.owner_peer_id THEN
|
|
UPDATE public.star_gift_upgrade_commands
|
|
SET source_edit_pts = next_pts
|
|
WHERE source_saved_gift_id = gift.id;
|
|
END IF;
|
|
END IF;
|
|
|
|
IF pair.unique_media IS DISTINCT FROM repaired_unique_media THEN
|
|
INSERT INTO public.user_update_watermarks (user_id, contiguous_pts)
|
|
VALUES (pair.owner_user_id, 0)
|
|
ON CONFLICT (user_id) DO NOTHING;
|
|
|
|
UPDATE public.user_update_watermarks
|
|
SET contiguous_pts = contiguous_pts + 1,
|
|
updated_at = now()
|
|
WHERE user_id = pair.owner_user_id
|
|
RETURNING contiguous_pts INTO next_pts;
|
|
|
|
UPDATE public.message_boxes
|
|
SET media = repaired_unique_media,
|
|
pts = next_pts
|
|
WHERE owner_user_id = pair.owner_user_id
|
|
AND box_id = pair.unique_box_id
|
|
AND NOT deleted;
|
|
|
|
INSERT INTO public.user_update_events (
|
|
user_id, pts, pts_count, date, event_type,
|
|
message_box_id, peer_type, peer_id
|
|
) VALUES (
|
|
pair.owner_user_id, next_pts, 1, event_date, 'edit_message',
|
|
pair.unique_box_id, pair.unique_peer_type, pair.unique_peer_id
|
|
);
|
|
|
|
INSERT INTO public.dispatch_outbox (
|
|
target_user_id, pts, event_type,
|
|
exclude_auth_key_id, exclude_session_id
|
|
) VALUES (pair.owner_user_id, next_pts, 'edit_message', 0, 0);
|
|
END IF;
|
|
END LOOP;
|
|
|
|
SELECT media INTO STRICT private_media
|
|
FROM public.message_boxes
|
|
WHERE message_sender_id = source_root.message_sender_id
|
|
AND private_message_id = source_root.private_message_id
|
|
AND NOT deleted
|
|
ORDER BY (owner_user_id = message_sender_id) DESC, owner_user_id
|
|
LIMIT 1;
|
|
UPDATE public.private_messages
|
|
SET media = private_media
|
|
WHERE sender_user_id = source_root.message_sender_id
|
|
AND id = source_root.private_message_id;
|
|
|
|
SELECT media INTO STRICT private_media
|
|
FROM public.message_boxes
|
|
WHERE message_sender_id = upgrade_root.message_sender_id
|
|
AND private_message_id = upgrade_root.private_message_id
|
|
AND NOT deleted
|
|
ORDER BY (owner_user_id = message_sender_id) DESC, owner_user_id
|
|
LIMIT 1;
|
|
UPDATE public.private_messages
|
|
SET media = private_media
|
|
WHERE sender_user_id = upgrade_root.message_sender_id
|
|
AND id = upgrade_root.private_message_id;
|
|
|
|
IF EXISTS (
|
|
SELECT 1 FROM public.star_gift_upgrade_commands
|
|
WHERE source_saved_gift_id = gift.id AND source_edit_pts <= 0
|
|
) THEN
|
|
RAISE EXCEPTION 'saved gift % is missing its owner source edit receipt', gift.id;
|
|
END IF;
|
|
END LOOP;
|
|
END
|
|
$$;
|