Loading migrate_int_to_uuid.sql 0 → 100644 +479 −0 Original line number Diff line number Diff line -- ============================================================================= -- Blogi Migration: INTEGER id -> UUID -- Database: PostgreSQL (requires 13+ for gen_random_uuid()) -- ============================================================================= -- -- Run: psql -d <dbname> -f migrate_int_to_uuid.sql -- -- This script converts all integer primary keys and foreign keys to UUID. -- It preserves existing data and relationships. -- Back up your database before running! -- -- ============================================================================= BEGIN; -- --------------------------------------------------------------------------- -- 0. Prerequisites (gen_random_uuid() is built-in since PostgreSQL 13) -- --------------------------------------------------------------------------- -- --------------------------------------------------------------------------- -- 1. Add UUID columns to all tables (parent tables first) -- --------------------------------------------------------------------------- -- == Level 0: Independent tables (no FK to other migrated tables) == ALTER TABLE users ADD COLUMN id_new UUID; ALTER TABLE session ADD COLUMN id_new UUID; ALTER TABLE options ADD COLUMN id_new UUID; ALTER TABLE theme_colors ADD COLUMN id_new UUID; ALTER TABLE cookie_rules ADD COLUMN id_new UUID; ALTER TABLE tags ADD COLUMN id_new UUID; ALTER TABLE gameserver_protocols ADD COLUMN id_new UUID; ALTER TABLE navbar ADD COLUMN id_new UUID; ALTER TABLE youtube_channels ADD COLUMN id_new UUID; ALTER TABLE templates ADD COLUMN id_new UUID; ALTER TABLE static_content ADD COLUMN id_new UUID; ALTER TABLE survey_results ADD COLUMN id_new UUID; ALTER TABLE editor_templates ADD COLUMN id_new UUID; -- contact_pending.token is already the PK; if it's INTEGER, migrate it too DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token' AND data_type IN ('integer','bigint','smallint') ) THEN EXECUTE 'ALTER TABLE contact_pending ADD COLUMN token_new UUID'; END IF; END$$; -- == Level 1: Tables with FK to level 0 == ALTER TABLE session_data ADD COLUMN sessionid_new UUID; ALTER TABLE content ADD COLUMN id_new UUID; ALTER TABLE content ADD COLUMN author_new UUID; ALTER TABLE gameserver ADD COLUMN id_new UUID; ALTER TABLE gameserver ADD COLUMN protocol_new UUID; ALTER TABLE navbar_items ADD COLUMN id_new UUID; ALTER TABLE navbar_items ADD COLUMN navbar_id_new UUID; ALTER TABLE youtube_videos ADD COLUMN id_new UUID; ALTER TABLE youtube_videos ADD COLUMN youtube_channels_pkey_new UUID; ALTER TABLE editor_template_revisions ADD COLUMN id_new UUID; ALTER TABLE editor_template_revisions ADD COLUMN template_id_new UUID; -- == Level 2: Tables with FK to level 1 == ALTER TABLE tags_content ADD COLUMN tag_id_new UUID; ALTER TABLE tags_content ADD COLUMN content_id_new UUID; ALTER TABLE comments ADD COLUMN id_new UUID; ALTER TABLE comments ADD COLUMN content_id_new UUID; ALTER TABLE comments ADD COLUMN user_id_new UUID; -- --------------------------------------------------------------------------- -- 2. Generate UUIDs for primary keys -- --------------------------------------------------------------------------- UPDATE users SET id_new = gen_random_uuid(); UPDATE session SET id_new = gen_random_uuid(); UPDATE options SET id_new = gen_random_uuid(); UPDATE theme_colors SET id_new = gen_random_uuid(); UPDATE cookie_rules SET id_new = gen_random_uuid(); UPDATE tags SET id_new = gen_random_uuid(); UPDATE gameserver_protocols SET id_new = gen_random_uuid(); UPDATE navbar SET id_new = gen_random_uuid(); UPDATE youtube_channels SET id_new = gen_random_uuid(); UPDATE templates SET id_new = gen_random_uuid(); UPDATE static_content SET id_new = gen_random_uuid(); UPDATE survey_results SET id_new = gen_random_uuid(); UPDATE editor_templates SET id_new = gen_random_uuid(); -- contact_pending (only if token was integer) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token_new' ) THEN EXECUTE 'UPDATE contact_pending SET token_new = gen_random_uuid()'; END IF; END$$; UPDATE content SET id_new = gen_random_uuid(); UPDATE gameserver SET id_new = gen_random_uuid(); UPDATE navbar_items SET id_new = gen_random_uuid(); UPDATE youtube_videos SET id_new = gen_random_uuid(); UPDATE editor_template_revisions SET id_new = gen_random_uuid(); UPDATE tags_content SET tag_id_new = NULL; -- FK only, set below UPDATE tags_content SET content_id_new = NULL; UPDATE comments SET id_new = gen_random_uuid(); -- --------------------------------------------------------------------------- -- 3. Propagate UUIDs through foreign key references -- --------------------------------------------------------------------------- -- session_data.sessionid -> session.id UPDATE session_data sd SET sessionid_new = s.id_new FROM session s WHERE sd.sessionid::text = s.id::text; -- content.author -> users.id UPDATE content c SET author_new = u.id_new FROM users u WHERE c.author::text = u.id::text; -- gameserver.protocol -> gameserver_protocols.id UPDATE gameserver g SET protocol_new = gp.id_new FROM gameserver_protocols gp WHERE g.protocol::text = gp.id::text; -- navbar_items.navbar_id -> navbar.id UPDATE navbar_items ni SET navbar_id_new = n.id_new FROM navbar n WHERE ni.navbar_id::text = n.id::text; -- youtube_videos.youtube_channels_pkey -> youtube_channels.id UPDATE youtube_videos yv SET youtube_channels_pkey_new = yc.id_new FROM youtube_channels yc WHERE yv.youtube_channels_pkey::text = yc.id::text; -- editor_template_revisions.template_id -> editor_templates.id UPDATE editor_template_revisions etr SET template_id_new = et.id_new FROM editor_templates et WHERE etr.template_id::text = et.id::text; -- tags_content.tag_id -> tags.id UPDATE tags_content tc SET tag_id_new = t.id_new FROM tags t WHERE tc.tag_id::text = t.id::text; -- tags_content.content_id -> content.id UPDATE tags_content tc SET content_id_new = c.id_new FROM content c WHERE tc.content_id::text = c.id::text; -- comments.content_id -> content.id UPDATE comments cm SET content_id_new = c.id_new FROM content c WHERE cm.content_id::text = c.id::text; -- comments.user_id -> users.id UPDATE comments cm SET user_id_new = u.id_new FROM users u WHERE cm.user_id::text = u.id::text; -- --------------------------------------------------------------------------- -- 4. Drop ALL foreign key constraints referencing migrated tables -- --------------------------------------------------------------------------- DO $$ DECLARE r RECORD; BEGIN -- Drop all FK constraints that reference any of the tables being migrated FOR r IN ( SELECT con.conname, con.conrelid::regclass AS tbl FROM pg_constraint con JOIN pg_constraint ref ON con.confrelid = ref.conrelid WHERE con.contype = 'f' AND con.confrelid::regclass::text IN ( 'users', 'session', 'options', 'theme_colors', 'cookie_rules', 'tags', 'gameserver_protocols', 'navbar', 'youtube_channels', 'templates', 'static_content', 'survey_results', 'editor_templates', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'comments' ) AND ref.contype = 'p' ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname); END LOOP; -- Also drop FK constraints ON the migrated tables themselves FOR r IN ( SELECT conname, conrelid::regclass AS tbl FROM pg_constraint WHERE contype = 'f' AND conrelid::regclass::text IN ( 'session_data', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'tags_content', 'comments', 'media_albums' ) ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname); END LOOP; END$$; -- --------------------------------------------------------------------------- -- 5. Drop old primary key constraints -- --------------------------------------------------------------------------- DO $$ DECLARE r RECORD; BEGIN FOR r IN ( SELECT conname, conrelid::regclass AS tbl FROM pg_constraint WHERE contype = 'p' AND conrelid::regclass::text IN ( 'users', 'session', 'options', 'theme_colors', 'cookie_rules', 'tags', 'gameserver_protocols', 'navbar', 'youtube_channels', 'templates', 'static_content', 'survey_results', 'editor_templates', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'comments' ) ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname); END LOOP; END$$; -- --------------------------------------------------------------------------- -- 6. Drop old columns, rename new columns -- --------------------------------------------------------------------------- -- == Level 0 tables == ALTER TABLE users DROP COLUMN id CASCADE; ALTER TABLE users RENAME COLUMN id_new TO id; ALTER TABLE session DROP COLUMN id CASCADE; ALTER TABLE session RENAME COLUMN id_new TO id; ALTER TABLE options DROP COLUMN id CASCADE; ALTER TABLE options RENAME COLUMN id_new TO id; ALTER TABLE theme_colors DROP COLUMN id CASCADE; ALTER TABLE theme_colors RENAME COLUMN id_new TO id; ALTER TABLE cookie_rules DROP COLUMN id CASCADE; ALTER TABLE cookie_rules RENAME COLUMN id_new TO id; ALTER TABLE tags DROP COLUMN id CASCADE; ALTER TABLE tags RENAME COLUMN id_new TO id; ALTER TABLE gameserver_protocols DROP COLUMN id CASCADE; ALTER TABLE gameserver_protocols RENAME COLUMN id_new TO id; ALTER TABLE navbar DROP COLUMN id CASCADE; ALTER TABLE navbar RENAME COLUMN id_new TO id; ALTER TABLE youtube_channels DROP COLUMN id CASCADE; ALTER TABLE youtube_channels RENAME COLUMN id_new TO id; ALTER TABLE templates DROP COLUMN id CASCADE; ALTER TABLE templates RENAME COLUMN id_new TO id; ALTER TABLE static_content DROP COLUMN id CASCADE; ALTER TABLE static_content RENAME COLUMN id_new TO id; ALTER TABLE survey_results DROP COLUMN id CASCADE; ALTER TABLE survey_results RENAME COLUMN id_new TO id; ALTER TABLE editor_templates DROP COLUMN id CASCADE; ALTER TABLE editor_templates RENAME COLUMN id_new TO id; -- contact_pending (conditional) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token_new' ) THEN EXECUTE 'ALTER TABLE contact_pending DROP COLUMN token CASCADE'; EXECUTE 'ALTER TABLE contact_pending RENAME COLUMN token_new TO token'; END IF; END$$; -- == Level 1 tables == ALTER TABLE session_data DROP COLUMN sessionid CASCADE; ALTER TABLE session_data RENAME COLUMN sessionid_new TO sessionid; ALTER TABLE content DROP COLUMN id CASCADE; ALTER TABLE content RENAME COLUMN id_new TO id; ALTER TABLE content DROP COLUMN author CASCADE; ALTER TABLE content RENAME COLUMN author_new TO author; ALTER TABLE gameserver DROP COLUMN id CASCADE; ALTER TABLE gameserver RENAME COLUMN id_new TO id; ALTER TABLE gameserver DROP COLUMN protocol CASCADE; ALTER TABLE gameserver RENAME COLUMN protocol_new TO protocol; ALTER TABLE navbar_items DROP COLUMN id CASCADE; ALTER TABLE navbar_items RENAME COLUMN id_new TO id; ALTER TABLE navbar_items DROP COLUMN navbar_id CASCADE; ALTER TABLE navbar_items RENAME COLUMN navbar_id_new TO navbar_id; ALTER TABLE youtube_videos DROP COLUMN id CASCADE; ALTER TABLE youtube_videos RENAME COLUMN id_new TO id; ALTER TABLE youtube_videos DROP COLUMN youtube_channels_pkey CASCADE; ALTER TABLE youtube_videos RENAME COLUMN youtube_channels_pkey_new TO youtube_channels_pkey; ALTER TABLE editor_template_revisions DROP COLUMN id CASCADE; ALTER TABLE editor_template_revisions RENAME COLUMN id_new TO id; ALTER TABLE editor_template_revisions DROP COLUMN template_id CASCADE; ALTER TABLE editor_template_revisions RENAME COLUMN template_id_new TO template_id; -- == Level 2 tables == ALTER TABLE tags_content DROP COLUMN tag_id CASCADE; ALTER TABLE tags_content RENAME COLUMN tag_id_new TO tag_id; ALTER TABLE tags_content DROP COLUMN content_id CASCADE; ALTER TABLE tags_content RENAME COLUMN content_id_new TO content_id; ALTER TABLE comments DROP COLUMN id CASCADE; ALTER TABLE comments RENAME COLUMN id_new TO id; ALTER TABLE comments DROP COLUMN content_id CASCADE; ALTER TABLE comments RENAME COLUMN content_id_new TO content_id; ALTER TABLE comments DROP COLUMN user_id CASCADE; ALTER TABLE comments RENAME COLUMN user_id_new TO user_id; -- --------------------------------------------------------------------------- -- 7. Re-add primary key constraints -- --------------------------------------------------------------------------- ALTER TABLE users ADD PRIMARY KEY (id); ALTER TABLE session ADD PRIMARY KEY (id); ALTER TABLE options ADD PRIMARY KEY (id); ALTER TABLE theme_colors ADD PRIMARY KEY (id); ALTER TABLE cookie_rules ADD PRIMARY KEY (id); ALTER TABLE tags ADD PRIMARY KEY (id); ALTER TABLE gameserver_protocols ADD PRIMARY KEY (id); ALTER TABLE navbar ADD PRIMARY KEY (id); ALTER TABLE youtube_channels ADD PRIMARY KEY (id); ALTER TABLE templates ADD PRIMARY KEY (id); ALTER TABLE static_content ADD PRIMARY KEY (id); ALTER TABLE survey_results ADD PRIMARY KEY (id); ALTER TABLE editor_templates ADD PRIMARY KEY (id); ALTER TABLE content ADD PRIMARY KEY (id); ALTER TABLE gameserver ADD PRIMARY KEY (id); ALTER TABLE navbar_items ADD PRIMARY KEY (id); ALTER TABLE youtube_videos ADD PRIMARY KEY (id); ALTER TABLE editor_template_revisions ADD PRIMARY KEY (id); ALTER TABLE comments ADD PRIMARY KEY (id); -- contact_pending: only add PK if we migrated it (token_new existed) DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conrelid = 'contact_pending'::regclass AND contype = 'p' ) THEN EXECUTE 'ALTER TABLE contact_pending ADD PRIMARY KEY (token)'; END IF; END$$; -- --------------------------------------------------------------------------- -- 8. Re-add foreign key constraints -- --------------------------------------------------------------------------- ALTER TABLE session_data ADD CONSTRAINT session_data_sessionid_fkey FOREIGN KEY (sessionid) REFERENCES session (id); ALTER TABLE content ADD CONSTRAINT content_author_fkey FOREIGN KEY (author) REFERENCES users (id); ALTER TABLE gameserver ADD CONSTRAINT gameserver_protocol_fkey FOREIGN KEY (protocol) REFERENCES gameserver_protocols (id); ALTER TABLE navbar_items ADD CONSTRAINT navbar_items_navbar_id_fkey FOREIGN KEY (navbar_id) REFERENCES navbar (id); ALTER TABLE youtube_videos ADD CONSTRAINT youtube_videos_youtube_channels_pkey_fkey FOREIGN KEY (youtube_channels_pkey) REFERENCES youtube_channels (id); ALTER TABLE editor_template_revisions ADD CONSTRAINT editor_template_revisions_template_id_fkey FOREIGN KEY (template_id) REFERENCES editor_templates (id); ALTER TABLE tags_content ADD CONSTRAINT tags_content_tag_id_fkey FOREIGN KEY (tag_id) REFERENCES tags (id); ALTER TABLE tags_content ADD CONSTRAINT tags_content_content_id_fkey FOREIGN KEY (content_id) REFERENCES content (id); ALTER TABLE comments ADD CONSTRAINT comments_content_id_fkey FOREIGN KEY (content_id) REFERENCES content (id); ALTER TABLE comments ADD CONSTRAINT comments_user_id_fkey FOREIGN KEY (user_id) REFERENCES users (id); -- --------------------------------------------------------------------------- -- 9. Set NOT NULL constraints where required -- --------------------------------------------------------------------------- ALTER TABLE users ALTER COLUMN id SET NOT NULL; ALTER TABLE session ALTER COLUMN id SET NOT NULL; ALTER TABLE options ALTER COLUMN id SET NOT NULL; ALTER TABLE theme_colors ALTER COLUMN id SET NOT NULL; ALTER TABLE cookie_rules ALTER COLUMN id SET NOT NULL; ALTER TABLE tags ALTER COLUMN id SET NOT NULL; ALTER TABLE gameserver_protocols ALTER COLUMN id SET NOT NULL; ALTER TABLE navbar ALTER COLUMN id SET NOT NULL; ALTER TABLE youtube_channels ALTER COLUMN id SET NOT NULL; ALTER TABLE templates ALTER COLUMN id SET NOT NULL; ALTER TABLE static_content ALTER COLUMN id SET NOT NULL; ALTER TABLE survey_results ALTER COLUMN id SET NOT NULL; ALTER TABLE editor_templates ALTER COLUMN id SET NOT NULL; ALTER TABLE content ALTER COLUMN id SET NOT NULL; ALTER TABLE gameserver ALTER COLUMN id SET NOT NULL; ALTER TABLE navbar_items ALTER COLUMN id SET NOT NULL; ALTER TABLE youtube_videos ALTER COLUMN id SET NOT NULL; ALTER TABLE editor_template_revisions ALTER COLUMN id SET NOT NULL; ALTER TABLE comments ALTER COLUMN id SET NOT NULL; ALTER TABLE tags_content ALTER COLUMN tag_id SET NOT NULL; ALTER TABLE tags_content ALTER COLUMN content_id SET NOT NULL; ALTER TABLE comments ALTER COLUMN content_id SET NOT NULL; ALTER TABLE editor_template_revisions ALTER COLUMN template_id SET NOT NULL; -- --------------------------------------------------------------------------- -- 10. Set defaults for new inserts -- --------------------------------------------------------------------------- ALTER TABLE users ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE session ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE options ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE theme_colors ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE cookie_rules ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE tags ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE gameserver_protocols ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE navbar ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE youtube_channels ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE templates ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE static_content ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE survey_results ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE editor_templates ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE content ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE gameserver ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE navbar_items ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE youtube_videos ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE editor_template_revisions ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE comments ALTER COLUMN id SET DEFAULT gen_random_uuid(); -- --------------------------------------------------------------------------- -- Done -- --------------------------------------------------------------------------- COMMIT; Loading
migrate_int_to_uuid.sql 0 → 100644 +479 −0 Original line number Diff line number Diff line -- ============================================================================= -- Blogi Migration: INTEGER id -> UUID -- Database: PostgreSQL (requires 13+ for gen_random_uuid()) -- ============================================================================= -- -- Run: psql -d <dbname> -f migrate_int_to_uuid.sql -- -- This script converts all integer primary keys and foreign keys to UUID. -- It preserves existing data and relationships. -- Back up your database before running! -- -- ============================================================================= BEGIN; -- --------------------------------------------------------------------------- -- 0. Prerequisites (gen_random_uuid() is built-in since PostgreSQL 13) -- --------------------------------------------------------------------------- -- --------------------------------------------------------------------------- -- 1. Add UUID columns to all tables (parent tables first) -- --------------------------------------------------------------------------- -- == Level 0: Independent tables (no FK to other migrated tables) == ALTER TABLE users ADD COLUMN id_new UUID; ALTER TABLE session ADD COLUMN id_new UUID; ALTER TABLE options ADD COLUMN id_new UUID; ALTER TABLE theme_colors ADD COLUMN id_new UUID; ALTER TABLE cookie_rules ADD COLUMN id_new UUID; ALTER TABLE tags ADD COLUMN id_new UUID; ALTER TABLE gameserver_protocols ADD COLUMN id_new UUID; ALTER TABLE navbar ADD COLUMN id_new UUID; ALTER TABLE youtube_channels ADD COLUMN id_new UUID; ALTER TABLE templates ADD COLUMN id_new UUID; ALTER TABLE static_content ADD COLUMN id_new UUID; ALTER TABLE survey_results ADD COLUMN id_new UUID; ALTER TABLE editor_templates ADD COLUMN id_new UUID; -- contact_pending.token is already the PK; if it's INTEGER, migrate it too DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token' AND data_type IN ('integer','bigint','smallint') ) THEN EXECUTE 'ALTER TABLE contact_pending ADD COLUMN token_new UUID'; END IF; END$$; -- == Level 1: Tables with FK to level 0 == ALTER TABLE session_data ADD COLUMN sessionid_new UUID; ALTER TABLE content ADD COLUMN id_new UUID; ALTER TABLE content ADD COLUMN author_new UUID; ALTER TABLE gameserver ADD COLUMN id_new UUID; ALTER TABLE gameserver ADD COLUMN protocol_new UUID; ALTER TABLE navbar_items ADD COLUMN id_new UUID; ALTER TABLE navbar_items ADD COLUMN navbar_id_new UUID; ALTER TABLE youtube_videos ADD COLUMN id_new UUID; ALTER TABLE youtube_videos ADD COLUMN youtube_channels_pkey_new UUID; ALTER TABLE editor_template_revisions ADD COLUMN id_new UUID; ALTER TABLE editor_template_revisions ADD COLUMN template_id_new UUID; -- == Level 2: Tables with FK to level 1 == ALTER TABLE tags_content ADD COLUMN tag_id_new UUID; ALTER TABLE tags_content ADD COLUMN content_id_new UUID; ALTER TABLE comments ADD COLUMN id_new UUID; ALTER TABLE comments ADD COLUMN content_id_new UUID; ALTER TABLE comments ADD COLUMN user_id_new UUID; -- --------------------------------------------------------------------------- -- 2. Generate UUIDs for primary keys -- --------------------------------------------------------------------------- UPDATE users SET id_new = gen_random_uuid(); UPDATE session SET id_new = gen_random_uuid(); UPDATE options SET id_new = gen_random_uuid(); UPDATE theme_colors SET id_new = gen_random_uuid(); UPDATE cookie_rules SET id_new = gen_random_uuid(); UPDATE tags SET id_new = gen_random_uuid(); UPDATE gameserver_protocols SET id_new = gen_random_uuid(); UPDATE navbar SET id_new = gen_random_uuid(); UPDATE youtube_channels SET id_new = gen_random_uuid(); UPDATE templates SET id_new = gen_random_uuid(); UPDATE static_content SET id_new = gen_random_uuid(); UPDATE survey_results SET id_new = gen_random_uuid(); UPDATE editor_templates SET id_new = gen_random_uuid(); -- contact_pending (only if token was integer) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token_new' ) THEN EXECUTE 'UPDATE contact_pending SET token_new = gen_random_uuid()'; END IF; END$$; UPDATE content SET id_new = gen_random_uuid(); UPDATE gameserver SET id_new = gen_random_uuid(); UPDATE navbar_items SET id_new = gen_random_uuid(); UPDATE youtube_videos SET id_new = gen_random_uuid(); UPDATE editor_template_revisions SET id_new = gen_random_uuid(); UPDATE tags_content SET tag_id_new = NULL; -- FK only, set below UPDATE tags_content SET content_id_new = NULL; UPDATE comments SET id_new = gen_random_uuid(); -- --------------------------------------------------------------------------- -- 3. Propagate UUIDs through foreign key references -- --------------------------------------------------------------------------- -- session_data.sessionid -> session.id UPDATE session_data sd SET sessionid_new = s.id_new FROM session s WHERE sd.sessionid::text = s.id::text; -- content.author -> users.id UPDATE content c SET author_new = u.id_new FROM users u WHERE c.author::text = u.id::text; -- gameserver.protocol -> gameserver_protocols.id UPDATE gameserver g SET protocol_new = gp.id_new FROM gameserver_protocols gp WHERE g.protocol::text = gp.id::text; -- navbar_items.navbar_id -> navbar.id UPDATE navbar_items ni SET navbar_id_new = n.id_new FROM navbar n WHERE ni.navbar_id::text = n.id::text; -- youtube_videos.youtube_channels_pkey -> youtube_channels.id UPDATE youtube_videos yv SET youtube_channels_pkey_new = yc.id_new FROM youtube_channels yc WHERE yv.youtube_channels_pkey::text = yc.id::text; -- editor_template_revisions.template_id -> editor_templates.id UPDATE editor_template_revisions etr SET template_id_new = et.id_new FROM editor_templates et WHERE etr.template_id::text = et.id::text; -- tags_content.tag_id -> tags.id UPDATE tags_content tc SET tag_id_new = t.id_new FROM tags t WHERE tc.tag_id::text = t.id::text; -- tags_content.content_id -> content.id UPDATE tags_content tc SET content_id_new = c.id_new FROM content c WHERE tc.content_id::text = c.id::text; -- comments.content_id -> content.id UPDATE comments cm SET content_id_new = c.id_new FROM content c WHERE cm.content_id::text = c.id::text; -- comments.user_id -> users.id UPDATE comments cm SET user_id_new = u.id_new FROM users u WHERE cm.user_id::text = u.id::text; -- --------------------------------------------------------------------------- -- 4. Drop ALL foreign key constraints referencing migrated tables -- --------------------------------------------------------------------------- DO $$ DECLARE r RECORD; BEGIN -- Drop all FK constraints that reference any of the tables being migrated FOR r IN ( SELECT con.conname, con.conrelid::regclass AS tbl FROM pg_constraint con JOIN pg_constraint ref ON con.confrelid = ref.conrelid WHERE con.contype = 'f' AND con.confrelid::regclass::text IN ( 'users', 'session', 'options', 'theme_colors', 'cookie_rules', 'tags', 'gameserver_protocols', 'navbar', 'youtube_channels', 'templates', 'static_content', 'survey_results', 'editor_templates', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'comments' ) AND ref.contype = 'p' ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname); END LOOP; -- Also drop FK constraints ON the migrated tables themselves FOR r IN ( SELECT conname, conrelid::regclass AS tbl FROM pg_constraint WHERE contype = 'f' AND conrelid::regclass::text IN ( 'session_data', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'tags_content', 'comments', 'media_albums' ) ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname); END LOOP; END$$; -- --------------------------------------------------------------------------- -- 5. Drop old primary key constraints -- --------------------------------------------------------------------------- DO $$ DECLARE r RECORD; BEGIN FOR r IN ( SELECT conname, conrelid::regclass AS tbl FROM pg_constraint WHERE contype = 'p' AND conrelid::regclass::text IN ( 'users', 'session', 'options', 'theme_colors', 'cookie_rules', 'tags', 'gameserver_protocols', 'navbar', 'youtube_channels', 'templates', 'static_content', 'survey_results', 'editor_templates', 'content', 'gameserver', 'navbar_items', 'youtube_videos', 'editor_template_revisions', 'comments' ) ) LOOP EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname); END LOOP; END$$; -- --------------------------------------------------------------------------- -- 6. Drop old columns, rename new columns -- --------------------------------------------------------------------------- -- == Level 0 tables == ALTER TABLE users DROP COLUMN id CASCADE; ALTER TABLE users RENAME COLUMN id_new TO id; ALTER TABLE session DROP COLUMN id CASCADE; ALTER TABLE session RENAME COLUMN id_new TO id; ALTER TABLE options DROP COLUMN id CASCADE; ALTER TABLE options RENAME COLUMN id_new TO id; ALTER TABLE theme_colors DROP COLUMN id CASCADE; ALTER TABLE theme_colors RENAME COLUMN id_new TO id; ALTER TABLE cookie_rules DROP COLUMN id CASCADE; ALTER TABLE cookie_rules RENAME COLUMN id_new TO id; ALTER TABLE tags DROP COLUMN id CASCADE; ALTER TABLE tags RENAME COLUMN id_new TO id; ALTER TABLE gameserver_protocols DROP COLUMN id CASCADE; ALTER TABLE gameserver_protocols RENAME COLUMN id_new TO id; ALTER TABLE navbar DROP COLUMN id CASCADE; ALTER TABLE navbar RENAME COLUMN id_new TO id; ALTER TABLE youtube_channels DROP COLUMN id CASCADE; ALTER TABLE youtube_channels RENAME COLUMN id_new TO id; ALTER TABLE templates DROP COLUMN id CASCADE; ALTER TABLE templates RENAME COLUMN id_new TO id; ALTER TABLE static_content DROP COLUMN id CASCADE; ALTER TABLE static_content RENAME COLUMN id_new TO id; ALTER TABLE survey_results DROP COLUMN id CASCADE; ALTER TABLE survey_results RENAME COLUMN id_new TO id; ALTER TABLE editor_templates DROP COLUMN id CASCADE; ALTER TABLE editor_templates RENAME COLUMN id_new TO id; -- contact_pending (conditional) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'contact_pending' AND column_name = 'token_new' ) THEN EXECUTE 'ALTER TABLE contact_pending DROP COLUMN token CASCADE'; EXECUTE 'ALTER TABLE contact_pending RENAME COLUMN token_new TO token'; END IF; END$$; -- == Level 1 tables == ALTER TABLE session_data DROP COLUMN sessionid CASCADE; ALTER TABLE session_data RENAME COLUMN sessionid_new TO sessionid; ALTER TABLE content DROP COLUMN id CASCADE; ALTER TABLE content RENAME COLUMN id_new TO id; ALTER TABLE content DROP COLUMN author CASCADE; ALTER TABLE content RENAME COLUMN author_new TO author; ALTER TABLE gameserver DROP COLUMN id CASCADE; ALTER TABLE gameserver RENAME COLUMN id_new TO id; ALTER TABLE gameserver DROP COLUMN protocol CASCADE; ALTER TABLE gameserver RENAME COLUMN protocol_new TO protocol; ALTER TABLE navbar_items DROP COLUMN id CASCADE; ALTER TABLE navbar_items RENAME COLUMN id_new TO id; ALTER TABLE navbar_items DROP COLUMN navbar_id CASCADE; ALTER TABLE navbar_items RENAME COLUMN navbar_id_new TO navbar_id; ALTER TABLE youtube_videos DROP COLUMN id CASCADE; ALTER TABLE youtube_videos RENAME COLUMN id_new TO id; ALTER TABLE youtube_videos DROP COLUMN youtube_channels_pkey CASCADE; ALTER TABLE youtube_videos RENAME COLUMN youtube_channels_pkey_new TO youtube_channels_pkey; ALTER TABLE editor_template_revisions DROP COLUMN id CASCADE; ALTER TABLE editor_template_revisions RENAME COLUMN id_new TO id; ALTER TABLE editor_template_revisions DROP COLUMN template_id CASCADE; ALTER TABLE editor_template_revisions RENAME COLUMN template_id_new TO template_id; -- == Level 2 tables == ALTER TABLE tags_content DROP COLUMN tag_id CASCADE; ALTER TABLE tags_content RENAME COLUMN tag_id_new TO tag_id; ALTER TABLE tags_content DROP COLUMN content_id CASCADE; ALTER TABLE tags_content RENAME COLUMN content_id_new TO content_id; ALTER TABLE comments DROP COLUMN id CASCADE; ALTER TABLE comments RENAME COLUMN id_new TO id; ALTER TABLE comments DROP COLUMN content_id CASCADE; ALTER TABLE comments RENAME COLUMN content_id_new TO content_id; ALTER TABLE comments DROP COLUMN user_id CASCADE; ALTER TABLE comments RENAME COLUMN user_id_new TO user_id; -- --------------------------------------------------------------------------- -- 7. Re-add primary key constraints -- --------------------------------------------------------------------------- ALTER TABLE users ADD PRIMARY KEY (id); ALTER TABLE session ADD PRIMARY KEY (id); ALTER TABLE options ADD PRIMARY KEY (id); ALTER TABLE theme_colors ADD PRIMARY KEY (id); ALTER TABLE cookie_rules ADD PRIMARY KEY (id); ALTER TABLE tags ADD PRIMARY KEY (id); ALTER TABLE gameserver_protocols ADD PRIMARY KEY (id); ALTER TABLE navbar ADD PRIMARY KEY (id); ALTER TABLE youtube_channels ADD PRIMARY KEY (id); ALTER TABLE templates ADD PRIMARY KEY (id); ALTER TABLE static_content ADD PRIMARY KEY (id); ALTER TABLE survey_results ADD PRIMARY KEY (id); ALTER TABLE editor_templates ADD PRIMARY KEY (id); ALTER TABLE content ADD PRIMARY KEY (id); ALTER TABLE gameserver ADD PRIMARY KEY (id); ALTER TABLE navbar_items ADD PRIMARY KEY (id); ALTER TABLE youtube_videos ADD PRIMARY KEY (id); ALTER TABLE editor_template_revisions ADD PRIMARY KEY (id); ALTER TABLE comments ADD PRIMARY KEY (id); -- contact_pending: only add PK if we migrated it (token_new existed) DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conrelid = 'contact_pending'::regclass AND contype = 'p' ) THEN EXECUTE 'ALTER TABLE contact_pending ADD PRIMARY KEY (token)'; END IF; END$$; -- --------------------------------------------------------------------------- -- 8. Re-add foreign key constraints -- --------------------------------------------------------------------------- ALTER TABLE session_data ADD CONSTRAINT session_data_sessionid_fkey FOREIGN KEY (sessionid) REFERENCES session (id); ALTER TABLE content ADD CONSTRAINT content_author_fkey FOREIGN KEY (author) REFERENCES users (id); ALTER TABLE gameserver ADD CONSTRAINT gameserver_protocol_fkey FOREIGN KEY (protocol) REFERENCES gameserver_protocols (id); ALTER TABLE navbar_items ADD CONSTRAINT navbar_items_navbar_id_fkey FOREIGN KEY (navbar_id) REFERENCES navbar (id); ALTER TABLE youtube_videos ADD CONSTRAINT youtube_videos_youtube_channels_pkey_fkey FOREIGN KEY (youtube_channels_pkey) REFERENCES youtube_channels (id); ALTER TABLE editor_template_revisions ADD CONSTRAINT editor_template_revisions_template_id_fkey FOREIGN KEY (template_id) REFERENCES editor_templates (id); ALTER TABLE tags_content ADD CONSTRAINT tags_content_tag_id_fkey FOREIGN KEY (tag_id) REFERENCES tags (id); ALTER TABLE tags_content ADD CONSTRAINT tags_content_content_id_fkey FOREIGN KEY (content_id) REFERENCES content (id); ALTER TABLE comments ADD CONSTRAINT comments_content_id_fkey FOREIGN KEY (content_id) REFERENCES content (id); ALTER TABLE comments ADD CONSTRAINT comments_user_id_fkey FOREIGN KEY (user_id) REFERENCES users (id); -- --------------------------------------------------------------------------- -- 9. Set NOT NULL constraints where required -- --------------------------------------------------------------------------- ALTER TABLE users ALTER COLUMN id SET NOT NULL; ALTER TABLE session ALTER COLUMN id SET NOT NULL; ALTER TABLE options ALTER COLUMN id SET NOT NULL; ALTER TABLE theme_colors ALTER COLUMN id SET NOT NULL; ALTER TABLE cookie_rules ALTER COLUMN id SET NOT NULL; ALTER TABLE tags ALTER COLUMN id SET NOT NULL; ALTER TABLE gameserver_protocols ALTER COLUMN id SET NOT NULL; ALTER TABLE navbar ALTER COLUMN id SET NOT NULL; ALTER TABLE youtube_channels ALTER COLUMN id SET NOT NULL; ALTER TABLE templates ALTER COLUMN id SET NOT NULL; ALTER TABLE static_content ALTER COLUMN id SET NOT NULL; ALTER TABLE survey_results ALTER COLUMN id SET NOT NULL; ALTER TABLE editor_templates ALTER COLUMN id SET NOT NULL; ALTER TABLE content ALTER COLUMN id SET NOT NULL; ALTER TABLE gameserver ALTER COLUMN id SET NOT NULL; ALTER TABLE navbar_items ALTER COLUMN id SET NOT NULL; ALTER TABLE youtube_videos ALTER COLUMN id SET NOT NULL; ALTER TABLE editor_template_revisions ALTER COLUMN id SET NOT NULL; ALTER TABLE comments ALTER COLUMN id SET NOT NULL; ALTER TABLE tags_content ALTER COLUMN tag_id SET NOT NULL; ALTER TABLE tags_content ALTER COLUMN content_id SET NOT NULL; ALTER TABLE comments ALTER COLUMN content_id SET NOT NULL; ALTER TABLE editor_template_revisions ALTER COLUMN template_id SET NOT NULL; -- --------------------------------------------------------------------------- -- 10. Set defaults for new inserts -- --------------------------------------------------------------------------- ALTER TABLE users ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE session ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE options ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE theme_colors ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE cookie_rules ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE tags ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE gameserver_protocols ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE navbar ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE youtube_channels ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE templates ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE static_content ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE survey_results ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE editor_templates ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE content ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE gameserver ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE navbar_items ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE youtube_videos ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE editor_template_revisions ALTER COLUMN id SET DEFAULT gen_random_uuid(); ALTER TABLE comments ALTER COLUMN id SET DEFAULT gen_random_uuid(); -- --------------------------------------------------------------------------- -- Done -- --------------------------------------------------------------------------- COMMIT;