45 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			PL/PgSQL
		
	
	
	
	
	
			
		
		
	
	
			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;
 | |
| $$; |