-- Bezeichner für die öffentliche Einzel-URL /erklaerung/ ALTER TABLE "PrivacyPolicy" ADD COLUMN "slug" TEXT; -- Der Bezeichner wird aus dem Titel abgeleitet – dieselbe Regel wie in -- lib/slug.ts. SQLite kennt kein REGEXP, deshalb Schritt für Schritt. UPDATE "PrivacyPolicy" SET "slug" = "title"; -- Umlaute umschreiben. LOWER() in SQLite kennt nur ASCII und würde ein "Ä" -- unverändert stehen lassen, deshalb kommen die Großbuchstaben zuerst dran. UPDATE "PrivacyPolicy" SET "slug" = REPLACE(REPLACE(REPLACE(REPLACE("slug", 'Ä', 'ae'), 'Ö', 'oe'), 'Ü', 'ue'), 'ẞ', 'ss'); UPDATE "PrivacyPolicy" SET "slug" = LOWER("slug"); UPDATE "PrivacyPolicy" SET "slug" = REPLACE(REPLACE(REPLACE(REPLACE("slug", 'ä', 'ae'), 'ö', 'oe'), 'ü', 'ue'), 'ß', 'ss'); -- Alles Übrige, was kein Buchstabe und keine Ziffer ist, wird zum Bindestrich. UPDATE "PrivacyPolicy" SET "slug" = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE("slug", ' ', '-'), '/', '-'), '.', '-'), ',', '-'), ':', '-'), ';', '-'), '(', '-'), ')', '-'), '[', '-'), ']', '-'), '&', '-'), '+', '-'), '§', '-'), '%', '-'), '!', '-'), '?', '-'), '#', '-'), '*', '-'), '"', '-'), '''', '-'), '„', '-'), '“', '-'), '–', '-'), '_', '-'); -- Mehrfache Bindestriche zusammenfassen (deckt bis zu acht in Folge ab) UPDATE "PrivacyPolicy" SET "slug" = REPLACE("slug", '--', '-'); UPDATE "PrivacyPolicy" SET "slug" = REPLACE("slug", '--', '-'); UPDATE "PrivacyPolicy" SET "slug" = REPLACE("slug", '--', '-'); -- Auf dieselbe Länge wie in lib/slug.ts kürzen, dann die Ränder säubern UPDATE "PrivacyPolicy" SET "slug" = SUBSTR("slug", 1, 60); UPDATE "PrivacyPolicy" SET "slug" = LTRIM("slug", '-'); UPDATE "PrivacyPolicy" SET "slug" = RTRIM("slug", '-'); -- Was jetzt noch ein anderes Zeichen enthält – etwa ein Buchstabe mit Akzent, -- der oben nicht aufgeführt ist – bekommt einen Bezeichner aus der ID. -- Lieber unschön als nicht adressierbar. UPDATE "PrivacyPolicy" SET "slug" = 'erklaerung-' || "id" WHERE "slug" IS NULL OR "slug" = '' OR "slug" GLOB '*[^a-z0-9-]*'; -- Kollisionen über die ID eindeutig machen; der älteste Datensatz behält den -- kurzen Bezeichner. UPDATE "PrivacyPolicy" SET "slug" = "slug" || '-' || "id" WHERE "id" NOT IN (SELECT MIN("id") FROM "PrivacyPolicy" GROUP BY "slug"); -- RedefineTables: slug als NOT NULL mit eindeutigem Index PRAGMA defer_foreign_keys=ON; PRAGMA foreign_keys=OFF; CREATE TABLE "new_PrivacyPolicy" ( "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "slug" TEXT NOT NULL, "title" TEXT NOT NULL, "responsible" TEXT, "contactDPO" TEXT, "dataSubjectsRights" TEXT, "complaintRight" TEXT, "withdrawalRight" TEXT, "processingDescription" TEXT NOT NULL, "processingPurposes" TEXT, "legalBasis" TEXT, "recipients" TEXT NOT NULL, "storageDuration" TEXT, "dataSource" TEXT, "provisionObligation" TEXT, "provisionConsequences" TEXT, "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" DATETIME NOT NULL, "isPublic" BOOLEAN NOT NULL DEFAULT true ); INSERT INTO "new_PrivacyPolicy" ("id", "slug", "title", "responsible", "contactDPO", "dataSubjectsRights", "complaintRight", "withdrawalRight", "processingDescription", "processingPurposes", "legalBasis", "recipients", "storageDuration", "dataSource", "provisionObligation", "provisionConsequences", "createdAt", "updatedAt", "isPublic") SELECT "id", "slug", "title", "responsible", "contactDPO", "dataSubjectsRights", "complaintRight", "withdrawalRight", "processingDescription", "processingPurposes", "legalBasis", "recipients", "storageDuration", "dataSource", "provisionObligation", "provisionConsequences", "createdAt", "updatedAt", "isPublic" FROM "PrivacyPolicy"; DROP TABLE "PrivacyPolicy"; ALTER TABLE "new_PrivacyPolicy" RENAME TO "PrivacyPolicy"; CREATE UNIQUE INDEX "PrivacyPolicy_slug_key" ON "PrivacyPolicy"("slug"); PRAGMA foreign_keys=ON; PRAGMA defer_foreign_keys=OFF;