refactor: database initialize checker

This commit is contained in:
2025-08-13 15:17:46 +08:00
parent 806acd5793
commit 06a1ca00bd
6 changed files with 80 additions and 37 deletions

10
core/database/__init__.py Normal file
View File

@ -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",
]

View File

@ -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

28
core/database/utils.py Normal file
View File

@ -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)

View File

@ -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:

View File

@ -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):

View File

@ -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'<font color="red">Error: {e}</font>'
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,