Changes between Version 2 and Version 3 of P7


Ignore:
Timestamp:
04/25/26 22:58:36 (7 days ago)
Author:
211099
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P7

    v2 v3  
    107107}}}
    108108
    109 == Stored Procedures / Functions
     109== Stored Procedures and Functions
    110110{{{
    111111-- Table for daily top story
     
    200200$$;
    201201}}}
     202
     203== Triggers
     204==== Automatically updates the story timestamp on every update
     205{{{
     206CREATE OR REPLACE FUNCTION update_timestamp()
     207RETURNS TRIGGER
     208LANGUAGE plpgsql
     209AS $$
     210BEGIN
     211    NEW.story_updated_at := CURRENT_TIMESTAMP;
     212    RETURN NEW;
     213END;
     214$$;
     215
     216CREATE OR REPLACE TRIGGER story_update_timestamp
     217    BEFORE UPDATE ON story
     218    FOR EACH ROW
     219EXECUTE FUNCTION update_timestamp();
     220}}}
     221==== Sends a notification to the writer when someone likes their story
     222{{{
     223CREATE OR REPLACE FUNCTION notify_writer_on_like()
     224RETURNS TRIGGER
     225LANGUAGE plpgsql
     226AS $$
     227DECLARE
     228    v_writer_id      INTEGER;
     229    v_liker_username VARCHAR;
     230    v_story_desc     VARCHAR;
     231BEGIN
     232    SELECT s.user_id, s.short_description
     233    INTO v_writer_id, v_story_desc
     234    FROM story s
     235    WHERE s.story_id = NEW.story_id;
     236
     237    SELECT username INTO v_liker_username
     238    FROM users
     239    WHERE user_id = NEW.user_id;
     240
     241    -- Do not notify if the writer likes their own story
     242    IF v_writer_id != NEW.user_id THEN
     243        INSERT INTO notification (
     244            notification_content,
     245            is_read,
     246            recipient_user_id,
     247            type,
     248            link,
     249            notification_created_at
     250        )
     251        VALUES (
     252            v_liker_username || ' liked your story "' || v_story_desc || '"',
     253            FALSE,
     254            v_writer_id,
     255            'like',
     256            '/story/' || NEW.story_id::VARCHAR,
     257            CURRENT_TIMESTAMP
     258        );
     259    END IF;
     260
     261    RETURN NEW;
     262END;
     263$$;
     264
     265CREATE OR REPLACE TRIGGER on_story_liked
     266    AFTER INSERT ON likes
     267    FOR EACH ROW
     268EXECUTE FUNCTION notify_writer_on_like();
     269}}}
     270
     271==== Prevents adding a story to a reading list if it is not published
     272{{{
     273CREATE OR REPLACE FUNCTION check_story_published_before_adding()
     274RETURNS TRIGGER
     275LANGUAGE plpgsql
     276AS $$
     277BEGIN
     278    IF NOT EXISTS (
     279        SELECT 1 FROM "status"
     280        WHERE story_id = NEW.story_id
     281          AND status   = 'published'
     282    ) THEN
     283        RAISE EXCEPTION
     284            'story_id=% is not published and cannot be added to a reading list.',
     285            NEW.story_id;
     286    END IF;
     287    RETURN NEW;
     288END;
     289$$;
     290
     291CREATE OR REPLACE TRIGGER enforce_published_before_list_add
     292    BEFORE INSERT ON reading_list_items
     293    FOR EACH ROW
     294EXECUTE FUNCTION check_story_published_before_adding();
     295}}}
     296==== Trigger: prevents a writer from collaborating on their own story
     297{{{
     298CREATE OR REPLACE FUNCTION check_not_own_story()
     299RETURNS TRIGGER
     300LANGUAGE plpgsql
     301AS $$
     302BEGIN
     303    IF EXISTS (
     304        SELECT 1 FROM story
     305        WHERE story_id = NEW.story_id
     306          AND user_id  = NEW.user_id
     307    ) THEN
     308        RAISE EXCEPTION
     309            'user_id=% is the owner of story_id=% and cannot be a collaborator.',
     310            NEW.user_id,
     311            NEW.story_id;
     312    END IF;
     313    RETURN NEW;
     314END;
     315$$;
     316
     317CREATE OR REPLACE TRIGGER prevent_self_collaboration
     318    BEFORE INSERT ON collaboration
     319    FOR EACH ROW
     320EXECUTE FUNCTION check_not_own_story();
     321}}}