From bf419ec3bf10c0edb22f61fe0369e14fd835db94 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Wed, 3 Sep 2025 10:41:26 +0200 Subject: [PATCH] Implement startup check and table creation in Database class; add methods to retrieve books and manage apparat deletion --- src/backend/database.py | 126 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/src/backend/database.py b/src/backend/database.py index 2148b31..e2e5d03 100644 --- a/src/backend/database.py +++ b/src/backend/database.py @@ -67,6 +67,57 @@ class Database: self.db_path = db_path log.debug(f"Database path: {self.db_path}") self.db_initialized = False + self.startup_check() + + def startup_check(self): + # check existence of all tables. if any is missing, recreate the table + if not self.db_initialized: + self.initializeDatabase() + tables = self.get_db_contents() + tables = [t[1] for t in tables] if tables is not None else [] + required_tables = [ + "semesterapparat", + "messages", + "media", + "files", + "prof", + "user", + "subjects", + "elsa", + "elsa_files", + "elsa_media", + ] + + for table in required_tables: + if table not in tables: + log.critical(f"Table {table} is missing, recreating...") + self.create_table(table) + + def create_table(self, table_name: str): + match table_name: + case "semesterapparat": + query = CREATE_TABLE_APPARAT + case "messages": + query = CREATE_TABLE_MESSAGES + case "media": + query = CREATE_TABLE_MEDIA + case "files": + query = CREATE_TABLE_FILES + case "prof": + query = CREATE_TABLE_PROF + case "user": + query = CREATE_TABLE_USER + case "subjects": + query = CREATE_TABLE_SUBJECTS + case "elsa": + query = CREATE_ELSA_TABLE + case "elsa_files": + query = CREATE_ELSA_FILES_TABLE + case "elsa_media": + query = CREATE_ELSA_MEDIA_TABLE + case _: + log.error(f"Table {table_name} is not a valid table name") + self.query_db(query) def initializeDatabase(self): if not self.db_initialized: @@ -451,6 +502,46 @@ class Database: ret_result.append(data) return ret_result + def getAllBooks(self): + # return all books in the database + qdata = self.query_db("SELECT id,bookdata FROM media WHERE deleted=0") + ret_result: list[dict[str, Any]] = [] + if qdata is None: + return [] + for result_a in qdata: + data: dict[str, Any] = {"id": int, "bookdata": BookData} + data["id"] = result_a[0] + data["bookdata"] = BookData().from_string(result_a[1]) + + ret_result.append(data) + return ret_result + + def getBooksByProfId(self, prof_id: int, deleted: int = 0): + """ + Get the Books based on the professor id + + Args: + prof_id (str): The ID of the professor + deleted (int, optional): The state of the book. Set to 1 to include deleted ones. Defaults to 0. + + Returns: + + list[dict[int, BookData, int]]: A list of dictionaries containing the id, the metadata of the book and the availability of the book + """ + qdata = self.query_db( + f"SELECT id,bookdata,available FROM media WHERE prof_id={prof_id} AND (deleted={deleted if deleted == 0 else '1 OR deleted=0'})" + ) + ret_result = [] + if qdata is None: + return [] + for result_a in qdata: + data: dict[str, Any] = {"id": int, "bookdata": BookData, "available": int} + data["id"] = result_a[0] + data["bookdata"] = BookData().from_string(result_a[1]) + data["available"] = result_a[2] + ret_result.append(data) + return ret_result + def updateBookdata(self, book_id: int, bookdata: BookData): """ Update the bookdata in the database @@ -892,6 +983,23 @@ class Database: (newDate, today, app_id), ) + def getId(self, apparat_name) -> Optional[int]: + """get the id of an apparat based on the name + + Args: + apparat_name (str): the name of the apparat e.g. "Semesterapparat 1" + + Returns: + Optional[int]: the id of the apparat, if the apparat is not found, None is returned + """ + data = self.query_db( + "SELECT id FROM semesterapparat WHERE name=?", (apparat_name,), one=True + ) + if data is None: + return None + else: + return data[0] + def getApparatId(self, apparat_name) -> Optional[int]: """get the id of an apparat based on the name @@ -1029,22 +1137,22 @@ class Database: self.close_connection(conn) return ret - def deleteApparat(self, app_id: Union[str, int], semester): + def deleteApparat(self, apparat: Apparat, semester: str): """Delete an apparat from the database Args: - app_id (Union[str, int]): the id of the apparat + apparat: (Apparat): the apparat to be deleted semester (str): the semester the apparat should be deleted from """ - log.info(f"Deleting apparat with id {app_id} in semester {semester}") + apparat_nr = apparat.appnr + app_id = self.getId(apparat.name) self.query_db( - "UPDATE semesterapparat SET deletion_status=1, deleted_date=? WHERE appnr=?", - (semester, app_id), - ) - self.query_db( - "UPDATE media SET deleted=1 WHERE app_id=?", - (app_id,), + "UPDATE semesterapparat SET deletion_status=1, deleted_date=? WHERE appnr=? AND name=?", + (semester, apparat_nr, apparat.name), ) + # delete all books associated with the app_id + print(apparat_nr, app_id) + self.query_db("UPDATE media SET deleted=1 WHERE app_id=?", (app_id,)) def isEternal(self, id): """check if the apparat is eternal (dauerapparat)