* @brief Opens the SQLite file, runs schema migration, and ships caches back to the manager. */
| 69 | * @brief Opens the SQLite file, runs schema migration, and ships caches back to the manager. |
| 70 | */ |
| 71 | void Sessions::DatabaseWorker::openDatabase(const QString& filePath) |
| 72 | { |
| 73 | closeDatabase(); |
| 74 | m_cancelRequested.store(false, std::memory_order_release); |
| 75 | |
| 76 | if (filePath.isEmpty()) { |
| 77 | Q_EMIT openFailed(filePath, tr("Empty file path")); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | m_filePath = filePath; |
| 82 | m_connectionName = QStringLiteral("ss_dbmgr_%1").arg(QDateTime::currentMSecsSinceEpoch()); |
| 83 | |
| 84 | m_db = QSqlDatabase::addDatabase("QSQLITE", m_connectionName); |
| 85 | m_db.setDatabaseName(filePath); |
| 86 | |
| 87 | if (!m_db.open()) { |
| 88 | const QString error = m_db.lastError().text(); |
| 89 | const QString conn = m_connectionName; |
| 90 | m_db = QSqlDatabase(); |
| 91 | if (!conn.isEmpty()) |
| 92 | QSqlDatabase::removeDatabase(conn); |
| 93 | |
| 94 | m_filePath.clear(); |
| 95 | m_connectionName.clear(); |
| 96 | Q_EMIT openFailed(filePath, error); |
| 97 | return; |
| 98 | } |
| 99 | |
| 100 | QSqlQuery pragma(m_db); |
| 101 | pragma.exec("PRAGMA journal_mode=WAL"); |
| 102 | pragma.exec("PRAGMA busy_timeout=5000"); |
| 103 | |
| 104 | ensureSchemaInternal(); |
| 105 | refreshSessionListInternal(); |
| 106 | refreshTagListInternal(); |
| 107 | refreshLockStateInternal(); |
| 108 | |
| 109 | Q_EMIT opened(m_filePath, m_sessionList, m_tagList, m_locked, m_passwordHash); |
| 110 | } |
| 111 | |
| 112 | /** |
| 113 | * @brief Closes the database, removes the connection, clears caches. |