feat(chuni): Implement GameLoginApi/GameLogoutApi

This commit is contained in:
2024-06-23 12:30:30 +07:00
parent 79d27b0582
commit 63987f2095
3 changed files with 95 additions and 4 deletions

View File

@ -1,7 +1,9 @@
from typing import Optional, List
from sqlalchemy import Table, Column
from sqlalchemy.types import Integer, String, TIMESTAMP
from sqlalchemy import Table, Column, text, UniqueConstraint
from sqlalchemy.dialects import mysql
from sqlalchemy.types import Integer, String, TIMESTAMP, JSON
from sqlalchemy.sql import func
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.dialects.mysql import insert
from sqlalchemy.sql import func, select
from sqlalchemy.engine import Row
@ -23,6 +25,18 @@ aime_user = Table(
mysql_charset="utf8mb4",
)
game_locks = Table(
"aime_user_game_locks",
metadata,
Column("id", Integer, nullable=False, primary_key=True, autoincrement=True),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("game", String(4), nullable=False),
Column("expires_at", TIMESTAMP, server_default=func.date_add(func.now(), text("INTERVAL 15 MINUTE"))),
Column("extra", JSON),
UniqueConstraint("user", "game", name="aime_user_title_locks"),
mysql_charset="utf8mb4",
)
class UserData(BaseData):
async def create_user(
self,
@ -123,4 +137,33 @@ class UserData(BaseData):
async def get_user_by_username(self, username: str) -> Optional[Row]:
result = await self.execute(aime_user.select(aime_user.c.username == username))
if result: return result.fetchone()
if result:
return result.fetchone()
async def acquire_lock_for_game(self, user_id: int, game: str, extra: dict | None = None):
sql = game_locks.select(
(game_locks.c.user == user_id)
& (game_locks.c.game == game)
& func.timestampdiff(text("SECOND"), func.now(), game_locks.c.expires_at) > 0)
result = await self.execute(sql)
if result:
return result.fetchone()
sql = (
insert(game_locks)
.values(user=user_id, game=game, extra=extra)
.on_duplicate_key_update(
expires_at=func.date_add(func.now(), text("INTERVAL 15 MINUTE")),
extra=extra,
)
)
await self.execute(sql)
return None
async def release_lock_for_game(self, user_id: int, game: str):
sql = game_locks.delete(game_locks.c.user == user_id & game_locks.c.game == game)
await self.execute(sql)