diff --git a/core/database/__init__.py b/core/database/__init__.py new file mode 100644 index 0000000..80a1491 --- /dev/null +++ b/core/database/__init__.py @@ -0,0 +1,10 @@ +from .init_checker import DatabaseInitCheckResult, check_db_init +from .utils import create_engine, db_path_to_sqlite_url, sqlite_url_to_db_path + +__all__ = [ + "check_db_init", + "create_engine", + "db_path_to_sqlite_url", + "DatabaseInitCheckResult", + "sqlite_url_to_db_path", +] diff --git a/core/database/init_checker.py b/core/database/init_checker.py new file mode 100644 index 0000000..37abc07 --- /dev/null +++ b/core/database/init_checker.py @@ -0,0 +1,30 @@ +from enum import Flag, auto +from pathlib import Path + +from arcaea_offline.database import Database + +from .utils import create_engine, db_path_to_sqlite_url + + +class DatabaseInitCheckResult(Flag): + NONE = 0 + FILE_EXISTS = auto() + INITIALIZED = auto() + + OK = FILE_EXISTS | INITIALIZED + + +def check_db_init(file: Path) -> DatabaseInitCheckResult: + flags = DatabaseInitCheckResult.NONE + + if not file.exists(): + return flags + + flags |= DatabaseInitCheckResult.FILE_EXISTS + + db_url = db_path_to_sqlite_url(file) + db = Database(create_engine(db_url)) + if db.check_init(): + flags |= DatabaseInitCheckResult.INITIALIZED + + return flags diff --git a/core/database/utils.py b/core/database/utils.py new file mode 100644 index 0000000..80a1a32 --- /dev/null +++ b/core/database/utils.py @@ -0,0 +1,28 @@ +from pathlib import Path + +from PySide6.QtCore import QSysInfo, QUrl +from sqlalchemy import Engine +from sqlalchemy import create_engine as sa_create_engine +from sqlalchemy.pool import NullPool, Pool + + +def db_path_to_sqlite_url(file: Path) -> QUrl: + kernelType = QSysInfo.kernelType() + + # the slash count varies depending on the kernel + # https://docs.sqlalchemy.org/en/20/core/engines.html#sqlite + uri = file.resolve().as_uri() + if kernelType == "winnt": + return QUrl(uri.replace("file://", "sqlite://")) + else: + return QUrl(uri.replace("file://", "sqlite:///")) + + +def sqlite_url_to_db_path(url: str) -> Path: + db_file_url = url.replace("sqlite://", "file://") + return Path(QUrl(db_file_url).toLocalFile()).resolve() + + +def create_engine(_url: str | QUrl, pool: type[Pool] = NullPool) -> Engine: + url = _url.toString() if isinstance(_url, QUrl) else _url + return sa_create_engine(url, poolclass=pool) diff --git a/index.py b/index.py index 0fd2b39..da4ec2a 100644 --- a/index.py +++ b/index.py @@ -13,7 +13,7 @@ import ui.resources.resources_rc # noqa: F401 from core.settings import SettingsKeys, settings from ui.extends.shared.language import changeAppLanguage from ui.implements.mainwindow import MainWindow -from ui.startup.databaseChecker import DatabaseChecker, DatabaseCheckerResult +from ui.startup.databaseChecker import DatabaseChecker, DatabaseInitCheckResult rootLogger = logging.getLogger("root") rootLogger.setLevel(logging.DEBUG) @@ -71,10 +71,10 @@ if __name__ == "__main__": databaseCheckResult = ( databaseChecker.confirmDb() if settings.stringValue(SettingsKeys.General.DatabaseUrl) - else 0 + else DatabaseInitCheckResult.NONE ) - if not databaseCheckResult & DatabaseCheckerResult.Initted: + if not databaseCheckResult & DatabaseInitCheckResult.INITIALIZED: result = databaseChecker.exec() if result == QDialog.DialogCode.Accepted: diff --git a/ui/extends/shared/database.py b/ui/extends/shared/database.py index 58dc750..92ef0a8 100644 --- a/ui/extends/shared/database.py +++ b/ui/extends/shared/database.py @@ -1,14 +1,4 @@ -from typing import Type - -from PySide6.QtCore import QObject, QUrl, Signal -from sqlalchemy import Engine -from sqlalchemy import create_engine as sa_create_engine -from sqlalchemy.pool import NullPool, Pool - - -def create_engine(_url: str | QUrl, pool: Type[Pool] = NullPool) -> Engine: - url = _url.toString() if isinstance(_url, QUrl) else _url - return sa_create_engine(url, poolclass=pool) +from PySide6.QtCore import QObject, Signal class DatabaseUpdateSignals(QObject): diff --git a/ui/startup/databaseChecker.py b/ui/startup/databaseChecker.py index d785063..176d8f8 100644 --- a/ui/startup/databaseChecker.py +++ b/ui/startup/databaseChecker.py @@ -1,24 +1,19 @@ import logging import traceback -from enum import IntEnum +from pathlib import Path from arcaea_offline.database import Database from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, QSysInfo, Qt, QUrl, Slot from PySide6.QtWidgets import QDialog, QMessageBox +from core.database import DatabaseInitCheckResult, check_db_init, create_engine from core.settings import SettingsKeys, settings -from ui.extends.shared.database import create_engine from .databaseChecker_ui import Ui_DatabaseChecker logger = logging.getLogger(__name__) -class DatabaseCheckerResult(IntEnum): - FileExist = 0x001 - Initted = 0x002 - - class DatabaseChecker(Ui_DatabaseChecker, QDialog): def __init__(self, parent=None): super().__init__(parent) @@ -69,21 +64,11 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): else: return QUrl(self.dbFileUrl().toString().replace("file://", "sqlite:///")) - def confirmDb(self) -> DatabaseCheckerResult: - flags = 0x000 - + def confirmDb(self) -> DatabaseInitCheckResult: dbFileInfo = self.dbFileInfo() - dbSqliteUrl = self.dbSqliteUrl() - if not dbFileInfo.exists(): - return flags + dbPath = Path(dbFileInfo.absoluteFilePath()) - flags |= DatabaseCheckerResult.FileExist - db = Database(create_engine(dbSqliteUrl)) - if db.check_init(): - flags |= DatabaseCheckerResult.Initted - self.writeDatabaseUrlToSettings(self.dbSqliteUrl().toString()) - - return flags + return check_db_init(dbPath) def updateLabels(self): result = self.confirmDb() @@ -102,7 +87,7 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): self.dbVersionLabel.setText("-") self.dbCheckConnLabel.setText( f'Error: {e}' - if result & DatabaseCheckerResult.FileExist + if result & DatabaseInitCheckResult.FILE_EXISTS else "-" ) self.continueButton.setEnabled(False) @@ -113,10 +98,10 @@ class DatabaseChecker(Ui_DatabaseChecker, QDialog): self.writeDatabaseUrlToSettings(dbSqliteUrl.toString()) result = self.confirmDb() - if result & DatabaseCheckerResult.Initted: + if result & DatabaseInitCheckResult.INITIALIZED: if not self.confirmDbByExistingSettings: self.writeDatabaseUrlToSettings(dbSqliteUrl.toString()) - elif result & DatabaseCheckerResult.FileExist: + elif result & DatabaseInitCheckResult.FILE_EXISTS: confirm_try_init = QMessageBox.question( self, None,