diff --git a/CMakeLists.txt b/CMakeLists.txt index e02d771..aaebeb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ find_package(Qt6 COMPONENTS Core Gui Widgets Network Sql WebEngineWidgets REQUIR # Include directories include_directories(${PROJECT_SOURCE_DIR}/src) -# Source files - we will add them later +# Source files set(SRC_FILES src/main.cpp src/core/translator.cpp @@ -24,6 +24,7 @@ set(SRC_FILES src/core/models/folder.cpp src/services/synchronizer.cpp src/services/imap/imapsynchronizer.cpp + src/db/databasemanager.cpp ) # Executable @@ -37,4 +38,4 @@ target_link_libraries(wino-mail-qt PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6:: # target_include_directories(wino-mail-qt PRIVATE ${LIBETPAN_INCLUDE_DIRS} ${GMIME_INCLUDE_DIRS}) # Install (optional) -install(TARGETS wino-mail-qt DESTINATION bin) \ No newline at end of file +install(TARGETS wino-mail-qt DESTINATION bin) diff --git a/src/db/databasemanager.cpp b/src/db/databasemanager.cpp new file mode 100644 index 0000000..d1970bc --- /dev/null +++ b/src/db/databasemanager.cpp @@ -0,0 +1,131 @@ +#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; + } + + // Create tables if they don't exist + QSqlQuery query(m_db); + // We'll create a minimal set of tables for now; can be expanded later. + // Based on Wino Mail schema: Account, Folder, MailCopy (mail items), etc. + + // Account table + if (!query.exec( + "CREATE TABLE IF NOT EXISTS Account (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "email TEXT NOT NULL, " + "displayName TEXT, " + "type INTEGER NOT NULL, " // 0=Outlook,1=Gmail,2=IMAP + "accessToken TEXT, " + "refreshToken TEXT, " + "tokenExpires DATETIME" + ");")) { + 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)" + ");")) { + 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, " + "fileId TEXT, " // references the .eml file in storage + "FOREIGN KEY(folderId) REFERENCES Folder(id)" + ");")) { + 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)" + ");")) { + 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; +} \ No newline at end of file diff --git a/src/db/databasemanager.h b/src/db/databasemanager.h new file mode 100644 index 0000000..d23f919 --- /dev/null +++ b/src/db/databasemanager.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +class DatabaseManager +{ +public: + static DatabaseManager& instance(); + ~DatabaseManager(); + + bool initialize(const QString& databasePath = QStringLiteral("wino-mail.sqlite")); + QSqlDatabase& database(); + +private: + DatabaseManager(); + Q_DISABLE_COPY(DatabaseManager) + + QSqlDatabase m_db; + QMutex m_mutex; + bool m_initialized{false}; +}; \ No newline at end of file