diff --git a/src/ttt/infrastructure/adapters/map.py b/src/ttt/infrastructure/adapters/map.py index adac34e..96d8505 100644 --- a/src/ttt/infrastructure/adapters/map.py +++ b/src/ttt/infrastructure/adapters/map.py @@ -39,7 +39,8 @@ def _handle_integrity_error(self, error: IntegrityError) -> None: case UniqueViolation() as unique_error: constraint_name = unique_error.diag.constraint_name - if constraint_name == "players_pkey": + if constraint_name == "users_pkey": raise NotUniqueUserIdError from error - case _: - raise error from error + case _: ... + + raise error from error diff --git a/src/ttt/infrastructure/alembic/script.py.mako b/src/ttt/infrastructure/alembic/script.py.mako index f28bee7..b377953 100644 --- a/src/ttt/infrastructure/alembic/script.py.mako +++ b/src/ttt/infrastructure/alembic/script.py.mako @@ -1,4 +1,4 @@ -"""${message} +"""${message}. Revision ID: ${up_revision} Revises: ${down_revision | comma,n} diff --git a/src/ttt/infrastructure/alembic/versions/0ab305265ed4_rename_games_player_x__id_to_games_user_.py b/src/ttt/infrastructure/alembic/versions/0ab305265ed4_rename_games_player_x__id_to_games_user_.py new file mode 100644 index 0000000..635810f --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/0ab305265ed4_rename_games_player_x__id_to_games_user_.py @@ -0,0 +1,82 @@ +""" +rename `games.player{x}_id` to `games.user{x}_id`. + +Revision ID: 0ab305265ed4 +Revises: 3cbb0bf26e9e +Create Date: 2025-07-24 05:25:29.573399 + +""" + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "0ab305265ed4" +down_revision: str | None = "3cbb0bf26e9e" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute(""" + ALTER TABLE games RENAME CONSTRAINT + games_player1_id_fkey + TO games_user1_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_games_player1_id RENAME + TO ix_games_user1_id; + """) + op.alter_column( + "games", + "player1_id", + new_column_name="user1_id", + ) + + op.execute(""" + ALTER TABLE games RENAME CONSTRAINT + games_player2_id_fkey + TO games_user2_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_games_player2_id RENAME + TO ix_games_user2_id; + """) + op.alter_column( + "games", + "player2_id", + new_column_name="user2_id", + ) + + +def downgrade() -> None: + op.execute(""" + ALTER TABLE games RENAME CONSTRAINT + games_user1_id_fkey + TO games_player1_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_games_user1_id RENAME + TO ix_games_player1_id; + """) + op.alter_column( + "games", + "user1_id", + new_column_name="player1_id", + ) + + op.execute(""" + ALTER TABLE games RENAME CONSTRAINT + games_user2_id_fkey + TO games_player2_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_games_user2_id RENAME + TO ix_games_player2_id; + """) + op.alter_column( + "games", + "user2_id", + new_column_name="player2_id", + ) diff --git a/src/ttt/infrastructure/alembic/versions/1360cc49b0b6_remove_players_id_seq.py b/src/ttt/infrastructure/alembic/versions/1360cc49b0b6_remove_players_id_seq.py new file mode 100644 index 0000000..05d6958 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/1360cc49b0b6_remove_players_id_seq.py @@ -0,0 +1,36 @@ +""" +remove `players_id_seq`. + +Revision ID: 1360cc49b0b6 +Revises: fb04714a84d4 +Create Date: 2025-07-24 05:50:47.308411 + +""" + +from collections.abc import Sequence + +import sqlalchemy as sa +from alembic import op + + +revision: str = "1360cc49b0b6" +down_revision: str | None = "fb04714a84d4" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute("ALTER TABLE users ALTER COLUMN id DROP DEFAULT;") + op.execute("DROP SEQUENCE players_id_seq;") + + +def downgrade() -> None: + connection = op.get_bind() + + max_user_id: int = connection.scalar(sa.text("SELECT max(id) from users;")) + sequence_start = max_user_id + 1000 + op.execute(f"CREATE SEQUENCE players_id_seq START WITH {sequence_start};") + + op.execute(""" + ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('players_id_seq'); + """) diff --git a/src/ttt/infrastructure/alembic/versions/274a1fc84d0c_rename_player_emojis_pkey_to_user_.py b/src/ttt/infrastructure/alembic/versions/274a1fc84d0c_rename_player_emojis_pkey_to_user_.py new file mode 100644 index 0000000..2b8e7b8 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/274a1fc84d0c_rename_player_emojis_pkey_to_user_.py @@ -0,0 +1,32 @@ +""" +rename `player_emojis_pkey` to `user_emojis_pkey`. + +Revision ID: 274a1fc84d0c +Revises: fde32a1982c7 +Create Date: 2025-07-23 08:45:07.054035 + +""" + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "274a1fc84d0c" +down_revision: str | None = "fde32a1982c7" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute(""" + ALTER TABLE user_emojis + RENAME CONSTRAINT player_emojis_pkey TO user_emojis_pkey; + """) + + +def downgrade() -> None: + op.execute(""" + ALTER TABLE user_emojis + RENAME CONSTRAINT user_emojis_pkey TO player_emojis_pkey; + """) diff --git a/src/ttt/infrastructure/alembic/versions/3cbb0bf26e9e_rename_cells_filler_id_to_cells_user_.py b/src/ttt/infrastructure/alembic/versions/3cbb0bf26e9e_rename_cells_filler_id_to_cells_user_.py new file mode 100644 index 0000000..6af91a4 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/3cbb0bf26e9e_rename_cells_filler_id_to_cells_user_.py @@ -0,0 +1,52 @@ +""" +rename `cells.filler_id` to `cells.user_filler_id`. + +Revision ID: 3cbb0bf26e9e +Revises: 3f0d6b39f862 +Create Date: 2025-07-24 05:21:06.119116 + +""" + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "3cbb0bf26e9e" +down_revision: str | None = "3f0d6b39f862" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute(""" + ALTER TABLE cells RENAME CONSTRAINT + cells_filler_id_fkey + TO cells_user_filler_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_cells_filler_id RENAME + TO ix_cells_user_filler_id; + """) + op.alter_column( + "cells", + "filler_id", + new_column_name="user_filler_id", + ) + + +def downgrade() -> None: + op.execute(""" + ALTER TABLE cells RENAME CONSTRAINT + cells_user_filler_id_fkey + TO cells_filler_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_cells_user_filler_id RENAME + TO ix_cells_filler_id; + """) + op.alter_column( + "cells", + "user_filler_id", + new_column_name="filler_id", + ) diff --git a/src/ttt/infrastructure/alembic/versions/3f0d6b39f862_rename_stars_purchases_location_player_.py b/src/ttt/infrastructure/alembic/versions/3f0d6b39f862_rename_stars_purchases_location_player_.py new file mode 100644 index 0000000..73d712a --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/3f0d6b39f862_rename_stars_purchases_location_player_.py @@ -0,0 +1,52 @@ +""" +rename `stars_purchases.location_player_id` to `stars_purchases.location_user_id`. + +Revision ID: 3f0d6b39f862 +Revises: 50990aed76a8 +Create Date: 2025-07-24 05:12:08.982879 + +""" # noqa: E501 + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "3f0d6b39f862" +down_revision: str | None = "50990aed76a8" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute(""" + ALTER TABLE stars_purchases RENAME CONSTRAINT + stars_purchases_location_player_id_fkey + TO stars_purchases_location_user_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_stars_purchases_location_player_id RENAME + TO ix_stars_purchases_location_user_id; + """) + op.alter_column( + "stars_purchases", + "location_player_id", + new_column_name="location_user_id", + ) + + +def downgrade() -> None: + op.execute(""" + ALTER TABLE stars_purchases RENAME CONSTRAINT + stars_purchases_location_user_id_fkey + TO stars_purchases_location_player_id_fkey; + """) + op.execute(""" + ALTER INDEX ix_stars_purchases_location_user_id RENAME + TO ix_stars_purchases_location_player_id; + """) + op.alter_column( + "stars_purchases", + "location_user_id", + new_column_name="location_player_id", + ) diff --git a/src/ttt/infrastructure/alembic/versions/42ad1196c6da_rename_players_to_users.py b/src/ttt/infrastructure/alembic/versions/42ad1196c6da_rename_players_to_users.py new file mode 100644 index 0000000..7e19a2a --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/42ad1196c6da_rename_players_to_users.py @@ -0,0 +1,25 @@ +""" +rename `players` to `users`. + +Revision ID: 42ad1196c6da +Revises: 0ab305265ed4 +Create Date: 2025-07-24 05:38:35.259138 + +""" +from collections.abc import Sequence + +from alembic import op + + +revision: str = "42ad1196c6da" +down_revision: str | None = "0ab305265ed4" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.rename_table("players", "users") + + +def downgrade() -> None: + op.rename_table("users", "players") diff --git a/src/ttt/infrastructure/alembic/versions/50990aed76a8_rename_player_emojis_user_id_fkey_to_.py b/src/ttt/infrastructure/alembic/versions/50990aed76a8_rename_player_emojis_user_id_fkey_to_.py new file mode 100644 index 0000000..054d7b8 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/50990aed76a8_rename_player_emojis_user_id_fkey_to_.py @@ -0,0 +1,32 @@ +""" +rename `player_emojis_user_id_fkey` to `user_emojis_user_id_fkey`. + +Revision ID: 50990aed76a8 +Revises: 274a1fc84d0c +Create Date: 2025-07-23 08:54:03.378941 + +""" + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "50990aed76a8" +down_revision: str | None = "274a1fc84d0c" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute(""" + ALTER TABLE user_emojis RENAME CONSTRAINT + player_emojis_user_id_fkey TO user_emojis_user_id_fkey; + """) + + +def downgrade() -> None: + op.execute(""" + ALTER TABLE user_emojis RENAME CONSTRAINT + user_emojis_user_id_fkey TO player_emojis_user_id_fkey; + """) diff --git a/src/ttt/infrastructure/alembic/versions/fb04714a84d4_rename_players_constrains_to_users_.py b/src/ttt/infrastructure/alembic/versions/fb04714a84d4_rename_players_constrains_to_users_.py new file mode 100644 index 0000000..761f404 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/fb04714a84d4_rename_players_constrains_to_users_.py @@ -0,0 +1,59 @@ +""" +rename `players` constrains to `users` constrains. + +Revision ID: fb04714a84d4 +Revises: 42ad1196c6da +Create Date: 2025-07-24 05:40:57.564599 + +""" +from collections.abc import Sequence + +from alembic import op + + +revision: str = "fb04714a84d4" +down_revision: str | None = "42ad1196c6da" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute("ALTER INDEX players_pkey RENAME TO users_pkey;") + op.execute(""" + ALTER INDEX ix_players_game_location_game_id + RENAME TO ix_users_game_location_game_id; + """) + op.execute(""" + ALTER INDEX ix_players_selected_emoji_id + RENAME TO ix_users_selected_emoji_id; + """) + + op.execute(""" + ALTER TABLE users RENAME CONSTRAINT + players_game_location_game_id_fkey TO users_game_location_game_id_fkey; + """) + op.execute(""" + ALTER TABLE users RENAME CONSTRAINT + players_selected_emoji_id_fkey TO users_selected_emoji_id_fkey; + """) + + +def downgrade() -> None: + op.execute("ALTER INDEX users_pkey RENAME TO players_pkey;") + op.execute(""" + ALTER INDEX ix_users_game_location_game_id + RENAME TO ix_players_game_location_game_id; + """) + op.execute(""" + ALTER INDEX ix_users_selected_emoji_id + RENAME TO ix_players_selected_emoji_id; + """) + + op.execute(""" + ALTER TABLE users RENAME CONSTRAINT + users_game_location_game_id_fkey TO players_game_location_game_id_fkey; + """) + op.execute(""" + ALTER TABLE users RENAME CONSTRAINT + users_selected_emoji_id_fkey TO players_selected_emoji_id_fkey; + """) diff --git a/src/ttt/infrastructure/alembic/versions/fde32a1982c7_rename_user_emojis_player_id_to_user_.py b/src/ttt/infrastructure/alembic/versions/fde32a1982c7_rename_user_emojis_player_id_to_user_.py new file mode 100644 index 0000000..40f8006 --- /dev/null +++ b/src/ttt/infrastructure/alembic/versions/fde32a1982c7_rename_user_emojis_player_id_to_user_.py @@ -0,0 +1,64 @@ +""" +rename `user_emojis.player_id` to `user_emojis.user_id`. + +Revision ID: fde32a1982c7 +Revises: e05971d2b8d5 +Create Date: 2025-07-23 08:36:01.306514 + +""" + +from collections.abc import Sequence + +from alembic import op + + +revision: str = "fde32a1982c7" +down_revision: str | None = "e05971d2b8d5" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.alter_column("user_emojis", "player_id", new_column_name="user_id") + op.drop_index(op.f("ix_user_emojis_player_id"), table_name="user_emojis") + op.create_index( + op.f("ix_user_emojis_user_id"), + "user_emojis", + ["user_id"], + unique=False, + ) + op.drop_constraint( + op.f("player_emojis_player_id_fkey"), "user_emojis", type_="foreignkey", + ) + op.create_foreign_key( + "player_emojis_user_id_fkey", + "user_emojis", + "players", + ["user_id"], + ["id"], + initially="DEFERRED", + deferrable=True, + ) + + +def downgrade() -> None: + op.alter_column("user_emojis", "user_id", new_column_name="player_id") + op.drop_index(op.f("ix_user_emojis_user_id"), table_name="user_emojis") + op.create_index( + op.f("ix_user_emojis_player_id"), + "user_emojis", + ["player_id"], + unique=False, + ) + op.drop_constraint( + op.f("player_emojis_user_id_fkey"), "user_emojis", type_="foreignkey", + ) + op.create_foreign_key( + "player_emojis_player_id_fkey", + "user_emojis", + "players", + ["user_id"], + ["id"], + initially="DEFERRED", + deferrable=True, + ) diff --git a/src/ttt/infrastructure/sqlalchemy/tables.py b/src/ttt/infrastructure/sqlalchemy/tables.py index e61c5f3..c388aae 100644 --- a/src/ttt/infrastructure/sqlalchemy/tables.py +++ b/src/ttt/infrastructure/sqlalchemy/tables.py @@ -121,8 +121,8 @@ class TableUserEmoji(Base): __tablename__ = "user_emojis" id: Mapped[UUID] = mapped_column(primary_key=True) - player_id: Mapped[int] = mapped_column( - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + user_id: Mapped[int] = mapped_column( + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) emoji_str: Mapped[str] = mapped_column(CHAR(1)) @@ -131,7 +131,7 @@ class TableUserEmoji(Base): def entity(self) -> UserEmoji: return UserEmoji( self.id, - self.player_id, + self.user_id, Emoji(self.emoji_str), self.datetime_of_purchase, ) @@ -140,7 +140,7 @@ def entity(self) -> UserEmoji: def of(cls, it: UserEmoji) -> "TableUserEmoji": return TableUserEmoji( id=it.id, - player_id=it.user_id, + user_id=it.user_id, emoji_str=it.emoji.str_, datetime_of_purchase=it.datetime_of_purchase, ) @@ -150,8 +150,8 @@ class TableStarsPurchase(Base): __tablename__ = "stars_purchases" id: Mapped[UUID] = mapped_column(primary_key=True) - location_player_id: Mapped[int] = mapped_column( - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + location_user_id: Mapped[int] = mapped_column( + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) location_chat_id: Mapped[int] = mapped_column(BigInteger()) @@ -177,7 +177,7 @@ def entity(self) -> StarsPurchase: return StarsPurchase( id_=self.id, location=UserLocation( - self.location_player_id, + self.location_user_id, self.location_chat_id, ), stars=self.stars, @@ -188,7 +188,7 @@ def entity(self) -> StarsPurchase: def of(cls, it: StarsPurchase) -> "TableStarsPurchase": return TableStarsPurchase( id=it.id_, - location_player_id=it.location.user_id, + location_user_id=it.location.user_id, location_chat_id=it.location.chat_id, stars=it.stars, payment_id=None if it.payment is None else it.payment.id_, @@ -196,9 +196,13 @@ def of(cls, it: StarsPurchase) -> "TableStarsPurchase": class TableUser(Base): - __tablename__ = "players" + __tablename__ = "users" - id: Mapped[int] = mapped_column(BigInteger(), primary_key=True) + id: Mapped[int] = mapped_column( + BigInteger(), + primary_key=True, + autoincrement=False, + ) account_stars: Mapped[int] = mapped_column(server_default="0") selected_emoji_id: Mapped[UUID | None] = mapped_column( ForeignKey("user_emojis.id", deferrable=True, initially="DEFERRED"), @@ -215,11 +219,11 @@ class TableUser(Base): emojis: Mapped[list[TableUserEmoji]] = relationship( lazy="selectin", - foreign_keys=[TableUserEmoji.player_id], + foreign_keys=[TableUserEmoji.user_id], ) stars_purchases: Mapped[list[TableStarsPurchase]] = relationship( lazy="selectin", - foreign_keys=[TableStarsPurchase.location_player_id], + foreign_keys=[TableStarsPurchase.location_user_id], ) def entity(self) -> User: @@ -320,7 +324,7 @@ class TableGameResult(Base): win_winner_id: Mapped[int | None] = mapped_column( BigInteger(), - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) win_new_stars: Mapped[int | None] @@ -332,7 +336,7 @@ class TableGameResult(Base): canceler_id: Mapped[int | None] = mapped_column( BigInteger(), - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) @@ -409,9 +413,9 @@ class TableCell(Base): ) board_position_x: Mapped[int] board_position_y: Mapped[int] - filler_id: Mapped[int | None] = mapped_column( + user_filler_id: Mapped[int | None] = mapped_column( BigInteger(), - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) ai_filler_id: Mapped[UUID | None] = mapped_column( @@ -424,7 +428,7 @@ def entity(self) -> Cell: self.id, self.game_id, (self.board_position_x, self.board_position_y), - self.filler_id, + self.user_filler_id, self.ai_filler_id, ) @@ -435,7 +439,7 @@ def of(cls, it: Cell) -> "TableCell": game_id=it.game_id, board_position_x=it.board_position[0], board_position_y=it.board_position[1], - filler_id=it.user_filler_id, + user_filler_id=it.user_filler_id, ai_filler_id=it.ai_filler_id, ) @@ -476,14 +480,14 @@ class TableGame(Base): __tablename__ = "games" id: Mapped[UUID] = mapped_column(primary_key=True) - player1_id: Mapped[int | None] = mapped_column( + user1_id: Mapped[int | None] = mapped_column( BigInteger(), - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) - player2_id: Mapped[int | None] = mapped_column( + user2_id: Mapped[int | None] = mapped_column( BigInteger(), - ForeignKey("players.id", deferrable=True, initially="DEFERRED"), + ForeignKey("users.id", deferrable=True, initially="DEFERRED"), index=True, ) ai1_id: Mapped[UUID | None] = mapped_column( @@ -499,13 +503,13 @@ class TableGame(Base): player2_emoji_str: Mapped[str] = mapped_column(server_default="⭕️") result: Mapped["TableGameResult | None"] = relationship(lazy="joined") - player1: Mapped["TableUser | None"] = relationship( + user1: Mapped["TableUser | None"] = relationship( lazy="joined", - foreign_keys=[player1_id], + foreign_keys=[user1_id], ) - player2: Mapped["TableUser | None"] = relationship( + user2: Mapped["TableUser | None"] = relationship( lazy="joined", - foreign_keys=[player2_id], + foreign_keys=[user2_id], ) ai1: Mapped["TableAi | None"] = relationship( lazy="joined", @@ -522,8 +526,8 @@ def entity(self) -> Game: player1: Player - if self.player1 is not None: - player1 = self.player1.entity() + if self.user1 is not None: + player1 = self.user1.entity() elif self.ai1 is not None: player1 = self.ai1.entity() else: @@ -531,8 +535,8 @@ def entity(self) -> Game: player2: Player - if self.player2 is not None: - player2 = self.player2.entity() + if self.user2 is not None: + player2 = self.user2.entity() elif self.ai2 is not None: player2 = self.ai2.entity() else: @@ -568,10 +572,10 @@ def of(cls, it: Game) -> "TableGame": return TableGame( id=it.id, - player1_id=player1_id, + user1_id=player1_id, ai1_id=ai1_id, player1_emoji_str=it.player1_emoji.str_, - player2_id=player2_id, + user2_id=player2_id, ai2_id=ai2_id, player2_emoji_str=it.player2_emoji.str_, state=TableGameState.of(it.state), diff --git a/src/ttt/presentation/adapters/user_views.py b/src/ttt/presentation/adapters/user_views.py index f457504..da2a84a 100644 --- a/src/ttt/presentation/adapters/user_views.py +++ b/src/ttt/presentation/adapters/user_views.py @@ -68,7 +68,7 @@ async def view_of_user_with_id( ) emoji_stmt = ( select(TableUserEmoji.emoji_str) - .where(TableUserEmoji.player_id == location.user_id) + .where(TableUserEmoji.user_id == location.user_id) .order_by(TableUserEmoji.datetime_of_purchase) )