308 lines
12 KiB
MySQL
308 lines
12 KiB
MySQL
|
|
-- Migration: Convertir users.id de BIGINT vers UUID
|
||
|
|
-- CRITIQUE: Cette migration doit être exécutée AVANT tout déploiement utilisant les nouveaux modèles UUID
|
||
|
|
-- Date: 2024-11-27
|
||
|
|
-- Impact: BREAKING CHANGE - Toutes les FK doivent être migrées
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 1: Créer une colonne temporaire UUID
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
-- Activer l'extension UUID si pas déjà fait
|
||
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- Pour gen_random_uuid()
|
||
|
|
|
||
|
|
-- Ajouter une colonne temporaire pour stocker les nouveaux UUIDs
|
||
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS id_uuid UUID;
|
||
|
|
|
||
|
|
-- Générer un UUID pour chaque utilisateur existant (mapping déterministe depuis l'ID)
|
||
|
|
-- Note: On utilise uuid_generate_v5 pour créer un UUID déterministe basé sur l'ID existant
|
||
|
|
UPDATE users
|
||
|
|
SET id_uuid = uuid_generate_v5(
|
||
|
|
'6ba7b810-9dad-11d1-80b4-00c04fd430c8'::uuid, -- Namespace UUID arbitraire mais fixe
|
||
|
|
id::text
|
||
|
|
)
|
||
|
|
WHERE id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 2: Migrer les tables dépendantes (FK)
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
-- Pour chaque table avec user_id en BIGINT, créer une colonne temporaire UUID
|
||
|
|
|
||
|
|
-- user_roles
|
||
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE user_roles ur
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE ur.user_id = u.id AND ur.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- tracks
|
||
|
|
ALTER TABLE tracks ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE tracks t
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE t.user_id = u.id AND t.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- playlists
|
||
|
|
ALTER TABLE playlists ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE playlists p
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE p.user_id = u.id AND p.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- refresh_tokens
|
||
|
|
ALTER TABLE refresh_tokens ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE refresh_tokens rt
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE rt.user_id = u.id AND rt.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- sessions (déjà en UUID, mais vérifier cohérence)
|
||
|
|
-- Si sessions.user_id est déjà UUID, créer un mapping inverse
|
||
|
|
-- Note: Cette table semble déjà utiliser UUID, donc on va juste s'assurer de la cohérence
|
||
|
|
-- UPDATE sessions s SET user_id = u.id_uuid FROM users u WHERE ... (si nécessaire)
|
||
|
|
|
||
|
|
-- messages
|
||
|
|
ALTER TABLE messages ADD COLUMN IF NOT EXISTS sender_id_uuid UUID;
|
||
|
|
UPDATE messages m
|
||
|
|
SET sender_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE m.sender_id = u.id AND m.sender_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- rooms (owner_id)
|
||
|
|
ALTER TABLE rooms ADD COLUMN IF NOT EXISTS owner_id_uuid UUID;
|
||
|
|
UPDATE rooms r
|
||
|
|
SET owner_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE r.owner_id = u.id AND r.owner_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- room_members
|
||
|
|
ALTER TABLE room_members ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE room_members rm
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE rm.user_id = u.id AND rm.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- track_likes
|
||
|
|
ALTER TABLE track_likes ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE track_likes tl
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE tl.user_id = u.id AND tl.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- track_comments
|
||
|
|
ALTER TABLE track_comments ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE track_comments tc
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE tc.user_id = u.id AND tc.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- track_shares
|
||
|
|
ALTER TABLE track_shares ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE track_shares ts
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE ts.user_id = u.id AND ts.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- playlist_collaborators
|
||
|
|
ALTER TABLE playlist_collaborators ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE playlist_collaborators pc
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE pc.user_id = u.id AND pc.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- playlist_follows
|
||
|
|
ALTER TABLE playlist_follows ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE playlist_follows pf
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE pf.user_id = u.id AND pf.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- user_settings
|
||
|
|
ALTER TABLE user_settings ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
||
|
|
UPDATE user_settings us
|
||
|
|
SET user_id_uuid = u.id_uuid
|
||
|
|
FROM users u
|
||
|
|
WHERE us.user_id = u.id AND us.user_id_uuid IS NULL;
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 3: Supprimer anciennes colonnes et renommer UUID
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
-- NOTE: Ces étapes sont DESTRUCTIVES et ne peuvent être annulées sans backup
|
||
|
|
-- En production, exécuter avec précaution et APRÈS validation complète
|
||
|
|
|
||
|
|
-- Supprimer les anciennes FK constraints
|
||
|
|
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_user_id_fkey;
|
||
|
|
ALTER TABLE tracks DROP CONSTRAINT IF EXISTS tracks_user_id_fkey;
|
||
|
|
ALTER TABLE playlists DROP CONSTRAINT IF EXISTS playlists_user_id_fkey;
|
||
|
|
ALTER TABLE refresh_tokens DROP CONSTRAINT IF EXISTS refresh_tokens_user_id_fkey;
|
||
|
|
ALTER TABLE messages DROP CONSTRAINT IF EXISTS messages_sender_id_fkey;
|
||
|
|
ALTER TABLE rooms DROP CONSTRAINT IF EXISTS rooms_owner_id_fkey;
|
||
|
|
ALTER TABLE room_members DROP CONSTRAINT IF EXISTS room_members_user_id_fkey;
|
||
|
|
ALTER TABLE track_likes DROP CONSTRAINT IF EXISTS track_likes_user_id_fkey;
|
||
|
|
ALTER TABLE track_comments DROP CONSTRAINT IF EXISTS track_comments_user_id_fkey;
|
||
|
|
ALTER TABLE track_shares DROP CONSTRAINT IF EXISTS track_shares_user_id_fkey;
|
||
|
|
ALTER TABLE playlist_collaborators DROP CONSTRAINT IF EXISTS playlist_collaborators_user_id_fkey;
|
||
|
|
ALTER TABLE playlist_follows DROP CONSTRAINT IF EXISTS playlist_follows_user_id_fkey;
|
||
|
|
ALTER TABLE user_settings DROP CONSTRAINT IF EXISTS user_settings_user_id_fkey;
|
||
|
|
|
||
|
|
-- Supprimer anciennes colonnes INT
|
||
|
|
ALTER TABLE user_roles DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE tracks DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE playlists DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE refresh_tokens DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE messages DROP COLUMN IF EXISTS sender_id;
|
||
|
|
ALTER TABLE rooms DROP COLUMN IF EXISTS owner_id;
|
||
|
|
ALTER TABLE room_members DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE track_likes DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE track_comments DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE track_shares DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE playlist_collaborators DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE playlist_follows DROP COLUMN IF EXISTS user_id;
|
||
|
|
ALTER TABLE user_settings DROP COLUMN IF EXISTS user_id;
|
||
|
|
|
||
|
|
-- Renommer colonnes UUID vers le nom standard
|
||
|
|
ALTER TABLE user_roles RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE tracks RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE playlists RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE refresh_tokens RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE messages RENAME COLUMN sender_id_uuid TO sender_id;
|
||
|
|
ALTER TABLE rooms RENAME COLUMN owner_id_uuid TO owner_id;
|
||
|
|
ALTER TABLE room_members RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE track_likes RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE track_comments RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE track_shares RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE playlist_collaborators RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE playlist_follows RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
ALTER TABLE user_settings RENAME COLUMN user_id_uuid TO user_id;
|
||
|
|
|
||
|
|
-- Définir NOT NULL sur les colonnes
|
||
|
|
ALTER TABLE user_roles ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE tracks ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE playlists ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE refresh_tokens ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE messages ALTER COLUMN sender_id SET NOT NULL;
|
||
|
|
ALTER TABLE rooms ALTER COLUMN owner_id SET NOT NULL;
|
||
|
|
ALTER TABLE room_members ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE track_likes ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE track_comments ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE track_shares ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE playlist_collaborators ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE playlist_follows ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
ALTER TABLE user_settings ALTER COLUMN user_id SET NOT NULL;
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 4: Migrer users.id vers UUID
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
-- Supprimer l'ancienne colonne id (BIGINT)
|
||
|
|
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey;
|
||
|
|
ALTER TABLE users DROP COLUMN IF EXISTS id;
|
||
|
|
|
||
|
|
-- Renommer id_uuid vers id
|
||
|
|
ALTER TABLE users RENAME COLUMN id_uuid TO id;
|
||
|
|
|
||
|
|
-- Définir comme PRIMARY KEY
|
||
|
|
ALTER TABLE users ADD PRIMARY KEY (id);
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 5: Recréer les FK constraints avec UUID
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
ALTER TABLE user_roles
|
||
|
|
ADD CONSTRAINT fk_user_roles_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE tracks
|
||
|
|
ADD CONSTRAINT fk_tracks_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE playlists
|
||
|
|
ADD CONSTRAINT fk_playlists_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE refresh_tokens
|
||
|
|
ADD CONSTRAINT fk_refresh_tokens_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE messages
|
||
|
|
ADD CONSTRAINT fk_messages_users
|
||
|
|
FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE rooms
|
||
|
|
ADD CONSTRAINT fk_rooms_users
|
||
|
|
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE room_members
|
||
|
|
ADD CONSTRAINT fk_room_members_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE track_likes
|
||
|
|
ADD CONSTRAINT fk_track_likes_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE track_comments
|
||
|
|
ADD CONSTRAINT fk_track_comments_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE track_shares
|
||
|
|
ADD CONSTRAINT fk_track_shares_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE playlist_collaborators
|
||
|
|
ADD CONSTRAINT fk_playlist_collaborators_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE playlist_follows
|
||
|
|
ADD CONSTRAINT fk_playlist_follows_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
ALTER TABLE user_settings
|
||
|
|
ADD CONSTRAINT fk_user_settings_users
|
||
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- ÉTAPE 6: Recréer les indexes
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tracks_user_id ON tracks(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_playlists_user_id ON playlists(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_messages_sender_id ON messages(sender_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_rooms_owner_id ON rooms(owner_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_room_members_user_id ON room_members(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_likes_user_id ON track_likes(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_comments_user_id ON track_comments(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_shares_user_id ON track_shares(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_playlist_collaborators_user_id ON playlist_collaborators(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_playlist_follows_user_id ON playlist_follows(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_user_settings_user_id ON user_settings(user_id);
|
||
|
|
|
||
|
|
-- =====================================================
|
||
|
|
-- VERIFICATION
|
||
|
|
-- =====================================================
|
||
|
|
|
||
|
|
-- Vérifier que tous les users ont un UUID valide
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
user_count INT;
|
||
|
|
null_uuid_count INT;
|
||
|
|
BEGIN
|
||
|
|
SELECT COUNT(*) INTO user_count FROM users;
|
||
|
|
SELECT COUNT(*) INTO null_uuid_count FROM users WHERE id IS NULL;
|
||
|
|
|
||
|
|
RAISE NOTICE 'Migration UUID - Total users: %, Users avec UUID NULL: %', user_count, null_uuid_count;
|
||
|
|
|
||
|
|
IF null_uuid_count > 0 THEN
|
||
|
|
RAISE EXCEPTION 'Migration échouée: % utilisateurs ont un UUID NULL', null_uuid_count;
|
||
|
|
END IF;
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
-- Vérifier l'intégrité référentielle
|
||
|
|
-- TODO: Ajouter des checks supplémentaires si nécessaire
|
||
|
|
|
||
|
|
COMMENT ON COLUMN users.id IS 'UUID unique de l''utilisateur (migré de BIGINT)';
|
||
|
|
|