LCOV - code coverage report
Current view: top level - shared_model/builders/protobuf/builder_templates - query_template.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 67 69 97.1 %
Date: 2018-12-05 17:11:35 Functions: 237 274 86.5 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       6             : #ifndef IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP
       7             : #define IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP
       8             : 
       9             : #include <boost/range/algorithm/for_each.hpp>
      10             : 
      11             : #include "backend/protobuf/queries/proto_query.hpp"
      12             : #include "builders/protobuf/unsigned_proto.hpp"
      13             : #include "interfaces/common_objects/types.hpp"
      14             : #include "interfaces/transaction.hpp"
      15             : #include "queries.pb.h"
      16             : #include "validators/default_validator.hpp"
      17             : 
      18             : namespace shared_model {
      19             :   namespace proto {
      20             : 
      21             :     /**
      22             :      * Template query builder for creating new types of query builders by
      23             :      * means of replacing template parameters
      24             :      * @tparam S -- field counter for checking that all required fields are
      25             :      * set
      26             :      * @tparam SV -- stateless validator called when build method is invoked
      27             :      * @tparam BT -- build type of built object returned by build method
      28             :      */
      29             :     template <int S = 0,
      30             :               typename SV = validation::DefaultUnsignedQueryValidator,
      31             :               typename BT = UnsignedWrapper<Query>>
      32             :     class DEPRECATED TemplateQueryBuilder {
      33             :      private:
      34             :       template <int, typename, typename>
      35             :       friend class TemplateQueryBuilder;
      36             : 
      37             :       enum RequiredFields {
      38             :         CreatedTime,
      39             :         CreatorAccountId,
      40             :         QueryField,
      41             :         QueryCounter,
      42             :         TOTAL
      43             :       };
      44             : 
      45             :       template <int s>
      46             :       using NextBuilder = TemplateQueryBuilder<S | (1 << s), SV, BT>;
      47             : 
      48             :       using ProtoQuery = iroha::protocol::Query;
      49             : 
      50             :       template <int Sp>
      51             :       TemplateQueryBuilder(const TemplateQueryBuilder<Sp, SV, BT> &o)
      52          19 :           : query_(o.query_), stateless_validator_(o.stateless_validator_) {}
      53             : 
      54             :       /**
      55             :        * Make transformation on copied content
      56             :        * @tparam Transformation - callable type for changing the copy
      57             :        * @param t - transform function for proto object
      58             :        * @return new builder with updated state
      59             :        */
      60             :       template <int Fields, typename Transformation>
      61             :       auto transform(Transformation t) const {
      62         326 :         NextBuilder<Fields> copy = *this;
      63         326 :         t(copy.query_);
      64         326 :         return copy;
      65         326 :       }
      66             : 
      67             :       /**
      68             :        * Make query field transformation on copied object
      69             :        * @tparam Transformation - callable type for changing query
      70             :        * @param t - transform function for proto query
      71             :        * @return new builder with set query
      72             :        */
      73             :       template <typename Transformation>
      74             :       auto queryField(Transformation t) const {
      75         182 :         NextBuilder<QueryField> copy = *this;
      76         182 :         t(copy.query_.mutable_payload());
      77         182 :         return copy;
      78         182 :       }
      79             : 
      80             :      public:
      81             :       TemplateQueryBuilder(const SV &validator = SV())
      82         223 :           : stateless_validator_(validator) {}
      83             : 
      84             :       auto createdTime(interface::types::TimestampType created_time) const {
      85             :         return transform<CreatedTime>([&](auto &qry) {
      86         176 :           qry.mutable_payload()->mutable_meta()->set_created_time(created_time);
      87         176 :         });
      88             :       }
      89             : 
      90             :       auto creatorAccountId(
      91             :           const interface::types::AccountIdType &creator_account_id) const {
      92             :         return transform<CreatorAccountId>([&](auto &qry) {
      93         226 :           qry.mutable_payload()->mutable_meta()->set_creator_account_id(
      94         226 :               creator_account_id);
      95         226 :         });
      96             :       }
      97             : 
      98             :       auto queryCounter(interface::types::CounterType query_counter) const {
      99             :         return transform<QueryCounter>([&](auto &qry) {
     100         212 :           qry.mutable_payload()->mutable_meta()->set_query_counter(
     101         212 :               query_counter);
     102         212 :         });
     103             :       }
     104             : 
     105             :       auto getAccount(const interface::types::AccountIdType &account_id) const {
     106             :         return queryField([&](auto proto_query) {
     107          39 :           auto query = proto_query->mutable_get_account();
     108          39 :           query->set_account_id(account_id);
     109          39 :         });
     110             :       }
     111             : 
     112             :       auto getSignatories(
     113             :           const interface::types::AccountIdType &account_id) const {
     114             :         return queryField([&](auto proto_query) {
     115          23 :           auto query = proto_query->mutable_get_signatories();
     116          23 :           query->set_account_id(account_id);
     117          23 :         });
     118             :       }
     119             : 
     120             :       auto getAccountTransactions(
     121             :           const interface::types::AccountIdType &account_id) const {
     122             :         return queryField([&](auto proto_query) {
     123          19 :           auto query = proto_query->mutable_get_account_transactions();
     124          19 :           query->set_account_id(account_id);
     125          19 :         });
     126             :       }
     127             : 
     128             :       auto getAccountAssetTransactions(
     129             :           const interface::types::AccountIdType &account_id,
     130             :           const interface::types::AssetIdType &asset_id) const {
     131             :         return queryField([&](auto proto_query) {
     132          17 :           auto query = proto_query->mutable_get_account_asset_transactions();
     133          17 :           query->set_account_id(account_id);
     134          17 :           query->set_asset_id(asset_id);
     135          17 :         });
     136             :       }
     137             : 
     138             :       auto getAccountAssets(
     139             :           const interface::types::AccountIdType &account_id) const {
     140             :         return queryField([&](auto proto_query) {
     141          23 :           auto query = proto_query->mutable_get_account_assets();
     142          23 :           query->set_account_id(account_id);
     143          23 :         });
     144             :       }
     145             : 
     146             :       auto getAccountDetail(
     147             :           const interface::types::AccountIdType &account_id = "",
     148             :           const interface::types::AccountDetailKeyType &key = "",
     149             :           const interface::types::AccountIdType &writer = "") {
     150             :         return queryField([&](auto proto_query) {
     151          24 :           auto query = proto_query->mutable_get_account_detail();
     152          24 :           if (not account_id.empty()) {
     153          23 :             query->set_account_id(account_id);
     154          23 :           }
     155          24 :           if (not key.empty()) {
     156           2 :             query->set_key(key);
     157           2 :           }
     158          24 :           if (not writer.empty()) {
     159           2 :             query->set_writer(writer);
     160           2 :           }
     161          24 :         });
     162             :       }
     163             : 
     164             :       auto getRoles() const {
     165          21 :         return queryField(
     166             :             [&](auto proto_query) { proto_query->mutable_get_roles(); });
     167             :       }
     168             : 
     169             :       auto getAssetInfo(const interface::types::AssetIdType &asset_id) const {
     170             :         return queryField([&](auto proto_query) {
     171           6 :           auto query = proto_query->mutable_get_asset_info();
     172           6 :           query->set_asset_id(asset_id);
     173           6 :         });
     174             :       }
     175             : 
     176             :       auto getRolePermissions(
     177             :           const interface::types::RoleIdType &role_id) const {
     178             :         return queryField([&](auto proto_query) {
     179           5 :           auto query = proto_query->mutable_get_role_permissions();
     180           5 :           query->set_role_id(role_id);
     181           5 :         });
     182             :       }
     183             : 
     184             :       template <typename Collection>
     185             :       auto getTransactions(const Collection &hashes) const {
     186             :         return queryField([&](auto proto_query) {
     187          40 :           auto query = proto_query->mutable_get_transactions();
     188             :           boost::for_each(hashes, [&query](const auto &hash) {
     189          42 :             query->add_tx_hashes(toBinaryString(hash));
     190          42 :           });
     191          40 :         });
     192             :       }
     193             : 
     194             :       auto getTransactions(
     195             :           std::initializer_list<interface::types::HashType> hashes) const {
     196             :         return getTransactions(hashes);
     197             :       }
     198             : 
     199             :       template <typename... Hash>
     200             :       auto getTransactions(const Hash &... hashes) const {
     201             :         return getTransactions({hashes...});
     202             :       }
     203             : 
     204             :       auto getPendingTransactions() const {
     205             :         return queryField([&](auto proto_query) {
     206           5 :           proto_query->mutable_get_pending_transactions();
     207           5 :         });
     208             :       }
     209             : 
     210             :       auto build() const {
     211             :         static_assert(S == (1 << TOTAL) - 1, "Required fields are not set");
     212         223 :         if (not query_.has_payload()) {
     213           0 :           throw std::invalid_argument("Query missing payload");
     214             :         }
     215         223 :         if (query_.payload().query_case()
     216         223 :             == iroha::protocol::Query_Payload::QueryCase::QUERY_NOT_SET) {
     217           1 :           throw std::invalid_argument("Missing concrete query");
     218             :         }
     219         222 :         auto result = Query(iroha::protocol::Query(query_));
     220         222 :         auto answer = stateless_validator_.validate(result);
     221         221 :         if (answer.hasErrors()) {
     222           0 :           throw std::invalid_argument(answer.reason());
     223             :         }
     224         221 :         return BT(std::move(result));
     225         221 :       }
     226             : 
     227             :       static const int total = RequiredFields::TOTAL;
     228             : 
     229             :      private:
     230             :       ProtoQuery query_;
     231             :       SV stateless_validator_;
     232             :     };
     233             :   }  // namespace proto
     234             : }  // namespace shared_model
     235             : 
     236             : #endif  // IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP

Generated by: LCOV version 1.13