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

Merge branch 'f-query' into dev

parents b339a6b5 17acd8db
No related branches found
No related tags found
1 merge request!7ENH: Support FIND and COUNT queries
Pipeline #11714 passed
Pipeline: caosdb-cppinttest

#11725

    ......@@ -20,7 +20,7 @@
    cmake_minimum_required(VERSION 3.13)
    set(libcaosdb_VERSION 0.0.9)
    set(libcaosdb_VERSION 0.0.10)
    set(libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR 0)
    set(libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR 5)
    set(libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH 0)
    ......
    ......@@ -3,7 +3,7 @@ from conans import ConanFile, CMake, tools
    class CaosdbConan(ConanFile):
    name = "caosdb"
    version = "0.0.9"
    version = "0.0.10"
    license = "AGPL-3.0-or-later"
    author = "Timm C. Fitschen <t.fitschen@indiscale.com>"
    url = "https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib.git"
    ......
    ......@@ -208,7 +208,7 @@ private:
    class MultiResultSet : public ResultSet {
    public:
    ~MultiResultSet() = default;
    explicit MultiResultSet(MultiTransactionResponse *response);
    explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set);
    [[nodiscard]] inline auto Size() const noexcept -> int override {
    return this->entities.size();
    }
    ......@@ -357,6 +357,17 @@ public:
    return *result_set;
    }
    /**
    * Return the result of a count query
    *
    * Only meaningful if there was exactly one COUNT query executed in
    * this transaction. In all other cases, the return value will be
    * -1.
    */
    [[nodiscard]] inline auto GetCountResult() const -> long {
    return query_count;
    }
    /**
    * Return the number of sub-requests in this transaction.
    *
    ......@@ -367,6 +378,23 @@ public:
    return this->request->requests_size();
    }
    /**
    * Get a JSON representation of the response.
    *
    * For debugging.
    */
    inline auto ResponseToString() const -> const std::string {
    google::protobuf::util::JsonOptions options;
    std::string out;
    google::protobuf::util::MessageToJsonString(*this->response, &out, options);
    return out;
    }
    /**
    * Get a JSON representation of the request.
    *
    * For debugging.
    */
    inline auto RequestToString() const -> const std::string {
    google::protobuf::util::JsonOptions options;
    std::string out;
    ......@@ -383,6 +411,7 @@ private:
    MultiTransactionRequest *request;
    mutable MultiTransactionResponse *response;
    std::string error_message;
    mutable long query_count;
    };
    template <class InputIterator>
    ......
    ......@@ -96,6 +96,8 @@ using caosdb::entity::v1alpha1::MultiTransactionRequest;
    using caosdb::entity::v1alpha1::MultiTransactionResponse;
    using WrappedResponseCase =
    caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase;
    using QueryResponseCase =
    caosdb::entity::v1alpha1::RetrieveResponse::QueryResponseCase;
    using caosdb::utility::get_arena;
    using grpc::ClientAsyncResponseReader;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    ......@@ -131,28 +133,8 @@ auto ResultSet::end() const -> ResultSet::iterator {
    return ResultSet::iterator(this, Size());
    }
    MultiResultSet::MultiResultSet(MultiTransactionResponse *response) {
    auto *responses = response->mutable_responses();
    for (auto sub_response : *responses) {
    switch (sub_response.wrapped_response_case()) {
    case WrappedResponseCase::kRetrieveResponse:
    this->entities.push_back(std::make_unique<Entity>(
    sub_response.mutable_retrieve_response()->release_entity()));
    break;
    case WrappedResponseCase::kInsertResponse:
    this->entities.push_back(
    std::make_unique<Entity>(sub_response.release_insert_response()));
    break;
    case WrappedResponseCase::kDeleteResponse:
    this->entities.push_back(
    std::make_unique<Entity>(sub_response.release_insert_response()));
    break;
    default:
    // TODO(tf) Updates
    break;
    }
    }
    }
    MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
    : entities(std::move(result_set)) {}
    [[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & {
    const Entity *result = this->entity.get();
    ......@@ -166,6 +148,7 @@ Transaction::Transaction(
    response(google::protobuf::Arena::CreateMessage<MultiTransactionResponse>(
    get_arena())) {
    this->service_stub = std::move(service_stub);
    this->query_count = -1;
    }
    auto Transaction::RetrieveById(const std::string &id) noexcept -> StatusCode {
    ......@@ -197,7 +180,7 @@ auto Transaction::DeleteById(const std::string &id) noexcept -> StatusCode {
    auto *sub_request = this->request->add_requests();
    sub_request->mutable_delete_request()->set_id(id);
    this->status = TransactionStatus::READY();
    this->status = TransactionStatus::GO_ON();
    return this->status.GetCode();
    }
    ......@@ -300,13 +283,30 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus {
    auto *responses = this->response->mutable_responses(0);
    switch (responses->wrapped_response_case()) {
    case WrappedResponseCase::kRetrieveResponse: {
    auto *entity = responses->mutable_retrieve_response()->release_entity();
    auto *retrieve_response = responses->mutable_retrieve_response();
    switch (retrieve_response->query_response_case()) {
    case QueryResponseCase::kEntity: {
    auto *entity = retrieve_response->release_entity();
    if (!entity->errors().empty()) {
    this->status = TransactionStatus::TRANSACTION_ERROR(
    "The request returned with errors.");
    }
    this->result_set = std::make_unique<UniqueResult>(entity);
    } break;
    case QueryResponseCase::kSelectResult: {
    // TODO(tf) Select queries
    } break;
    case QueryResponseCase::kCountResult: {
    this->query_count = retrieve_response->count_result();
    std::vector<std::unique_ptr<Entity>> entities;
    this->result_set =
    std::make_unique<MultiResultSet>(std::move(entities));
    } break;
    default:
    // TODO(tf) Error
    break;
    }
    } break;
    case WrappedResponseCase::kUpdateResponse: {
    auto *updatedIdResponse = responses->mutable_update_response();
    if (!updatedIdResponse->entity_errors().empty()) {
    ......@@ -336,7 +336,28 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus {
    break;
    }
    } else {
    this->result_set = std::make_unique<MultiResultSet>(this->response);
    auto *responses = this->response->mutable_responses();
    std::vector<std::unique_ptr<Entity>> entities;
    for (auto sub_response : *responses) {
    switch (sub_response.wrapped_response_case()) {
    case WrappedResponseCase::kRetrieveResponse:
    entities.push_back(std::make_unique<Entity>(
    sub_response.mutable_retrieve_response()->release_entity()));
    break;
    case WrappedResponseCase::kInsertResponse:
    entities.push_back(
    std::make_unique<Entity>(sub_response.release_insert_response()));
    break;
    case WrappedResponseCase::kDeleteResponse:
    entities.push_back(
    std::make_unique<Entity>(sub_response.release_insert_response()));
    break;
    default:
    // TODO(tf) Updates
    break;
    }
    }
    this->result_set = std::make_unique<MultiResultSet>(std::move(entities));
    }
    return this->status;
    ......
    ......@@ -31,6 +31,7 @@
    #include "gtest/gtest_pred_impl.h" // for Test, TestInfo, TEST
    #include <memory> // for allocator, unique_ptr
    #include <string> // for string, basic_string
    #include <utility> // for move
    #include <vector> // for vector
    namespace caosdb::transaction {
    ......@@ -39,6 +40,7 @@ using caosdb::connection::Connection;
    using caosdb::exceptions::ConnectionError;
    using caosdb::transaction::UniqueResult;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    using caosdb::entity::v1alpha1::RetrieveResponse;
    TEST(test_transaction, create_transaction) {
    const auto *host = "localhost";
    ......@@ -92,21 +94,18 @@ TEST(test_transaction, test_retrieve_by_ids) {
    }
    TEST(test_transaction, test_multi_result_set_empty) {
    MultiTransactionResponse response;
    MultiResultSet rs(&response);
    std::vector<std::unique_ptr<Entity>> empty;
    MultiResultSet rs(std::move(empty));
    EXPECT_EQ(rs.Size(), 0);
    }
    TEST(test_transaction, test_multi_result_iterator) {
    MultiTransactionResponse response;
    response.add_responses()
    ->mutable_retrieve_response()
    ->mutable_entity()
    ->set_id("100");
    std::vector<std::unique_ptr<Entity>> one_elem;
    RetrieveResponse response;
    response.mutable_entity()->set_id("100");
    one_elem.push_back(std::make_unique<Entity>(response.release_entity()));
    MultiResultSet rs(&response);
    MultiResultSet rs(std::move(one_elem));
    EXPECT_EQ(rs.Size(), 1);
    for (const Entity &entity : rs) {
    ......@@ -126,18 +125,19 @@ TEST(test_transaction, test_unique_result_iterator) {
    }
    TEST(test_transaction, test_multi_result_set_one) {
    MultiTransactionResponse response;
    response.add_responses()
    ->mutable_retrieve_response()
    ->mutable_entity()
    ->set_id("100");
    std::vector<std::unique_ptr<Entity>> one_elem;
    RetrieveResponse response;
    response.mutable_entity()->set_id("100");
    one_elem.push_back(std::make_unique<Entity>(response.release_entity()));
    MultiResultSet rs(&response);
    MultiResultSet rs(std::move(one_elem));
    EXPECT_EQ(rs.Size(), 1);
    EXPECT_EQ(rs.At(0).GetId(), "100");
    }
    TEST(test_transaction, test_multi_result_set_three) {
    std::vector<std::unique_ptr<Entity>> three_elem;
    MultiTransactionResponse response;
    response.add_responses()
    ->mutable_retrieve_response()
    ......@@ -152,7 +152,14 @@ TEST(test_transaction, test_multi_result_set_three) {
    ->mutable_entity()
    ->set_id("102");
    MultiResultSet rs(&response);
    auto *responses = response.mutable_responses();
    std::vector<std::unique_ptr<Entity>> entities;
    for (auto sub_response : *responses) {
    three_elem.push_back(std::make_unique<Entity>(
    sub_response.mutable_retrieve_response()->release_entity()));
    }
    MultiResultSet rs(std::move(three_elem));
    EXPECT_EQ(rs.Size(), 3);
    EXPECT_TRUE(rs.At(1).HasErrors());
    }
    ......@@ -170,4 +177,16 @@ TEST(test_transaction, test_update_entity) {
    EXPECT_EQ(error, StatusCode::ORIGINAL_ENTITY_MISSING_ID);
    }
    TEST(test_transaction, test_multi_deletion) {
    const auto *host = "localhost";
    auto configuration = InsecureConnectionConfiguration(host, 8000);
    Connection connection(configuration);
    auto transaction = connection.CreateTransaction();
    EXPECT_EQ(transaction->GetStatus().GetCode(), StatusCode::INITIAL);
    for (int i = 0; i < 3; i++) {
    auto status = transaction->DeleteById("asdf");
    EXPECT_EQ(status, StatusCode::GO_ON);
    }
    }
    } // namespace caosdb::transaction
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment