~aleteoryx/muditaos

78904a6b5d80ab55e1fbf2861ab3a905c96ae94d — Tomas Rogala 5 years ago 1e70bd1
[EGD-3307] Review changes
35 files changed, 662 insertions(+), 257 deletions(-)

M .idea/runConfigurations/JLink_server.xml
M .idea/runConfigurations/JLink_server__no_upload_.xml
M .idea/runConfigurations/PurePhone.xml
M CMakeLists.txt
M changelog.md
M doc/database_v2.md
M module-apps/DatabaseModel.hpp
M module-apps/application-calendar/ApplicationCalendar.cpp
M module-apps/application-calendar/models/CalendarEventsModel.cpp
M module-apps/application-calendar/models/DayEventsModel.cpp
M module-apps/application-calendar/models/DayEventsModel.hpp
M module-apps/application-calendar/widgets/DayEventsItem.cpp
M module-apps/application-calendar/windows/CalendarEventsOptionsWindow.cpp
M module-apps/application-calendar/windows/CalendarMainWindow.cpp
M module-apps/application-calendar/windows/CalendarMainWindow.hpp
M module-apps/application-calendar/windows/DayEventsWindow.cpp
M module-db/CMakeLists.txt
M module-db/Databases/EventsDB.cpp
M module-db/Databases/EventsDB.hpp
M module-db/Interface/EventsRecord.cpp
M module-db/Interface/EventsRecord.hpp
M module-db/Tables/EventsTable.cpp
M module-db/Tables/EventsTable.hpp
M module-db/queries/calendar/QueryEventsEdit.cpp
M module-db/queries/calendar/QueryEventsEdit.hpp
M module-db/queries/calendar/QueryEventsGetFiltered.hpp
M module-db/tests/CMakeLists.txt
A module-db/tests/EventsRecord_tests.cpp
M module-db/tests/EventsTable_tests.cpp
M module-db/tests/ThreadRecord_tests.cpp
M module-os/RTOSWrapper/include/thread.hpp
M module-services/service-db/CMakeLists.txt
M module-services/service-db/ServiceDB.cpp
D module-services/service-db/messages/DBEventsMessage.cpp
D module-services/service-db/messages/DBEventsMessage.hpp
M .idea/runConfigurations/JLink_server.xml => .idea/runConfigurations/JLink_server.xml +1 -1
@@ 1,5 1,5 @@
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="JLink server" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-if SWD -device MCIMXRT1051 -speed 25000 -jlinkscriptfile &quot;evkbimxrt1050_sdram_init.jlinkscript&quot; -strict -ir -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so" WORKING_DIR="file://$PROJECT_DIR$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
  <configuration default="false" name="JLink server" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-if SWD -device MCIMXRT1051 -speed 25000 -jlinkscriptfile &quot;evkbimxrt1050_sdram_init.jlinkscript&quot; -strict -ir -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so" WORKING_DIR="file://$PROJECT_DIR$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Linux" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
    <custom-gdb-server version="1" gdb-connect="localhost:2331" executable="JLinkGDBServerCLExe" warmup-ms="0" download-type="ALWAYS" reset-cmd="monitor reset 0" />
    <method v="2">
      <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />

M .idea/runConfigurations/JLink_server__no_upload_.xml => .idea/runConfigurations/JLink_server__no_upload_.xml +1 -1
@@ 1,5 1,5 @@
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="JLink server (no upload)" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-if SWD -device MCIMXRT1051 -speed 25000 -jlinkscriptfile &quot;evkbimxrt1050_sdram_init.jlinkscript&quot; -strict -ir -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so" WORKING_DIR="file://$PROJECT_DIR$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
  <configuration default="false" name="JLink server (no upload)" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-if SWD -device MCIMXRT1051 -speed 25000 -jlinkscriptfile &quot;evkbimxrt1050_sdram_init.jlinkscript&quot; -strict -ir -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so" WORKING_DIR="file://$PROJECT_DIR$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Linux" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
    <custom-gdb-server version="1" gdb-connect="localhost:2331" executable="JLinkGDBServerCLExe" warmup-ms="0" download-type="NONE" reset-cmd="monitor reset 0" />
    <method v="2" />
  </configuration>

M .idea/runConfigurations/PurePhone.xml => .idea/runConfigurations/PurePhone.xml +1 -1
@@ 1,5 1,5 @@
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="PurePhone" type="CMakeRunConfiguration" factoryName="Application" activateToolWindowBeforeRun="false" WORKING_DIR="file://$PROJECT_DIR$/build-linux" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
  <configuration default="false" name="PurePhone" type="CMakeRunConfiguration" factoryName="Application" activateToolWindowBeforeRun="false" WORKING_DIR="file://$PROJECT_DIR$/build-linux" PASS_PARENT_ENVS_2="true" PROJECT_NAME="PurePhone" TARGET_NAME="PurePhone" CONFIG_NAME="Linux" RUN_TARGET_PROJECT_NAME="PurePhone" RUN_TARGET_NAME="PurePhone">
    <method v="2">
      <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
    </method>

M CMakeLists.txt => CMakeLists.txt +0 -1
@@ 7,7 7,6 @@ project(PurePhone)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/config")

include(Target_Linux.cmake)
include(Colours)
include(CCacheConfig)
include(ProjectConfig)

M changelog.md => changelog.md +1 -1
@@ 5,6 5,7 @@
### Added

* `[torch]` Toggle torch colours for certification purposes (redish, blueish, off).
* `[calendar]` database structure

### Changed



@@ 79,7 80,6 @@
* `[calendar]` Added day window with list of events.
* `[calendar]` main screen UI
* `[calendar]` main screen navigation
* `[calendar]` database structure
* `[audio]` added incoming call ringtone
* `[phonebook]` general support for groups in DB
* `[phonebook]` proper displaying of favorites, ice, blocked flags

M doc/database_v2.md => doc/database_v2.md +14 -0
@@ 351,6 351,20 @@ By default sepecial gorups are created:
| group_id | (r) | INTEGER | Id of group. |
| contact_id | (r) | INTEGER | Id of contact. |

#### 17. Events table
Name: events

| ID | Title | Description |
| -------- | ----------- | ------- | -------------------|
| _id | (um) | INTEGER PRIMARY KEY | Unique number assigned to the event |
| title | (m) | TEXT | Event title provided by the user. |
| description | (m) | TEXT | Event description provided by the user. |
| date_from | (m) | INTEGER | Event start time provided by the user. |
| date_till | (m) | INTEGER | Event end time provided by the user. |
| reminder | (m) | INTEGER | Event reminder time provided by the user. |
| repeat | (m) | INTEGER | Event repeat option provided by the user. |
| time_zone | (m) | INTEGER | Event creation time zone imported from settings. Needed to calculate the offset of event while changing time zone |

## Database Triggers <a name="triggers"></a>

This trigger is responsible for taking action when new thread is created and inserted to threads table. As a result value of the count column with _id equal to 1 in the threads_count table is incremented by 1.

M module-apps/DatabaseModel.hpp => module-apps/DatabaseModel.hpp +0 -1
@@ 58,7 58,6 @@ namespace app
            auto index = modelIndex;

            if ((index < 0) || (index >= records.size())) {
                LOG_ERROR("Null pointer received from DB!!!!!!!!!!!!!!!!");
                return nullptr;
            }


M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +6 -26
@@ 17,7 17,6 @@
#include <module-db/queries/calendar/QueryEventsGetFiltered.hpp>
#include <module-services/service-db/messages/QueryMessage.hpp>
#include <messages/QueryMessage.hpp>
#include <messages/DBEventsMessage.hpp>

namespace app
{


@@ 31,37 30,18 @@ namespace app

    sys::Message_t ApplicationCalendar::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
    {

        auto retMsg = Application::DataReceivedHandler(msgl);
        // if message was handled by application's template there is no need to process further.
        if (reinterpret_cast<sys::ResponseMessage *>(retMsg.get())->retCode == sys::ReturnCodes::Success) {
            return retMsg;
        }

        // this variable defines whether message was processed.
        bool handled = false;

        // handle database response
        if (resp != nullptr) {
            handled = true;
            if (dynamic_cast<db::QueryResponse *>(resp)) {
                if (getCurrentWindow()->onDatabaseMessage(resp))
                    refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
            }
        }

        if (handled)
            return std::make_shared<sys::ResponseMessage>();
        else
            return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Unresolved);
        return Application::DataReceivedHandler(msgl);
    }

    sys::ReturnCodes ApplicationCalendar::InitHandler()
    {
        auto ret = Application::InitHandler();
        EventsRecord event(EventsTableRow{{1}, "tytfsfsful", "opsfsfis", 1910201424, 1910201536, 1, 2, 1});
        EventsRecord event(EventsTableRow{{1}, "TEST", "TEST", 191020142, 191020153, 1, 2, 1});
        EventsRecord event2(EventsTableRow{{2}, "TEST2", "TEST2", 191020152, 191020163, 1, 2, 1});
        DBServiceAPI::GetQuery(this, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(event));
        DBServiceAPI::GetQuery(this, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(event));
        DBServiceAPI::GetQuery(this, db::Interface::Name::Events, std::make_unique<db::query::events::GetAll>());
        DBServiceAPI::GetQuery(this, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(event2));
        DBServiceAPI::GetQuery(this, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(event2));
        createUserInterface();
        return ret;
    }

