1
0
mirror of synced 2024-12-21 01:05:53 +01:00
artemis/titles/mai2/schema/item.py

589 lines
18 KiB
Python
Raw Normal View History

from core.data.schema import BaseData, metadata
from datetime import datetime
from typing import Optional, Dict, List
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.dialects.mysql import insert
from sqlalchemy.engine import Row
character = Table(
"mai2_item_character",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("characterId", Integer),
Column("level", Integer),
Column("awakening", Integer),
Column("useCount", Integer),
Column("point", Integer),
UniqueConstraint("user", "characterId", name="mai2_item_character_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
card = Table(
"mai2_item_card",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("cardId", Integer),
Column("cardTypeId", Integer),
Column("charaId", Integer),
Column("mapId", Integer),
Column("startDate", TIMESTAMP, server_default=func.now()),
Column("endDate", TIMESTAMP),
UniqueConstraint("user", "cardId", "cardTypeId", name="mai2_item_card_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
item = Table(
"mai2_item_item",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("itemId", Integer),
Column("itemKind", Integer),
Column("stock", Integer),
Column("isValid", Boolean),
UniqueConstraint("user", "itemId", "itemKind", name="mai2_item_item_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
map = Table(
"mai2_item_map",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("mapId", Integer),
Column("distance", Integer),
Column("isLock", Boolean),
Column("isClear", Boolean),
Column("isComplete", Boolean),
2023-04-10 18:58:19 +02:00
UniqueConstraint("user", "mapId", name="mai2_item_map_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
login_bonus = Table(
"mai2_item_login_bonus",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("bonusId", Integer),
Column("point", Integer),
Column("isCurrent", Boolean),
Column("isComplete", Boolean),
2023-04-10 18:58:19 +02:00
UniqueConstraint("user", "bonusId", name="mai2_item_login_bonus_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
friend_season_ranking = Table(
"mai2_item_friend_season_ranking",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("seasonId", Integer),
Column("point", Integer),
Column("rank", Integer),
Column("rewardGet", Boolean),
Column("userName", String(8)),
Column("recordDate", TIMESTAMP),
2023-04-10 18:58:19 +02:00
UniqueConstraint(
"user", "seasonId", "userName", name="mai2_item_friend_season_ranking_uk"
),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
favorite = Table(
"mai2_item_favorite",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("itemKind", Integer),
Column("itemIdList", JSON),
UniqueConstraint("user", "itemKind", name="mai2_item_favorite_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
fav_music = Table(
"mai2_item_favorite_music",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
Column("musicId", Integer, nullable=False),
UniqueConstraint("user", "musicId", name="mai2_item_favorite_music_uk"),
mysql_charset="utf8mb4",
)
charge = Table(
"mai2_item_charge",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
2023-03-09 17:38:58 +01:00
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
2023-06-27 06:32:35 +02:00
Column("chargeId", Integer),
Column("stock", Integer),
Column("purchaseDate", String(255)),
Column("validDate", String(255)),
UniqueConstraint("user", "chargeId", name="mai2_item_charge_uk"),
mysql_charset="utf8mb4",
)
print_detail = Table(
"mai2_item_print_detail",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column(
"user",
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
Column("orderId", Integer),
Column("printNumber", Integer),
2023-06-27 06:32:35 +02:00
Column("printDate", TIMESTAMP, server_default=func.now()),
Column("serialId", String(20)),
Column("placeId", Integer),
Column("clientId", String(11)),
Column("printerSerialId", String(20)),
Column("cardRomVersion", Integer),
Column("isHolograph", Boolean, server_default="1"),
Column("printOption1", Boolean, server_default="0"),
Column("printOption2", Boolean, server_default="0"),
Column("printOption3", Boolean, server_default="0"),
Column("printOption4", Boolean, server_default="0"),
Column("printOption5", Boolean, server_default="0"),
Column("printOption6", Boolean, server_default="0"),
Column("printOption7", Boolean, server_default="0"),
Column("printOption8", Boolean, server_default="0"),
Column("printOption9", Boolean, server_default="0"),
Column("printOption10", Boolean, server_default="0"),
Column("created", String(255), server_default=""),
UniqueConstraint("user", "serialId", name="mai2_item_print_detail_uk"),
2023-03-09 17:38:58 +01:00
mysql_charset="utf8mb4",
)
2023-03-09 17:38:58 +01:00
class Mai2ItemData(BaseData):
2024-01-09 20:42:17 +01:00
async def put_item(
2023-03-09 17:38:58 +01:00
self, user_id: int, item_kind: int, item_id: int, stock: int, is_valid: bool
) -> None:
sql = insert(item).values(
user=user_id,
itemKind=item_kind,
itemId=item_id,
stock=stock,
isValid=is_valid,
)
conflict = sql.on_duplicate_key_update(
stock=stock,
isValid=is_valid,
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-03-09 17:38:58 +01:00
f"put_item: failed to insert item! user_id: {user_id}, item_kind: {item_kind}, item_id: {item_id}"
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_items(self, user_id: int, item_kind: int = None) -> Optional[List[Row]]:
if item_kind is None:
sql = item.select(item.c.user == user_id)
else:
2023-03-09 17:38:58 +01:00
sql = item.select(
and_(item.c.user == user_id, item.c.itemKind == item_kind)
2023-03-09 17:38:58 +01:00
)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchall()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_item(self, user_id: int, item_kind: int, item_id: int) -> Optional[Row]:
2023-03-09 17:38:58 +01:00
sql = item.select(
and_(
item.c.user == user_id,
item.c.itemKind == item_kind,
item.c.itemId == item_id,
2023-03-09 17:38:58 +01:00
)
)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchone()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def put_login_bonus(
2023-03-09 17:38:58 +01:00
self,
user_id: int,
bonus_id: int,
point: int,
is_current: bool,
is_complete: bool,
) -> None:
sql = insert(login_bonus).values(
user=user_id,
bonusId=bonus_id,
point=point,
isCurrent=is_current,
isComplete=is_complete,
)
conflict = sql.on_duplicate_key_update(
point=point,
isCurrent=is_current,
isComplete=is_complete,
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-03-09 17:38:58 +01:00
f"put_login_bonus: failed to insert item! user_id: {user_id}, bonus_id: {bonus_id}, point: {point}"
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_login_bonuses(self, user_id: int) -> Optional[List[Row]]:
sql = login_bonus.select(login_bonus.c.user == user_id)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchall()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_login_bonus(self, user_id: int, bonus_id: int) -> Optional[Row]:
2023-03-09 17:38:58 +01:00
sql = login_bonus.select(
and_(login_bonus.c.user == user_id, login_bonus.c.bonus_id == bonus_id)
)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchone()
2024-01-09 20:42:17 +01:00
async def put_map(
2023-03-09 17:38:58 +01:00
self,
user_id: int,
map_id: int,
distance: int,
is_lock: bool,
is_clear: bool,
is_complete: bool,
) -> None:
sql = insert(map).values(
user=user_id,
2023-04-10 18:58:19 +02:00
mapId=map_id,
distance=distance,
2023-04-10 18:58:19 +02:00
isLock=is_lock,
isClear=is_clear,
isComplete=is_complete,
)
conflict = sql.on_duplicate_key_update(
distance=distance,
2023-04-10 18:58:19 +02:00
isLock=is_lock,
isClear=is_clear,
isComplete=is_complete,
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-03-09 17:38:58 +01:00
f"put_map: failed to insert item! user_id: {user_id}, map_id: {map_id}, distance: {distance}"
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_maps(self, user_id: int) -> Optional[List[Row]]:
sql = map.select(map.c.user == user_id)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchall()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_map(self, user_id: int, map_id: int) -> Optional[Row]:
2023-04-10 18:58:19 +02:00
sql = map.select(and_(map.c.user == user_id, map.c.mapId == map_id))
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchone()
2023-10-16 21:36:26 +02:00
2024-01-09 20:42:17 +01:00
async def put_character_(self, user_id: int, char_data: Dict) -> Optional[int]:
2023-07-01 08:04:30 +02:00
char_data["user"] = user_id
sql = insert(character).values(**char_data)
conflict = sql.on_duplicate_key_update(**char_data)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
2023-07-01 08:04:30 +02:00
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-07-01 08:04:30 +02:00
f"put_character_: failed to insert item! user_id: {user_id}"
)
return None
return result.lastrowid
2024-01-09 20:42:17 +01:00
async def put_character(
2023-03-09 17:38:58 +01:00
self,
user_id: int,
character_id: int,
level: int,
awakening: int,
use_count: int,
) -> None:
sql = insert(character).values(
user=user_id,
2023-04-10 18:58:19 +02:00
characterId=character_id,
level=level,
awakening=awakening,
2023-04-10 18:58:19 +02:00
useCount=use_count,
)
conflict = sql.on_duplicate_key_update(
level=level,
awakening=awakening,
2023-04-10 18:58:19 +02:00
useCount=use_count,
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-03-09 17:38:58 +01:00
f"put_character: failed to insert item! user_id: {user_id}, character_id: {character_id}, level: {level}"
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_characters(self, user_id: int) -> Optional[List[Row]]:
sql = character.select(character.c.user == user_id)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchall()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_character(self, user_id: int, character_id: int) -> Optional[Row]:
2023-03-09 17:38:58 +01:00
sql = character.select(
and_(character.c.user == user_id, character.c.character_id == character_id)
)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchone()
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_friend_season_ranking(self, user_id: int) -> Optional[Row]:
sql = friend_season_ranking.select(friend_season_ranking.c.user == user_id)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
2023-04-10 18:58:19 +02:00
return result.fetchall()
2024-01-09 20:42:17 +01:00
async def put_friend_season_ranking(
2023-04-10 18:58:19 +02:00
self, aime_id: int, friend_season_ranking_data: Dict
) -> Optional[int]:
sql = insert(friend_season_ranking).values(
user=aime_id, **friend_season_ranking_data
)
conflict = sql.on_duplicate_key_update(**friend_season_ranking_data)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
2023-04-10 18:58:19 +02:00
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-04-10 18:58:19 +02:00
f"put_friend_season_ranking: failed to insert",
f"friend_season_ranking! aime_id: {aime_id}",
2023-04-10 18:58:19 +02:00
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def put_favorite(
2023-03-09 17:38:58 +01:00
self, user_id: int, kind: int, item_id_list: List[int]
) -> Optional[int]:
sql = insert(favorite).values(
2023-03-09 17:38:58 +01:00
user=user_id, kind=kind, item_id_list=item_id_list
)
2023-03-09 17:38:58 +01:00
conflict = sql.on_duplicate_key_update(item_id_list=item_id_list)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-03-09 17:38:58 +01:00
f"put_favorite: failed to insert item! user_id: {user_id}, kind: {kind}"
)
return None
return result.lastrowid
2023-03-09 17:38:58 +01:00
2024-01-09 20:42:17 +01:00
async def get_favorites(self, user_id: int, kind: int = None) -> Optional[Row]:
if kind is None:
sql = favorite.select(favorite.c.user == user_id)
else:
2023-03-09 17:38:58 +01:00
sql = favorite.select(
and_(favorite.c.user == user_id, favorite.c.itemKind == kind)
)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
2023-03-09 17:38:58 +01:00
if result is None:
return None
return result.fetchall()
async def get_fav_music(self, user_id: int) -> Optional[List[Row]]:
result = await self.execute(fav_music.select(fav_music.c.user == user_id))
if result:
return result.fetchall()
async def add_fav_music(self, user_id: int, music_id: int) -> Optional[int]:
sql = insert(fav_music).values(
user = user_id,
musicId = music_id
)
conflict = sql.on_duplicate_key_do_nothing()
result = await self.execute(conflict)
if result:
return result.lastrowid
self.logger.error(f"Failed to add music {music_id} as favorite for user {user_id}!")
async def remove_fav_music(self, user_id: int, music_id: int) -> None:
result = await self.execute(fav_music.delete(and_(fav_music.c.user == user_id, fav_music.c.musicId == music_id)))
if not result:
self.logger.error(f"Failed to remove music {music_id} as favorite for user {user_id}!")
2024-01-09 20:42:17 +01:00
async def put_card(
self,
user_id: int,
card_type_id: int,
card_kind: int,
chara_id: int,
map_id: int,
start_date: datetime,
end_date: datetime,
) -> Optional[Row]:
sql = insert(card).values(
user=user_id,
cardId=card_type_id,
cardTypeId=card_kind,
charaId=chara_id,
mapId=map_id,
startDate=start_date,
endDate=end_date,
)
conflict = sql.on_duplicate_key_update(
charaId=chara_id, mapId=map_id, startDate=start_date, endDate=end_date
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
2023-04-19 17:26:33 +02:00
f"put_card: failed to insert card! user_id: {user_id}, kind: {card_kind}"
)
return None
return result.lastrowid
2024-01-09 20:42:17 +01:00
async def get_cards(self, user_id: int, kind: int = None) -> Optional[Row]:
if kind is None:
sql = card.select(card.c.user == user_id)
else:
sql = card.select(and_(card.c.user == user_id, card.c.cardKind == kind))
2023-10-16 21:36:26 +02:00
sql = sql.order_by(card.c.startDate.desc())
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
2024-01-09 20:42:17 +01:00
async def put_charge(
self,
user_id: int,
charge_id: int,
stock: int,
purchase_date: str,
valid_date: str,
) -> Optional[Row]:
sql = insert(charge).values(
user=user_id,
chargeId=charge_id,
stock=stock,
purchaseDate=purchase_date,
validDate=valid_date,
)
conflict = sql.on_duplicate_key_update(
stock=stock, purchaseDate=purchase_date, validDate=valid_date
)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
f"put_card: failed to insert charge! user_id: {user_id}, chargeId: {charge_id}"
)
return None
return result.lastrowid
2024-01-09 20:42:17 +01:00
async def get_charges(self, user_id: int) -> Optional[Row]:
sql = charge.select(charge.c.user == user_id)
2024-01-09 20:42:17 +01:00
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
2024-01-09 20:42:17 +01:00
async def put_user_print_detail(
self, aime_id: int, serial_id: str, user_print_data: Dict
) -> Optional[int]:
sql = insert(print_detail).values(
user=aime_id, serialId=serial_id, **user_print_data
)
conflict = sql.on_duplicate_key_update(**user_print_data)
2024-01-09 20:42:17 +01:00
result = await self.execute(conflict)
if result is None:
2023-08-08 16:17:56 +02:00
self.logger.warning(
f"put_user_print_detail: Failed to insert! aime_id: {aime_id}"
)
return None
return result.lastrowid