- ImapSynchronizer::syncFolder(): detecta eliminados (UIDs locales no en servidor), fetch nuevos (sinceUid), actualiza flags (FLAGS batch) - fetchAllUids(): SELECT + SEARCH ALL para lista completa UIDs servidor - parseAndUpdateFlags(): FETCH FLAGS en lotes 100, update DB si cambió read/flagged - AccountSetupDialog: integra ConnectionWizard para IMAP/POP3 con test de conexión real - IMAP FETCH parser robusto: logging respuesta servidor + fallback UID-by-UID - Fix: FETCH failed logging muestra first/last UID + respuesta truncada
142 lines
4.0 KiB
Plaintext
142 lines
4.0 KiB
Plaintext
#include "databasemanager.h"
|
|
#include <QSqlQuery>
|
|
#include <QSqlError>
|
|
#include <QDebug>
|
|
#include <QStandardPaths>
|
|
#include <QDir>
|
|
|
|
DatabaseManager& DatabaseManager::instance()
|
|
{
|
|
static DatabaseManager instance;
|
|
return instance;
|
|
}
|
|
|
|
DatabaseManager::DatabaseManager() = default;
|
|
|
|
DatabaseManager::~DatabaseManager()
|
|
{
|
|
if (m_db.isOpen()) {
|
|
m_db.close();
|
|
}
|
|
}
|
|
|
|
bool DatabaseManager::initialize(const QString& databasePath)
|
|
{
|
|
QMutexLocker locker(&m_mutex);
|
|
if (m_initialized) {
|
|
return true;
|
|
}
|
|
|
|
QString dbPath = databasePath;
|
|
if (dbPath.isEmpty()) {
|
|
// Use application data location
|
|
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
|
if (!dir.exists()) {
|
|
dir.mkpath(".");
|
|
}
|
|
dbPath = dir.filePath("wino-mail.sqlite");
|
|
}
|
|
|
|
m_db = QSqlDatabase::addDatabase("QSQLITE", "wino_mail_connection");
|
|
m_db.setDatabaseName(dbPath);
|
|
|
|
if (!m_db.open()) {
|
|
qWarning() << "Failed to open database:" << m_db.lastError().text();
|
|
return false;
|
|
}
|
|
|
|
QSqlQuery query(m_db);
|
|
// Enable foreign keys
|
|
query.exec("PRAGMA foreign_keys = ON;");
|
|
|
|
// Create tables if they don't exist
|
|
|
|
// Account table
|
|
if (!query.exec(
|
|
"CREATE TABLE IF NOT EXISTS Account ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"email TEXT NOT NULL, "
|
|
"displayName TEXT, signature TEXT, "
|
|
"type INTEGER NOT NULL, " // 0=Outlook,1=Gmail,2=IMAP
|
|
"accessToken TEXT, "
|
|
"refreshToken TEXT, "
|
|
"tokenExpires DATETIME, "
|
|
"incomingHost TEXT, "
|
|
"incomingPort INTEGER, "
|
|
"incomingSsl INTEGER, "
|
|
"outgoingHost TEXT, "
|
|
"outgoingPort INTEGER, "
|
|
"outgoingSsl INTEGER, "
|
|
"connUsername TEXT, "
|
|
"connPassword TEXT, "
|
|
"authMethod TEXT"
|
|
");")) {
|
|
qWarning() << "Failed to create Account table:" << query.lastError().text();
|
|
return false;
|
|
}
|
|
|
|
// Folder table
|
|
if (!query.exec(
|
|
"CREATE TABLE IF NOT EXISTS Folder ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"accountId INTEGER NOT NULL, "
|
|
"name TEXT NOT NULL, "
|
|
"parentFolderId TEXT, "
|
|
"isInbox BOOLEAN DEFAULT 0, "
|
|
"isSent BOOLEAN DEFAULT 0, "
|
|
"isDrafts BOOLEAN DEFAULT 0, "
|
|
"isTrash BOOLEAN DEFAULT 0, "
|
|
"unreadCount INTEGER DEFAULT 0, "
|
|
"lastSynced DATETIME, "
|
|
"FOREIGN KEY(accountId) REFERENCES Account(id) ON DELETE CASCADE"
|
|
");")) {
|
|
qWarning() << "Failed to create Folder table:" << query.lastError().text();
|
|
return false;
|
|
}
|
|
|
|
// MailCopy table (simplified)
|
|
if (!query.exec(
|
|
"CREATE TABLE IF NOT EXISTS MailCopy ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"folderId INTEGER NOT NULL, "
|
|
"messageId TEXT UNIQUE, "
|
|
"subject TEXT, "
|
|
"sender TEXT, "
|
|
"recipient TEXT, "
|
|
"date DATETIME, "
|
|
"read BOOLEAN DEFAULT 0, "
|
|
"flagged BOOLEAN DEFAULT 0, "
|
|
"hasAttachment BOOLEAN DEFAULT 0, "
|
|
"size INTEGER, "
|
|
"uid INTEGER, "
|
|
"fileId TEXT, " // references the .eml file in storage
|
|
"FOREIGN KEY(folderId) REFERENCES Folder(id) ON DELETE CASCADE"
|
|
");")) {
|
|
qWarning() << "Failed to create MailCopy table:" << query.lastError().text();
|
|
return false;
|
|
}
|
|
|
|
// Attachments table (optional)
|
|
if (!query.exec(
|
|
"CREATE TABLE IF NOT EXISTS Attachment ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"mailCopyId INTEGER NOT NULL, "
|
|
"filename TEXT, "
|
|
"mimeType TEXT, "
|
|
"size INTEGER, "
|
|
"contentId TEXT, "
|
|
"FOREIGN KEY(mailCopyId) REFERENCES MailCopy(id) ON DELETE CASCADE"
|
|
");")) {
|
|
qWarning() << "Failed to create Attachment table:" << query.lastError().text();
|
|
return false;
|
|
}
|
|
|
|
m_initialized = true;
|
|
qDebug() << "Database initialized at:" << dbPath;
|
|
return true;
|
|
}
|
|
|
|
QSqlDatabase& DatabaseManager::database()
|
|
{
|
|
return m_db;
|
|
} |