M module-apps/application-calendar/models/CalendarEventsModel.cpp => module-apps/application-calendar/models/CalendarEventsModel.cpp +7 -1
@@ 28,7 28,8 @@ gui::ListItem *CalendarEventsModel::getItem(gui::Order order)
        item->setEvent(record);
    }
    else {
        LOG_DEBUG("Empty record in EventsMODEL::GetItem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        LOG_DEBUG("Empty record in EventsModel::GetItem");
        return nullptr;
    }
    LOG_DEBUG("Created new item in calendar day listView");
    item->activatedCallback = [=](gui::Item &item) {


@@ 49,3 50,8 @@ bool CalendarEventsModel::updateRecords(std::unique_ptr<std::vector<EventsRecord

    return true;
}

void CalendarEventsModel::setRecordsCount(const uint32_t &count)
{
    recordsCount = count;
}

M module-apps/application-calendar/models/DayEventsModel.cpp => module-apps/application-calendar/models/DayEventsModel.cpp +27 -3
@@ 2,7 2,7 @@
#include "application-calendar/widgets/DayEventsItem.hpp"
#include <ListView.hpp>

DayEventsModel::DayEventsModel(app::Application *app)
DayEventsModel::DayEventsModel(app::Application *app) : DatabaseModel(app)
{
    application = app;
    assert(app != nullptr);


@@ 20,11 20,35 @@ unsigned int DayEventsModel::getMinimalItemHeight() const

gui::ListItem *DayEventsModel::getItem(gui::Order order)
{
    auto *item              = new gui::DayEventsItem();
    auto item = new gui::DayEventsItem();

    auto record = getRecord(order);
    if (record != nullptr) {
        item->setEvent(record);
    }
    else {
        LOG_DEBUG("Empty record in EventsModel::GetItem");
        return nullptr;
    }
    LOG_DEBUG("Created new item in calendar day listView");
    item->activatedCallback = [=](gui::Item &item) {
        LOG_INFO("Switch to options/delete window");
        application->switchWindow(style::window::calendar::name::details_window);
        application->switchWindow(style::window::calendar::name::events_options);
        return true;
    };
    return item;
}

bool DayEventsModel::updateRecords(std::unique_ptr<std::vector<EventsRecord>> records)
{
    DatabaseModel::updateRecords(std::move(records));
    modelIndex = 0;
    list->onProviderDataUpdate();

    return true;
}

void DayEventsModel::setRecordsCount(const uint32_t &count)
{
    recordsCount = count;
}

M module-apps/application-calendar/models/DayEventsModel.hpp => module-apps/application-calendar/models/DayEventsModel.hpp +5 -8
@@ 6,26 6,23 @@
#include <ListItemProvider.hpp>
#include <module-db/Interface/EventsRecord.hpp>

class DayEventsModel :  public app::DatabaseModel<EventsRecord>, public gui::ListItemProvider
class DayEventsModel : public app::DatabaseModel<EventsRecord>, public gui::ListItemProvider
{
    const int tempItemCount       = 5;
    app::Application *application = nullptr;

  public:
    DayEventsModel(app::Application *app);
    virtual ~DayEventsModel() override = default;
    auto updateRecords(std::unique_ptr<std::vector<EventsRecord>> records,
                       const uint32_t offset = 0,
                       const uint32_t limit  = 0,
                       uint32_t count        = 0) -> bool override;
    auto updateRecords(std::unique_ptr<std::vector<EventsRecord>> records) -> bool override;

    void requestRecords(const uint32_t offset, const uint32_t limit) override;
    void setRecordsCount(const uint32_t &count);

    // virtual methods for ListViewProvider
    [[nodiscard]] unsigned int getMinimalItemHeight() const override;
    gui::ListItem *getItem(gui::Order order) override;
    [[nodiscard]] unsigned int requestRecordsCount() override
    {
        return tempItemCount;
    };
        return recordsCount;
    }
};

M module-apps/application-calendar/widgets/DayEventsItem.cpp => module-apps/application-calendar/widgets/DayEventsItem.cpp +1 -1
@@ 28,7 28,7 @@ namespace gui
        description->setAlignment(gui::Alignment{gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center});
    }

    void CalendarItem::setEvent(std::shared_ptr<EventsRecord> rec)
    void DayEventsItem::setEvent(std::shared_ptr<EventsRecord> rec)
    {
        this->record = rec;


M module-apps/application-calendar/windows/CalendarEventsOptionsWindow.cpp => module-apps/application-calendar/windows/CalendarEventsOptionsWindow.cpp +5 -0
@@ 2,6 2,8 @@
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "Dialog.hpp"
#include <Utils.hpp>
#include <module-services/service-db/api/DBServiceAPI.hpp>
#include <module-db/queries/calendar/QueryEventsRemove.hpp>

namespace gui
{


@@ 34,6 36,9 @@ namespace gui
        auto meta   = dialog->meta;
        meta.action = [=]() -> bool {
            LOG_INFO("Detele calendar event");
            uint32_t mockID = 2;
            DBServiceAPI::GetQuery(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::Remove>(mockID));
            return true;
        };
        meta.text  = utils::localize.get("app_calendar_event_delete_confirmation");

M module-apps/application-calendar/windows/CalendarMainWindow.cpp => module-apps/application-calendar/windows/CalendarMainWindow.cpp +1 -19
@@ 92,7 92,7 @@ namespace gui
        LOG_DEBUG("MonthBox constructor Completed Successfully!");
    }

    void MonthBox::buildMap(app::Application *app)
    void MonthBox::buildMap(app::ApplicationCalendar *app)
    {
        LOG_DEBUG("Start build month box map");
        for (auto &day : days) {


@@ 104,11 104,6 @@ namespace gui

                dayMap[key]->setLabel(day.number.c_str(), [=](gui::Item &item) {
                    LOG_DEBUG("Switch to DayEventsWindow");
                    uint32_t date_from = 0;
                    uint32_t date_till = 3099999999;
                    DBServiceAPI::GetQuery(app,
                                           db::Interface::Name::Events,
                                           std::make_unique<db::query::events::GetFiltered>(date_from, date_till));
                    app->switchWindow("DayEventsWindow", nullptr);
                    return true;
                });


@@ 331,19 326,6 @@ namespace gui
        erase();
    }

    bool CalendarMainWindow::onDatabaseMessage(sys::Message *msgl)
    {
        auto msg = dynamic_cast<db::QueryResponse *>(msgl);
        if (auto response = dynamic_cast<db::query::events::GetAllResult *>(msg->getResult())) {
            auto records = response->getResult();
            for (auto &rec : *records) {
                LOG_DEBUG("RESP!!!!!!: %s", rec.title.c_str());
            }
            return true;
        }
        return false;
    }

    bool CalendarMainWindow::onInput(const gui::InputEvent &inputEvent)
    {
        if (AppWindow::onInput(inputEvent)) {

M module-apps/application-calendar/windows/CalendarMainWindow.hpp => module-apps/application-calendar/windows/CalendarMainWindow.hpp +1 -1
@@ 58,7 58,7 @@ namespace gui

        ~MonthBox() override = default;

        void buildMap(app::Application *app);
        void buildMap(app::ApplicationCalendar *app);
    };

    class CalendarMainWindow : public gui::AppWindow

M module-apps/application-calendar/windows/DayEventsWindow.cpp => module-apps/application-calendar/windows/DayEventsWindow.cpp +24 -8
@@ 9,8 9,10 @@

#include <time/time_conversion.hpp>
#include <module-services/service-db/messages/QueryMessage.hpp>
#include <module-db/queries/calendar/QueryEventsGetAll.hpp>
#include <module-db/queries/calendar/QueryEventsGetFiltered.hpp>
#include <module-db/queries/calendar/QueryEventsGetAll.hpp>
#include <module-services/service-db/api/DBServiceAPI.hpp>
#include <module-apps/application-calendar/ApplicationCalendar.hpp>

namespace gui
{


@@ 67,23 69,37 @@ namespace gui
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_LEFT) {
            LOG_DEBUG("TODO: Switch to new window - edit window");
            LOG_DEBUG("Switch to new window - edit window");
            auto msg = DBServiceAPI::GetQueryWithReply(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::GetAll>(), 1000);

            LOG_DEBUG("Type id %s", typeid(*msg.second).name());
            auto msgl = msg.second.get();
            assert(msgl != nullptr);
            onDatabaseMessage(msgl);
            return true;
        }

        return false;
    }

    bool DayEventsWindow::onDatabaseMessage(sys::Message *msgl)
    {
        auto msg = dynamic_cast<db::QueryResponse *>(msgl);
        if (auto response = dynamic_cast<db::query::events::GetFilteredResult *>(msg->getResult())) {
            auto records = response->getResult();
            for (auto &rec : *records) {
                LOG_DEBUG("RESP!!!!!!: %s", rec.title.c_str());
        if (msg != nullptr) {
            auto temp = msg->getResult();
            if (auto response = dynamic_cast<db::query::events::GetAllResult *>(temp.get())) {
                unique_ptr<vector<EventsRecord>> records = response->getResult();
                for (auto &rec : *records) {
                    LOG_DEBUG("record: %s", rec.title.c_str());
                }
                uint32_t numberOfItems = records->size();
                dayEventsModel->setRecordsCount(numberOfItems);
                return dayEventsModel->updateRecords(std::move(records));
            }
            return calendarEventsModel->updateRecords(std::move(records));
            LOG_DEBUG("Response False");
            return false;
        }
        LOG_DEBUG("DayWindow DB Message != QueryResponse");
        return false;
    }
} /* namespace gui */

M module-db/CMakeLists.txt => module-db/CMakeLists.txt +3 -2
@@ 72,8 72,9 @@ set(SOURCES
        queries/calendar/QueryEventsGetAll.cpp
        queries/calendar/QueryEventsAdd.cpp
        queries/calendar/QueryEventsEdit.cpp

        queries/calendar/QueryEventsGetFiltered.hpp queries/calendar/QueryEventsGetFiltered.cpp tests/EventsTable_tests.cpp)
        queries/calendar/QueryEventsGetFiltered.hpp
        queries/calendar/QueryEventsGetFiltered.cpp
        )

if(NOT ${PROJECT_TARGET} STREQUAL "TARGET_Linux")
    include(targets/Target_Cross.cmake)

M module-db/Databases/EventsDB.cpp => module-db/Databases/EventsDB.cpp +2 -1
@@ 6,7 6,8 @@ const char *EventsDB::dbName = USER_PATH("events.db");

EventsDB::EventsDB() : Database(dbName), events(this)
{
    if (events.create() == false)
    if (events.create() == false) {
        return;
    }
    isInitialized_ = true;
}

M module-db/Databases/EventsDB.hpp => module-db/Databases/EventsDB.hpp +1 -1
@@ 7,7 7,7 @@ class EventsDB : public Database
{
  public:
    EventsDB();
    virtual ~EventsDB() = default;
    ~EventsDB() override = default;

    EventsTable events;


M module-db/Interface/EventsRecord.cpp => module-db/Interface/EventsRecord.cpp +17 -12
@@ 73,10 73,11 @@ std::unique_ptr<std::vector<EventsRecord>> EventsRecordInterface::GetLimitOffset
    return records;
}

bool EventsRecordInterface::Update(const EventsRecord &rec)
bool EventsRecordInterface::Update(const EventsRecord &rec, const uint32_t &checkValue)
{
    auto entry = eventsDb->events.getById(rec.ID);
    if (!entry.isValid() || entry.date_from != static_cast<uint32_t>(rec.date_from)) {
    if (!entry.isValid() || entry.date_from != checkValue) {
        LOG_DEBUG("IS NOT VALID");
        return false;
    }



@@ 113,26 114,30 @@ uint32_t EventsRecordInterface::GetCount()
    return eventsDb->events.count();
}

std::unique_ptr<db::QueryResult> EventsRecordInterface::runQuery(const db::Query *query)
std::unique_ptr<db::QueryResult> EventsRecordInterface::runQuery(std::shared_ptr<db::Query> query)
{

    if (const auto local_query = dynamic_cast<const db::query::events::Get *>(query)) {
    if (typeid(*query) == typeid(db::query::events::Get)) {
        const auto local_query = dynamic_cast<const db::query::events::Get *>(query.get());
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::events::GetAll *>(query)) {
    if (typeid(*query) == typeid(db::query::events::GetAll)) {
        const auto local_query = dynamic_cast<const db::query::events::GetAll *>(query.get());
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::events::GetFiltered *>(query)) {
    if (typeid(*query) == typeid(db::query::events::GetFiltered)) {
        const auto local_query = dynamic_cast<const db::query::events::GetFiltered *>(query.get());
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::events::Add *>(query)) {
    if (typeid(*query) == typeid(db::query::events::Add)) {
        const auto local_query = dynamic_cast<const db::query::events::Add *>(query.get());
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::events::Remove *>(query)) {
    if (typeid(*query) == typeid(db::query::events::Remove)) {
        const auto local_query = dynamic_cast<const db::query::events::Remove *>(query.get());
        return runQueryImpl(local_query);
    }

    if (const auto local_query = dynamic_cast<const db::query::events::Edit *>(query)) {
    if (typeid(*query) == typeid(db::query::events::Edit)) {
        const auto local_query = dynamic_cast<const db::query::events::Edit *>(query.get());
        return runQueryImpl(local_query);
    }
    return nullptr;


@@ 174,6 179,6 @@ std::unique_ptr<db::query::events::RemoveResult> EventsRecordInterface::runQuery

std::unique_ptr<db::query::events::EditResult> EventsRecordInterface::runQueryImpl(const db::query::events::Edit *query)
{
    bool ret = Update(query->getRecord());
    bool ret = Update(query->getRecord(), query->getDateFrom());
    return std::make_unique<db::query::events::EditResult>(ret);
}

M module-db/Interface/EventsRecord.hpp => module-db/Interface/EventsRecord.hpp +3 -3
@@ 55,12 55,12 @@ class EventsRecordInterface : public RecordInterface<EventsRecord, EventsRecordF
{
  public:
    EventsRecordInterface(EventsDB *eventsDb);
    virtual ~EventsRecordInterface() = default;
    ~EventsRecordInterface() override = default;

    bool Add(const EventsRecord &rec) override final;
    bool RemoveByID(uint32_t id) override final;
    bool RemoveByField(EventsRecordField field, const char *str) override final;
    bool Update(const EventsRecord &rec) override final;
    bool Update(const EventsRecord &rec, const uint32_t &dateFromCheckVal);
    EventsRecord GetByID(uint32_t id) override final;
    uint32_t GetCount() override final;
    std::unique_ptr<std::vector<EventsRecord>> Select(uint32_t from, uint32_t till);


@@ 70,7 70,7 @@ class EventsRecordInterface : public RecordInterface<EventsRecord, EventsRecordF
                                                                     EventsRecordField field,
                                                                     const char *str) override final;

    std::unique_ptr<db::QueryResult> runQuery(const db::Query *query) override;
    std::unique_ptr<db::QueryResult> runQuery(std::shared_ptr<db::Query> query) override;

  private:
    EventsDB *eventsDb = nullptr;

M module-db/Tables/EventsTable.cpp => module-db/Tables/EventsTable.cpp +6 -6
@@ 34,7 34,7 @@ bool EventsTable::add(EventsTableRow entry)

bool EventsTable::removeById(uint32_t id)
{
    return db->execute("DELETE FROM events where _id = %lu;", id);
    return db->execute("DELETE FROM events where _id = %u;", id);
}

bool EventsTable::removeByField(EventsTableFields field, const char *str)


@@ 57,8 57,8 @@ bool EventsTable::removeByField(EventsTableFields field, const char *str)

bool EventsTable::update(EventsTableRow entry)
{
    return db->execute("UPDATE events SET title= %'q', description = %'q', date_from = %lu, date_till = %lu, reminder "
                       "= %lu, repeat = %lu, time_zone = %lu WHERE _id = %lu;",
    return db->execute("UPDATE events SET title= '%q', description = '%q', date_from = %u, date_till = %u, reminder "
                       "= %u, repeat = %u, time_zone = %u WHERE _id = %u;",
                       entry.title.c_str(),
                       entry.description.c_str(),
                       entry.date_from,


@@ 87,7 87,7 @@ EventsTableRow EventsTable::getById(uint32_t id)
        (*retQuery)[4].getUInt32(), // date_till
        (*retQuery)[5].getUInt32(), // reminder
        (*retQuery)[6].getUInt32(), // repeat
        (*retQuery)[6].getUInt32()  // time_zone
        (*retQuery)[7].getUInt32()  // time_zone

    };
}


@@ 111,7 111,7 @@ std::vector<EventsTableRow> EventsTable::selectByDatePeriod(uint32_t date_from, 
            (*retQuery)[4].getUInt32(), // date_till
            (*retQuery)[5].getUInt32(), // reminder
            (*retQuery)[6].getUInt32(), // repeat
            (*retQuery)[6].getUInt32()  // time_zone
            (*retQuery)[7].getUInt32()  // time_zone
        });
    } while (retQuery->nextRow());



@@ 138,7 138,7 @@ std::vector<EventsTableRow> EventsTable::getLimitOffset(uint32_t offset, uint32_
            (*retQuery)[4].getUInt32(), // date_till
            (*retQuery)[5].getUInt32(), // reminder
            (*retQuery)[6].getUInt32(), // repeat
            (*retQuery)[6].getUInt32()  // time_zone
            (*retQuery)[7].getUInt32()  // time_zone
        });
    } while (retQuery->nextRow());


M module-db/Tables/EventsTable.hpp => module-db/Tables/EventsTable.hpp +4 -6
@@ 2,9 2,9 @@

#include "Table.hpp"
#include "Record.hpp"
#include "Database/Database.hpp"
#include "utf8/UTF8.hpp"
#include "Common/Common.hpp"
#include <Database/Database.hpp>
#include <Common/Common.hpp>
#include <utf8/UTF8.hpp>

struct EventsTableRow : public Record
{


@@ 27,7 27,7 @@ class EventsTable : public Table<EventsTableRow, EventsTableFields>
{
  public:
    EventsTable(Database *db);
    virtual ~EventsTable() = default;
    ~EventsTable() override = default;

    bool create() override final;
    bool add(EventsTableRow entry) override final;


@@ 39,8 39,6 @@ class EventsTable : public Table<EventsTableRow, EventsTableFields>
    uint32_t count() override final;
    uint32_t countByFieldId(const char *field, uint32_t id) override final;
    std::vector<EventsTableRow> getLimitOffset(uint32_t offset, uint32_t limit) override final;
    ///@param offset: (start index of record)
    ///@param limit: (end index of record)
    std::vector<EventsTableRow> getLimitOffsetByField(uint32_t offset,
                                                      uint32_t limit,
                                                      EventsTableFields field,

M module-db/queries/calendar/QueryEventsEdit.cpp => module-db/queries/calendar/QueryEventsEdit.cpp +8 -2
@@ 2,7 2,8 @@

namespace db::query::events
{
    Edit::Edit(EventsRecord record) : Query(Query::Type::Update), record(record)
    Edit::Edit(EventsRecord record, const uint32_t &dateFrom)
        : Query(Query::Type::Update), record(record), dateFrom(dateFrom)
    {}

    auto Edit::getRecord() const -> EventsRecord


@@ 10,6 11,11 @@ namespace db::query::events
        return record;
    }

    auto Edit::getDateFrom() const -> uint32_t
    {
        return dateFrom;
    }

    auto Edit::debugInfo() const -> std::string
    {
        return "Edit";


@@ 27,4 33,4 @@ namespace db::query::events
    {
        return "EditResult";
    }
} // namespace db::query::events
\ No newline at end of file
} // namespace db::query::events

M module-db/queries/calendar/QueryEventsEdit.hpp => module-db/queries/calendar/QueryEventsEdit.hpp +4 -1
@@ 9,10 9,13 @@ namespace db::query::events
    class Edit : public Query
    {
        EventsRecord record;
        /// Check value
        uint32_t dateFrom;

      public:
        Edit(EventsRecord record);
        Edit(EventsRecord record, const uint32_t &dateFrom);

        [[nodiscard]] auto getDateFrom() const -> uint32_t;
        [[nodiscard]] auto getRecord() const -> EventsRecord;
        [[nodiscard]] auto debugInfo() const -> std::string override;
    };

M module-db/queries/calendar/QueryEventsGetFiltered.hpp => module-db/queries/calendar/QueryEventsGetFiltered.hpp +1 -1
@@ 27,4 27,4 @@ namespace db::query::events
        [[nodiscard]] auto debugInfo() const -> std::string override;
    };

} // namespace db::query::events
\ No newline at end of file
} // namespace db::query::events

M module-db/tests/CMakeLists.txt => module-db/tests/CMakeLists.txt +3 -0
@@ 21,6 21,7 @@ add_catch2_executable(
        "${CMAKE_CURRENT_SOURCE_DIR}/SMSTemplateTable_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/CalllogTable_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/NotificationsTable_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/EventsTable_tests.cpp"

        "${CMAKE_CURRENT_SOURCE_DIR}/CalllogRecord_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/ContactsRecord_tests.cpp"


@@ 30,7 31,9 @@ add_catch2_executable(
        "${CMAKE_CURRENT_SOURCE_DIR}/AlarmsRecord_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/SMSTemplateRecord_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/NotificationsRecord_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/EventsRecord_tests.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/QueryInterface.cpp"

        
    LIBS
        module-db

A module-db/tests/EventsRecord_tests.cpp => module-db/tests/EventsRecord_tests.cpp +336 -0
@@ 0,0 1,336 @@
#include <catch2/catch.hpp>

#include "Interface/EventsRecord.hpp"
#include "Database/Database.hpp"
#include "Databases/EventsDB.hpp"
#include "module-db/queries/calendar/QueryEventsGet.hpp"
#include "module-db/queries/calendar/QueryEventsGetAll.hpp"
#include "module-db/queries/calendar/QueryEventsGetFiltered.hpp"
#include "module-db/queries/calendar/QueryEventsAdd.hpp"
#include "module-db/queries/calendar/QueryEventsRemove.hpp"
#include "module-db/queries/calendar/QueryEventsEdit.hpp"

#include <vfs.hpp>

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

TEST_CASE("Events Record tests")
{
    Database::initialize();

    vfs.remove(EventsDB::GetDBName());

    EventsDB eventsDb;

    REQUIRE(eventsDb.isInitialized());

    SECTION("Default Constructor")
    {
        EventsRecord testRec;
        REQUIRE(testRec.title == "");
        REQUIRE(testRec.description == "");
        REQUIRE(testRec.date_from == 0);
        REQUIRE(testRec.date_till == 0);
        REQUIRE(testRec.reminder == 0);
        REQUIRE(testRec.repeat == 0);
        REQUIRE(testRec.time_zone == 0);
    }

    SECTION("Constructor from EventsTableRow")
    {
        EventsTableRow tableRow{{.ID = 10}, "Event3", "Desc3", 1910201424, 1910201536, 1, 2, 1};
        EventsRecord testRec(tableRow);
        REQUIRE(testRec.title == "Event3");
        REQUIRE(testRec.description == "Desc3");
        REQUIRE(testRec.date_from == 1910201424);
        REQUIRE(testRec.date_till == 1910201536);
        REQUIRE(testRec.reminder == 1);
        REQUIRE(testRec.repeat == 2);
        REQUIRE(testRec.time_zone == 1);
        REQUIRE(testRec.isValid());
    }

    EventsRecord testRec;
    EventsRecordInterface eventsRecordInterface(&eventsDb);

    auto numberOfEvents = eventsRecordInterface.GetCount();
    REQUIRE(numberOfEvents == 0);

    EventsTableRow tableRow{{.ID = 10}, "Event1", "Desc1", 1910201424, 1910201536, 1, 2, 1};
    auto rec = EventsRecord(tableRow);
    REQUIRE(rec.title == "Event1");
    REQUIRE(rec.description == "Desc1");
    REQUIRE(rec.date_from == 1910201424);
    REQUIRE(rec.date_till == 1910201536);
    REQUIRE(rec.reminder == 1);
    REQUIRE(rec.repeat == 2);
    REQUIRE(rec.time_zone == 1);
    REQUIRE(rec.isValid());

    REQUIRE(eventsRecordInterface.Add(rec));

    numberOfEvents = eventsRecordInterface.GetCount();
    REQUIRE(numberOfEvents == 1);

    SECTION("Get entry by ID")
    {
        auto entry = eventsRecordInterface.GetByID(1);
        REQUIRE(entry.ID == 1);
        REQUIRE(entry.title == "Event1");
        REQUIRE(entry.description == "Desc1");
        REQUIRE(entry.date_from == 1910201424);
        REQUIRE(entry.date_till == 1910201536);
        REQUIRE(entry.reminder == 1);
        REQUIRE(entry.repeat == 2);
        REQUIRE(entry.time_zone == 1);
        REQUIRE(entry.isValid());
    }

    SECTION("Get entry - invalid ID")
    {
        auto entry = eventsRecordInterface.GetByID(100);
        REQUIRE(entry.ID == DB_ID_NONE);
        REQUIRE(entry.title == "");
        REQUIRE(entry.description == "");
        REQUIRE(entry.date_from == 0);
        REQUIRE(entry.date_till == 0);
        REQUIRE(entry.reminder == 0);
        REQUIRE(entry.repeat == 0);
        REQUIRE(entry.time_zone == 0);
        REQUIRE_FALSE(entry.isValid());
    }

    EventsTableRow tableRow2{{.ID = 10}, "Event2", "Desc2", 2510201424, 2510201536, 1, 2, 1};
    auto rec2 = EventsRecord(tableRow2);
    REQUIRE(rec2.title == "Event2");
    REQUIRE(rec2.description == "Desc2");
    REQUIRE(rec2.date_from == 2510201424);
    REQUIRE(rec2.date_till == 2510201536);
    REQUIRE(rec2.reminder == 1);
    REQUIRE(rec2.repeat == 2);
    REQUIRE(rec2.time_zone == 1);
    REQUIRE(rec2.isValid());

    REQUIRE(eventsRecordInterface.Add(rec2));

    numberOfEvents = eventsRecordInterface.GetCount();
    REQUIRE(numberOfEvents == 2);

    SECTION("Get entries")
    {

        SECTION("Get records using valid offset/limit parameters")
        {
            auto retOffsetLimit = eventsRecordInterface.GetLimitOffset(0, numberOfEvents);
            REQUIRE(retOffsetLimit->size() == numberOfEvents);
        }

        SECTION("Get table rows using bigger limit parameters")
        {
            auto retOffsetLimit = eventsRecordInterface.GetLimitOffset(0, 100);
            REQUIRE(retOffsetLimit->size() == numberOfEvents);
        }

        SECTION("Get table rows using invalid offset/limit parameters(should return empty object)")
        {
            auto retOffsetLimit = eventsRecordInterface.GetLimitOffset(5, 4);
            REQUIRE(retOffsetLimit->size() == 0);
        }

        SECTION("0 - get all")
        {
            auto retOffsetLimit = eventsRecordInterface.GetLimitOffset(0, 0);
            REQUIRE(retOffsetLimit->size() == numberOfEvents);
        }

        SECTION("Get table rows by SELECT")
        {
            auto retOffsetLimit = eventsRecordInterface.Select(1810201424, 1911201536);
            REQUIRE(retOffsetLimit->size() == 1);
            auto entry = retOffsetLimit->back();
            REQUIRE(entry.ID == 1);
            REQUIRE(entry.title == "Event1");
            REQUIRE(entry.description == "Desc1");
            REQUIRE(entry.date_from == 1910201424);
            REQUIRE(entry.date_till == 1910201536);
            REQUIRE(entry.reminder == 1);
            REQUIRE(entry.repeat == 2);
            REQUIRE(entry.time_zone == 1);
            REQUIRE(entry.isValid());
        }
    }

    SECTION("Entry update value")
    {
        auto entryPre        = eventsRecordInterface.GetByID(1);
        auto checkV          = entryPre.date_from;
        entryPre.title       = "newTitle";
        entryPre.description = "newDesc";
        entryPre.date_from   = 1999999999;
        entryPre.date_till   = 1999999999;
        LOG_DEBUG("LOG ON!!!!!!!!!!!!!!!!!!");
        REQUIRE(eventsRecordInterface.Update(entryPre, checkV));

        auto entry = eventsRecordInterface.GetByID(1);
        REQUIRE(entry.ID == entryPre.ID);
        REQUIRE(entry.title == entryPre.title);
        REQUIRE(entry.description == entryPre.description);
        REQUIRE(entry.date_from == entryPre.date_from);
        REQUIRE(entry.date_till == entryPre.date_till);
        REQUIRE(entry.reminder == entryPre.reminder);
        REQUIRE(entry.repeat == entryPre.repeat);
        REQUIRE(entry.time_zone == entryPre.time_zone);
    }

    EventsTableRow tableRow3{{.ID = 3}, "Event3", "Desc3", 2110201424, 2110201536, 1, 2, 1};
    auto rec3 = EventsRecord(tableRow3);
    REQUIRE(rec3.title == "Event3");
    REQUIRE(rec3.description == "Desc3");
    REQUIRE(rec3.date_from == 2110201424);
    REQUIRE(rec3.date_till == 2110201536);
    REQUIRE(rec3.reminder == 1);
    REQUIRE(rec3.repeat == 2);
    REQUIRE(rec3.time_zone == 1);
    REQUIRE(rec3.isValid());

    REQUIRE(eventsRecordInterface.Add(rec3));

    numberOfEvents = eventsRecordInterface.GetCount();
    REQUIRE(numberOfEvents == 3);

    auto getQuery =
        [&](uint32_t id, std::string title, std::string description, uint32_t date_from, uint32_t date_till) {
            auto query  = std::make_shared<db::query::events::Get>(id);
            auto ret    = eventsRecordInterface.runQuery(query);
            auto result = dynamic_cast<db::query::events::GetResult *>(ret.get());
            REQUIRE(result != nullptr);
            auto record = result->getResult();
            REQUIRE(record.isValid());
            REQUIRE(record.title == title);
            REQUIRE(record.description == description);
            REQUIRE(record.date_from == date_from);
            REQUIRE(record.date_till == date_till);

            return record.date_from;
        };

    auto getFiltered = [&](uint32_t id,
                           std::string title,
                           std::string description,
                           uint32_t date_from,
                           uint32_t date_till,
                           uint32_t filter_from,
                           uint32_t filter_till) {
        auto query  = std::make_shared<db::query::events::GetFiltered>(filter_from, filter_till);
        auto ret    = eventsRecordInterface.runQuery(query);
        auto result = dynamic_cast<db::query::events::GetFilteredResult *>(ret.get());
        REQUIRE(result != nullptr);
        auto records = result->getResult();
        auto record  = records->back();
        REQUIRE(record.isValid());
        REQUIRE(record.title == title);
        REQUIRE(record.description == description);
        REQUIRE(record.date_from == date_from);
        REQUIRE(record.date_till == date_till);
    };

    auto AddQuery =
        [&](uint32_t id, std::string title, std::string description, uint32_t date_from, uint32_t date_till) {
            EventsTableRow tableRow2{{.ID = id}, title, description, date_from, date_till, 1, 2, 1};
            auto record = EventsRecord(tableRow2);
            auto query  = std::make_shared<db::query::events::Add>(record);
            auto ret    = eventsRecordInterface.runQuery(query);
            auto result = dynamic_cast<db::query::events::AddResult *>(ret.get());
            REQUIRE(result != nullptr);
            REQUIRE(result->getResult());
        };

    auto RemoveQuery = [&](uint32_t id) {
        auto query  = std::make_shared<db::query::events::Remove>(id);
        auto ret    = eventsRecordInterface.runQuery(query);
        auto result = dynamic_cast<db::query::events::RemoveResult *>(ret.get());
        REQUIRE(result != nullptr);
        REQUIRE(result->getResult());
    };

    auto EditQuery = [&](uint32_t id,
                         std::string title,
                         std::string description,
                         uint32_t date_from,
                         uint32_t date_till,
                         uint32_t reminder,
                         uint32_t repeat,
                         uint32_t time_zone,
                         uint32_t checkV) {
        EventsTableRow tableRow2{{.ID = id}, title, description, date_from, date_till, reminder, repeat, time_zone};
        auto record = EventsRecord(tableRow2);
        auto query  = std::make_shared<db::query::events::Edit>(record, checkV);
        auto ret    = eventsRecordInterface.runQuery(query);
        auto result = dynamic_cast<db::query::events::EditResult *>(ret.get());
        REQUIRE(result != nullptr);
        REQUIRE(result->getResult());

        auto queryGet  = std::make_shared<db::query::events::Get>(id);
        auto retGet    = eventsRecordInterface.runQuery(queryGet);
        auto resultGet = dynamic_cast<db::query::events::GetResult *>(retGet.get());
        REQUIRE(result != nullptr);
        auto recordGet = resultGet->getResult();
        REQUIRE(recordGet.isValid());
        REQUIRE(recordGet.title == title);
        REQUIRE(recordGet.description == description);
        REQUIRE(recordGet.date_from == date_from);
        REQUIRE(recordGet.date_till == date_till);
        REQUIRE(recordGet.reminder == reminder);
        REQUIRE(recordGet.repeat == repeat);
        REQUIRE(recordGet.time_zone == time_zone);
    };

    SECTION("Get via query")
    {
        getQuery(3, "Event3", "Desc3", 2110201424, 2110201536);
    }

    SECTION("GetFiltered via query")
    {
        getFiltered(1, "Event1", "Desc1", 1910201424, 1910201536, 1810201424, 1912201536);
    }

    SECTION("Add via query")
    {
        AddQuery(3, "Event3", "Desc3", 2610201424, 2210201536);
        getQuery(4, "Event3", "Desc3", 2610201424, 2210201536);
    }

    SECTION("Remove via query")
    {
        RemoveQuery(2);
        auto query  = std::make_shared<db::query::events::GetAll>();
        auto ret    = eventsRecordInterface.runQuery(query);
        auto result = dynamic_cast<db::query::events::GetAllResult *>(ret.get());
        REQUIRE(result != nullptr);
        auto records = result->getResult();
        REQUIRE(records->size() == 3);
    }

    SECTION("Update via query")
    {
        uint32_t checkV = getQuery(2, "Event2", "Desc2", 2510201424, 2510201536);
        EditQuery(2, "Event3", "Desc2", 2110201424, 2110201536, 1, 2, 2, checkV);
    }

    SECTION("Get All via query")
    {
        auto query  = std::make_shared<db::query::events::GetAll>();
        auto ret    = eventsRecordInterface.runQuery(query);
        auto result = dynamic_cast<db::query::events::GetAllResult *>(ret.get());
        REQUIRE(result != nullptr);
        auto records = result->getResult();
        REQUIRE(records->size() == 3);
    }

    Database::deinitialize();
}

M module-db/tests/EventsTable_tests.cpp => module-db/tests/EventsTable_tests.cpp +173 -113
@@ 1,113 1,173 @@
//
// Created by tomasz on 23.07.2020.
//

//#include "vfs.hpp"
//
//#include <catch2/catch.hpp>
//
//#include "Database/Database.hpp"
//#include "Databases/EventsDB.hpp"
//
//#include "Tables/SettingsTable.hpp"
//
//#include <algorithm>
//
//#include <cstdint>
//#include <cstdio>
//#include <cstring>
//
// TEST_CASE("Events Table tests")
//{
//    Database::initialize();
//
//    vfs.remove(EventsDB::GetDBName());
//
//    EventsDB eventsdb;
//    REQUIRE(eventsdb.isInitialized());
//
//    EventsTableRow testRow1 = {
//        {.ID = 0},
//        .title "tytul",
//        .description = "opis",
//        .date_from   = 2007242323,
//        .date_till   = 2007262323,
//        .reminder    = 0,
//        .repeat      = 0,
//        .time_zone   = 0,
//
//    };
//
//    // add 5 elements into table
//    REQUIRE(eventsdb.events.add(testRow1));
//    REQUIRE(eventsdb.events.add(testRow1));
//    REQUIRE(eventsdb.events.add(testRow1));
//    REQUIRE(eventsdb.events.add(testRow1));
//    REQUIRE(eventsdb.events.add(testRow1));
//
//    // Table should have 5 elements
//    REQUIRE(eventsdb.events.count() == 5);
//
//    // update existing element in table
//    testRow1.ID    = 5;
//    testRow1.title = "updated Test Events message ";
//    REQUIRE(eventsdb.events.update(testRow1));
//
//    // Get table row using valid ID & check if it was updated
//    auto events = eventsdb.events.getById(5);
//    REQUIRE(events.title == testRow1.title);
//
//    // Get table row using invalid ID(should return empty eventsdb.eventsRow)
//    auto eventsFailed = eventsdb.events.getById(100);
//    REQUIRE(eventsFailed.title == "");
//
//    // Get table row using invalid ID(should return empty eventsdb.eventsRow)
//    auto eventsFailed = eventsdb.events.getById(-1);
//    REQUIRE(eventsFailed.title == "");
//
//    // Get table rows using valid offset/limit parameters
//    auto retOffsetLimit = eventsdb.events.getLimitOffset(0, 5);
//    REQUIRE(retOffsetLimit.size() == 5);
//
//    // Get table rows using valid offset/limit parameters and specific field's ID
//    REQUIRE(eventsdb.events.getLimitOffsetByField(0, 4, EventsTableFields::Date, "0").size() == 4);
//
//    // Get table rows using invalid limit parameters(should return 4 elements instead of 100)
//    auto retOffsetLimitBigger = eventsdb.events.getLimitOffset(0, 100);
//    REQUIRE(retOffsetLimitBigger.size() == 4);
//
//    // Get table rows using invalid offset/limit parameters(should return empty object)
//    auto retOffsetLimitFailed = eventsdb.events.getLimitOffset(5, 4);
//    REQUIRE(retOffsetLimitFailed.size() == 0);
//
//    REQUIRE(eventsdb.events.removeById(2));
//
//    // All records should fit in this date time period
//    auto retFiltered = selectByDatePeriod(2007242323, 2401251353);
//    REQUIRE(retOffsetLimitBigger.size() == 4);
//
//    // Should return empty vector
//    auto retFiltered = selectByDatePeriod(2007242323, 2401251353);
//    REQUIRE(retOffsetLimitBigger.size() == 0);
//
//    // Table should have now 4 elements
//    REQUIRE(eventsdb.events.count() == 4);
//
//    // Get table row using invalid ID(should return empty eventsdb.eventsRow)
//    auto eventsFailed = eventsdb.events.getById(5);
//    REQUIRE(eventsFailed.title == "");
//
//    // Remove non existing element
//    REQUIRE(eventsdb.events.removeById(100));
//
//    // Remove all elements from table
//    REQUIRE(eventsdb.events.removeById(1));
//    REQUIRE(eventsdb.events.removeById(3));
//    REQUIRE(eventsdb.events.removeById(4));
//    REQUIRE(eventsdb.events.removeById(5));
//
//    // Table should be empty now
//    REQUIRE(eventsdb.events.count() == 0);
//
//    Database::deinitialize();
//}
\ No newline at end of file
#include <catch2/catch.hpp>

#include "Database/Database.hpp"
#include "Databases/EventsDB.hpp"

#include "Tables/EventsTable.hpp"

#include <vfs.hpp>
#include <stdint.h>
#include <string>
#include <algorithm>
#include <iostream>

TEST_CASE("Events Table tests")
{
    Database::initialize();

    vfs.remove(EventsDB::GetDBName());

    EventsDB eventsDb;
    REQUIRE(eventsDb.isInitialized());

    auto &eventsTbl = eventsDb.events;
    REQUIRE(eventsTbl.count() == 0);

    SECTION("Default Constructor")
    {
        EventsTableRow testRow;
        REQUIRE(testRow.ID == DB_ID_NONE);
        REQUIRE(testRow.title == "");
        REQUIRE(testRow.description == "");
        REQUIRE(testRow.date_from == 0);
        REQUIRE(testRow.date_till == 0);
        REQUIRE(testRow.reminder == 0);
        REQUIRE(testRow.repeat == 0);
        REQUIRE(testRow.time_zone == 0);
        REQUIRE_FALSE(testRow.isValid());
    }

    REQUIRE(eventsTbl.add({{.ID = 0},
                           .title       = "Event3",
                           .description = "Desc3",
                           .date_from   = 1910201424,
                           .date_till   = 1910201536,
                           .reminder    = 1,
                           .repeat      = 2,
                           .time_zone   = 1}));
    REQUIRE(eventsTbl.add({{.ID = 0},
                           .title       = "Event4",
                           .description = "Desc4",
                           .date_from   = 2104191224,
                           .date_till   = 2104201536,
                           .reminder    = 0,
                           .repeat      = 3,
                           .time_zone   = 0}));

    REQUIRE(eventsTbl.count() == 2);

    SECTION("Get entry by ID")
    {
        auto entry = eventsTbl.getById(2);
        REQUIRE(entry.ID == 2);
        REQUIRE(entry.title == "Event4");
        REQUIRE(entry.description == "Desc4");
        REQUIRE(entry.date_from == 2104191224);
        REQUIRE(entry.date_till == 2104201536);
        REQUIRE(entry.reminder == 0);
        REQUIRE(entry.repeat == 3);
        REQUIRE(entry.time_zone == 0);
        REQUIRE(entry.isValid());
    }

    SECTION("Remove entry by ID")
    {
        auto response = eventsTbl.removeById(2);
        REQUIRE(response);
        REQUIRE_FALSE(eventsTbl.count() == 2);
        REQUIRE_NOTHROW(eventsTbl.getById(2));
        auto entry = eventsTbl.getById(1);
        REQUIRE(entry.ID == 1);
        REQUIRE(entry.title == "Event3");
        REQUIRE(entry.description == "Desc3");
        REQUIRE(entry.date_from == 1910201424);
        REQUIRE(entry.date_till == 1910201536);
        REQUIRE(entry.reminder == 1);
        REQUIRE(entry.repeat == 2);
        REQUIRE(entry.time_zone == 1);
        REQUIRE(entry.isValid());
    }

    SECTION("Update entry by ID")
    {
        auto entry =
            EventsTableRow({{.ID = 2}, "TestUpdateEvent", "Tested update event", 1910201500, 1910201854, 0, 2, 1});
        REQUIRE(eventsTbl.update(entry));
        auto record = eventsTbl.getById(2);
        REQUIRE(record.ID == 2);
        REQUIRE(record.title == "TestUpdateEvent");
        REQUIRE(record.description == "Tested update event");
        REQUIRE(record.date_from == 1910201500);
        REQUIRE(record.date_till == 1910201854);
        REQUIRE(record.reminder == 0);
        REQUIRE(record.repeat == 2);
        REQUIRE(record.time_zone == 1);
        REQUIRE(record.isValid());
    }

    SECTION("Select entry by date")
    {
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event5",
                               .description = "Desc5",
                               .date_from   = 1910201424,
                               .date_till   = 1910201536,
                               .reminder    = 1,
                               .repeat      = 2,
                               .time_zone   = 1}));
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event6",
                               .description = "Desc6",
                               .date_from   = 2104191224,
                               .date_till   = 2104201536,
                               .reminder    = 0,
                               .repeat      = 3,
                               .time_zone   = 0}));
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event7",
                               .description = "Desc7",
                               .date_from   = 1910201524,
                               .date_till   = 1910201536,
                               .reminder    = 1,
                               .repeat      = 2,
                               .time_zone   = 1}));
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event8",
                               .description = "Desc8",
                               .date_from   = 1504191224,
                               .date_till   = 1504201536,
                               .reminder    = 0,
                               .repeat      = 3,
                               .time_zone   = 0}));
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event9",
                               .description = "Desc9",
                               .date_from   = 2510201424,
                               .date_till   = 2510201536,
                               .reminder    = 1,
                               .repeat      = 2,
                               .time_zone   = 1}));
        REQUIRE(eventsTbl.add({{.ID = 0},
                               .title       = "Event10",
                               .description = "Desc10",
                               .date_from   = 2112191224,
                               .date_till   = 2112201536,
                               .reminder    = 0,
                               .repeat      = 3,
                               .time_zone   = 0}));

        auto entries = eventsTbl.selectByDatePeriod(1910201500, 2104201500);
        auto entry   = entries.back();
        REQUIRE(entry.ID == 5);
        REQUIRE(entry.title == "Event7");
        REQUIRE(entry.description == "Desc7");
        REQUIRE(entry.date_from == 1910201524);
        REQUIRE(entry.date_till == 1910201536);
        REQUIRE(entry.reminder == 1);
        REQUIRE(entry.repeat == 2);
        REQUIRE(entry.time_zone == 1);
        REQUIRE(entry.isValid());
    }

    Database::deinitialize();
}

