didier/database/schemas.py

337 lines
12 KiB
Python
Raw Normal View History

from __future__ import annotations
from datetime import date, datetime
from typing import List, Optional
from sqlalchemy import BigInteger, ForeignKey, UniqueConstraint
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.types import DateTime
2022-06-17 01:36:47 +02:00
from database import enums
2022-06-17 01:36:47 +02:00
2022-07-11 22:23:38 +02:00
__all__ = [
"Base",
"Bank",
2022-07-19 22:58:59 +02:00
"Birthday",
2022-08-30 01:32:46 +02:00
"Bookmark",
2022-09-20 14:47:26 +02:00
"CommandStats",
2022-07-11 22:23:38 +02:00
"CustomCommand",
"CustomCommandAlias",
2022-07-16 00:14:02 +02:00
"DadJoke",
2022-08-13 00:07:48 +02:00
"Deadline",
2022-09-20 00:31:33 +02:00
"EasterEgg",
2023-02-02 23:16:51 +01:00
"Event",
2022-10-13 20:00:46 +02:00
"FreeGame",
"GitHubLink",
2022-08-10 01:04:19 +02:00
"Link",
2022-08-25 02:07:02 +02:00
"MemeTemplate",
2022-07-11 22:23:38 +02:00
"NightlyData",
"Reminder",
"Task",
2022-07-11 22:23:38 +02:00
"UforaAnnouncement",
"UforaCourse",
"UforaCourseAlias",
"User",
]
class Base(DeclarativeBase):
"""Required base class for all tables"""
# Make all DateTimes timezone-aware
type_annotation_map = {datetime: DateTime(timezone=True)}
2022-06-30 19:42:48 +02:00
class Bank(Base):
"""A user's currency information"""
__tablename__ = "bank"
bank_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
2022-06-30 19:42:48 +02:00
dinks: Mapped[int] = mapped_column(BigInteger, server_default="0", nullable=False)
invested: Mapped[int] = mapped_column(BigInteger, server_default="0", nullable=False)
2022-06-30 21:17:48 +02:00
2022-06-30 19:42:48 +02:00
# Interest rate
interest_level: Mapped[int] = mapped_column(server_default="1", nullable=False)
2022-06-30 19:42:48 +02:00
# Maximum amount that can be stored in the bank
capacity_level: Mapped[int] = mapped_column(server_default="1", nullable=False)
2022-06-30 19:42:48 +02:00
# Maximum amount that can be robbed
rob_level: Mapped[int] = mapped_column(server_default="1", nullable=False)
2022-06-30 19:42:48 +02:00
user: Mapped[User] = relationship(uselist=False, back_populates="bank", lazy="selectin")
2022-06-30 19:42:48 +02:00
2022-07-19 22:58:59 +02:00
class Birthday(Base):
"""A user's birthday"""
__tablename__ = "birthdays"
birthday_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
birthday: Mapped[date] = mapped_column(nullable=False)
2022-07-19 22:58:59 +02:00
user: Mapped[User] = relationship(uselist=False, back_populates="birthday", lazy="selectin")
2022-07-19 22:58:59 +02:00
2022-08-30 01:32:46 +02:00
class Bookmark(Base):
"""A bookmark to a given message"""
__tablename__ = "bookmarks"
__table_args__ = (UniqueConstraint("user_id", "label"),)
bookmark_id: Mapped[int] = mapped_column(primary_key=True)
label: Mapped[str] = mapped_column(nullable=False)
jump_url: Mapped[str] = mapped_column(nullable=False)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
2022-08-30 01:32:46 +02:00
user: Mapped[User] = relationship(back_populates="bookmarks", uselist=False, lazy="selectin")
2022-08-30 01:32:46 +02:00
2022-09-20 14:47:26 +02:00
class CommandStats(Base):
"""Metrics on how often commands are used"""
__tablename__ = "command_stats"
command_stats_id: Mapped[int] = mapped_column(primary_key=True)
command: Mapped[str] = mapped_column(nullable=False)
timestamp: Mapped[datetime] = mapped_column(nullable=False)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
slash: Mapped[bool] = mapped_column(nullable=False)
context_menu: Mapped[bool] = mapped_column(nullable=False)
2022-09-20 14:47:26 +02:00
user: Mapped[User] = relationship(back_populates="command_stats", uselist=False, lazy="selectin")
2022-09-20 14:47:26 +02:00
2022-06-21 23:58:21 +02:00
class CustomCommand(Base):
"""Custom commands to fill the hole Dyno couldn't"""
__tablename__ = "custom_commands"
command_id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False, unique=True)
indexed_name: Mapped[str] = mapped_column(nullable=False, index=True)
response: Mapped[str] = mapped_column(nullable=False)
2022-06-21 23:58:21 +02:00
aliases: Mapped[List[CustomCommandAlias]] = relationship(
back_populates="command", uselist=True, cascade="all, delete-orphan", lazy="selectin"
2022-06-21 23:58:21 +02:00
)
class CustomCommandAlias(Base):
"""Aliases for custom commands"""
__tablename__ = "custom_command_aliases"
alias_id: Mapped[int] = mapped_column(primary_key=True)
alias: Mapped[str] = mapped_column(nullable=False, unique=True)
indexed_alias: Mapped[str] = mapped_column(nullable=False, index=True)
command_id: Mapped[int] = mapped_column(ForeignKey("custom_commands.command_id"))
2022-06-21 23:58:21 +02:00
command: Mapped[CustomCommand] = relationship(back_populates="aliases", uselist=False, lazy="selectin")
2022-06-21 23:58:21 +02:00
2022-07-16 00:14:02 +02:00
class DadJoke(Base):
"""When I finally understood asymptotic notation, it was a big "oh" moment"""
__tablename__ = "dad_jokes"
dad_joke_id: Mapped[int] = mapped_column(primary_key=True)
joke: Mapped[str] = mapped_column(nullable=False)
2022-07-16 00:14:02 +02:00
2022-08-13 00:07:48 +02:00
class Deadline(Base):
"""A deadline for a university project"""
__tablename__ = "deadlines"
deadline_id: Mapped[int] = mapped_column(primary_key=True)
course_id: Mapped[int] = mapped_column(ForeignKey("ufora_courses.course_id"))
name: Mapped[str] = mapped_column(nullable=False)
deadline: Mapped[datetime] = mapped_column(nullable=False)
2022-08-13 00:07:48 +02:00
course: Mapped[UforaCourse] = relationship(back_populates="deadlines", uselist=False, lazy="selectin")
2022-08-13 00:07:48 +02:00
2022-09-20 00:31:33 +02:00
class EasterEgg(Base):
"""An easter egg response"""
__tablename__ = "easter_eggs"
easter_egg_id: Mapped[int] = mapped_column(primary_key=True)
match: Mapped[str] = mapped_column(nullable=False)
response: Mapped[str] = mapped_column(nullable=False)
exact: Mapped[bool] = mapped_column(nullable=False, server_default="1")
startswith: Mapped[bool] = mapped_column(nullable=False, server_default="1")
2022-09-20 00:31:33 +02:00
2023-02-02 23:16:51 +01:00
class Event(Base):
"""A scheduled event"""
__tablename__ = "events"
event_id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False)
description: Mapped[Optional[str]] = mapped_column(nullable=True)
notification_channel: Mapped[int] = mapped_column(BigInteger, nullable=False)
timestamp: Mapped[datetime] = mapped_column(nullable=False)
2023-02-02 23:16:51 +01:00
2022-10-13 20:00:46 +02:00
class FreeGame(Base):
"""A temporarily free game"""
__tablename__ = "free_games"
free_game_id: Mapped[int] = mapped_column(primary_key=True)
2022-10-13 20:00:46 +02:00
class GitHubLink(Base):
"""A user's GitHub link"""
__tablename__ = "github_links"
github_link_id: Mapped[int] = mapped_column(primary_key=True)
url: Mapped[str] = mapped_column(nullable=False, unique=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
user: Mapped[User] = relationship(back_populates="github_links", uselist=False, lazy="selectin")
2022-08-10 01:04:19 +02:00
class Link(Base):
"""Useful links that go useful places"""
__tablename__ = "links"
link_id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False, unique=True)
url: Mapped[str] = mapped_column(nullable=False)
2022-08-25 02:07:02 +02:00
class MemeTemplate(Base):
"""A meme template for the Imgflip API"""
__tablename__ = "meme"
meme_id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False, unique=True)
template_id: Mapped[int] = mapped_column(nullable=False, unique=True)
field_count: Mapped[int] = mapped_column(nullable=False)
2022-08-10 01:04:19 +02:00
2022-06-30 19:42:48 +02:00
class NightlyData(Base):
"""Data for a user's Nightly stats"""
__tablename__ = "nightly_data"
nightly_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
last_nightly: Mapped[Optional[date]] = mapped_column(nullable=True)
count: Mapped[int] = mapped_column(server_default="0", nullable=False)
2022-06-30 19:42:48 +02:00
user: Mapped[User] = relationship(back_populates="nightly_data", uselist=False, lazy="selectin")
2022-06-30 19:42:48 +02:00
class Reminder(Base):
"""Something that a user should be reminded of"""
__tablename__ = "reminders"
reminder_id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("users.user_id"))
category: Mapped[enums.ReminderCategory] = mapped_column(nullable=False)
user: Mapped[User] = relationship(back_populates="reminders", uselist=False, lazy="selectin")
class Task(Base):
"""A Didier task"""
__tablename__ = "tasks"
task_id: Mapped[int] = mapped_column(primary_key=True)
task: Mapped[enums.TaskType] = mapped_column(nullable=False, unique=True)
previous_run: Mapped[datetime] = mapped_column(nullable=True)
2022-06-17 01:36:47 +02:00
class UforaCourse(Base):
"""A course on Ufora"""
__tablename__ = "ufora_courses"
course_id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False, unique=True)
code: Mapped[str] = mapped_column(nullable=False, unique=True)
year: Mapped[int] = mapped_column(nullable=False)
compulsory: Mapped[bool] = mapped_column(server_default="1", nullable=False)
role_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True, unique=False)
overarching_role_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True, unique=False)
2022-09-25 00:09:28 +02:00
# This is not the greatest fix, but there can only ever be two, so it will do the job
alternative_overarching_role_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True, unique=False)
log_announcements: Mapped[bool] = mapped_column(server_default="0", nullable=False)
2022-06-17 01:36:47 +02:00
announcements: Mapped[List[UforaAnnouncement]] = relationship(
back_populates="course", cascade="all, delete-orphan", lazy="selectin"
2022-06-17 01:36:47 +02:00
)
aliases: Mapped[List[UforaCourseAlias]] = relationship(
back_populates="course", cascade="all, delete-orphan", lazy="selectin"
2022-06-17 01:36:47 +02:00
)
deadlines: Mapped[List[Deadline]] = relationship(
back_populates="course", cascade="all, delete-orphan", lazy="selectin"
2022-08-13 00:07:48 +02:00
)
2022-06-17 01:36:47 +02:00
class UforaCourseAlias(Base):
"""An alias for a course on Ufora that we use to refer to them"""
__tablename__ = "ufora_course_aliases"
alias_id: Mapped[int] = mapped_column(primary_key=True)
alias: Mapped[str] = mapped_column(nullable=False, unique=True)
course_id: Mapped[int] = mapped_column(ForeignKey("ufora_courses.course_id"))
2022-06-17 01:36:47 +02:00
course: Mapped[UforaCourse] = relationship(back_populates="aliases", uselist=False, lazy="selectin")
2022-06-17 01:36:47 +02:00
class UforaAnnouncement(Base):
"""An announcement sent on Ufora"""
__tablename__ = "ufora_announcements"
announcement_id: Mapped[int] = mapped_column(primary_key=True)
course_id: Mapped[int] = mapped_column(ForeignKey("ufora_courses.course_id"))
publication_date: Mapped[date] = mapped_column()
2022-06-17 01:36:47 +02:00
course: Mapped[UforaCourse] = relationship(back_populates="announcements", uselist=False, lazy="selectin")
2022-06-30 19:42:48 +02:00
class User(Base):
"""A Didier user"""
__tablename__ = "users"
user_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
2022-06-30 19:42:48 +02:00
bank: Mapped[Bank] = relationship(
back_populates="user", uselist=False, lazy="selectin", cascade="all, delete-orphan"
2022-06-30 19:42:48 +02:00
)
birthday: Mapped[Optional[Birthday]] = relationship(
back_populates="user", uselist=False, lazy="selectin", cascade="all, delete-orphan"
2022-07-19 22:58:59 +02:00
)
bookmarks: Mapped[List[Bookmark]] = relationship(
back_populates="user", uselist=True, lazy="selectin", cascade="all, delete-orphan"
2022-08-30 01:32:46 +02:00
)
command_stats: Mapped[List[CommandStats]] = relationship(
back_populates="user", uselist=True, lazy="selectin", cascade="all, delete-orphan"
)
github_links: Mapped[List[GitHubLink]] = relationship(
back_populates="user", uselist=True, lazy="selectin", cascade="all, delete-orphan"
)
nightly_data: Mapped[NightlyData] = relationship(
back_populates="user", uselist=False, lazy="selectin", cascade="all, delete-orphan"
2022-06-30 19:42:48 +02:00
)
reminders: Mapped[List[Reminder]] = relationship(
back_populates="user", uselist=True, lazy="selectin", cascade="all, delete-orphan"
)