diff --git a/CMakeLists.txt b/CMakeLists.txt index aaebeb5..1284161 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(SRC_FILES src/services/synchronizer.cpp src/services/imap/imapsynchronizer.cpp src/db/databasemanager.cpp + src/db/dao/accountdao.cpp ) # Executable diff --git a/src/db/dao/accountdao.cpp b/src/db/dao/accountdao.cpp new file mode 100644 index 0000000..7142f8a --- /dev/null +++ b/src/db/dao/accountdao.cpp @@ -0,0 +1,146 @@ +#include "accountdao.h" +#include + +bool AccountDao::insert(const Account& account) +{ + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + query.prepare( + "INSERT INTO Account (email, displayName, type, accessToken, refreshToken, tokenExpires) " + "VALUES (:email, :displayName, :type, :accessToken, :refreshToken, :tokenExpires)" + ); + query.bindValue(":email", account.email()); + query.bindValue(":displayName", account.displayName()); + query.bindValue(":type", static_cast(account.type())); + query.bindValue(":accessToken", account.accessToken()); + query.bindValue(":refreshToken", account.refreshToken()); + query.bindValue(":tokenExpires", account.tokenExpires()); + + if (!query.exec()) { + qWarning() << "Failed to insert account:" << query.lastError().text(); + return false; + } + + // Optionally set the id on the account object if needed (pass by reference?) + // Since account is const, we cannot modify it. Caller can retrieve lastInsertId. + return true; +} + +bool AccountDao::update(const Account& account) +{ + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + query.prepare( + "UPDATE Account SET " + "email = :email, " + "displayName = :displayName, " + "type = :type, " + "accessToken = :accessToken, " + "refreshToken = :refreshToken, " + "tokenExpires = :tokenExpires " + "WHERE id = :id" + ); + query.bindValue(":id", account.id()); + query.bindValue(":email", account.email()); + query.bindValue(":displayName", account.displayName()); + query.bindValue(":type", static_cast(account.type())); + query.bindValue(":accessToken", account.accessToken()); + query.bindValue(":refreshToken", account.refreshToken()); + query.bindValue(":tokenExpires", account.tokenExpires()); + + if (!query.exec()) { + qWarning() << "Failed to update account:" << query.lastError().text(); + return false; + } + return true; +} + +bool AccountDao::remove(int id) +{ + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + query.prepare("DELETE FROM Account WHERE id = :id"); + query.bindValue(":id", id); + + if (!query.exec()) { + qWarning() << "Failed to delete account:" << query.lastError().text(); + return false; + } + return true; +} + +std::optional AccountDao::findById(int id) +{ + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + query.prepare("SELECT id, email, displayName, type, accessToken, refreshToken, tokenExpires FROM Account WHERE id = :id"); + query.bindValue(":id", id); + + if (!query.exec()) { + qWarning() << "Failed to find account by id:" << query.lastError().text(); + return std::nullopt; + } + + if (query.next()) { + Account acc; + acc.setId(query.value(0).toInt()); + acc.setEmail(query.value(1).toString()); + acc.setDisplayName(query.value(2).toString()); + acc.setType(static_cast(query.value(3).toInt())); + acc.setAccessToken(query.value(4).toString()); + acc.setRefreshToken(query.value(5).toString()); + acc.setTokenExpires(query.value(6).toDateTime()); + return acc; + } + return std::nullopt; +} + +QVector AccountDao::findAll() +{ + QVector accounts; + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + if (!query.exec("SELECT id, email, displayName, type, accessToken, refreshToken, tokenExpires FROM Account")) { + qWarning() << "Failed to fetch all accounts:" << query.lastError().text(); + return accounts; + } + + while (query.next()) { + Account acc; + acc.setId(query.value(0).toInt()); + acc.setEmail(query.value(1).toString()); + acc.setDisplayName(query.value(2).toString()); + acc.setType(static_cast(query.value(3).toInt())); + acc.setAccessToken(query.value(4).toString()); + acc.setRefreshToken(query.value(5).toString()); + acc.setTokenExpires(query.value(6).toDateTime()); + accounts.append(acc); + } + return accounts; +} + +std::optional AccountDao::findByEmail(const QString& email) +{ + QSqlDatabase& db = DatabaseManager::instance().database(); + QSqlQuery query(db); + query.prepare("SELECT id, email, displayName, type, accessToken, refreshToken, tokenExpires FROM Account WHERE email = :email"); + query.bindValue(":email", email); + + if (!query.exec()) { + qWarning() << "Failed to find account by email:" << query.lastError().text(); + return std::nullopt; + } + + if (query.next()) { + Account acc; + acc.setId(query.value(0).toInt()); + acc.setEmail(query.value(1).toString()); + acc.setDisplayName(query.value(2).toString()); + acc.setType(static_cast(query.value(3).toInt())); + acc.setAccessToken(query.value(4).toString()); + acc.setRefreshToken(query.value(5).toString()); + acc.setTokenExpires(query.value(6).toDateTime()); + return acc; + } + return std::nullopt; +} \ No newline at end of file diff --git a/src/db/dao/accountdao.h b/src/db/dao/accountdao.h new file mode 100644 index 0000000..4f3ae8d --- /dev/null +++ b/src/db/dao/accountdao.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../databasemanager.h" +#include "../../core/models/account.h" +#include +#include +#include +#include + +class AccountDao +{ +public: + static bool insert(const Account& account); + static bool update(const Account& account); + static bool remove(int id); + static Account* findById(int id); + static QVector findAll(); + static Account* findByEmail(const QString& email); +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 880bd0e..c332213 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,9 @@ #include #include #include "core/translator.h" +#include "db/databasemanager.h" +#include "core/models/account.h" +#include "core/models/folder.h" int main(int argc, char *argv[]) { @@ -15,5 +18,41 @@ int main(int argc, char *argv[]) qDebug() << translator.tr("appName"); qDebug() << translator.tr("welcomeMessage"); + // Initialize database + DatabaseManager& dbManager = DatabaseManager::instance(); + if (!dbManager.initialize()) { + qCritical() << "Failed to initialize database"; + return -1; + } + + // Test: Add an account + Account testAccount; + testAccount.setId(1); + testAccount.setEmail("test@example.com"); + testAccount.setDisplayName("Test User"); + testAccount.setType(AccountType::IMAP); + testAccount.setAccessToken("dummy_token"); + testAccount.setRefreshToken("dummy_refresh"); + testAccount.setTokenExpires(QDateTime::currentDateTimeUtc().addSecs(3600)); + + // In a real app, we would use a DAO to insert into the database. + // For now, we just log the account details. + qDebug() << "Created test account:" << testAccount.email() << testAccount.displayName(); + + // Test: Add a folder for the account + Folder testFolder; + testFolder.setId(1); + testFolder.setAccountId(testAccount.id()); + testFolder.setName("Inbox"); + testFolder.setInbox(true); + testFolder.setLastSynced(QDateTime::currentDateTime()); + + qDebug() << "Created test folder:" << testFolder.name() << "for account ID" << testFolder.accountId(); + + // Test: Create a mail item + MailItem testMail(1, "Test Subject", "sender@example.com", "recipient@example.com", + QDateTime::currentDateTime(), false, false, QStringList{"attachment1.txt"}); + qDebug() << "Created test mail:" << testMail.subject(); + return 0; } \ No newline at end of file