hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
query_template.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP
7 #define IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP
8 
9 #include <boost/optional.hpp>
10 #include <boost/range/algorithm/for_each.hpp>
11 
16 #include "queries.pb.h"
18 
19 namespace shared_model {
20  namespace proto {
21 
30  template <int S = 0,
32  typename BT = UnsignedWrapper<Query>>
34  private:
35  template <int, typename, typename>
36  friend class TemplateQueryBuilder;
37 
38  enum RequiredFields {
39  CreatedTime,
40  CreatorAccountId,
41  QueryField,
42  QueryCounter,
43  TOTAL
44  };
45 
46  template <int s>
48 
49  using ProtoQuery = iroha::protocol::Query;
50 
51  template <int Sp>
53  : query_(o.query_), stateless_validator_(o.stateless_validator_) {}
54 
61  template <int Fields, typename Transformation>
62  auto transform(Transformation t) const {
63  NextBuilder<Fields> copy = *this;
64  t(copy.query_);
65  return copy;
66  }
67 
74  template <typename Transformation>
75  auto queryField(Transformation t) const {
76  NextBuilder<QueryField> copy = *this;
77  t(copy.query_.mutable_payload());
78  return copy;
79  }
80 
82  template <typename PageMetaPayload>
83  static auto setTxPaginationMeta(
84  PageMetaPayload *page_meta_payload,
86  const boost::optional<interface::types::HashType> &first_hash =
87  boost::none) {
88  page_meta_payload->set_page_size(page_size);
89  if (first_hash) {
90  page_meta_payload->set_first_tx_hash(first_hash->hex());
91  }
92  }
93 
94  public:
95  TemplateQueryBuilder(const SV &validator = SV())
96  : stateless_validator_(validator) {}
97 
98  auto createdTime(interface::types::TimestampType created_time) const {
99  return transform<CreatedTime>([&](auto &qry) {
100  qry.mutable_payload()->mutable_meta()->set_created_time(created_time);
101  });
102  }
103 
105  const interface::types::AccountIdType &creator_account_id) const {
106  return transform<CreatorAccountId>([&](auto &qry) {
107  qry.mutable_payload()->mutable_meta()->set_creator_account_id(
108  creator_account_id);
109  });
110  }
111 
112  auto queryCounter(interface::types::CounterType query_counter) const {
113  return transform<QueryCounter>([&](auto &qry) {
114  qry.mutable_payload()->mutable_meta()->set_query_counter(
115  query_counter);
116  });
117  }
118 
119  auto getAccount(const interface::types::AccountIdType &account_id) const {
120  return queryField([&](auto proto_query) {
121  auto query = proto_query->mutable_get_account();
122  query->set_account_id(account_id);
123  });
124  }
125 
127  const interface::types::AccountIdType &account_id) const {
128  return queryField([&](auto proto_query) {
129  auto query = proto_query->mutable_get_signatories();
130  query->set_account_id(account_id);
131  });
132  }
133 
135  const interface::types::AccountIdType &account_id,
137  const boost::optional<interface::types::HashType> &first_hash =
138  boost::none) const {
139  return queryField([&](auto proto_query) {
140  auto query = proto_query->mutable_get_account_transactions();
141  query->set_account_id(account_id);
142  setTxPaginationMeta(
143  query->mutable_pagination_meta(), page_size, first_hash);
144  });
145  }
146 
148  const interface::types::AccountIdType &account_id,
149  const interface::types::AssetIdType &asset_id,
151  const boost::optional<interface::types::HashType> &first_hash =
152  boost::none) const {
153  return queryField([&](auto proto_query) {
154  auto query = proto_query->mutable_get_account_asset_transactions();
155  query->set_account_id(account_id);
156  query->set_asset_id(asset_id);
157  setTxPaginationMeta(
158  query->mutable_pagination_meta(), page_size, first_hash);
159  });
160  }
161 
163  const interface::types::AccountIdType &account_id) const {
164  return queryField([&](auto proto_query) {
165  auto query = proto_query->mutable_get_account_assets();
166  query->set_account_id(account_id);
167  });
168  }
169 
171  const interface::types::AccountIdType &account_id = "",
173  const interface::types::AccountIdType &writer = "") {
174  return queryField([&](auto proto_query) {
175  auto query = proto_query->mutable_get_account_detail();
176  if (not account_id.empty()) {
177  query->set_account_id(account_id);
178  }
179  if (not key.empty()) {
180  query->set_key(key);
181  }
182  if (not writer.empty()) {
183  query->set_writer(writer);
184  }
185  });
186  }
187 
189  return queryField([&](auto proto_query) {
190  auto query = proto_query->mutable_get_block();
191  query->set_height(height);
192  });
193  }
194 
195  auto getRoles() const {
196  return queryField(
197  [&](auto proto_query) { proto_query->mutable_get_roles(); });
198  }
199 
200  auto getAssetInfo(const interface::types::AssetIdType &asset_id) const {
201  return queryField([&](auto proto_query) {
202  auto query = proto_query->mutable_get_asset_info();
203  query->set_asset_id(asset_id);
204  });
205  }
206 
208  const interface::types::RoleIdType &role_id) const {
209  return queryField([&](auto proto_query) {
210  auto query = proto_query->mutable_get_role_permissions();
211  query->set_role_id(role_id);
212  });
213  }
214 
215  template <typename Collection>
216  auto getTransactions(const Collection &hashes) const {
217  return queryField([&](auto proto_query) {
218  auto query = proto_query->mutable_get_transactions();
219  boost::for_each(hashes, [&query](const auto &hash) {
220  query->add_tx_hashes(hash.hex());
221  });
222  });
223  }
224 
226  std::initializer_list<interface::types::HashType> hashes) const {
227  return getTransactions(hashes);
228  }
229 
230  template <typename... Hash>
231  auto getTransactions(const Hash &... hashes) const {
232  return getTransactions({hashes...});
233  }
234 
235  auto getPendingTransactions() const {
236  return queryField([&](auto proto_query) {
237  proto_query->mutable_get_pending_transactions();
238  });
239  }
240 
241  auto build() const {
242  static_assert(S == (1 << TOTAL) - 1, "Required fields are not set");
243  if (not query_.has_payload()) {
244  throw std::invalid_argument("Query missing payload");
245  }
246  if (query_.payload().query_case()
247  == iroha::protocol::Query_Payload::QueryCase::QUERY_NOT_SET) {
248  throw std::invalid_argument("Missing concrete query");
249  }
250  auto result = Query(iroha::protocol::Query(query_));
251  auto answer = stateless_validator_.validate(result);
252  if (answer.hasErrors()) {
253  throw std::invalid_argument(answer.reason());
254  }
255  return BT(std::move(result));
256  }
257 
258  static const int total = RequiredFields::TOTAL;
259 
260  private:
261  ProtoQuery query_;
262  SV stateless_validator_;
263  };
264  } // namespace proto
265 } // namespace shared_model
266 
267 #endif // IROHA_PROTO_QUERY_BUILDER_TEMPLATE_HPP
uint64_t HeightType
Type of height (for Block, Proposal etc)
Definition: types.hpp:41
auto getTransactions(std::initializer_list< interface::types::HashType > hashes) const
Definition: query_template.hpp:225
auto createdTime(interface::types::TimestampType created_time) const
Definition: query_template.hpp:98
TemplateQueryBuilder(const SV &validator=SV())
Definition: query_template.hpp:95
auto getAccountAssets(const interface::types::AccountIdType &account_id) const
Definition: query_template.hpp:162
auto getRoles() const
Definition: query_template.hpp:195
std::string AccountDetailKeyType
Type of account detail key.
Definition: types.hpp:75
auto getAccount(const interface::types::AccountIdType &account_id) const
Definition: query_template.hpp:119
auto getAccountTransactions(const interface::types::AccountIdType &account_id, interface::types::TransactionsNumberType page_size, const boost::optional< interface::types::HashType > &first_hash=boost::none) const
Definition: query_template.hpp:134
auto getBlock(interface::types::HeightType height) const
Definition: query_template.hpp:188
auto getAccountDetail(const interface::types::AccountIdType &account_id="", const interface::types::AccountDetailKeyType &key="", const interface::types::AccountIdType &writer="")
Definition: query_template.hpp:170
std::string AccountIdType
Type of account id.
Definition: types.hpp:37
hash256_t hash(const T &pb)
Definition: pb_common.hpp:43
auto getSignatories(const interface::types::AccountIdType &account_id) const
Definition: query_template.hpp:126
auto creatorAccountId(const interface::types::AccountIdType &creator_account_id) const
Definition: query_template.hpp:104
QueryValidator< FieldValidator, QueryValidatorVisitor< FieldValidator >> DefaultUnsignedQueryValidator
Definition: default_validator.hpp:57
auto getTransactions(const Hash &...hashes) const
Definition: query_template.hpp:231
auto getRolePermissions(const interface::types::RoleIdType &role_id) const
Definition: query_template.hpp:207
auto getAssetInfo(const interface::types::AssetIdType &asset_id) const
Definition: query_template.hpp:200
uint16_t TransactionsNumberType
Type of a number of transactions in block and query response page.
Definition: types.hpp:79
uint64_t CounterType
Type of counter.
Definition: types.hpp:65
auto getAccountAssetTransactions(const interface::types::AccountIdType &account_id, const interface::types::AssetIdType &asset_id, interface::types::TransactionsNumberType page_size, const boost::optional< interface::types::HashType > &first_hash=boost::none) const
Definition: query_template.hpp:147
auto getPendingTransactions() const
Definition: query_template.hpp:235
auto queryCounter(interface::types::CounterType query_counter) const
Definition: query_template.hpp:112
Definition: command_executor.hpp:12
auto getTransactions(const Collection &hashes) const
Definition: query_template.hpp:216
auto build() const
Definition: query_template.hpp:241
Definition: query_template.hpp:33
std::string RoleIdType
Type of role (i.e admin, user)
Definition: types.hpp:49
#define DEPRECATED
Definition: swig_keyword_hider.hpp:15
uint64_t TimestampType
Type of timestamp.
Definition: types.hpp:61
std::string AssetIdType
Type of asset id.
Definition: types.hpp:53