diff --git a/tagstudio/resources/translations/en.json b/tagstudio/resources/translations/en.json index 706507ff..8ef50351 100644 --- a/tagstudio/resources/translations/en.json +++ b/tagstudio/resources/translations/en.json @@ -197,6 +197,9 @@ "status.library_closing": "Closing Library...", "status.library_save_success": "Library Saved and Closed!", "status.library_search_query": "Searching Library...", + "status.library_version_expected": "Expected:", + "status.library_version_found": "Found:", + "status.library_version_mismatch": "Library Version Mismatch!", "status.results_found": "{count} Results Found ({time_span})", "status.results": "Results", "tag_manager.title": "Library Tags", diff --git a/tagstudio/src/core/library/alchemy/db.py b/tagstudio/src/core/library/alchemy/db.py index 61269c2c..e57c4882 100644 --- a/tagstudio/src/core/library/alchemy/db.py +++ b/tagstudio/src/core/library/alchemy/db.py @@ -6,6 +6,7 @@ from pathlib import Path import structlog from sqlalchemy import Dialect, Engine, String, TypeDecorator, create_engine, text +from sqlalchemy.exc import OperationalError from sqlalchemy.orm import DeclarativeBase from src.core.constants import RESERVED_TAG_END @@ -36,7 +37,7 @@ def make_engine(connection_string: str) -> Engine: def make_tables(engine: Engine) -> None: - logger.info("creating db tables") + logger.info("[Library] Creating DB tables...") Base.metadata.create_all(engine) # tag IDs < 1000 are reserved @@ -47,14 +48,19 @@ def make_tables(engine: Engine) -> None: result = conn.execute(text("SELECT SEQ FROM sqlite_sequence WHERE name='tags'")) autoincrement_val = result.scalar() if not autoincrement_val or autoincrement_val <= RESERVED_TAG_END: - conn.execute( - text( - "INSERT INTO tags (id, name, color_namespace, color_slug, is_category) VALUES " - f"({RESERVED_TAG_END}, 'temp', NULL, NULL, false)" + try: + conn.execute( + text( + "INSERT INTO tags " + "(id, name, color_namespace, color_slug, is_category) VALUES " + f"({RESERVED_TAG_END}, 'temp', NULL, NULL, false)" + ) ) - ) - conn.execute(text(f"DELETE FROM tags WHERE id = {RESERVED_TAG_END}")) - conn.commit() + conn.execute(text(f"DELETE FROM tags WHERE id = {RESERVED_TAG_END}")) + conn.commit() + except OperationalError as e: + logger.error("Could not initialize built-in tags", error=e) + conn.rollback() def drop_tables(engine: Engine) -> None: diff --git a/tagstudio/src/core/library/alchemy/library.py b/tagstudio/src/core/library/alchemy/library.py index 102e4cf5..982b19ca 100644 --- a/tagstudio/src/core/library/alchemy/library.py +++ b/tagstudio/src/core/library/alchemy/library.py @@ -42,6 +42,7 @@ from sqlalchemy.orm import ( selectinload, ) from src.core.library.json.library import Library as JsonLibrary # type: ignore +from src.qt.translations import Translations from ...constants import ( BACKUP_FOLDER_NAME, @@ -295,10 +296,35 @@ class Library: poolclass = None if self.storage_path == ":memory:" else NullPool logger.info( - "Opening SQLite Library", library_dir=library_dir, connection_string=connection_string + "[Library] Opening SQLite Library", + library_dir=library_dir, + connection_string=connection_string, ) self.engine = create_engine(connection_string, poolclass=poolclass) with Session(self.engine) as session: + # dont check db version when creating new library + if not is_new: + db_version = session.scalar( + select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name) + ) + + if not db_version or db_version.value != LibraryPrefs.DB_VERSION.default: + mismatch_text = Translations.translate_formatted( + "status.library_version_mismatch" + ) + found_text = Translations.translate_formatted("status.library_version_found") + expected_text = Translations.translate_formatted( + "status.library_version_expected" + ) + return LibraryStatus( + success=False, + message=( + f"{mismatch_text}\n" + f"{found_text} v{0 if not db_version else db_version.value}, " + f"{expected_text} v{LibraryPrefs.DB_VERSION.default}" + ), + ) + make_tables(self.engine) # TODO: Determine a good way of updating built-in data after updates. @@ -337,21 +363,6 @@ class Library: except IntegrityError: session.rollback() - # dont check db version when creating new library - if not is_new: - db_version = session.scalar( - select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name) - ) - - if not db_version: - return LibraryStatus( - success=False, - message=( - "Library version mismatch.\n" - f"Found: v0, expected: v{LibraryPrefs.DB_VERSION.default}" - ), - ) - for pref in LibraryPrefs: with catch_warnings(record=True): try: @@ -377,24 +388,6 @@ class Library: logger.debug("ValueType already exists", field=field) session.rollback() - db_version = session.scalar( - select(Preferences).where(Preferences.key == LibraryPrefs.DB_VERSION.name) - ) - # if the db version is different, we cant proceed - if db_version.value != LibraryPrefs.DB_VERSION.default: - logger.error( - "DB version mismatch", - db_version=db_version.value, - expected=LibraryPrefs.DB_VERSION.default, - ) - return LibraryStatus( - success=False, - message=( - "Library version mismatch.\n" - f"Found: v{db_version.value}, expected: v{LibraryPrefs.DB_VERSION.default}" - ), - ) - # check if folder matching current path exists already self.folder = session.scalar(select(Folder).where(Folder.path == library_dir)) if not self.folder: