"""allow only operation-guarded alias restoration during rollback Revision ID: a4d5e6f7b8c9 Revises: f3c4d5e6a7b8 """ from alembic import op import sqlalchemy as sa revision = "a4d5e6f7b8c9" down_revision = "f3c4d5e6a7b8" branch_labels = None depends_on = None def upgrade() -> None: # T02 made aliases immutable. Rollback needs exactly one controlled # exception: the alias created by this operation may become canonical while # that same operation is in rollback-preflight. Ownership, spelling, # protection, and provenance remain immutable. op.execute( sa.text( """ CREATE OR REPLACE FUNCTION guard_repository_slug_history() RETURNS trigger AS $$ BEGIN IF TG_OP = 'DELETE' THEN RAISE EXCEPTION 'repository slug rows are durable'; END IF; IF NEW.repo_id IS DISTINCT FROM OLD.repo_id OR NEW.slug IS DISTINCT FROM OLD.slug THEN RAISE EXCEPTION 'repository slug ownership is immutable'; END IF; IF OLD.kind = 'alias' AND ROW( NEW.kind, NEW.protected, NEW.source_operation_id ) IS DISTINCT FROM ROW( OLD.kind, OLD.protected, OLD.source_operation_id ) THEN IF NOT ( NEW.kind = 'canonical' AND NEW.protected AND NEW.source_operation_id = OLD.source_operation_id AND EXISTS ( SELECT 1 FROM repository_rename_operations operation WHERE operation.id = OLD.source_operation_id AND operation.repo_id = OLD.repo_id AND operation.phase = 'rollback-preflight' ) ) THEN RAISE EXCEPTION 'protected repository alias is immutable'; END IF; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql """ ) ) def downgrade() -> None: op.execute( sa.text( """ CREATE OR REPLACE FUNCTION guard_repository_slug_history() RETURNS trigger AS $$ BEGIN IF TG_OP = 'DELETE' THEN RAISE EXCEPTION 'repository slug rows are durable'; END IF; IF NEW.repo_id IS DISTINCT FROM OLD.repo_id OR NEW.slug IS DISTINCT FROM OLD.slug THEN RAISE EXCEPTION 'repository slug ownership is immutable'; END IF; IF OLD.kind = 'alias' AND ROW( NEW.kind, NEW.protected, NEW.source_operation_id ) IS DISTINCT FROM ROW( OLD.kind, OLD.protected, OLD.source_operation_id ) THEN RAISE EXCEPTION 'protected repository alias is immutable'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql """ ) )