stacker.news/prisma/migrations/20211015180613_invite_func/migration.sql

45 lines
1.5 KiB
PL/PgSQL

CREATE OR REPLACE FUNCTION invite_drain(user_id INTEGER, invite_id TEXT)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
inviter_id INTEGER;
inviter_sats INTEGER;
gift INTEGER;
BEGIN
PERFORM ASSERT_SERIALIZED();
-- check user was created in last hour
-- check user did not already redeem an invite
PERFORM FROM users
WHERE id = user_id AND users.created_at >= NOW() AT TIME ZONE 'UTC' - INTERVAL '1 HOUR'
AND users."inviteId" IS NULL;
IF NOT FOUND THEN
RAISE EXCEPTION 'SN_INELIGIBLE';
END IF;
-- check that invite has not reached limit
-- check that invite is not revoked
SELECT "Invite"."userId", "Invite".gift INTO inviter_id, gift FROM "Invite"
LEFT JOIN users ON users."inviteId" = invite_id
WHERE "Invite".id = invite_id AND NOT "Invite".revoked
GROUP BY "Invite".id
HAVING COUNT(DISTINCT users.id) < "Invite".limit OR "Invite".limit IS NULL;
IF NOT FOUND THEN
RAISE EXCEPTION 'SN_REVOKED_OR_EXHAUSTED';
END IF;
-- check that inviter has sufficient balance
SELECT (msats / 1000) INTO inviter_sats
FROM users WHERE id = inviter_id;
IF inviter_sats < gift THEN
RAISE EXCEPTION 'SN_REVOKED_OR_EXHAUSTED';
END IF;
-- subtract amount from inviter
UPDATE users SET msats = msats - (1000 * gift) WHERE id = inviter_id;
-- add amount to invitee
UPDATE users SET msats = msats + (1000 * gift), "inviteId" = invite_id WHERE id = user_id;
RETURN 0;
END;
$$;