#include "databasemanager.h" #include #include #include #include #include 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; }