Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
"""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
|
|
"""
|
|
)
|
|
)
|