M module-db/tests/ThreadRecord_tests.cpp => module-db/tests/ThreadRecord_tests.cpp +0 -1
@@ 77,7 77,6 @@ TEST_CASE("Thread Record tests")
            REQUIRE(w.contactID == contactIDTest);
        }
    }

    SECTION("Get all available records with query")
    {
        auto query  = std::make_shared<db::query::SMSThreadsGet>(0, 100);

M module-os/RTOSWrapper/include/thread.hpp => module-os/RTOSWrapper/include/thread.hpp +6 -6
@@ 343,12 343,7 @@ class Thread {


#ifdef CPP_FREERTOS_CONDITION_VARIABLES
/**
 *  Reference to the underlying task handle for this thread.
 *  Can be obtained from GetHandle().
 */
TaskHandle_t handle;
    public: // TODO: M.P
public: // TODO: M.P
        /**
         *  Have this thread wait on a condition variable.
         *


@@ 377,6 372,11 @@ TaskHandle_t handle;
    //
    /////////////////////////////////////////////////////////////////////////
    private:
        /**
         *  Reference to the underlying task handle for this thread.
         *  Can be obtained from GetHandle().
         */
        TaskHandle_t handle;

        /**
         *  We need to track whether the scheduler is active or not.

M module-services/service-db/CMakeLists.txt => module-services/service-db/CMakeLists.txt +0 -1
@@ 15,7 15,6 @@ target_sources( ${PROJECT_NAME}
        "messages/DBCountryCodeMessage.cpp"
        "messages/DBNotesMessage.cpp"
        "messages/DBNotificationMessage.cpp"
        "messages/DBEventsMessage.cpp"
        "messages/DBSettingsMessage.cpp"
        "messages/DBServiceMessage.cpp"
        "messages/DBSMSMessage.cpp"

M module-services/service-db/ServiceDB.cpp => module-services/service-db/ServiceDB.cpp +0 -2
@@ 13,9 13,7 @@
#include "messages/DBSMSMessage.hpp"
#include "messages/DBThreadMessage.hpp"
#include "messages/DBNotificationMessage.hpp"
#include "messages/DBEventsMessage.hpp"
#include "messages/DBSettingsMessage.hpp"
#include "messages/DBSMSMessage.hpp"
#include "messages/DBSMSTemplateMessage.hpp"
#include "messages/DBContactMessage.hpp"
#include "messages/DBAlarmMessage.hpp"

D module-services/service-db/messages/DBEventsMessage.cpp => module-services/service-db/messages/DBEventsMessage.cpp +0 -8
@@ 1,8 0,0 @@
#include "DBEventsMessage.hpp"

namespace db
{
    EventsMessage::EventsMessage(db::Interface::Name interface, Query::Type type)
        : sys::DataMessage(MessageType::DBServiceEvents), interface(interface), type(type)
    {}
} // namespace db

D module-services/service-db/messages/DBEventsMessage.hpp => module-services/service-db/messages/DBEventsMessage.hpp +0 -18
@@ 1,18 0,0 @@
#pragma once

#include "DBMessage.hpp"
#include "Service/Message.hpp"
#include <module-db/Interface/BaseInterface.hpp>
#include <module-db/Common/Query.hpp>
#include <memory>

namespace db
{
    class EventsMessage : public sys::DataMessage
    {
      public:
        EventsMessage(db::Interface::Name interface, Query::Type type);
        db::Interface::Name interface;
        const Query::Type type;
    };
} // namespace db