diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h index 7be9d18ebf117942507ad33e26b13370bd56138a..f4332883791efe889d6683cbb5ed29fed88592ff 100644 --- a/include/caosdb/transaction.h +++ b/include/caosdb/transaction.h @@ -368,6 +368,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 -> int { + return query_count; + } + /** * Return the number of sub-requests in this transaction. * @@ -394,6 +405,7 @@ private: MultiTransactionRequest *request; mutable MultiTransactionResponse *response; std::string error_message; + mutable long query_count; }; template <class InputIterator> diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index 698218a820c403a60eb322fedf8cf58228a6c11b..f866ca337a382fab7d8a0d7032ed3600be886e7a 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -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; @@ -146,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 { @@ -282,12 +285,26 @@ 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(); - if (!entity->errors().empty()) { - this->status = TransactionStatus::TRANSACTION_ERROR( - "The request returned with errors."); + 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(); + } break; + default: + // TODO(tf) Error + break; } - this->result_set = std::make_unique<UniqueResult>(entity); } break; case WrappedResponseCase::kUpdateResponse: { auto *updatedIdResponse = responses->mutable_update_response();