85 lines
2.3 KiB
PL/PgSQL
85 lines
2.3 KiB
PL/PgSQL
-- =====================================================
|
|
-- Optimistic Locking for Courses, Events, Bookings
|
|
--
|
|
-- Problem: Concurrent edits to courses, events, or bookings
|
|
-- can silently overwrite each other (last write wins).
|
|
--
|
|
-- Fix: Add version column to each table with an auto-
|
|
-- increment trigger on update. API layer checks version
|
|
-- match before writing, preventing silent overwrites.
|
|
--
|
|
-- Reuses the same trigger function pattern established
|
|
-- in 20260416000005_member_versioning.sql but creates a
|
|
-- shared generic function instead of table-specific ones.
|
|
-- =====================================================
|
|
|
|
-- Shared version increment function (CREATE OR REPLACE is idempotent)
|
|
CREATE OR REPLACE FUNCTION public.increment_version()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
NEW.version := OLD.version + 1;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
-- -------------------------------------------------------
|
|
-- COURSES
|
|
-- -------------------------------------------------------
|
|
|
|
ALTER TABLE public.courses
|
|
ADD COLUMN IF NOT EXISTS version integer NOT NULL DEFAULT 1;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_trigger WHERE tgname = 'trg_courses_increment_version'
|
|
) THEN
|
|
CREATE TRIGGER trg_courses_increment_version
|
|
BEFORE UPDATE ON public.courses
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.increment_version();
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
-- -------------------------------------------------------
|
|
-- EVENTS
|
|
-- -------------------------------------------------------
|
|
|
|
ALTER TABLE public.events
|
|
ADD COLUMN IF NOT EXISTS version integer NOT NULL DEFAULT 1;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_trigger WHERE tgname = 'trg_events_increment_version'
|
|
) THEN
|
|
CREATE TRIGGER trg_events_increment_version
|
|
BEFORE UPDATE ON public.events
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.increment_version();
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
-- -------------------------------------------------------
|
|
-- BOOKINGS
|
|
-- -------------------------------------------------------
|
|
|
|
ALTER TABLE public.bookings
|
|
ADD COLUMN IF NOT EXISTS version integer NOT NULL DEFAULT 1;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_trigger WHERE tgname = 'trg_bookings_increment_version'
|
|
) THEN
|
|
CREATE TRIGGER trg_bookings_increment_version
|
|
BEFORE UPDATE ON public.bookings
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.increment_version();
|
|
END IF;
|
|
END;
|
|
$$;
|