attempt to solve #898

This commit is contained in:
Martin Rotter 2023-03-13 14:15:48 +01:00
parent defd8c6f48
commit 163f012b71
4 changed files with 33 additions and 69 deletions

View File

@ -183,7 +183,7 @@ bool MessagesProxyModel::filterAcceptsRow(int source_row, const QModelIndex& sou
// and we want to show only regexped AND unread messages when unread should be visible. // and we want to show only regexped AND unread messages when unread should be visible.
// //
// But also, we want to see messages which have their dirty states cached, because // But also, we want to see messages which have their dirty states cached, because
// otherwise they would just disappeaar from the list for example when batch marked as read // otherwise they would just disappear from the list for example when batch marked as read
// which is distracting. // which is distracting.
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) && return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) &&
(m_sourceModel->cache()->containsData(source_row) || (m_sourceModel->cache()->containsData(source_row) ||

View File

@ -11,9 +11,8 @@
SqliteDriver::SqliteDriver(bool in_memory, QObject* parent) SqliteDriver::SqliteDriver(bool in_memory, QObject* parent)
: DatabaseDriver(parent), m_inMemoryDatabase(in_memory), : DatabaseDriver(parent), m_inMemoryDatabase(in_memory),
m_databaseFilePath(qApp->userDataFolder() + QDir::separator() + QSL(APP_DB_SQLITE_PATH)), m_databaseFilePath(qApp->userDataFolder() + QDir::separator() + QSL(APP_DB_SQLITE_PATH)),
m_fileBasedDatabaseInitialized(false), m_fileBasedDatabaseInitialized(false), m_inMemoryDatabaseInitialized(false) {}
m_inMemoryDatabaseInitialized(false) {}
QString SqliteDriver::location() const { QString SqliteDriver::location() const {
return QDir::toNativeSeparators(m_databaseFilePath); return QDir::toNativeSeparators(m_databaseFilePath);
@ -69,22 +68,16 @@ bool SqliteDriver::saveDatabase() {
qDebugNN << LOGSEC_DB << "Cleaning old data from 'storage." << table << "'."; qDebugNN << LOGSEC_DB << "Cleaning old data from 'storage." << table << "'.";
} }
else { else {
qCriticalNN << LOGSEC_DB << "Failed to clean old data from 'storage." qCriticalNN << LOGSEC_DB << "Failed to clean old data from 'storage." << table << "', error: '"
<< table << "', error: '"
<< copy_contents.lastError().text() << "'."; << copy_contents.lastError().text() << "'.";
} }
if (copy_contents.exec(QString(QSL("INSERT INTO storage.%1 SELECT * FROM main.%1;")).arg(table))) { if (copy_contents.exec(QString(QSL("INSERT INTO storage.%1 SELECT * FROM main.%1;")).arg(table))) {
qDebugNN << LOGSEC_DB << "Copying new data into 'main." qDebugNN << LOGSEC_DB << "Copying new data into 'main." << table << "'.";
<< table << "'.";
} }
else { else {
qCriticalNN << LOGSEC_DB qCriticalNN << LOGSEC_DB << "Failed to copy new data to 'main." << table << "', error: '"
<< "Failed to copy new data to 'main." << copy_contents.lastError().text() << "'.";
<< table
<< "', error: '"
<< copy_contents.lastError().text()
<< "'.";
} }
} }
@ -93,10 +86,7 @@ bool SqliteDriver::saveDatabase() {
qDebugNN << LOGSEC_DB << "Detaching persistent SQLite file."; qDebugNN << LOGSEC_DB << "Detaching persistent SQLite file.";
} }
else { else {
qCriticalNN << LOGSEC_DB qCriticalNN << LOGSEC_DB << "Failed to detach SQLite file, error: '" << copy_contents.lastError().text() << "'.";
<< "Failed to detach SQLite file, error: '"
<< copy_contents.lastError().text()
<< "'.";
} }
copy_contents.finish(); copy_contents.finish();
@ -107,8 +97,7 @@ QSqlDatabase SqliteDriver::connection(const QString& connection_name, DesiredSto
bool want_in_memory = desired_type == DatabaseDriver::DesiredStorageType::StrictlyInMemory || bool want_in_memory = desired_type == DatabaseDriver::DesiredStorageType::StrictlyInMemory ||
(desired_type == DatabaseDriver::DesiredStorageType::FromSettings && m_inMemoryDatabase); (desired_type == DatabaseDriver::DesiredStorageType::FromSettings && m_inMemoryDatabase);
if ((want_in_memory && !m_inMemoryDatabaseInitialized) || if ((want_in_memory && !m_inMemoryDatabaseInitialized) || (!want_in_memory && !m_fileBasedDatabaseInitialized)) {
(!want_in_memory && !m_fileBasedDatabaseInitialized)) {
return initializeDatabase(connection_name, want_in_memory); return initializeDatabase(connection_name, want_in_memory);
} }
else { else {
@ -116,10 +105,7 @@ QSqlDatabase SqliteDriver::connection(const QString& connection_name, DesiredSto
QSqlDatabase database; QSqlDatabase database;
if (QSqlDatabase::contains(connection_name)) { if (QSqlDatabase::contains(connection_name)) {
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "SQLite connection" << QUOTE_W_SPACE(connection_name) << "is already active.";
<< "SQLite connection"
<< QUOTE_W_SPACE(connection_name)
<< "is already active.";
// This database connection was added previously, no need to // This database connection was added previously, no need to
// setup its properties. // setup its properties.
@ -136,21 +122,17 @@ QSqlDatabase SqliteDriver::connection(const QString& connection_name, DesiredSto
const QDir db_path(m_databaseFilePath); const QDir db_path(m_databaseFilePath);
QFile db_file(db_path.absoluteFilePath(QSL(APP_DB_SQLITE_FILE))); QFile db_file(db_path.absoluteFilePath(QSL(APP_DB_SQLITE_FILE)));
database.setConnectOptions(QSL("QSQLITE_ENABLE_SHARED_CACHE"));
database.setDatabaseName(db_file.fileName()); database.setDatabaseName(db_file.fileName());
} }
} }
if (!database.isOpen() && !database.open()) { if (!database.isOpen() && !database.open()) {
qFatal("SQLite database was NOT opened. Delivered error message: '%s'.", qFatal("SQLite database was NOT opened. Delivered error message: '%s'.", qPrintable(database.lastError().text()));
qPrintable(database.lastError().text()));
} }
else { else {
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "SQLite database connection" << QUOTE_W_SPACE(connection_name) << "to file"
<< "SQLite database connection" << QUOTE_W_SPACE(database.databaseName()) << "seems to be established.";
<< QUOTE_W_SPACE(connection_name)
<< "to file"
<< QUOTE_W_SPACE(database.databaseName())
<< "seems to be established.";
} }
QSqlQuery query_db(database); QSqlQuery query_db(database);
@ -164,17 +146,15 @@ QSqlDatabase SqliteDriver::connection(const QString& connection_name, DesiredSto
bool SqliteDriver::initiateRestoration(const QString& database_package_file) { bool SqliteDriver::initiateRestoration(const QString& database_package_file) {
return IOFactory::copyFile(database_package_file, return IOFactory::copyFile(database_package_file,
m_databaseFilePath + QDir::separator() + m_databaseFilePath + QDir::separator() + BACKUP_NAME_DATABASE + BACKUP_SUFFIX_DATABASE);
BACKUP_NAME_DATABASE + BACKUP_SUFFIX_DATABASE);
} }
bool SqliteDriver::finishRestoration() { bool SqliteDriver::finishRestoration() {
const QString backup_database_file = m_databaseFilePath + QDir::separator() + BACKUP_NAME_DATABASE + BACKUP_SUFFIX_DATABASE; const QString backup_database_file =
m_databaseFilePath + QDir::separator() + BACKUP_NAME_DATABASE + BACKUP_SUFFIX_DATABASE;
if (QFile::exists(backup_database_file)) { if (QFile::exists(backup_database_file)) {
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "Backup database file '" << QDir::toNativeSeparators(backup_database_file)
<< "Backup database file '"
<< QDir::toNativeSeparators(backup_database_file)
<< "' was detected. Restoring it."; << "' was detected. Restoring it.";
if (IOFactory::copyFile(backup_database_file, m_databaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) { if (IOFactory::copyFile(backup_database_file, m_databaseFilePath + QDir::separator() + APP_DB_SQLITE_FILE)) {
@ -182,8 +162,7 @@ bool SqliteDriver::finishRestoration() {
qDebugNN << LOGSEC_DB << "Database file was restored successully."; qDebugNN << LOGSEC_DB << "Database file was restored successully.";
} }
else { else {
qCriticalNN << LOGSEC_DB qCriticalNN << LOGSEC_DB << "Database file was NOT restored due to error when copying the file.";
<< "Database file was NOT restored due to error when copying the file.";
return false; return false;
} }
} }
@ -226,12 +205,14 @@ QSqlDatabase SqliteDriver::initializeDatabase(const QString& connection_name, bo
if (in_memory) { if (in_memory) {
database.setConnectOptions(QSL("QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE")); database.setConnectOptions(QSL("QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE"));
} }
else {
database.setConnectOptions(QSL("QSQLITE_ENABLE_SHARED_CACHE"));
}
database.setDatabaseName(db_file_name); database.setDatabaseName(db_file_name);
if (!database.open()) { if (!database.open()) {
qFatal("SQLite database was NOT opened. Delivered error message: '%s'", qFatal("SQLite database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text()));
qPrintable(database.lastError().text()));
} }
else { else {
QSqlQuery query_db(database); QSqlQuery query_db(database);
@ -277,34 +258,21 @@ QSqlDatabase SqliteDriver::initializeDatabase(const QString& connection_name, bo
try { try {
updateDatabaseSchema(query_db, installed_db_schema); updateDatabaseSchema(query_db, installed_db_schema);
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "Database schema was updated from" << QUOTE_W_SPACE(installed_db_schema) << "to"
<< "Database schema was updated from" << QUOTE_W_SPACE(APP_DB_SCHEMA_VERSION) << "successully.";
<< QUOTE_W_SPACE(installed_db_schema)
<< "to"
<< QUOTE_W_SPACE(APP_DB_SCHEMA_VERSION)
<< "successully.";
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
qFatal("Error when updating DB schema from %d: %s.", installed_db_schema, qPrintable(ex.message())); qFatal("Error when updating DB schema from %d: %s.", installed_db_schema, qPrintable(ex.message()));
} }
} }
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "File-based SQLite database connection '" << connection_name << "' to file '"
<< "File-based SQLite database connection '" << QDir::toNativeSeparators(database.databaseName()) << "' seems to be established.";
<< connection_name qDebugNN << LOGSEC_DB << "File-based SQLite database has version '" << installed_db_schema << "'.";
<< "' to file '"
<< QDir::toNativeSeparators(database.databaseName())
<< "' seems to be established.";
qDebugNN << LOGSEC_DB
<< "File-based SQLite database has version '"
<< installed_db_schema
<< "'.";
} }
else { else {
query_db.next(); query_db.next();
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "SQLite database has version" << QUOTE_W_SPACE_DOT(query_db.value(0).toString());
<< "SQLite database has version"
<< QUOTE_W_SPACE_DOT(query_db.value(0).toString());
} }
} }
@ -332,8 +300,7 @@ QSqlDatabase SqliteDriver::initializeDatabase(const QString& connection_name, bo
copy_contents.exec(QSL("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table)); copy_contents.exec(QSL("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
} }
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "Copying data from file-based database into working in-memory database.";
<< "Copying data from file-based database into working in-memory database.";
// Detach database and finish. // Detach database and finish.
copy_contents.exec(QSL("DETACH 'storage'")); copy_contents.exec(QSL("DETACH 'storage'"));
@ -357,11 +324,12 @@ QString SqliteDriver::databaseFilePath() const {
void SqliteDriver::setPragmas(QSqlQuery& query) { void SqliteDriver::setPragmas(QSqlQuery& query) {
query.exec(QSL("PRAGMA encoding = \"UTF-8\"")); query.exec(QSL("PRAGMA encoding = \"UTF-8\""));
query.exec(QSL("PRAGMA synchronous = OFF")); query.exec(QSL("PRAGMA synchronous = OFF"));
query.exec(QSL("PRAGMA journal_mode = MEMORY")); // query.exec(QSL("PRAGMA journal_mode = MEMORY"));
query.exec(QSL("PRAGMA page_size = 4096")); query.exec(QSL("PRAGMA page_size = 4096"));
query.exec(QSL("PRAGMA cache_size = 16384")); query.exec(QSL("PRAGMA cache_size = 16384"));
query.exec(QSL("PRAGMA count_changes = OFF")); query.exec(QSL("PRAGMA count_changes = OFF"));
query.exec(QSL("PRAGMA temp_store = MEMORY")); query.exec(QSL("PRAGMA temp_store = MEMORY"));
query.exec(QSL("PRAGMA journal_mode = WAL"));
} }
qint64 SqliteDriver::databaseDataSize() { qint64 SqliteDriver::databaseDataSize() {

View File

@ -10,8 +10,6 @@
#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/cacheforserviceroot.h"
#include "services/abstract/feed.h" #include "services/abstract/feed.h"
#include <QFutureWatcher>
class FeedsModel; class FeedsModel;
class MessagesModel; class MessagesModel;
class MessagesProxyModel; class MessagesProxyModel;

View File

@ -18,8 +18,6 @@
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QFuture>
#include <QFutureWatcher>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -122,7 +120,7 @@ bool SystemFactory::setAutoStartStatus(AutoStartStatus new_status) {
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"), QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"),
QSettings::NativeFormat); QSettings::Format::NativeFormat);
switch (new_status) { switch (new_status) {
case AutoStartStatus::Enabled: { case AutoStartStatus::Enabled: {