123 lines
4.2 KiB
PL/PgSQL
123 lines
4.2 KiB
PL/PgSQL
-- This is an empty migration.
|
|
|
|
-- This is an empty migration.
|
|
CREATE OR REPLACE FUNCTION bounty_paid_after_act(item_id INTEGER, user_id INTEGER)
|
|
RETURNS INTEGER
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
DECLARE
|
|
root_id INTEGER;
|
|
item_bounty INTEGER;
|
|
sats_paid INTEGER;
|
|
BEGIN
|
|
PERFORM ASSERT_SERIALIZED();
|
|
|
|
-- get root item
|
|
SELECT "rootId" INTO root_id FROM "Item" WHERE id = item_id;
|
|
|
|
-- check if root item is 1. a bounty, 2. actor is the OP, 3. hasn't paid yet
|
|
SELECT bounty
|
|
INTO item_bounty
|
|
FROM "Item"
|
|
WHERE id = root_id
|
|
AND "userId" = user_id
|
|
AND ("bountyPaidTo" IS NULL OR item_id <> any ("bountyPaidTo"));
|
|
|
|
-- if it is get the bounty amount
|
|
IF item_bounty IS NOT NULL THEN
|
|
-- check if the cumulative sats sent to this item by user_id is >= to bounty
|
|
SELECT coalesce(sum("ItemAct"."msats"), 0)/1000
|
|
INTO sats_paid
|
|
FROM "ItemAct"
|
|
WHERE "ItemAct"."userId" = user_id
|
|
AND "ItemAct"."itemId" = item_id
|
|
AND "ItemAct".act IN ('TIP','FEE');
|
|
IF sats_paid >= item_bounty THEN
|
|
UPDATE "Item"
|
|
SET "bountyPaidTo" = array_append("bountyPaidTo", item_id)
|
|
WHERE id = root_id;
|
|
END IF;
|
|
END IF;
|
|
|
|
RETURN 0;
|
|
END;
|
|
$$;
|
|
|
|
-- This is an empty migration.
|
|
CREATE OR REPLACE FUNCTION item_act(item_id INTEGER, user_id INTEGER, act "ItemActType", act_sats INTEGER)
|
|
RETURNS INTEGER
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
DECLARE
|
|
user_msats BIGINT;
|
|
act_msats BIGINT;
|
|
fee_msats BIGINT;
|
|
item_act_id INTEGER;
|
|
referrer_id INTEGER;
|
|
BEGIN
|
|
PERFORM ASSERT_SERIALIZED();
|
|
|
|
act_msats := act_sats * 1000;
|
|
SELECT msats, "referrerId" INTO user_msats, referrer_id FROM users WHERE id = user_id;
|
|
IF act_msats > user_msats THEN
|
|
RAISE EXCEPTION 'SN_INSUFFICIENT_FUNDS';
|
|
END IF;
|
|
|
|
-- deduct msats from actor
|
|
UPDATE users SET msats = msats - act_msats WHERE id = user_id;
|
|
|
|
IF act = 'VOTE' THEN
|
|
RAISE EXCEPTION 'SN_UNSUPPORTED';
|
|
END IF;
|
|
|
|
IF act = 'TIP' THEN
|
|
-- call to influence weightedVotes ... we need to do this before we record the acts because
|
|
-- the priors acts are taken into account
|
|
PERFORM weighted_votes_after_tip(item_id, user_id, act_sats);
|
|
|
|
-- take 10% and insert as FEE
|
|
fee_msats := CEIL(act_msats * 0.1);
|
|
act_msats := act_msats - fee_msats;
|
|
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (fee_msats, item_id, user_id, 'FEE', now_utc(), now_utc())
|
|
RETURNING id INTO item_act_id;
|
|
|
|
-- add sats to actee's balance and stacked count
|
|
UPDATE users
|
|
SET msats = msats + act_msats, "stackedMsats" = "stackedMsats" + act_msats
|
|
WHERE id = (SELECT COALESCE("fwdUserId", "userId") FROM "Item" WHERE id = item_id)
|
|
RETURNING "referrerId" INTO referrer_id;
|
|
|
|
-- leave the rest as a tip
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (act_msats, item_id, user_id, 'TIP', now_utc(), now_utc());
|
|
|
|
-- call to denormalize sats and commentSats
|
|
PERFORM sats_after_tip(item_id, user_id, act_msats + fee_msats);
|
|
-- denormalize bounty paid
|
|
PERFORM bounty_paid_after_act(item_id, user_id);
|
|
ELSE -- BOOST, POLL, DONT_LIKE_THIS, STREAM
|
|
-- call to influence if DONT_LIKE_THIS weightedDownVotes
|
|
IF act = 'DONT_LIKE_THIS' THEN
|
|
-- make sure they haven't done this before
|
|
IF EXISTS (SELECT 1 FROM "ItemAct" WHERE "itemId" = item_id AND "userId" = user_id AND "ItemAct".act = 'DONT_LIKE_THIS') THEN
|
|
RAISE EXCEPTION 'SN_DUPLICATE';
|
|
END IF;
|
|
|
|
PERFORM weighted_downvotes_after_act(item_id, user_id, act_sats);
|
|
END IF;
|
|
|
|
INSERT INTO "ItemAct" (msats, "itemId", "userId", act, created_at, updated_at)
|
|
VALUES (act_msats, item_id, user_id, act, now_utc(), now_utc())
|
|
RETURNING id INTO item_act_id;
|
|
END IF;
|
|
|
|
-- they have a referrer and the referrer isn't the one tipping them
|
|
IF referrer_id IS NOT NULL AND user_id <> referrer_id THEN
|
|
PERFORM referral_act(referrer_id, item_act_id);
|
|
END IF;
|
|
|
|
RETURN 0;
|
|
END;
|
|
$$; |