-- Ein Gruppen-CC wird fuer jeden Nutzer einzeln gerechnet: fuer den einen ist -- er der gekaufte Platz, fuer den anderen ein Redesign seines vorherigen CCs. -- Deshalb wandert die Liste vom CC an die Mitgliedschaft. ALTER TABLE "CharacterMember" ADD COLUMN IF NOT EXISTS "lineageId" TEXT; ALTER TABLE "CharacterMember" ADD COLUMN IF NOT EXISTS "chainPosition" INTEGER NOT NULL DEFAULT 0; -- Wer den CC angelegt hat, bringt seine bisherige Kette mit. UPDATE "CharacterMember" m SET "lineageId" = c."lineageId", "chainPosition" = c."chainPosition" FROM "Character" c WHERE c.id = m."characterId" AND c."playerId" = m."playerId" AND m."lineageId" IS NULL; -- Die uebrigen haengen an einem Eintrag, der schon zugeordnet ist: entweder am -- CC, den sie dafuer aufgegeben haben, oder an einem frueheren Glied derselben -- Kette, in der sie mitgezogen wurden. Beides kann mehrere Stufen tief gehen, -- deshalb die Schleife. DO $$ DECLARE ueber_vorgaenger INTEGER; ueber_kette INTEGER; geaendert INTEGER := 1; BEGIN WHILE geaendert > 0 LOOP UPDATE "CharacterMember" m SET "lineageId" = v."lineageId", "chainPosition" = v."chainPosition" + 10 FROM "CharacterMember" v WHERE v."characterId" = m."predecessorId" AND v."playerId" = m."playerId" AND v."lineageId" IS NOT NULL AND m."lineageId" IS NULL; GET DIAGNOSTICS ueber_vorgaenger = ROW_COUNT; UPDATE "CharacterMember" m SET "lineageId" = q."lineageId", "chainPosition" = q."chainPosition" + (q."cc_pos" - q."von_pos") FROM ( SELECT DISTINCT ON (offen.id) offen.id AS mitglied_id, v."lineageId", v."chainPosition", cm."chainPosition" AS cc_pos, cv."chainPosition" AS von_pos FROM "CharacterMember" offen JOIN "Character" cm ON cm.id = offen."characterId" JOIN "Character" cv ON cv."lineageId" = cm."lineageId" AND cv."chainPosition" < cm."chainPosition" JOIN "CharacterMember" v ON v."characterId" = cv.id AND v."playerId" = offen."playerId" WHERE offen."lineageId" IS NULL AND v."lineageId" IS NOT NULL ORDER BY offen.id, cv."chainPosition" DESC ) q WHERE m.id = q.mitglied_id; GET DIAGNOSTICS ueber_kette = ROW_COUNT; geaendert := ueber_vorgaenger + ueber_kette; END LOOP; END $$; -- Alles Uebrige beginnt eine eigene Liste: ein Platz, der fuer sich steht. UPDATE "CharacterMember" SET "lineageId" = gen_random_uuid()::text, "chainPosition" = 0 WHERE "lineageId" IS NULL; ALTER TABLE "CharacterMember" ALTER COLUMN "lineageId" SET NOT NULL; CREATE INDEX IF NOT EXISTS "CharacterMember_lineageId_idx" ON "CharacterMember"("lineageId");