"""Immutable revisions. Old fork bases cannot be reconstructed reliably.""" import json import uuid import sqlalchemy as sa from alembic import op from sqlalchemy.dialects import postgresql revision = "0003" down_revision = "0002" branch_labels = depends_on = None def upgrade(): op.create_table("revisions", sa.Column("id", sa.String(36), primary_key=True), sa.Column("game_id", sa.Integer, sa.ForeignKey("games.id", ondelete="CASCADE"), nullable=False), sa.Column("user_id", sa.Integer, sa.ForeignKey("users.id", ondelete="SET NULL")), sa.Column("parents", postgresql.ARRAY(sa.String), nullable=False), sa.Column("manifest", postgresql.JSONB, nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False)) op.create_index("ix_revisions_game_id", "revisions", ["game_id"]) op.add_column("game_versions", sa.Column("revision_id", sa.String(36))) op.add_column("game_versions", sa.Column("base_revision_id", sa.String(36))) bind = op.get_bind() for row in bind.execute(sa.text("SELECT id, game_id, owner_id, manifest FROM game_versions WHERE manifest IS NOT NULL")).mappings(): rid = str(uuid.uuid4()) bind.execute(sa.text("INSERT INTO revisions (id, game_id, user_id, parents, manifest) VALUES (:id, :game, :user, '{}', CAST(:manifest AS jsonb))"), dict(id=rid, game=row["game_id"], user=row["owner_id"], manifest=json.dumps(row["manifest"]))) bind.execute(sa.text("UPDATE game_versions SET revision_id=:rid WHERE id=:id"), dict(rid=rid, id=row["id"])) def downgrade(): op.drop_column("game_versions", "base_revision_id") op.drop_column("game_versions", "revision_id") op.drop_table("revisions")