Skip to content

Commit

Permalink
feat(daemon): implement save function for repositories
Browse files Browse the repository at this point in the history
Implements a function that will either add or update entity based on its existence.
  • Loading branch information
LordTermor committed Jul 16, 2024
1 parent 5ccc825 commit 9b28b52
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions daemon/core/domain/repositories/RepositoryBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "core/domain/repositories/ReadOnlyRepositoryBase.h"
#include "core/domain/repositories/UnitOfWorkBase.h"
#include "frozen/string.h"
#include "utilities/Error.h"
#include "utilities/errors/Macro.h"

#include <coro/sync_wait.hpp>
Expand Down Expand Up @@ -138,6 +139,60 @@ struct ReadWriteRepositoryBase : public ReadOnlyRepositoryBase<TEntity> {
co_return {};
}

/**
* @brief Asynchronously saves an entity in the repository.
* If the entity exists, it will be updated; otherwise, it will be added.
*
* @param entity The entity to be saved.
* @param uow The shared pointer to the unit of work.
* @return coro::task<Result<void>> A task that represents the asynchronous
* operation.
*/
inline virtual coro::task<Result<void>>
save_async(const TEntity& entity, std::shared_ptr<UnitOfWorkBase> uow) {
auto find_result = co_await this->find_by_id_async(entity.id(), uow);

if (!find_result.has_value()) {
if (find_result.error().error_type
== ReadError::Type::EntityNotFound) {
co_return co_await add_async(entity, uow);
} else {
co_return bxt::make_error_with_source<WriteError>(
std::move(find_result.error()), WriteError::OperationError);
}
}

co_return co_await update_async(entity, uow);
}

/**
* @brief Asynchronously saves a list of entities in the repository.
* For each entity, if it exists, it will be updated; otherwise, it will be
* added.
*
* @param entities The entities to be saved.
* @param uow The shared pointer to the unit of work.
* @return coro::task<Result<void>> A task that represents the asynchronous
* operation.
*/
inline virtual coro::task<Result<void>>
save_async(const TEntities& entities,
std::shared_ptr<UnitOfWorkBase> uow) {
auto tasks = entities
| std::views::transform([&](const TEntity& entity) {
return save_async(entity, uow);
})
| std::ranges::to<std::vector>();

auto results = co_await coro::when_all(std::move(tasks));
for (const auto& result : results) {
if (!result.return_value().has_value()) {
co_return std::unexpected(result.return_value().error());
}
}
co_return {};
}

/**
* @brief Asynchronously removes an entity from the repository.
*
Expand Down

0 comments on commit 9b28b52

Please sign in to comment.