"""initial schema Revision ID: 0001_initial Revises: Create Date: 2024-01-01 00:00:00.000000 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. revision: str = "0001_initial" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: """Upgrade database schema.""" # Create ENUM types world_visibility = postgresql.ENUM( "public", "private", "friends_only", name="world_visibility" ) world_visibility.create(op.get_bind(), checkfirst=True) asset_type = postgresql.ENUM( "image", "audio", "video", "document", "model_3d", "other", name="asset_type" ) asset_type.create(op.get_bind(), checkfirst=True) # Create users table op.create_table( "users", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("username", sa.String(length=50), nullable=False), sa.Column("email", sa.String(length=120), nullable=False), sa.Column("hashed_password", sa.String(length=255), nullable=False), sa.Column("is_active", sa.Boolean(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True), ) op.create_index(op.f("ix_users_email"), "users", ["email"], unique=True) op.create_index(op.f("ix_users_id"), "users", ["id"], unique=False) op.create_index(op.f("ix_users_username"), "users", ["username"], unique=True) # Create sessions table op.create_table( "sessions", sa.Column("id", sa.String(length=36), primary_key=True), sa.Column("user_id", sa.Integer(), nullable=False), sa.Column("token", sa.String(), nullable=False), sa.Column("expires_at", sa.DateTime(timezone=True), nullable=False), sa.Column("is_active", sa.Boolean(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"), ) op.create_index(op.f("ix_sessions_token"), "sessions", ["token"], unique=True) # Create worlds table op.create_table( "worlds", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("name", sa.String(length=255), nullable=False), sa.Column("description", sa.Text(), nullable=True), sa.Column("owner_id", sa.Integer(), nullable=False), sa.Column( "visibility", postgresql.ENUM( "public", "private", "friends_only", name="world_visibility" ), nullable=True, ), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint(["owner_id"], ["users.id"]), ) op.create_index(op.f("ix_worlds_id"), "worlds", ["id"], unique=False) # Create assets table op.create_table( "assets", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("name", sa.String(length=255), nullable=False), sa.Column("description", sa.Text(), nullable=True), sa.Column( "asset_type", postgresql.ENUM( "image", "audio", "video", "document", "model_3d", "other", name="asset_type", ), nullable=False, ), sa.Column("file_path", sa.String(length=512), nullable=False), sa.Column("file_size", sa.Integer(), nullable=True), sa.Column("mime_type", sa.String(length=128), nullable=True), sa.Column("metadata_json", sa.Text(), nullable=True), sa.Column("world_id", sa.Integer(), nullable=True), sa.Column("owner_id", sa.Integer(), nullable=False), sa.Column("is_public", sa.Boolean(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()), sa.ForeignKeyConstraint(["owner_id"], ["users.id"]), sa.ForeignKeyConstraint(["world_id"], ["worlds.id"]), ) op.create_index(op.f("ix_assets_id"), "assets", ["id"], unique=False) def downgrade() -> None: """Downgrade database schema.""" op.drop_index(op.f("ix_assets_id"), table_name="assets") op.drop_table("assets") op.drop_index(op.f("ix_worlds_id"), table_name="worlds") op.drop_table("worlds") op.drop_index(op.f("ix_sessions_token"), table_name="sessions") op.drop_table("sessions") op.drop_index(op.f("ix_users_username"), table_name="users") op.drop_index(op.f("ix_users_id"), table_name="users") op.drop_index(op.f("ix_users_email"), table_name="users") op.drop_table("users") # Drop ENUM types postgresql.ENUM(name="asset_type").drop(op.get_bind(), checkfirst=True) postgresql.ENUM(name="world_visibility").drop(op.get_bind(), checkfirst=True)