-- Synthetisches Katalogvolumen fuer die Latenzmessung KAT-01 Kriterium 7 (Playwright-Projekt `perf`, -- Spec #3 Abschnitt 7.3). Anders als catalog_search_perf.sql (Messung in der Datenbank, Rollback) wird hier -- COMMITTET: Die App im Browser muss die Daten ueber Kong lesen koennen. Deshalb nur lokal, nur kurz, und immer -- mit catalog_search_perf_unload.sql wieder entfernen. -- -- Was es tut: legt 10 000 sichtbare Katalogspiele (Standard), je zwei alternative Titel, 2 000 Verlage -- (12 900 Zuordnungen) und je Spiel zwei Genres und drei Mechaniken aus dem VORHANDENEN Vokabular an. Alle Spiele -- und Verlage tragen IDs mit dem Praefix 9e4f0000- , das Entfernen loescht darueber (Zuordnungen und alternative -- Titel haengen per on delete cascade an den Spielen). Danach vacuum (analyze), damit der Planer die echten -- Groessen kennt. -- -- Schutz wie in catalog_search_perf.sql: -v confirm_local=yes, nur per Unix-Socket (docker exec ... psql), Abbruch -- bei mehr als 20 privaten Spielen. (Konten werden bewusst NICHT gezaehlt: die E2E-Tests legen laufend welche an.) -- Aufruf: -- docker exec -i supabase_db_shuffle psql -U postgres -d postgres -X -v confirm_local=yes -v n_games=10000 \ -- < supabase/perf/catalog_search_perf_load.sql \set ON_ERROR_STOP on \if :{?confirm_local} \else \set confirm_local no \endif select :'confirm_local' = 'yes' as confirm_ok, coalesce(:'HOST', '') like '/%' as socket_ok \gset \if :confirm_ok \else \echo 'Abbruch: mit -v confirm_local=yes aufrufen (nur lokal, siehe Kopfkommentar).' \quit \endif \if :socket_ok \else \echo 'Abbruch: nur per Unix-Socket im lokalen Container (docker exec ... psql), nie ueber TCP gegen einen Server.' \quit \endif \if :{?n_games} \else \set n_games 10000 \endif do $guard$ begin if (select count(*) from public.games where visibility = 'private') > 20 then raise exception 'Abbruch: Die Datenbank sieht nach echten Daten aus (mehr als 20 private Spiele). Nur lokal.'; end if; if exists (select 1 from public.games where id::text like '9e4f0000-%') then raise exception 'Abbruch: synthetische Daten sind schon geladen (erst catalog_search_perf_unload.sql ausfuehren).'; end if; if (select count(*) from public.genres) < 3 or (select count(*) from public.mechanics) < 3 then raise exception 'Abbruch: Genre-/Mechanik-Vokabular fehlt (supabase db reset einspielen).'; end if; end $guard$; begin; select setseed(0.42); create temp table perf_words on commit drop as select i, translate(substr(md5('w' || i), 1, 4 + (i % 6)), '0123456789', 'ghijklmnop') as w from generate_series(1, 3000) i; alter table perf_words add primary key (i); create function pg_temp.pick() returns text language sql volatile as $$ select w from perf_words where i = (select 1 + floor(power(random(), 2.2) * 3000)::int) $$; insert into public.publishers (id, name) select ('9e4f0000-0000-4000-9000-' || lpad(to_hex(i), 12, '0'))::uuid, initcap(pg_temp.pick()) || ' Spiele ' || i from generate_series(1, 2000) i; insert into public.games (id, title, visibility, year, min_players, max_players, min_minutes, max_minutes, min_age, description, description_locale) select ('9e4f0000-0000-4000-8000-' || lpad(to_hex(g), 12, '0'))::uuid, initcap(concat_ws(' ', pg_temp.pick(), case when k >= 2 then pg_temp.pick() end, case when k >= 3 then pg_temp.pick() end, case when k >= 4 then pg_temp.pick() end)), 'catalog', 1990 + (g % 35), mn, mn + (g % 5), 10 + (g % 12) * 10, 30 + (g % 12) * 10, 6 + (g % 4) * 3, 'Synthetischer Kurztext ' || g, 'de' from (select g, 1 + floor(random() * 3.99)::int as k, 1 + (g % 4) as mn from generate_series(1, :n_games) g) s; insert into public.game_alt_titles (game_id, locale, title) select g.id, l.locale, initcap(pg_temp.pick() || ' ' || pg_temp.pick()) from public.games g, (values ('de'), ('en')) as l(locale) where g.id::text like '9e4f0000-%' on conflict do nothing; insert into public.game_publishers (game_id, publisher_id) select g.id, p.id from public.games g cross join lateral (select id from public.publishers where id::text like '9e4f0000-%' order by md5(g.id::text || id::text) limit 1) p where g.id::text like '9e4f0000-%' on conflict do nothing; insert into public.game_publishers (game_id, publisher_id) select g.id, p.id from public.games g cross join lateral (select id from public.publishers where id::text like '9e4f0000-%' order by md5(g.id::text || id::text || 'b') limit 1) p where g.id::text like '9e4f0000-%' and random() < 0.3 on conflict do nothing; insert into public.game_genres (game_id, genre_id) select g.id, t.id from public.games g cross join lateral (select x.id from public.genres x order by md5(g.id::text || x.id::text) limit 2) t where g.id::text like '9e4f0000-%' on conflict do nothing; insert into public.game_mechanics (game_id, mechanic_id) select g.id, t.id from public.games g cross join lateral (select x.id from public.mechanics x order by md5(g.id::text || x.id::text) limit 3) t where g.id::text like '9e4f0000-%' on conflict do nothing; commit; vacuum (analyze) public.games; vacuum (analyze) public.game_alt_titles; vacuum (analyze) public.publishers; vacuum (analyze) public.game_publishers; vacuum (analyze) public.game_genres; vacuum (analyze) public.game_mechanics; \echo === geladen === select (select count(*) from public.catalog_games) as katalogspiele, (select count(*) from public.game_alt_titles) as alt_titel, (select count(*) from public.publishers) as verlage, (select count(*) from public.game_publishers) as verlag_zuordnungen;