"""File holds all model definitions of SQL tables.""" from sqlalchemy.dialects.mysql import BIGINT, BOOLEAN, FLOAT, INTEGER, SMALLINT, VARCHAR from sqlmodel import Column, Field, ForeignKey, Relationship, SQLModel, UniqueConstraint class Guild(SQLModel, table=True): """ Represents a Guild entity in the database. Attributes: id (int): The unique identifier for the guild. name (str): The name of the guild. submission_channel (int): The ID of the submission channel associated with the guild. verification_channel (int): The ID of the verification channel associated with the guild. active (bool): Indicates whether the guild is active. Defaults to True. category_groups (list[CategoryGroup]): A list of category groups associated with the guild. """ __tablename__: str = "Guilds" id: int = Field(sa_column=Column("GuildId", BIGINT(unsigned=True), primary_key=True, nullable=False)) name: str = Field(sa_column=Column("GuildName", VARCHAR), max_length=95) # deprecated, not currently used. submission_channel: int | None = Field( sa_column=Column("SubmissionChannel", BIGINT(unsigned=True), nullable=True), default=None ) verification_channel: int | None = Field( sa_column=Column("VerificationChannel", BIGINT(unsigned=True), nullable=True), default=None ) active: bool = Field(sa_column=Column("Active", BOOLEAN), default=True) category_groups: list["CategoryGroup"] = Relationship(back_populates="guild", cascade_delete=True) class CategoryGroup(SQLModel, table=True): """ Represents a category group in the database. Attributes: id (int | None): The primary key of the category group. name (str): The name of the category group, with a maximum length of 50 characters. channel_id (int): The ID of the channel associated with the category group. guild_id (int): The ID of the guild associated with the category group. message_id (int): The ID of the message associated with the category group. pad_length (int): The padding length for the category group, default is 12. username_length (int): The username length for the category group, default is 12. guild (Guild | None): The guild relationship back-populated from the Guild model. Table Constraints: __table_args__: Unique constraint on guild_id and name to ensure unique category groups within a guild. """ __tablename__: str = "CategoryGroups" id: int | None = Field(sa_column=Column("GroupId", INTEGER, primary_key=True), default=None) name: str = Field(sa_column=Column("GroupName", VARCHAR), max_length=50) channel_id: int = Field(sa_column=Column("ChannelId", BIGINT(unsigned=True))) guild_id: int = Field( sa_column=Column( "GuildId", BIGINT(unsigned=True), ForeignKey("Guilds.GuildId", ondelete="CASCADE"), nullable=False, ) ) message_id: int | None = Field(sa_column=Column("MessageId", BIGINT(unsigned=True)), default=None) pad_length: int = Field(default=12, sa_column=Column("PadLength", SMALLINT(unsigned=True))) username_length: int = Field(default=12, sa_column=Column("UsernameLength", SMALLINT(unsigned=True))) __table_args__ = (UniqueConstraint("GuildId", "GroupName", name="UniqueGuildCategoryGroup"),) guild: Guild | None = Relationship(back_populates="category_groups") categories: list["Category"] | None = Relationship(back_populates="category_group", cascade_delete=True) class Category(SQLModel, table=True): """ Represents a category in the database. Attributes: id (int): The unique identifier for the category. Primary key. name (str): The name of the category with a maximum length of 30 characters. group_id (int): The identifier of the group to which the category belongs. Foreign key referencing CategoryGroups.id. size (int): The size attribute of the category, default is 3. is_ascending (bool): Indicates if the category is in ascending order. Default is True. is_time_record (bool): Indicates if the category is a time record. Default is False. is_validated (bool): Indicates if the category is validated. Default is True. category_group (CategoryGroup | None): The relationship to the CategoryGroup model. scores (list["Score"] | None): The relationship to the Score model with cascade delete enabled. Table Constraints: __table_args__: Unique constraint on group_id and name to ensure unique category names within a group. """ __tablename__: str = "Categories" id: int = Field(sa_column=Column("CategoryId", INTEGER, primary_key=True), default=None) name: str = Field(sa_column=Column("CategoryName", VARCHAR), max_length=30) group_id: int = Field( sa_column=Column( "GroupId", INTEGER(unsigned=True), ForeignKey("CategoryGroups.GroupId", ondelete="CASCADE"), nullable=False, ) ) size: int = Field(sa_column=Column("Size", SMALLINT(unsigned=True), nullable=False), default=3) is_ascending: bool = Field(sa_column=Column("IsAscending", BOOLEAN, nullable=False), default=True) is_time_record: bool = Field(sa_column=Column("IsTimeRecord", BOOLEAN, nullable=False), default=False) is_validated: bool = Field(sa_column=Column("IsValidated", BOOLEAN, nullable=False), default=True) __table_args__ = (UniqueConstraint("GroupId", "CategoryName", name="UniqueCategoryInGroup"),) category_group: CategoryGroup | None = Relationship(back_populates="categories") scores: list["Score"] | None = Relationship(back_populates="category", cascade_delete=True) class Score(SQLModel, table=True): """ Represents a score entry in the database. Attributes: username (str): The username associated with the score. This is a primary key. score (float): The score value. category_id (int): The ID of the category this score belongs to. This is a primary key and a foreign key referencing the Categories table. category (Category | None): The relationship to the Category model, back-populated by the scores attribute in the Category model. """ __tablename__: str = "Scores" username: str = Field(sa_column=Column("UserName", VARCHAR, primary_key=True, nullable=False), max_length=30) score: float = Field(sa_column=Column("Score", FLOAT, nullable=False)) category_id: int = Field( sa_column=Column( "CategoryId", INTEGER(unsigned=True), ForeignKey("Categories.CategoryId", ondelete="CASCADE"), nullable=False, primary_key=True, ), ) category: Category | None = Relationship(back_populates="scores") class Submission(SQLModel, table=True): """ Represents a submission in the database. Attributes: category_id (int): The ID of the category. This is a primary key. group_id (int): The ID of the group. guild_id (int): The ID of the guild. message_id (int): The ID of the message. score (str): The score of the submission, with a maximum length of 30 characters. user_id (int): The ID of the user. username (str): The username of the user. This is a primary key. """ __tablename__: str = "Submissions" category_id: int = Field( sa_column=Column( "CategoryId", INTEGER(unsigned=True), nullable=False, primary_key=True, ), ) group_id: int = Field( sa_column=Column( "GroupId", INTEGER(unsigned=True), nullable=False, ) ) guild_id: int = Field(sa_column=Column("GuildId", BIGINT(unsigned=True), nullable=False)) message_id: int = Field(sa_column=Column("MessageId", BIGINT(unsigned=True), nullable=False)) # Score is stored as a string until converted during submission. score: str = Field(sa_column=Column("Score", VARCHAR, nullable=False), max_length=30) user_id: int = Field(sa_column=Column("UserId", BIGINT(unsigned=True), nullable=False)) username: str = Field(sa_column=Column("UserName", VARCHAR, nullable=False, primary_key=True), max_length=30)