76 lines
3.1 KiB
MySQL
76 lines
3.1 KiB
MySQL
|
|
-- Migrasjon 011: invitasjonskode (oppdagelse) + cachet matchledelse (ADR-020).
|
||
|
|
--
|
||
|
|
-- To uavhengige, additive endringer:
|
||
|
|
-- 1. tournament.join_code -- kort, menneske-skrivbar kode som løses til
|
||
|
|
-- riktig turnering FØR org-kontekst er kjent (samme "løs kontekst FØR
|
||
|
|
-- RLS kan håndheve noe"-problem som public_tournament_org, 007).
|
||
|
|
-- Bevisst OVERSTYRER visibility ved bruk (se ADR-020 Beslutning A) --
|
||
|
|
-- dette er ikke noe skjemaet håndhever, kun API-laget.
|
||
|
|
-- 2. match.leading_side -- cachet fortegn av MatchState.lead (ADR-020
|
||
|
|
-- Beslutning C), samme mønster som status_text/points_side_a/b.
|
||
|
|
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
-- 1. tournament.join_code
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
|
||
|
|
ALTER TABLE tournament ADD COLUMN join_code text;
|
||
|
|
|
||
|
|
-- Backfyll eksisterende rader (typisk 1-2 i prod på dette tidspunktet) med
|
||
|
|
-- en tilfeldig 6-tegns kode fra et alfabet uten forvekslingsbare tegn
|
||
|
|
-- (0/O, 1/I droppet). Kollisjonssjekk mot allerede-tildelte koder i samme
|
||
|
|
-- løkke -- radantallet er lite nok til at en enkel retry-løkke er trygg.
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
r RECORD;
|
||
|
|
alphabet text := 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
|
||
|
|
candidate text;
|
||
|
|
attempt int;
|
||
|
|
i int;
|
||
|
|
BEGIN
|
||
|
|
FOR r IN SELECT id FROM tournament WHERE join_code IS NULL LOOP
|
||
|
|
attempt := 0;
|
||
|
|
LOOP
|
||
|
|
candidate := '';
|
||
|
|
FOR i IN 1..6 LOOP
|
||
|
|
candidate := candidate || substr(alphabet, 1 + floor(random() * length(alphabet))::int, 1);
|
||
|
|
END LOOP;
|
||
|
|
attempt := attempt + 1;
|
||
|
|
EXIT WHEN attempt > 20 OR NOT EXISTS (
|
||
|
|
SELECT 1 FROM tournament WHERE join_code = candidate
|
||
|
|
);
|
||
|
|
END LOOP;
|
||
|
|
UPDATE tournament SET join_code = candidate WHERE id = r.id;
|
||
|
|
END LOOP;
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
ALTER TABLE tournament ALTER COLUMN join_code SET NOT NULL;
|
||
|
|
ALTER TABLE tournament ADD CONSTRAINT tournament_join_code_unique UNIQUE (join_code);
|
||
|
|
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
-- 2. match.leading_side
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
|
||
|
|
ALTER TABLE match ADD COLUMN leading_side text CHECK (leading_side IN ('a', 'b'));
|
||
|
|
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
-- 3. public_tournament_by_code() -- fjerde SECURITY DEFINER-bro i
|
||
|
|
-- prosjektet (etter public_tournament_org 007, link_player_by_email 008,
|
||
|
|
-- public_org_by_slug 009), samme herding (SET search_path = public mot
|
||
|
|
-- kapring). Eksponerer KUN uuid<-text-koblingen, ingenting annet fra
|
||
|
|
-- tournament-raden. NULL for ukjent kode -- ingen egen anti-
|
||
|
|
-- enumereringsbekymring her siden koden er MENT å deles (se ADR-020
|
||
|
|
-- Beslutning A), men samme returform som de tre andre broene uansett.
|
||
|
|
-- ---------------------------------------------------------------------
|
||
|
|
|
||
|
|
CREATE FUNCTION public_tournament_by_code(p_code text)
|
||
|
|
RETURNS uuid
|
||
|
|
LANGUAGE sql
|
||
|
|
SECURITY DEFINER
|
||
|
|
SET search_path = public
|
||
|
|
STABLE
|
||
|
|
AS $$
|
||
|
|
SELECT id FROM tournament WHERE upper(join_code) = upper(p_code);
|
||
|
|
$$;
|
||
|
|
|
||
|
|
GRANT EXECUTE ON FUNCTION public_tournament_by_code(text) TO teecup_app;
|