Skip to content
Snippets Groups Projects
Verified Commit 9f011472 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: files

parent b6086b31
No related branches found
No related tags found
1 merge request!11F files
Pipeline #11585 failed
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message #include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message
#include "caosdb/message_code.h" // for get_message_code, Messag... #include "caosdb/message_code.h" // for get_message_code, Messag...
#include "google/protobuf/util/json_util.h" // for MessageToJsonString, Jso... #include "google/protobuf/util/json_util.h" // for MessageToJsonString, Jso...
#include "boost/filesystem/path.hpp" // for path
namespace caosdb::entity { namespace caosdb::entity {
using caosdb::entity::v1alpha1::IdResponse; using caosdb::entity::v1alpha1::IdResponse;
...@@ -41,6 +42,20 @@ using ProtoProperty = caosdb::entity::v1alpha1::Property; ...@@ -41,6 +42,20 @@ using ProtoProperty = caosdb::entity::v1alpha1::Property;
using ProtoEntity = caosdb::entity::v1alpha1::Entity; using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using caosdb::entity::v1alpha1::FileTransmissionId; using caosdb::entity::v1alpha1::FileTransmissionId;
class FileDescriptor {
public:
auto GetEntityId() const -> const std::string &;
auto GetLocalPath() const -> const boost::filesystem::path &;
auto GetRemotePath() const -> const std::string &;
auto GetSize() const -> long long;
private:
std::string entity_id;
std::string remote_path;
std::string local_path;
long long size;
};
/** /**
* Messages convey information about the state and result of transactions. * Messages convey information about the state and result of transactions.
* *
......
...@@ -34,8 +34,9 @@ ...@@ -34,8 +34,9 @@
#include <iterator> #include <iterator>
// IWYU pragma: no_include <ext/alloc_traits.h> // IWYU pragma: no_include <ext/alloc_traits.h>
#include <memory> // for shared_ptr, unique_ptr #include <memory> // for shared_ptr, unique_ptr
#include <stdexcept> #include <stdexcept> // for out_of_range
#include <string> // for string #include <string> // for string
#include <utility> // for move
#include <vector> // for vector #include <vector> // for vector
/** /**
...@@ -158,6 +159,7 @@ ...@@ -158,6 +159,7 @@
*/ */
namespace caosdb::transaction { namespace caosdb::transaction {
using caosdb::entity::Entity; using caosdb::entity::Entity;
using caosdb::entity::FileDescriptor;
using ProtoEntity = caosdb::entity::v1alpha1::Entity; using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using caosdb::entity::v1alpha1::EntityTransactionService; using caosdb::entity::v1alpha1::EntityTransactionService;
using caosdb::entity::v1alpha1::FileDownloadResponse; using caosdb::entity::v1alpha1::FileDownloadResponse;
...@@ -181,49 +183,98 @@ static const std::string logger_name = "caosdb::transaction"; ...@@ -181,49 +183,98 @@ static const std::string logger_name = "caosdb::transaction";
/** /**
* Abstract base class for the results of a Transaction. * Abstract base class for the results of a Transaction.
*/ */
class ResultSet { template <class T> class ResultSet {
class iterator; class iterator;
public: public:
virtual ~ResultSet() = default; virtual ~ResultSet() = default;
[[nodiscard]] virtual auto Size() const noexcept -> int = 0; [[nodiscard]] virtual auto Size() const noexcept -> int = 0;
[[nodiscard]] virtual auto At(const int index) const -> const Entity & = 0; [[nodiscard]] virtual auto At(const int index) const -> const T & = 0;
auto begin() const -> iterator; auto begin() const -> iterator;
auto end() const -> iterator; auto end() const -> iterator;
private: private:
class iterator : public std::iterator<std::output_iterator_tag, Entity> { class iterator : public std::iterator<std::output_iterator_tag, T> {
public: public:
explicit iterator(const ResultSet *result_set, int index = 0); explicit iterator(const ResultSet<T> *result_set, int index = 0);
auto operator*() const -> const Entity &; auto operator*() const -> const T &;
auto operator++() -> iterator &; auto operator++() -> iterator &;
auto operator++(int) -> iterator; auto operator++(int) -> iterator;
auto operator!=(const iterator &rhs) const -> bool; auto operator!=(const iterator &rhs) const -> bool;
private: private:
int current_index = 0; int current_index = 0;
const ResultSet *result_set; const ResultSet<T> *result_set;
}; };
}; };
template <class T>
ResultSet<T>::iterator::iterator(const ResultSet *result_set_param, int index)
: current_index(index), result_set(result_set_param) {}
template <class T> auto ResultSet<T>::iterator::operator*() const -> const T & {
return this->result_set->At(current_index);
}
template <class T>
auto ResultSet<T>::iterator::operator++() -> ResultSet<T>::iterator & {
current_index++;
return *this;
}
template <class T>
auto ResultSet<T>::iterator::operator++(int) -> ResultSet<T>::iterator {
iterator tmp(*this);
operator++();
return tmp;
}
template <class T>
auto ResultSet<T>::iterator::operator!=(const iterator &rhs) const -> bool {
return this->current_index != rhs.current_index;
}
template <class T> auto ResultSet<T>::begin() const -> ResultSet<T>::iterator {
return ResultSet<T>::iterator(this, 0);
}
template <class T> auto ResultSet<T>::end() const -> ResultSet<T>::iterator {
return ResultSet<T>::iterator(this, Size());
}
template <class T> class IMultiResultSet : public ResultSet<T> {
public:
virtual ~IMultiResultSet() = default;
inline explicit IMultiResultSet(std::vector<std::unique_ptr<T>> 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 -> const T & override {
return *(this->items.at(index));
}
protected:
std::vector<std::unique_ptr<T>> items;
};
class FilesResultSet : public IMultiResultSet<FileDescriptor> {
public:
~FilesResultSet() = default;
explicit FilesResultSet(
std::vector<std::unique_ptr<FileDescriptor>> result_set);
};
/** /**
* Container with results of a transaction. * Container with results of a transaction.
* *
* In contrast to UniqueResult, this one can also hold multiple entities or zero * In contrast to UniqueResult, this one can also hold multiple entities or zero
* entities. * entities.
*/ */
class MultiResultSet : public ResultSet { class MultiResultSet : public IMultiResultSet<Entity> {
public: public:
~MultiResultSet() = default; ~MultiResultSet() = default;
explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set); explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set);
[[nodiscard]] inline auto Size() const noexcept -> int override {
return this->entities.size();
}
[[nodiscard]] inline auto At(const int index) const
-> const Entity & override {
return *(this->entities.at(index));
}
std::vector<std::unique_ptr<Entity>> entities;
}; };
/** /**
...@@ -232,7 +283,7 @@ public: ...@@ -232,7 +283,7 @@ public:
* In contrast to MultiResultSet, this one guarantees to hold exactly one * In contrast to MultiResultSet, this one guarantees to hold exactly one
* entity. * entity.
*/ */
class UniqueResult : public ResultSet { class UniqueResult : public ResultSet<Entity> {
public: public:
~UniqueResult() = default; ~UniqueResult() = default;
explicit inline UniqueResult(ProtoEntity *protoEntity) explicit inline UniqueResult(ProtoEntity *protoEntity)
...@@ -285,6 +336,29 @@ public: ...@@ -285,6 +336,29 @@ public:
Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service, Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service,
std::shared_ptr<FileTransmissionService::Stub> file_service); std::shared_ptr<FileTransmissionService::Stub> file_service);
/**
* 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) noexcept
-> StatusCode;
auto DownloadFilesById(const std::string &path) noexcept -> StatusCode;
auto RetrieveAndDownloadFilesByQuery(const std::string &query) noexcept
-> StatusCode;
auto DownloadFilesByQuery(const std::string &query) noexcept -> StatusCode;
/**
* Return a ResultSet<FileDescriptor>.
*
* The file result set is empty until the transaction terminates.
*/
auto GetDownloadedFiles() const noexcept -> const FilesResultSet &;
/** /**
* Add an entity id to this transaction for retrieval. * Add an entity id to this transaction for retrieval.
* *
...@@ -364,12 +438,13 @@ public: ...@@ -364,12 +438,13 @@ public:
/** /**
* Return the current status of the transaction. * Return the current status of the transaction.
*/ */
[[nodiscard]] inline auto GetStatus() const -> TransactionStatus { [[nodiscard]] inline auto GetStatus() const noexcept -> TransactionStatus {
return this->status; return this->status;
} }
[[nodiscard]] inline auto GetResultSet() const -> const ResultSet & { [[nodiscard]] inline auto GetResultSet() const noexcept
const ResultSet *result_set = this->result_set.get(); -> const ResultSet<Entity> & {
const ResultSet<Entity> *result_set = this->result_set.get();
return *result_set; return *result_set;
} }
...@@ -380,7 +455,7 @@ public: ...@@ -380,7 +455,7 @@ public:
* this transaction. In all other cases, the return value will be * this transaction. In all other cases, the return value will be
* -1. * -1.
*/ */
[[nodiscard]] inline auto GetCountResult() const -> long { [[nodiscard]] inline auto GetCountResult() const noexcept -> long {
return query_count; return query_count;
} }
...@@ -421,7 +496,7 @@ public: ...@@ -421,7 +496,7 @@ public:
private: private:
bool has_query = false; bool has_query = false;
TransactionType transaction_type = TransactionType::NONE; TransactionType transaction_type = TransactionType::NONE;
mutable std::unique_ptr<ResultSet> result_set; mutable std::unique_ptr<ResultSet<Entity>> result_set;
mutable TransactionStatus status = TransactionStatus::INITIAL(); mutable TransactionStatus status = TransactionStatus::INITIAL();
std::shared_ptr<EntityTransactionService::Stub> entity_service; std::shared_ptr<EntityTransactionService::Stub> entity_service;
std::shared_ptr<FileTransmissionService::Stub> file_service; std::shared_ptr<FileTransmissionService::Stub> file_service;
......
...@@ -112,38 +112,8 @@ using grpc::ClientAsyncResponseReader; ...@@ -112,38 +112,8 @@ using grpc::ClientAsyncResponseReader;
using ProtoEntity = caosdb::entity::v1alpha1::Entity; using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using grpc::CompletionQueue; using grpc::CompletionQueue;
ResultSet::iterator::iterator(const ResultSet *result_set_param, int index)
: current_index(index), result_set(result_set_param) {}
auto ResultSet::iterator::operator*() const -> const Entity & {
return this->result_set->At(current_index);
}
auto ResultSet::iterator::operator++() -> ResultSet::iterator & {
current_index++;
return *this;
}
auto ResultSet::iterator::operator++(int) -> ResultSet::iterator {
iterator tmp(*this);
operator++();
return tmp;
}
auto ResultSet::iterator::operator!=(const iterator &rhs) const -> bool {
return this->current_index != rhs.current_index;
}
auto ResultSet::begin() const -> ResultSet::iterator {
return ResultSet::iterator(this, 0);
}
auto ResultSet::end() const -> ResultSet::iterator {
return ResultSet::iterator(this, Size());
}
MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set) MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
: entities(std::move(result_set)) {} : IMultiResultSet<Entity>(std::move(result_set)) {}
[[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & { [[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & {
const Entity *result = this->entity.get(); const Entity *result = this->entity.get();
...@@ -160,6 +130,9 @@ Transaction::Transaction( ...@@ -160,6 +130,9 @@ Transaction::Transaction(
this->entity_service = std::move(entity_service); this->entity_service = std::move(entity_service);
this->file_service = std::move(file_service); this->file_service = std::move(file_service);
this->query_count = -1; this->query_count = -1;
}
auto Transaction::RetrieveById(const std::string &id) noexcept -> StatusCode {
ASSERT_CAN_ADD_RETRIEVAL ASSERT_CAN_ADD_RETRIEVAL
auto *sub_request = this->request->add_requests(); auto *sub_request = this->request->add_requests();
......
...@@ -182,7 +182,7 @@ TEST(test_transaction, test_multi_deletion) { ...@@ -182,7 +182,7 @@ TEST(test_transaction, test_multi_deletion) {
auto configuration = InsecureConnectionConfiguration(host, 8000); auto configuration = InsecureConnectionConfiguration(host, 8000);
Connection connection(configuration); Connection connection(configuration);
auto transaction = connection.CreateTransaction(); auto transaction = connection.CreateTransaction();
EXPECT_EQ(transaction.GetStatus().GetCode(), StatusCode::INITIAL); EXPECT_EQ(transaction->GetStatus().GetCode(), StatusCode::INITIAL);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
auto status = transaction->DeleteById("asdf"); auto status = transaction->DeleteById("asdf");
EXPECT_EQ(status, StatusCode::GO_ON); EXPECT_EQ(status, StatusCode::GO_ON);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment