Skip to content
Snippets Groups Projects

F files

Merged Timm Fitschen requested to merge f-files into dev
2 files
+ 4
4
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 138
72
@@ -20,23 +20,30 @@
*/
#ifndef CAOSDB_TRANSACTION_H
#define CAOSDB_TRANSACTION_H
#include "boost/log/core/record.hpp" // for record
#include "boost/log/sources/record_ostream.hpp" // for basic_record_o...
#include "boost/preprocessor/seq/limits/enum_256.hpp" // for BOOST_PP_SEQ_E...
#include "boost/preprocessor/seq/limits/size_256.hpp" // for BOOST_PP_SEQ_S...
#include "caosdb/entity.h" // for Entity
#include "caosdb/logging.h"
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe...
#include "caosdb/entity/v1alpha1/main.pb.h" // for Entity, RetrieveReq...
#include "caosdb/transaction_status.h" // for TransactionStatus
#include "caosdb/entity.h" // for Entity, FileDe...
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransact...
#include "caosdb/entity/v1alpha1/main.pb.h" // for MultiTransacti...
#include "caosdb/handler_interface.h" // for HandlerInterface
#include "caosdb/transaction_handler.h" // for EntityTransactionHandler
#include "caosdb/logging.h" // for CAOSDB_LOG_ERR...
#include "caosdb/protobuf_helper.h" // for get_arena
#include "caosdb/status_code.h" // for StatusCode
#include "google/protobuf/util/json_util.h" // for MessageToJsonString, Jso...
#include <iterator>
#include "caosdb/transaction_status.h" // for StatusCode
#include <boost/log/core/record.hpp> // for record
#include <boost/log/sources/record_ostream.hpp> // for basic_record_o...
#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_E...
#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_S...
#include <google/protobuf/arena.h> // for Arena
#include <google/protobuf/util/json_util.h> // for MessageToJsonS...
#include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
#include <iterator> // for iterator, next
#include <map> // for map
// IWYU pragma: no_include <ext/alloc_traits.h>
#include <memory> // for shared_ptr, unique_ptr
#include <stdexcept>
#include <string> // for string
#include <vector> // for vector
#include <memory> // for unique_ptr
#include <string> // for string
#include <utility> // for move
#include <vector> // for vector
/**
* Do all necessary checks and assure that another retrieval (by id or by
@@ -158,19 +165,28 @@
*/
namespace caosdb::transaction {
using caosdb::entity::Entity;
using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using caosdb::entity::FileDescriptor;
using caosdb::entity::v1alpha1::EntityResponse;
using caosdb::entity::v1alpha1::EntityTransactionService;
using caosdb::entity::v1alpha1::FileDownloadRequest;
using caosdb::entity::v1alpha1::FileDownloadResponse;
using caosdb::entity::v1alpha1::FileTransmissionId;
using caosdb::entity::v1alpha1::FileTransmissionService;
using caosdb::entity::v1alpha1::FileUploadRequest;
using caosdb::entity::v1alpha1::FileUploadResponse;
using caosdb::entity::v1alpha1::IdResponse;
using caosdb::entity::v1alpha1::MultiTransactionRequest;
using caosdb::entity::v1alpha1::MultiTransactionResponse;
using caosdb::entity::v1alpha1::RegisterFileUploadRequest;
using caosdb::entity::v1alpha1::RegisterFileUploadResponse;
using caosdb::transaction::TransactionStatus;
using WrappedResponseCase =
caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase;
using TransactionResponseCase =
caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase;
using caosdb::utility::get_arena;
using google::protobuf::Arena;
class Transaction;
static const std::string logger_name = "caosdb::transaction";
/**
* Abstract base class for the results of a Transaction.
*/
@@ -179,8 +195,9 @@ class ResultSet {
public:
virtual ~ResultSet() = default;
[[nodiscard]] virtual auto Size() const noexcept -> int = 0;
[[nodiscard]] virtual auto At(const int index) const -> const Entity & = 0;
[[nodiscard]] virtual auto size() const noexcept -> int = 0;
[[nodiscard]] virtual auto at(const int index) const -> const Entity & = 0;
[[nodiscard]] virtual auto mutable_at(int index) const -> Entity * = 0;
auto begin() const -> iterator;
auto end() const -> iterator;
@@ -199,51 +216,34 @@ private:
};
};
/**
* Container with results of a transaction.
*
* In contrast to UniqueResult, this one can also hold multiple entities or zero
* entities.
*/
class MultiResultSet : public ResultSet {
class AbstractMultiResultSet : public ResultSet {
public:
~MultiResultSet() = default;
explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set);
[[nodiscard]] inline auto Size() const noexcept -> int override {
return this->entities.size();
virtual ~AbstractMultiResultSet() = default;
inline explicit AbstractMultiResultSet(
std::vector<std::unique_ptr<Entity>> result_set)
: items(std::move(result_set)) {}
[[nodiscard]] inline auto size() const noexcept -> int override {
return this->items.size();
}
[[nodiscard]] inline auto At(const int index) const
[[nodiscard]] inline auto at(const int index) const
-> const Entity & override {
return *(this->entities.at(index));
return *(this->items.at(index));
}
[[nodiscard]] inline auto mutable_at(int index) const -> Entity * override {
return this->items.at(index).get();
}
std::vector<std::unique_ptr<Entity>> entities;
protected:
std::vector<std::unique_ptr<Entity>> items;
};
/**
* Container with the single result of a transaction.
*
* In contrast to MultiResultSet, this one guarantees to hold exactly one
* entity.
* Container with results of a transaction.
*/
class UniqueResult : public ResultSet {
class MultiResultSet : public AbstractMultiResultSet {
public:
~UniqueResult() = default;
explicit inline UniqueResult(ProtoEntity *protoEntity)
: entity(new Entity(protoEntity)){};
explicit inline UniqueResult(IdResponse *idResponse)
: entity(new Entity(idResponse)){};
[[nodiscard]] auto GetEntity() const -> const Entity &;
[[nodiscard]] inline auto Size() const noexcept -> int override { return 1; }
[[nodiscard]] inline auto At(const int index) const
-> const Entity & override {
if (index != 0) {
throw std::out_of_range("Index out of range. Length is 1.");
}
return *(this->entity);
}
private:
std::unique_ptr<Entity> entity;
~MultiResultSet() = default;
explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set);
};
/**
@@ -259,15 +259,36 @@ public:
* yet.
*/
enum TransactionType {
NONE, /// Unspecified or not specified yet.
READ_ONLY, /// Only retrievals (by id, by query)
INSERT, /// Only insertions
UPDATE, /// Only updates
DELETE, /// Only deletions
MIXED_WRITE, /// Only insertions, deletions, updates
MIXED_READ_AND_WRITE /// all kind of transaction.
NONE, //!< Unspecified or not specified yet.
READ_ONLY, //!< Only retrievals (by id, by query)
INSERT, //!< Only insertions
UPDATE, //!< Only updates
DELETE, //!< Only deletions
MIXED_WRITE, //!< Only insertions, deletions, updates
MIXED_READ_AND_WRITE //!< all kind of transaction.
};
Transaction(std::shared_ptr<EntityTransactionService::Stub> service_stub);
Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service,
std::shared_ptr<FileTransmissionService::Stub> file_service);
~Transaction();
Transaction(const Transaction &) = delete;
Transaction &operator=(const Transaction &) = delete;
Transaction(Transaction &&) = delete;
Transaction &operator=(Transaction &&) = delete;
/**
* Add an entity id to this transaction for retrieval and also download the
* file.
*
* If the entity doesn't have a file a warning is appended.
*
* If the file cannot be downloaded due to unsufficient permissions an error
* is appended.
*/
auto RetrieveAndDownloadFilesById(const std::string &id,
const std::string &local_path) noexcept
-> StatusCode;
/**
* Add an entity id to this transaction for retrieval.
@@ -348,13 +369,12 @@ public:
/**
* Return the current status of the transaction.
*/
[[nodiscard]] inline auto GetStatus() const -> TransactionStatus {
[[nodiscard]] inline auto GetStatus() const noexcept -> TransactionStatus {
return this->status;
}
[[nodiscard]] inline auto GetResultSet() const -> const ResultSet & {
const ResultSet *result_set = this->result_set.get();
return *result_set;
[[nodiscard]] inline auto GetResultSet() const noexcept -> const ResultSet & {
return *(this->result_set.get());
}
/**
@@ -364,7 +384,7 @@ public:
* this transaction. In all other cases, the return value will be
* -1.
*/
[[nodiscard]] inline auto GetCountResult() const -> long {
[[nodiscard]] inline auto GetCountResult() const noexcept -> long {
return query_count;
}
@@ -402,12 +422,58 @@ public:
return out;
}
/**
* Return the vector which holds all the files which are to be uploaded.
*/
inline auto GetUploadFiles() const -> const std::vector<FileDescriptor> & {
return upload_files;
}
protected:
/**
* Await and process the current handler's results.
*
* This implies consecutive calls to the handler's OnNext function.
*/
auto ProcessCalls() -> TransactionStatus;
/**
* Cancels any active handler and drains the completion_queue.
*
* Can stay protected until ExecuteAsynchronously() is actually asynchronous.
* Then it is also intended for aborting an execution after it has already
* started.
*/
auto Cancel() -> void;
/**
* Return the Arena where this transaction may create Message instances.
*
* Currently, this implementation is only a call to
* caosdb::utility::get_arena(), but in the future we might want to have a
* smarter memory management.
*/
inline auto GetArena() const -> Arena * { return get_arena(); }
private:
grpc::CompletionQueue completion_queue;
std::unique_ptr<HandlerInterface> handler_;
std::vector<FileDescriptor> upload_files;
std::map<std::string, FileDescriptor> download_files;
// auto RegisterUploadFile(RegisterFileUploadResponse *response) -> void;
auto UploadFile(FileUploadResponse *response,
const FileDescriptor &file_descriptor,
const std::string &registration_id) -> void;
auto DownloadFile(FileDownloadResponse *response,
const FileTransmissionId &file_transmission_id) -> void;
bool has_query = false;
TransactionType transaction_type = TransactionType::NONE;
mutable std::unique_ptr<ResultSet> result_set;
mutable TransactionStatus status = TransactionStatus::INITIAL();
std::shared_ptr<EntityTransactionService::Stub> service_stub;
std::shared_ptr<EntityTransactionService::Stub> entity_service;
std::shared_ptr<FileTransmissionService::Stub> file_service;
MultiTransactionRequest *request;
mutable MultiTransactionResponse *response;
std::string error_message;
Loading