From 0dbee56ecf76ca6f59e057c11e367bc724db5005 Mon Sep 17 00:00:00 2001 From: Aleksandr Fenin Date: Fri, 24 Oct 2025 11:52:41 +0300 Subject: [PATCH 1/2] api/migrate-to-wger: fix migration to ensure exercise_variations table creation --- migrations/000005_exercises.up.sql | 49 +++++++++++++---------- migrations/hotfix_exercise_variations.sql | 11 +++++ 2 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 migrations/hotfix_exercise_variations.sql diff --git a/migrations/000005_exercises.up.sql b/migrations/000005_exercises.up.sql index d40f000..86f356d 100644 --- a/migrations/000005_exercises.up.sql +++ b/migrations/000005_exercises.up.sql @@ -1,6 +1,6 @@ CREATE TABLE IF NOT EXISTS muscle_groups ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL UNIQUE, + wger_id INTEGER NOT NULL, name VARCHAR(100) NOT NULL, name_en VARCHAR(100) NOT NULL DEFAULT '', is_front BOOLEAN NOT NULL DEFAULT true, @@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS muscle_groups ( DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'exercise_db_id') THEN + ALTER TABLE muscle_groups DROP CONSTRAINT IF EXISTS muscle_groups_exercise_db_id_key; ALTER TABLE muscle_groups RENAME COLUMN exercise_db_id TO wger_id; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'name_en') THEN @@ -19,11 +20,14 @@ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'is_front') THEN ALTER TABLE muscle_groups ADD COLUMN is_front BOOLEAN NOT NULL DEFAULT true; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'muscle_groups' AND constraint_name = 'muscle_groups_wger_id_key') THEN + ALTER TABLE muscle_groups ADD CONSTRAINT muscle_groups_wger_id_key UNIQUE (wger_id); + END IF; END $$; CREATE TABLE IF NOT EXISTS equipment ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL UNIQUE, + wger_id INTEGER NOT NULL, name VARCHAR(100) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() @@ -32,13 +36,17 @@ CREATE TABLE IF NOT EXISTS equipment ( DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'equipment' AND column_name = 'exercise_db_id') THEN + ALTER TABLE equipment DROP CONSTRAINT IF EXISTS equipment_exercise_db_id_key; ALTER TABLE equipment RENAME COLUMN exercise_db_id TO wger_id; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'equipment' AND constraint_name = 'equipment_wger_id_key') THEN + ALTER TABLE equipment ADD CONSTRAINT equipment_wger_id_key UNIQUE (wger_id); + END IF; END $$; CREATE TABLE IF NOT EXISTS exercises ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL UNIQUE, + wger_id INTEGER NOT NULL, wger_uuid VARCHAR(255) NOT NULL DEFAULT '', name VARCHAR(255) NOT NULL, description TEXT NOT NULL DEFAULT '', @@ -48,7 +56,7 @@ CREATE TABLE IF NOT EXISTS exercises ( license_author VARCHAR(255) NOT NULL DEFAULT '', creation_date DATE, cached_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - expires_at TIMESTAMP WITH TIME ZONE NOT NULL, + expires_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() + INTERVAL '1 day', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); @@ -56,6 +64,7 @@ CREATE TABLE IF NOT EXISTS exercises ( DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'exercise_db_id') THEN + ALTER TABLE exercises DROP CONSTRAINT IF EXISTS exercises_exercise_db_id_key; ALTER TABLE exercises RENAME COLUMN exercise_db_id TO wger_id; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'wger_uuid') THEN @@ -76,15 +85,8 @@ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'uuid') THEN ALTER TABLE exercises DROP COLUMN uuid; END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'description') THEN - ALTER TABLE exercises ALTER COLUMN description TYPE TEXT; - ALTER TABLE exercises ALTER COLUMN description SET NOT NULL; - ALTER TABLE exercises ALTER COLUMN description SET DEFAULT ''; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'license_author') THEN - ALTER TABLE exercises ALTER COLUMN license_author TYPE VARCHAR(255); - ALTER TABLE exercises ALTER COLUMN license_author SET NOT NULL; - ALTER TABLE exercises ALTER COLUMN license_author SET DEFAULT ''; + IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'exercises' AND constraint_name = 'exercises_wger_id_key') THEN + ALTER TABLE exercises ADD CONSTRAINT exercises_wger_id_key UNIQUE (wger_id); END IF; END $$; @@ -106,19 +108,22 @@ CREATE TABLE IF NOT EXISTS exercise_equipment ( DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'exercise_alternatives') THEN + DROP TABLE IF EXISTS exercise_variations CASCADE; ALTER TABLE exercise_alternatives RENAME TO exercise_variations; - ALTER TABLE exercise_variations RENAME COLUMN alternative_exercise_id TO variation_exercise_id; - ELSE - CREATE TABLE IF NOT EXISTS exercise_variations ( - exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, - variation_exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - PRIMARY KEY (exercise_id, variation_exercise_id), - CHECK (exercise_id != variation_exercise_id) - ); + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercise_variations' AND column_name = 'alternative_exercise_id') THEN + ALTER TABLE exercise_variations RENAME COLUMN alternative_exercise_id TO variation_exercise_id; + END IF; END IF; END $$; +CREATE TABLE IF NOT EXISTS exercise_variations ( + exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, + variation_exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + PRIMARY KEY (exercise_id, variation_exercise_id), + CHECK (exercise_id != variation_exercise_id) +); + DROP INDEX IF EXISTS idx_exercises_exercise_db_id; DROP INDEX IF EXISTS idx_muscle_groups_exercise_db_id; DROP INDEX IF EXISTS idx_equipment_exercise_db_id; diff --git a/migrations/hotfix_exercise_variations.sql b/migrations/hotfix_exercise_variations.sql new file mode 100644 index 0000000..bae7d25 --- /dev/null +++ b/migrations/hotfix_exercise_variations.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS exercise_variations ( + exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, + variation_exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + PRIMARY KEY (exercise_id, variation_exercise_id), + CHECK (exercise_id != variation_exercise_id) +); + +CREATE INDEX IF NOT EXISTS idx_exercise_variations_exercise_id ON exercise_variations(exercise_id); +CREATE INDEX IF NOT EXISTS idx_exercise_variations_variation_id ON exercise_variations(variation_exercise_id); + From b56997409641a03f7f4b1940ecd79055bba9914e Mon Sep 17 00:00:00 2001 From: Aleksandr Fenin Date: Fri, 24 Oct 2025 11:53:28 +0300 Subject: [PATCH 2/2] api/migrate-to-wger: rewrite migration from scratch without legacy code --- migrations/000005_exercises.up.sql | 122 +++++----------------- migrations/hotfix_exercise_variations.sql | 11 -- 2 files changed, 24 insertions(+), 109 deletions(-) delete mode 100644 migrations/hotfix_exercise_variations.sql diff --git a/migrations/000005_exercises.up.sql b/migrations/000005_exercises.up.sql index 86f356d..74d3fdc 100644 --- a/migrations/000005_exercises.up.sql +++ b/migrations/000005_exercises.up.sql @@ -1,6 +1,6 @@ -CREATE TABLE IF NOT EXISTS muscle_groups ( +CREATE TABLE muscle_groups ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL, + wger_id INTEGER NOT NULL UNIQUE, name VARCHAR(100) NOT NULL, name_en VARCHAR(100) NOT NULL DEFAULT '', is_front BOOLEAN NOT NULL DEFAULT true, @@ -8,45 +8,17 @@ CREATE TABLE IF NOT EXISTS muscle_groups ( updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'exercise_db_id') THEN - ALTER TABLE muscle_groups DROP CONSTRAINT IF EXISTS muscle_groups_exercise_db_id_key; - ALTER TABLE muscle_groups RENAME COLUMN exercise_db_id TO wger_id; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'name_en') THEN - ALTER TABLE muscle_groups ADD COLUMN name_en VARCHAR(100) NOT NULL DEFAULT ''; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'muscle_groups' AND column_name = 'is_front') THEN - ALTER TABLE muscle_groups ADD COLUMN is_front BOOLEAN NOT NULL DEFAULT true; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'muscle_groups' AND constraint_name = 'muscle_groups_wger_id_key') THEN - ALTER TABLE muscle_groups ADD CONSTRAINT muscle_groups_wger_id_key UNIQUE (wger_id); - END IF; -END $$; - -CREATE TABLE IF NOT EXISTS equipment ( +CREATE TABLE equipment ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL, + wger_id INTEGER NOT NULL UNIQUE, name VARCHAR(100) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'equipment' AND column_name = 'exercise_db_id') THEN - ALTER TABLE equipment DROP CONSTRAINT IF EXISTS equipment_exercise_db_id_key; - ALTER TABLE equipment RENAME COLUMN exercise_db_id TO wger_id; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'equipment' AND constraint_name = 'equipment_wger_id_key') THEN - ALTER TABLE equipment ADD CONSTRAINT equipment_wger_id_key UNIQUE (wger_id); - END IF; -END $$; - -CREATE TABLE IF NOT EXISTS exercises ( +CREATE TABLE exercises ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - wger_id INTEGER NOT NULL, + wger_id INTEGER NOT NULL UNIQUE, wger_uuid VARCHAR(255) NOT NULL DEFAULT '', name VARCHAR(255) NOT NULL, description TEXT NOT NULL DEFAULT '', @@ -61,36 +33,7 @@ CREATE TABLE IF NOT EXISTS exercises ( updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'exercise_db_id') THEN - ALTER TABLE exercises DROP CONSTRAINT IF EXISTS exercises_exercise_db_id_key; - ALTER TABLE exercises RENAME COLUMN exercise_db_id TO wger_id; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'wger_uuid') THEN - ALTER TABLE exercises ADD COLUMN wger_uuid VARCHAR(255) NOT NULL DEFAULT ''; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'instructions') THEN - ALTER TABLE exercises DROP COLUMN instructions; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'tips') THEN - ALTER TABLE exercises DROP COLUMN tips; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'status') THEN - ALTER TABLE exercises DROP COLUMN status; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'name_original') THEN - ALTER TABLE exercises DROP COLUMN name_original; - END IF; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercises' AND column_name = 'uuid') THEN - ALTER TABLE exercises DROP COLUMN uuid; - END IF; - IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'exercises' AND constraint_name = 'exercises_wger_id_key') THEN - ALTER TABLE exercises ADD CONSTRAINT exercises_wger_id_key UNIQUE (wger_id); - END IF; -END $$; - -CREATE TABLE IF NOT EXISTS exercise_muscle_groups ( +CREATE TABLE exercise_muscle_groups ( exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, muscle_group_id UUID NOT NULL REFERENCES muscle_groups(id) ON DELETE CASCADE, is_primary BOOLEAN NOT NULL DEFAULT true, @@ -98,25 +41,14 @@ CREATE TABLE IF NOT EXISTS exercise_muscle_groups ( PRIMARY KEY (exercise_id, muscle_group_id, is_primary) ); -CREATE TABLE IF NOT EXISTS exercise_equipment ( +CREATE TABLE exercise_equipment ( exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, equipment_id UUID NOT NULL REFERENCES equipment(id) ON DELETE CASCADE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (exercise_id, equipment_id) ); -DO $$ -BEGIN - IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'exercise_alternatives') THEN - DROP TABLE IF EXISTS exercise_variations CASCADE; - ALTER TABLE exercise_alternatives RENAME TO exercise_variations; - IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'exercise_variations' AND column_name = 'alternative_exercise_id') THEN - ALTER TABLE exercise_variations RENAME COLUMN alternative_exercise_id TO variation_exercise_id; - END IF; - END IF; -END $$; - -CREATE TABLE IF NOT EXISTS exercise_variations ( +CREATE TABLE exercise_variations ( exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, variation_exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), @@ -124,29 +56,23 @@ CREATE TABLE IF NOT EXISTS exercise_variations ( CHECK (exercise_id != variation_exercise_id) ); -DROP INDEX IF EXISTS idx_exercises_exercise_db_id; -DROP INDEX IF EXISTS idx_muscle_groups_exercise_db_id; -DROP INDEX IF EXISTS idx_equipment_exercise_db_id; -DROP INDEX IF EXISTS idx_exercise_alternatives_exercise_id; -DROP INDEX IF EXISTS idx_exercise_alternatives_alternative_id; - -CREATE INDEX IF NOT EXISTS idx_exercises_wger_id ON exercises(wger_id); -CREATE INDEX IF NOT EXISTS idx_exercises_category ON exercises(category); -CREATE INDEX IF NOT EXISTS idx_exercises_name ON exercises(name); -CREATE INDEX IF NOT EXISTS idx_exercises_cached_at ON exercises(cached_at); -CREATE INDEX IF NOT EXISTS idx_exercises_expires_at ON exercises(expires_at); +CREATE INDEX idx_exercises_wger_id ON exercises(wger_id); +CREATE INDEX idx_exercises_category ON exercises(category); +CREATE INDEX idx_exercises_name ON exercises(name); +CREATE INDEX idx_exercises_cached_at ON exercises(cached_at); +CREATE INDEX idx_exercises_expires_at ON exercises(expires_at); -CREATE INDEX IF NOT EXISTS idx_muscle_groups_wger_id ON muscle_groups(wger_id); -CREATE INDEX IF NOT EXISTS idx_muscle_groups_name ON muscle_groups(name); +CREATE INDEX idx_muscle_groups_wger_id ON muscle_groups(wger_id); +CREATE INDEX idx_muscle_groups_name ON muscle_groups(name); -CREATE INDEX IF NOT EXISTS idx_equipment_wger_id ON equipment(wger_id); -CREATE INDEX IF NOT EXISTS idx_equipment_name ON equipment(name); +CREATE INDEX idx_equipment_wger_id ON equipment(wger_id); +CREATE INDEX idx_equipment_name ON equipment(name); -CREATE INDEX IF NOT EXISTS idx_exercise_muscle_groups_exercise_id ON exercise_muscle_groups(exercise_id); -CREATE INDEX IF NOT EXISTS idx_exercise_muscle_groups_muscle_group_id ON exercise_muscle_groups(muscle_group_id); +CREATE INDEX idx_exercise_muscle_groups_exercise_id ON exercise_muscle_groups(exercise_id); +CREATE INDEX idx_exercise_muscle_groups_muscle_group_id ON exercise_muscle_groups(muscle_group_id); -CREATE INDEX IF NOT EXISTS idx_exercise_equipment_exercise_id ON exercise_equipment(exercise_id); -CREATE INDEX IF NOT EXISTS idx_exercise_equipment_equipment_id ON exercise_equipment(equipment_id); +CREATE INDEX idx_exercise_equipment_exercise_id ON exercise_equipment(exercise_id); +CREATE INDEX idx_exercise_equipment_equipment_id ON exercise_equipment(equipment_id); -CREATE INDEX IF NOT EXISTS idx_exercise_variations_exercise_id ON exercise_variations(exercise_id); -CREATE INDEX IF NOT EXISTS idx_exercise_variations_variation_id ON exercise_variations(variation_exercise_id); +CREATE INDEX idx_exercise_variations_exercise_id ON exercise_variations(exercise_id); +CREATE INDEX idx_exercise_variations_variation_id ON exercise_variations(variation_exercise_id); diff --git a/migrations/hotfix_exercise_variations.sql b/migrations/hotfix_exercise_variations.sql deleted file mode 100644 index bae7d25..0000000 --- a/migrations/hotfix_exercise_variations.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE IF NOT EXISTS exercise_variations ( - exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, - variation_exercise_id UUID NOT NULL REFERENCES exercises(id) ON DELETE CASCADE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - PRIMARY KEY (exercise_id, variation_exercise_id), - CHECK (exercise_id != variation_exercise_id) -); - -CREATE INDEX IF NOT EXISTS idx_exercise_variations_exercise_id ON exercise_variations(exercise_id); -CREATE INDEX IF NOT EXISTS idx_exercise_variations_variation_id ON exercise_variations(variation_exercise_id); -