diff --git a/server/database.py b/server/database.py index 1f23d55..cfe492d 100644 --- a/server/database.py +++ b/server/database.py @@ -5,10 +5,6 @@ import dataclasses import argon2 import flask_login -from sqlalchemy import create_engine, Column, Integer, ForeignKey, Text, select -from sqlalchemy.orm import sessionmaker, DeclarativeBase -from sqlalchemy.exc import SQLAlchemyError - import mgU DATABASE = "./main2.db" @@ -41,41 +37,6 @@ class Opener(): self.con.commit() self.con.close() -# orm garbage - -class Base(DeclarativeBase): - pass - -class MessageORM(Base): - __tablename__ = "messages" - id = Column(Integer, primary_key=True, autoincrement=True) - user = Column(Integer, ForeignKey("users.id"), nullable=False) - thread = Column(Integer, ForeignKey("threads.id"), nullable=False) - content = Column(Text, nullable=False) - time = Column(Integer, nullable=False) - -class UserORM(Base): - __tablename__ = "users" - id = Column(Integer, primary_key=True, autoincrement=True) - name = Column(Text, nullable=False, unique=True) - passhash = Column(Text, nullable=False) - -class ForumORM(Base): - __tablename__ = "forums" - id = Column(Integer, primary_key=True, autoincrement=True) - name = Column(Text, nullable=False) - -class UserForumsORM(Base): - __tablename__ = "user_forums" - user_id = Column(Integer, ForeignKey("users.id"), primary_key=True, nullable=False) - forum_id = Column(Integer, ForeignKey("forums.id"), primary_key=True, nullable=False) - -class ThreadORM(Base): - __tablename__ = "threads" - id = Column(Integer, primary_key=True, autoincrement=True) - name = Column(Text, nullable=False) - forum = Column(Integer, ForeignKey("forums.id"), nullable=False) - # Raw SQL DTOs @dataclasses.dataclass @@ -91,22 +52,19 @@ class MessageDTO: thread_id: int id: int | None = None -engine = create_engine(f"sqlite:///{DATABASE}", echo=False, future=True) -SessionLocal = sessionmaker(bind=engine) - -def insert_message(message: MessageORM) -> None: +def insert_message(message: mgU.Message) -> None: """ Insert a new message (from mgU.Message dataclass) and return a new mgU.Message with id, or None on failure. """ - session = SessionLocal() - try: - session.add(message) - session.commit() - except SQLAlchemyError: - session.rollback() - return None - finally: - session.close() + with Opener() as (conn, cur): + q = load_query("insert_message") + cur.execute(q, [ + message.user, + message.thread, + message.content, + message.time + ]) + def get_messages_by_thread(thread_id: int) -> list[mgU.Message]: """ @@ -132,62 +90,51 @@ def get_messages_by_thread(thread_id: int) -> list[mgU.Message]: ] def get_user_forums(user_id: int) -> list[mgU.Forum]: - session = SessionLocal() - try: - q = ( - select(ForumORM.id, ForumORM.name) - .join_from(ForumORM, UserForumsORM) - .where(UserForumsORM.user_id == user_id) - ) - results = session.execute(q) + q = load_query("get_user_forums") + with Opener() as (conn, cur): + cur.execute(q, [user_id]) + results = cur.fetchall() return [ mgU.Forum( - name=forum.name, - id=forum.id + name=forum[0], + id=forum[1] ) for forum in results ] - finally: - session.close() def get_forum_threads(forum_id: int) -> list[mgU.Thread]: - session = SessionLocal() - try: - q = ( - select(ThreadORM.id, ThreadORM.name, ThreadORM.forum) - .where(ThreadORM.forum == forum_id) - ) - - results = session.execute(q) + q = load_query("get_forum_threads") + with Opener() as (conn, cur): + cur.execute(q, [forum_id]) + results = cur.fetchall() return [ mgU.Thread( - name=thread.name, - forum=thread.forum, - id=thread.id + name=thread[0], + forum=thread[1], + id=thread[2] ) for thread in results ] - finally: - session.close() # For flask_login def get_user(username: str, api_key: str) -> User | None: - session = SessionLocal() - try: - results = session.query(UserORM).where(UserORM.name == username) - finally: - session.close() + q = load_query("get_user_passhash") + with Opener() as (conn, cur): + cur.execute(q) + results = cur.fetchall() if not results: return None - user_row = results[0] + row = results[0] + + user_id, user_name, passhash = row[0], row[1], row[2] try: - ph.verify(user_row.passhash, api_key) + ph.verify(passhash, api_key) except argon2.exceptions.VerifyMismatchError: return None - return User(str(user_row.id), str(user_row.name)) + return User(str(user_id), str(user_name)) diff --git a/server/sql/get_forum_threads.sql b/server/sql/get_forum_threads.sql new file mode 100644 index 0000000..28b7275 --- /dev/null +++ b/server/sql/get_forum_threads.sql @@ -0,0 +1,7 @@ +select + threads.name, + threads.forum + threads.id +from threads +where threads.forum_id = ? +; \ No newline at end of file diff --git a/server/sql/get_user_by_username.sql b/server/sql/get_user_by_username.sql new file mode 100644 index 0000000..2930586 --- /dev/null +++ b/server/sql/get_user_by_username.sql @@ -0,0 +1,7 @@ +select + users.id, + users.name, + users.passhash +from users +where users.name = ? +; \ No newline at end of file diff --git a/server/sql/get_user_forums.sql b/server/sql/get_user_forums.sql new file mode 100644 index 0000000..4af228e --- /dev/null +++ b/server/sql/get_user_forums.sql @@ -0,0 +1,7 @@ +select + forum.name, + forum.id +from user_forums +inner join forums on user_forums.forum_id = forums.id +where user_forums.user_id = ? +; \ No newline at end of file diff --git a/server/sql/insert_message.sql b/server/sql/insert_message.sql new file mode 100644 index 0000000..65365ae --- /dev/null +++ b/server/sql/insert_message.sql @@ -0,0 +1,7 @@ +insert into messages ( + user, + thread, + content, + time +) values (?, ?, ?, ?) +; \ No newline at end of file