Skip to content

Commit

Permalink
feat(daemon): add Delete, Move and Copy action endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
LordTermor committed Jun 29, 2024
1 parent 0104e5b commit 7872890
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 10 deletions.
14 changes: 13 additions & 1 deletion daemon/core/application/services/PackageService.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,19 @@ class PackageService {

struct Transaction {
std::vector<PackageDTO> to_add;
std::vector<std::pair<PackageSectionDTO, std::string>> to_remove;
struct PackageAction {
PackageSectionDTO section;
std::string name;
};
std::vector<PackageAction> to_delete;
struct TransferAction {
std::string name;
PackageSectionDTO from_section;
PackageSectionDTO to_section;
};

std::vector<TransferAction> to_move;
std::vector<TransferAction> to_copy;
};

virtual coro::task<Result<void>>
Expand Down
107 changes: 98 additions & 9 deletions daemon/infrastructure/PackageService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,58 @@ coro::task<PackageService::Result<void>> PackageService::commit_transaction(

packages_to_add.reserve(transaction.to_add.size());

auto ids_to_remove =
transaction.to_remove
auto ids_to_delete =
transaction.to_delete
| std::views::transform(
[](const std::pair<PackageSectionDTO, std::string> &value) {
return Package::TId {SectionDTOMapper::to_entity(value.first),
Name(value.second)};
[](const PackageService::Transaction::PackageAction& action) {
return Package::TId {
SectionDTOMapper::to_entity(action.section),
Name(action.name)};
})
| std::ranges::to<std::vector>();

auto uow = co_await m_uow_factory(true);

std::vector<coro::task<PackageService::Result<void>>> tasks;
for (const auto &package : transaction.to_add) {
for (const auto& package : transaction.to_add) {
tasks.push_back(add_package(package, uow));
}

auto added = co_await coro::when_all(std::move(tasks));
for (auto &added_package : added) {
for (auto& added_package : added) {
if (!added_package.return_value().has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(added_package.return_value().error()),
CrudError::ErrorType::InternalError);
}
}
auto deleted = co_await m_repository.delete_async(ids_to_remove, uow);

auto deleted = co_await m_repository.delete_async(ids_to_delete, uow);
if (!deleted.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(deleted.error()), CrudError::ErrorType::InternalError);
}

for (const auto& action : transaction.to_move) {
auto move_result = co_await move_package(
action.name, action.from_section, action.to_section, uow);
if (!move_result.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(move_result.error()),
CrudError::ErrorType::InternalError);
}
}

for (const auto& action : transaction.to_copy) {
auto copy_result = co_await copy_package(
action.name, action.from_section, action.to_section, uow);
if (!copy_result.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(copy_result.error()),
CrudError::ErrorType::InternalError);
}
}

auto commit_ok = co_await uow->commit_async();
if (!commit_ok) {
co_return bxt::make_error_with_source<CrudError>(
Expand All @@ -63,6 +85,73 @@ coro::task<PackageService::Result<void>> PackageService::commit_transaction(

co_return {};
}
coro::task<PackageService::Result<void>>
PackageService::move_package(const std::string package_name,
const PackageSectionDTO from_section,
const PackageSectionDTO to_section,
std::shared_ptr<UnitOfWorkBase> unitofwork) {
// First, find the package in the from_section
auto package_to_move = co_await m_repository.find_by_section_async(
SectionDTOMapper::to_entity(from_section), package_name, unitofwork);

if (!package_to_move.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(package_to_move.error()),
CrudError::ErrorType::EntityNotFound);
}

package_to_move->set_section(SectionDTOMapper::to_entity(to_section));

// Then, add the package to the to_section
auto add_result =
co_await m_repository.add_async(*package_to_move, unitofwork);

if (!add_result.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(add_result.error()), CrudError::ErrorType::InternalError);
}

// Finally, remove the package from the from_section
auto remove_result =
co_await m_repository.delete_async(package_to_move->id(), unitofwork);

if (!remove_result.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(remove_result.error()),
CrudError::ErrorType::InternalError);
}

co_return {};
}

coro::task<PackageService::Result<void>>
PackageService::copy_package(const std::string package_name,
const PackageSectionDTO from_section,
const PackageSectionDTO to_section,
std::shared_ptr<UnitOfWorkBase> unitofwork) {
// First, find the package in the from_section
auto package_to_copy = co_await m_repository.find_by_section_async(
SectionDTOMapper::to_entity(from_section), package_name, unitofwork);

if (!package_to_copy.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(package_to_copy.error()),
CrudError::ErrorType::EntityNotFound);
}

package_to_copy->set_section(SectionDTOMapper::to_entity(to_section));

// Then, add the package to the to_section
auto add_result =
co_await m_repository.add_async(*package_to_copy, unitofwork);

if (!add_result.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(add_result.error()), CrudError::ErrorType::InternalError);
}

co_return {};
}

coro::task<PackageService::Result<void>>
PackageService::add_package(const PackageDTO package,
Expand Down Expand Up @@ -150,7 +239,7 @@ coro::task<PackageService::Result<void>>
std::move(deleted.error()), CrudError::ErrorType::InternalError);
}

for (auto &source_package : *source_packages) {
for (auto& source_package : *source_packages) {
source_package.set_section(SectionDTOMapper::to_entity(to_section));
}

Expand Down
12 changes: 12 additions & 0 deletions daemon/infrastructure/PackageService.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ class PackageService : public Core::Application::PackageService {
coro::task<Result<void>> add_package(const PackageDTO package,
std::shared_ptr<UnitOfWorkBase> uow);

coro::task<PackageService::Result<void>>
move_package(const std::string package_name,
const PackageSectionDTO from_section,
const PackageSectionDTO to_section,
std::shared_ptr<UnitOfWorkBase> unitofwork);

coro::task<PackageService::Result<void>>
copy_package(const std::string package_name,
const PackageSectionDTO from_section,
const PackageSectionDTO to_section,
std::shared_ptr<UnitOfWorkBase> unitofwork);

PackageServiceOptions m_options;
Core::Domain::PackageRepositoryBase& m_repository;
UnitOfWorkBaseFactory& m_uow_factory;
Expand Down
47 changes: 47 additions & 0 deletions daemon/presentation/web-controllers/PackageController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,53 @@ drogon::Task<drogon::HttpResponsePtr>
transaction.to_add.emplace_back(std::move(package.second));
}

auto to_delete_it = params_map.find("to_delete");
if (to_delete_it != params_map.end()) {
auto to_delete = rfl::json::read<
std::vector<PackageService::Transaction::PackageAction>>(
to_delete_it->second);

if (!to_delete) {
co_return drogon_helpers::make_error_response(fmt::format(
"Invalid to_delete format: {}", to_delete.error()->what()));
}

for (const auto &action : *to_delete) {
transaction.to_delete.emplace_back(action);
}
}

auto to_move_it = params_map.find("to_move");
if (to_move_it != params_map.end()) {
auto to_move = rfl::json::read<
std::vector<PackageService::Transaction::TransferAction>>(
to_move_it->second);

if (!to_move) {
co_return drogon_helpers::make_error_response(fmt::format(
"Invalid to_move format: {}", to_move.error()->what()));
}

for (const auto &action : *to_move) {
transaction.to_move.emplace_back(action);
}
}
auto to_copy_it = params_map.find("to_copy");
if (to_copy_it != params_map.end()) {
auto to_move = rfl::json::read<
std::vector<PackageService::Transaction::TransferAction>>(
to_copy_it->second);

if (!to_move) {
co_return drogon_helpers::make_error_response(fmt::format(
"Invalid to_move format: {}", to_move.error()->what()));
}

for (const auto &action : *to_move) {
transaction.to_copy.emplace_back(action);
}
}

auto result = co_await m_package_service.commit_transaction(transaction);

if (!result.has_value()) {
Expand Down
6 changes: 6 additions & 0 deletions daemon/swagger/openapi.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ paths:
format: binary
packageSection:
type: string
to_delete:
type: string
to_move:
type: string
to_copy:
type: string
responses:
"200":
description: Transaction committed successfully
Expand Down

0 comments on commit 7872890

Please sign in to comment.