From 50a73ca63888c09262176c1ec3f99ba0fbf610a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ta=C5=84ski?= Date: Wed, 30 Jun 2021 15:23:04 +0200 Subject: [PATCH] [EGD-7051] Fixed saving multiple notes at once When creating a new note, it was possible to save multiple notes with 1 click. --- .../application-notes/data/NoteSwitchData.cpp | 6 +++--- .../application-notes/data/NoteSwitchData.hpp | 8 ++++---- .../application-notes/model/NotesListModel.cpp | 4 ++-- .../model/NotesRepository.cpp | 6 +++--- .../model/NotesRepository.hpp | 13 +++++++------ .../presenter/NoteEditWindowPresenter.cpp | 10 +++++++--- .../presenter/NoteEditWindowPresenter.hpp | 4 ++-- .../windows/NoteEditWindow.cpp | 6 +++--- .../windows/NoteEditWindow.hpp | 4 ++-- .../windows/NoteMainWindow.cpp | 2 +- .../windows/NotePreviewWindow.cpp | 4 ++-- .../windows/NotePreviewWindow.hpp | 4 ++-- module-db/Interface/NotesRecord.cpp | 17 ++++++++++++----- module-db/queries/notes/QueryNoteStore.cpp | 9 +++++++-- module-db/queries/notes/QueryNoteStore.hpp | 6 ++++-- module-db/tests/NotesRecord_tests.cpp | 18 ++++++++++++++++++ 16 files changed, 79 insertions(+), 42 deletions(-) diff --git a/module-apps/application-notes/data/NoteSwitchData.cpp b/module-apps/application-notes/data/NoteSwitchData.cpp index 70b944adc7ec69c96812aafec79901077b9e0f64..b2589f7cd396afda4624144bf5f909632bc3c637 100644 --- a/module-apps/application-notes/data/NoteSwitchData.cpp +++ b/module-apps/application-notes/data/NoteSwitchData.cpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "NoteSwitchData.hpp" namespace app::notes { - NoteSwitchData::NoteSwitchData(NotesRecord record) + NoteSwitchData::NoteSwitchData(std::shared_ptr record) : gui::SwitchData(std::string{"NotePreview"}), record{std::move(record)} {} - const NotesRecord &NoteSwitchData::getRecord() const noexcept + std::shared_ptr NoteSwitchData::getRecord() noexcept { return record; } diff --git a/module-apps/application-notes/data/NoteSwitchData.hpp b/module-apps/application-notes/data/NoteSwitchData.hpp index 16ba077981b8bf132540ebce88b34dcd753f44ed..45f9d7c30dcb180232d5d15a98d51491056c0d9c 100644 --- a/module-apps/application-notes/data/NoteSwitchData.hpp +++ b/module-apps/application-notes/data/NoteSwitchData.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -12,11 +12,11 @@ namespace app::notes class NoteSwitchData : public gui::SwitchData { public: - explicit NoteSwitchData(NotesRecord record); + explicit NoteSwitchData(std::shared_ptr record); - const NotesRecord &getRecord() const noexcept; + std::shared_ptr getRecord() noexcept; private: - NotesRecord record; + std::shared_ptr record = nullptr; }; } // namespace app::notes diff --git a/module-apps/application-notes/model/NotesListModel.cpp b/module-apps/application-notes/model/NotesListModel.cpp index 09099d3af496955cd0ac8aa7f989e367d797f7dd..4ac4f7d9f28ed5972a9f9679ce601cdd43337acb 100644 --- a/module-apps/application-notes/model/NotesListModel.cpp +++ b/module-apps/application-notes/model/NotesListModel.cpp @@ -46,8 +46,8 @@ namespace app::notes } auto item = new gui::NotesItem(note); - item->activatedCallback = [this, note = note.get()](gui::Item &) { - application->switchWindow(gui::name::window::note_preview, std::make_unique(*note)); + item->activatedCallback = [this, note](gui::Item &) { + application->switchWindow(gui::name::window::note_preview, std::make_unique(note)); return true; }; item->inputCallback = [this, note = note.get()](gui::Item &, const gui::InputEvent &event) { diff --git a/module-apps/application-notes/model/NotesRepository.cpp b/module-apps/application-notes/model/NotesRepository.cpp index b100de838eea0ccf5e9e17d291bd5bfd5109de5b..9f10df41dc6ee410985d7f1a9e7fe22f70b1643e 100644 --- a/module-apps/application-notes/model/NotesRepository.cpp +++ b/module-apps/application-notes/model/NotesRepository.cpp @@ -53,7 +53,7 @@ namespace app::notes task->execute(application, this); } - void NotesDBRepository::save(const NotesRecord ¬e, const OnResultCallback &callback) + void NotesDBRepository::save(const NotesRecord ¬e, const OnSaveCallback &callback) { auto query = std::make_unique(note); auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); @@ -63,14 +63,14 @@ namespace app::notes return false; } if (callback) { - callback(result->succeed()); + callback(result->succeed(), result->getNoteId()); } return true; }); task->execute(application, this); } - void NotesDBRepository::remove(const NotesRecord ¬e, const OnResultCallback &callback) + void NotesDBRepository::remove(const NotesRecord ¬e, const OnRemoveCallback &callback) { auto query = std::make_unique(note.ID); auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Notes); diff --git a/module-apps/application-notes/model/NotesRepository.hpp b/module-apps/application-notes/model/NotesRepository.hpp index 74d2909a4093eb4291c8872b57e9d223a3da4fec..cf25bc15e28357ae71001725d61b9e8efb0c02fd 100644 --- a/module-apps/application-notes/model/NotesRepository.hpp +++ b/module-apps/application-notes/model/NotesRepository.hpp @@ -14,8 +14,9 @@ namespace app::notes class AbstractNotesRepository { public: - using OnGetCallback = std::function &, unsigned int)>; - using OnResultCallback = std::function; + using OnGetCallback = std::function &, unsigned int)>; + using OnSaveCallback = std::function; + using OnRemoveCallback = std::function; virtual ~AbstractNotesRepository() noexcept = default; @@ -24,8 +25,8 @@ namespace app::notes std::uint32_t offset, std::uint32_t limit, const OnGetCallback &callback) = 0; - virtual void save(const NotesRecord ¬e, const OnResultCallback &callback) = 0; - virtual void remove(const NotesRecord ¬e, const OnResultCallback &callback) = 0; + virtual void save(const NotesRecord ¬e, const OnSaveCallback &callback) = 0; + virtual void remove(const NotesRecord ¬e, const OnRemoveCallback &callback) = 0; }; class NotesDBRepository : public AbstractNotesRepository, public app::AsyncCallbackReceiver @@ -38,8 +39,8 @@ namespace app::notes std::uint32_t offset, std::uint32_t limit, const OnGetCallback &callback) override; - void save(const NotesRecord ¬e, const OnResultCallback &callback) override; - void remove(const NotesRecord ¬e, const OnResultCallback &callback) override; + void save(const NotesRecord ¬e, const OnSaveCallback &callback) override; + void remove(const NotesRecord ¬e, const OnRemoveCallback &callback) override; private: Application *application; diff --git a/module-apps/application-notes/presenter/NoteEditWindowPresenter.cpp b/module-apps/application-notes/presenter/NoteEditWindowPresenter.cpp index 4597c3c150669c4c3ae996f86584ba4341f622e9..b0c11d1d54d10f3aa7933edc85301d7ad1fd4e40 100644 --- a/module-apps/application-notes/presenter/NoteEditWindowPresenter.cpp +++ b/module-apps/application-notes/presenter/NoteEditWindowPresenter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "NoteEditWindowPresenter.hpp" @@ -9,8 +9,12 @@ namespace app::notes : notesRepository{std::move(notesRepository)} {} - void NoteEditWindowPresenter::save(const NotesRecord ¬e) + void NoteEditWindowPresenter::save(std::shared_ptr ¬e) { - notesRepository->save(note, nullptr); + notesRepository->save(*note, [this, note](bool succeed, std::uint32_t noteId) { + if (succeed) { + note->ID = noteId; + } + }); } } // namespace app::notes diff --git a/module-apps/application-notes/presenter/NoteEditWindowPresenter.hpp b/module-apps/application-notes/presenter/NoteEditWindowPresenter.hpp index 770fa5cbf7db8fad3905b9b92fe21dbb3fb97dee..32ba051ba02026f4b8ef5e62d3003471925ebb43 100644 --- a/module-apps/application-notes/presenter/NoteEditWindowPresenter.hpp +++ b/module-apps/application-notes/presenter/NoteEditWindowPresenter.hpp @@ -22,7 +22,7 @@ namespace app::notes public: virtual ~Presenter() noexcept = default; - virtual void save(const NotesRecord ¬e) = 0; + virtual void save(std::shared_ptr ¬e) = 0; }; }; @@ -31,7 +31,7 @@ namespace app::notes public: explicit NoteEditWindowPresenter(std::unique_ptr &¬esRepository); - void save(const NotesRecord ¬e) override; + void save(std::shared_ptr ¬e) override; private: std::unique_ptr notesRepository; diff --git a/module-apps/application-notes/windows/NoteEditWindow.cpp b/module-apps/application-notes/windows/NoteEditWindow.cpp index 830526e06a65216d39f6534aa1f3d361e006f70b..c104f38e6ac22dff2768bf8de34548a24444446f 100644 --- a/module-apps/application-notes/windows/NoteEditWindow.cpp +++ b/module-apps/application-notes/windows/NoteEditWindow.cpp @@ -107,7 +107,7 @@ namespace app::notes return; } - notesRecord = std::make_unique(editData->getRecord()); + notesRecord = editData->getRecord(); setNoteText(notesRecord->snippet); } @@ -121,7 +121,7 @@ namespace app::notes if (inputEvent.isShortRelease()) { if (inputEvent.is(gui::KeyCode::KEY_ENTER)) { saveNote(); - auto switchData = std::make_unique(*notesRecord); + auto switchData = std::make_unique(notesRecord); switchData->ignoreCurrentWindowOnStack = true; application->switchWindow(gui::name::window::note_preview, std::move(switchData)); } @@ -138,6 +138,6 @@ namespace app::notes { notesRecord->date = std::time(nullptr); notesRecord->snippet = edit->getText(); - presenter->save(*notesRecord); + presenter->save(notesRecord); } } // namespace app::notes diff --git a/module-apps/application-notes/windows/NoteEditWindow.hpp b/module-apps/application-notes/windows/NoteEditWindow.hpp index aeab480504188509aa02db718091236d4d5bb2ec..32fce6f637a972f601df3cbc2307551cf561379d 100644 --- a/module-apps/application-notes/windows/NoteEditWindow.hpp +++ b/module-apps/application-notes/windows/NoteEditWindow.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -36,7 +36,7 @@ namespace app::notes void saveNote(); std::unique_ptr presenter; - std::unique_ptr notesRecord; + std::shared_ptr notesRecord; gui::Label *charactersCounter; gui::Text *edit; }; diff --git a/module-apps/application-notes/windows/NoteMainWindow.cpp b/module-apps/application-notes/windows/NoteMainWindow.cpp index 78ca6f7898d95f4f01d69fa0e2ed454384d9dd60..60c4a1a30fd72d7c0476e535a84a71b2f5041eb6 100644 --- a/module-apps/application-notes/windows/NoteMainWindow.cpp +++ b/module-apps/application-notes/windows/NoteMainWindow.cpp @@ -119,7 +119,7 @@ namespace app::notes if (inputEvent.isShortRelease()) { if (inputEvent.is(gui::KeyCode::KEY_LEFT)) { application->switchWindow(gui::name::window::note_edit, - std::make_unique(NotesRecord{})); + std::make_unique(std::make_shared())); } else if (inputEvent.is(gui::KeyCode::KEY_RIGHT)) { application->switchWindow(gui::name::window::notes_search); diff --git a/module-apps/application-notes/windows/NotePreviewWindow.cpp b/module-apps/application-notes/windows/NotePreviewWindow.cpp index bc1ec303d22d0e904487f47ecdc6d69ef6510cc6..06c17bce6403dc163e11c4d1f8436413bd3036af 100644 --- a/module-apps/application-notes/windows/NotePreviewWindow.cpp +++ b/module-apps/application-notes/windows/NotePreviewWindow.cpp @@ -86,7 +86,7 @@ namespace app::notes return; } - notesRecord = std::make_unique(previewData->getRecord()); + notesRecord = previewData->getRecord(); setEditDateText(notesRecord->date); note->setText(notesRecord->snippet); } @@ -115,7 +115,7 @@ namespace app::notes { if (inputEvent.isShortRelease()) { if (inputEvent.is(gui::KeyCode::KEY_ENTER)) { - application->switchWindow(gui::name::window::note_edit, std::make_unique(*notesRecord)); + application->switchWindow(gui::name::window::note_edit, std::make_unique(notesRecord)); } else if (inputEvent.is(gui::KeyCode::KEY_LF)) { application->switchWindow(utils::translate("app_phonebook_options_title"), diff --git a/module-apps/application-notes/windows/NotePreviewWindow.hpp b/module-apps/application-notes/windows/NotePreviewWindow.hpp index 80f3e80fdf5cbc781ddc86152fe13ce6c4089290..80b24d0321ef49a355b04dbe614efbb0f6b4a5ac 100644 --- a/module-apps/application-notes/windows/NotePreviewWindow.hpp +++ b/module-apps/application-notes/windows/NotePreviewWindow.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -32,7 +32,7 @@ namespace app::notes void setEditDateText(std::uint32_t editTimestamp); std::unique_ptr presenter; - std::unique_ptr notesRecord; + std::shared_ptr notesRecord; gui::Text *note = nullptr; gui::Label *date = nullptr; }; diff --git a/module-db/Interface/NotesRecord.cpp b/module-db/Interface/NotesRecord.cpp index bdacfa149812ffa95232ec485f19379b3ccba429..9078c3b138f8048ddb848edfa43d6402f83abcaf 100644 --- a/module-db/Interface/NotesRecord.cpp +++ b/module-db/Interface/NotesRecord.cpp @@ -155,17 +155,24 @@ std::unique_ptr NotesRecordInterface::getByTextQuery(const std: std::unique_ptr NotesRecordInterface::storeQuery(const std::shared_ptr &query) { - const auto localQuery = static_cast(query.get()); - const auto &record = localQuery->getRecord(); - bool isSuccess = false; - if (const auto exists = notesDB->notes.getById(record.ID).ID != DB_ID_NONE; exists) { + const auto localQuery = static_cast(query.get()); + const auto &record = localQuery->getRecord(); + bool isSuccess = false; + std::uint32_t resultId = DB_ID_NONE; + + if (const auto id = notesDB->notes.getById(record.ID).ID; id != DB_ID_NONE) { + // Already exists in the DB. isSuccess = Update(record); + resultId = id; } else { isSuccess = Add(record); + if (isSuccess) { + resultId = notesDB->getLastInsertRowId(); + } } - auto response = std::make_unique(isSuccess); + auto response = std::make_unique(isSuccess, resultId); response->setRequestQuery(query); return response; } diff --git a/module-db/queries/notes/QueryNoteStore.cpp b/module-db/queries/notes/QueryNoteStore.cpp index 769ec94d4b6513fc11190a527f5d14af0e8633d7..4b7ab713db7e0db62fe65fe360fc2398b3b4b0a2 100644 --- a/module-db/queries/notes/QueryNoteStore.cpp +++ b/module-db/queries/notes/QueryNoteStore.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "QueryNoteStore.hpp" @@ -18,7 +18,7 @@ namespace db::query return {"QueryNoteStore"}; } - NoteStoreResult::NoteStoreResult(bool isSuccess) : isSuccess{isSuccess} + NoteStoreResult::NoteStoreResult(bool isSuccess, std::uint32_t noteId) : isSuccess{isSuccess}, noteId{noteId} {} bool NoteStoreResult::succeed() const noexcept @@ -26,6 +26,11 @@ namespace db::query return isSuccess; } + std::uint32_t NoteStoreResult::getNoteId() const noexcept + { + return noteId; + } + auto NoteStoreResult::debugInfo() const -> std::string { return {"NoteStoreResult"}; diff --git a/module-db/queries/notes/QueryNoteStore.hpp b/module-db/queries/notes/QueryNoteStore.hpp index 7516bb09c3120b084ba4a58a1c36eb997099908b..0f97bcd3eee5d381efe94a3e245ce9aaa0c98751 100644 --- a/module-db/queries/notes/QueryNoteStore.hpp +++ b/module-db/queries/notes/QueryNoteStore.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -25,12 +25,14 @@ namespace db::query class NoteStoreResult : public QueryResult { public: - explicit NoteStoreResult(bool isSuccess); + NoteStoreResult(bool isSuccess, std::uint32_t noteId); [[nodiscard]] bool succeed() const noexcept; + [[nodiscard]] std::uint32_t getNoteId() const noexcept; [[nodiscard]] std::string debugInfo() const override; private: bool isSuccess; + std::uint32_t noteId; }; } // namespace db::query diff --git a/module-db/tests/NotesRecord_tests.cpp b/module-db/tests/NotesRecord_tests.cpp index 1660169a490c25279213307b7c435dc49019ef70..db12afdac2b3f7a7b7bca37548e5a028aed4af2b 100644 --- a/module-db/tests/NotesRecord_tests.cpp +++ b/module-db/tests/NotesRecord_tests.cpp @@ -64,9 +64,27 @@ TEST_CASE("Notes Record tests") auto addResult = static_cast(response.get()); REQUIRE(addResult->succeed()); + REQUIRE(addResult->getNoteId() == 2); REQUIRE(notesRecordInterface.GetCount() == 2); } + SECTION("Update a note") + { + constexpr auto testId = 1; + + NotesRecord record; + record.ID = testId; + record.snippet = testSnippet; + + auto query = std::make_unique(record); + auto response = notesRecordInterface.runQuery(std::move(query)); + auto updateResult = static_cast(response.get()); + + REQUIRE(updateResult->succeed()); + REQUIRE(updateResult->getNoteId() == testId); + REQUIRE(notesRecordInterface.GetCount() == 1); + } + SECTION("Remove a note") { auto query = std::make_unique(1);