couchbase 3.2.2 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/binding.gyp +5 -0
  2. package/deps/lcb/CMakeLists.txt +1 -1
  3. package/deps/lcb/CONTRIBUTING.md +1 -1
  4. package/deps/lcb/README.markdown +2 -2
  5. package/deps/lcb/RELEASE_NOTES.markdown +84 -17
  6. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  7. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  8. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
  9. package/deps/lcb/doc/Doxyfile +1 -1
  10. package/deps/lcb/example/minimal/query.c +9 -7
  11. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  12. package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
  13. package/deps/lcb/include/libcouchbase/couchbase.h +55 -1
  14. package/deps/lcb/include/libcouchbase/error.h +6 -1
  15. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  16. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  17. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  18. package/deps/lcb/libcouchbase.gyp +353 -349
  19. package/deps/lcb/packaging/deb/control +1 -1
  20. package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
  21. package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
  22. package/deps/lcb/src/capi/cmd_counter.hh +18 -0
  23. package/deps/lcb/src/capi/cmd_exists.hh +18 -0
  24. package/deps/lcb/src/capi/cmd_get.hh +17 -0
  25. package/deps/lcb/src/capi/cmd_get_replica.hh +20 -1
  26. package/deps/lcb/src/capi/cmd_query.cc +13 -0
  27. package/deps/lcb/src/capi/cmd_query.hh +22 -14
  28. package/deps/lcb/src/capi/cmd_remove.hh +18 -0
  29. package/deps/lcb/src/capi/cmd_search.hh +6 -0
  30. package/deps/lcb/src/capi/cmd_store.hh +28 -21
  31. package/deps/lcb/src/capi/cmd_subdoc.hh +30 -0
  32. package/deps/lcb/src/capi/cmd_touch.hh +18 -0
  33. package/deps/lcb/src/capi/cmd_unlock.hh +18 -0
  34. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  35. package/deps/lcb/src/capi/collection_qualifier.hh +6 -8
  36. package/deps/lcb/src/cntl.cc +42 -8
  37. package/deps/lcb/src/dns-srv.cc +5 -3
  38. package/deps/lcb/src/errmap.cc +5 -9
  39. package/deps/lcb/src/errmap.h +7 -3
  40. package/deps/lcb/src/handler.cc +24 -18
  41. package/deps/lcb/src/internal.h +2 -1
  42. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  43. package/deps/lcb/src/mcserver/mcserver.cc +8 -5
  44. package/deps/lcb/src/mcserver/negotiate.cc +42 -17
  45. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  46. package/deps/lcb/src/n1ql/n1ql.cc +5 -1
  47. package/deps/lcb/src/n1ql/query_handle.cc +80 -44
  48. package/deps/lcb/src/n1ql/query_handle.hh +41 -3
  49. package/deps/lcb/src/operations/counter.cc +13 -1
  50. package/deps/lcb/src/operations/exists.cc +14 -2
  51. package/deps/lcb/src/operations/get.cc +14 -2
  52. package/deps/lcb/src/operations/get_replica.cc +18 -6
  53. package/deps/lcb/src/operations/observe.cc +1 -1
  54. package/deps/lcb/src/operations/remove.cc +13 -1
  55. package/deps/lcb/src/operations/store.cc +13 -1
  56. package/deps/lcb/src/operations/subdoc.cc +13 -2
  57. package/deps/lcb/src/operations/touch.cc +14 -2
  58. package/deps/lcb/src/operations/unlock.cc +14 -2
  59. package/deps/lcb/src/search/search_handle.cc +26 -8
  60. package/deps/lcb/src/search/search_handle.hh +29 -0
  61. package/deps/lcb/src/ssl/ssl_common.c +7 -8
  62. package/deps/lcb/src/tracing/span.cc +43 -10
  63. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  64. package/deps/lcb/src/utilities.cc +21 -0
  65. package/deps/lcb/src/utilities.h +3 -0
  66. package/deps/lcb/src/views/view_handle.cc +13 -5
  67. package/deps/lcb/src/views/view_handle.hh +29 -0
  68. package/deps/lcb/tests/CMakeLists.txt +21 -0
  69. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  70. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  71. package/deps/lcb/tests/iotests/mock-environment.cc +25 -1
  72. package/deps/lcb/tests/iotests/mock-environment.h +49 -1
  73. package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
  74. package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
  75. package/deps/lcb/tests/iotests/serverparams.h +7 -2
  76. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  77. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  78. package/deps/lcb/tests/iotests/t_get.cc +14 -4
  79. package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
  80. package/deps/lcb/tests/iotests/t_ratelimit.cc +729 -0
  81. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  82. package/deps/lcb/tests/iotests/testutil.cc +342 -0
  83. package/deps/lcb/tests/iotests/testutil.h +164 -0
  84. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  85. package/deps/lcb/tests/mocksupport/server.c +0 -1
  86. package/deps/lcb/tools/cbc.cc +7 -0
  87. package/dist/analyticsexecutor.js +2 -2
  88. package/dist/analyticsindexmanager.js +512 -524
  89. package/dist/binarycollection.d.ts +17 -0
  90. package/dist/binding.d.ts +2 -0
  91. package/dist/binding.js +1 -1
  92. package/dist/bindingutilities.js +9 -1
  93. package/dist/bucketmanager.d.ts +32 -23
  94. package/dist/bucketmanager.js +197 -189
  95. package/dist/cluster.js +37 -36
  96. package/dist/collection.js +17 -23
  97. package/dist/collectionmanager.js +181 -200
  98. package/dist/connection.js +6 -3
  99. package/dist/connspec.js +5 -1
  100. package/dist/couchbase.js +7 -14
  101. package/dist/datastructures.js +239 -310
  102. package/dist/diagnosticsexecutor.js +70 -85
  103. package/dist/errors.d.ts +18 -0
  104. package/dist/errors.js +26 -2
  105. package/dist/eventingfunctionmanager.js +267 -294
  106. package/dist/httpexecutor.js +31 -38
  107. package/dist/logging.js +1 -1
  108. package/dist/queryexecutor.js +3 -3
  109. package/dist/queryindexmanager.js +236 -263
  110. package/dist/scope.js +8 -2
  111. package/dist/searchexecutor.js +3 -0
  112. package/dist/searchindexmanager.js +240 -271
  113. package/dist/searchquery.d.ts +17 -0
  114. package/dist/searchquery.js +22 -1
  115. package/dist/searchtypes.d.ts +7 -2
  116. package/dist/searchtypes.js +2 -2
  117. package/dist/usermanager.js +250 -263
  118. package/dist/utilities.d.ts +3 -2
  119. package/dist/utilities.js +16 -4
  120. package/dist/viewexecutor.js +1 -1
  121. package/dist/viewindexmanager.js +131 -150
  122. package/package.json +1 -1
  123. package/src/connection.cpp +2 -0
  124. package/src/constants.cpp +2 -0
  125. package/src/instance.cpp +8 -1
  126. package/src/instance.h +1 -0
  127. package/src/uv-plugin-all.cpp +1 -0
  128. package/dist/cas.d.ts +0 -0
  129. package/dist/cas.js +0 -1
@@ -95,32 +95,52 @@ static void prepare_rowcb(lcb_INSTANCE *instance, int, const lcb_RESPQUERY *row)
95
95
 
96
96
  bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &rc)
97
97
  {
98
- first_error_message.clear();
99
- first_error_code = 0;
98
+ first_error.message.clear();
99
+ first_error.code = 0;
100
100
 
101
101
  Json::Value meta;
102
- if (!Json::Reader().parse(row, row + row_len, meta)) {
102
+ if (!Json::Reader(Json::Features::strictMode()).parse(row, row + row_len, meta)) {
103
103
  return false;
104
104
  }
105
105
  const Json::Value &errors = meta["errors"];
106
106
  if (errors.isArray() && !errors.empty()) {
107
107
  const Json::Value &err = errors[0];
108
+ if (err.isMember("retry") && err["retry"].isBool()) {
109
+ first_error.retry = err["retry"].asBool();
110
+ }
111
+ if (err.isMember("reason") && err["reason"].isObject()) {
112
+ const Json::Value &reason = err["reason"];
113
+ if (reason.isMember("code") && reason["code"].isNumeric()) {
114
+ first_error.reason_code = reason["code"].asInt();
115
+ }
116
+ }
108
117
  const Json::Value &msg = err["msg"];
109
118
  if (msg.isString()) {
110
- first_error_message = msg.asString();
119
+ first_error.message = msg.asString();
111
120
  }
112
121
  const Json::Value &code = err["code"];
113
122
  if (code.isNumeric()) {
114
- first_error_code = code.asUInt();
115
- switch (first_error_code) {
123
+ first_error.code = code.asUInt();
124
+ switch (first_error.code) {
116
125
  case 3000:
117
126
  rc = LCB_ERR_PARSING_FAILURE;
118
127
  break;
119
128
  case 12009:
120
129
  rc = LCB_ERR_DML_FAILURE;
121
- if (first_error_message.find("CAS mismatch") != std::string::npos) {
130
+ if (first_error.message.find("CAS mismatch") != std::string::npos) {
122
131
  rc = LCB_ERR_CAS_MISMATCH;
123
132
  }
133
+ switch (first_error.reason_code) {
134
+ case 12033:
135
+ rc = LCB_ERR_CAS_MISMATCH;
136
+ break;
137
+ case 17014:
138
+ rc = LCB_ERR_DOCUMENT_NOT_FOUND;
139
+ break;
140
+ case 17012:
141
+ rc = LCB_ERR_DOCUMENT_EXISTS;
142
+ break;
143
+ }
124
144
  break;
125
145
  case 4040:
126
146
  case 4050:
@@ -132,29 +152,34 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
132
152
  break;
133
153
  case 4300:
134
154
  rc = LCB_ERR_PLANNING_FAILURE;
135
- if (!first_error_message.empty()) {
155
+ if (!first_error.message.empty()) {
136
156
  std::regex already_exists("index.+already exists");
137
- if (std::regex_search(first_error_message, already_exists)) {
157
+ if (std::regex_search(first_error.message, already_exists)) {
138
158
  rc = LCB_ERR_INDEX_EXISTS;
139
159
  }
140
160
  }
141
161
  break;
142
162
  case 5000:
143
163
  rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
144
- if (!first_error_message.empty()) {
164
+ if (!first_error.message.empty()) {
145
165
  std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
146
- if (std::regex_search(first_error_message, already_exists)) {
166
+ std::regex not_found("index.+not found");
167
+ if (std::regex_search(first_error.message, already_exists)) {
147
168
  rc = LCB_ERR_INDEX_EXISTS;
148
- } else {
149
- std::regex not_found("index.+not found");
150
- if (std::regex_search(first_error_message, not_found)) {
151
- rc = LCB_ERR_INDEX_NOT_FOUND;
152
- }
169
+ } else if (std::regex_search(first_error.message, not_found)) {
170
+ rc = LCB_ERR_INDEX_NOT_FOUND;
171
+ } else if (first_error.message.find(
172
+ "Limit for number of indexes that can be created per scope has been reached") !=
173
+ std::string::npos) {
174
+ rc = LCB_ERR_QUOTA_LIMITED;
153
175
  }
154
176
  }
155
177
  break;
156
- case 12004:
157
178
  case 12016:
179
+ /* see MB-50643 */
180
+ first_error.retry = false;
181
+ /* fallthrough */
182
+ case 12004:
158
183
  rc = LCB_ERR_INDEX_NOT_FOUND;
159
184
  break;
160
185
  case 12003:
@@ -166,15 +191,23 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
166
191
  case 13014:
167
192
  rc = LCB_ERR_AUTHENTICATION_FAILURE;
168
193
  break;
194
+
195
+ case 1191:
196
+ case 1192:
197
+ case 1193:
198
+ case 1194:
199
+ rc = LCB_ERR_RATE_LIMITED;
200
+ break;
201
+
169
202
  default:
170
- if (first_error_code >= 4000 && first_error_code < 5000) {
203
+ if (first_error.code >= 4000 && first_error.code < 5000) {
171
204
  rc = LCB_ERR_PLANNING_FAILURE;
172
- } else if (first_error_code >= 5000 && first_error_code < 6000) {
205
+ } else if (first_error.code >= 5000 && first_error.code < 6000) {
173
206
  rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
174
- } else if (first_error_code >= 10000 && first_error_code < 11000) {
207
+ } else if (first_error.code >= 10000 && first_error.code < 11000) {
175
208
  rc = LCB_ERR_AUTHENTICATION_FAILURE;
176
- } else if ((first_error_code >= 12000 && first_error_code < 13000) ||
177
- (first_error_code >= 14000 && first_error_code < 15000)) {
209
+ } else if ((first_error.code >= 12000 && first_error.code < 13000) ||
210
+ (first_error.code >= 14000 && first_error.code < 15000)) {
178
211
  rc = LCB_ERR_INDEX_FAILURE;
179
212
  }
180
213
  break;
@@ -195,8 +228,8 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
195
228
  resp->ctx.endpoint = resp->htresp->ctx.endpoint;
196
229
  resp->ctx.endpoint_len = resp->htresp->ctx.endpoint_len;
197
230
  }
198
- resp->ctx.client_context_id = client_context_id.c_str();
199
- resp->ctx.client_context_id_len = client_context_id.size();
231
+ resp->ctx.client_context_id = client_context_id_.c_str();
232
+ resp->ctx.client_context_id_len = client_context_id_.size();
200
233
  resp->ctx.statement = statement_.c_str();
201
234
  resp->ctx.statement_len = statement_.size();
202
235
 
@@ -208,14 +241,18 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
208
241
  resp->row = static_cast<const char *>(meta_buf.iov_base);
209
242
  resp->nrow = meta_buf.iov_len;
210
243
  parse_meta(resp->row, resp->nrow, resp->ctx.rc);
211
- if (!first_error_message.empty()) {
212
- resp->ctx.first_error_message = first_error_message.c_str();
213
- resp->ctx.first_error_message_len = first_error_message.size();
244
+ resp->ctx.error_response_body = resp->row;
245
+ resp->ctx.error_response_body_len = resp->nrow;
246
+ if (!first_error.message.empty()) {
247
+ resp->ctx.first_error_message = first_error.message.c_str();
248
+ resp->ctx.first_error_message_len = first_error.message.size();
249
+ }
250
+ resp->ctx.first_error_code = first_error.code;
251
+ if (span_ != nullptr) {
252
+ lcb::trace::finish_http_span(span_, this);
253
+ span_ = nullptr;
214
254
  }
215
- resp->ctx.first_error_code = first_error_code;
216
- LCBTRACE_ADD_RETRIES(span_, retries_);
217
255
 
218
- LCBTRACE_HTTP_FINISH(span_);
219
256
  if (http_request_ != nullptr) {
220
257
  http_request_->span = nullptr;
221
258
  }
@@ -346,27 +383,27 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
346
383
  const uint32_t default_backoff = 100 /* ms */;
347
384
  if (rc == LCB_ERR_PREPARED_STATEMENT_FAILURE) {
348
385
  lcb_log(LOGARGS(this, TRACE), LOGFMT "Will retry request. rc: %s, code: %d, msg: %s", LOGID(this),
349
- lcb_strerror_short(rc), first_error_code, first_error_message.c_str());
386
+ lcb_strerror_short(rc), first_error.code, first_error.message.c_str());
350
387
  return {1, default_backoff};
351
388
  }
352
- if (first_error_code == 13014 &&
389
+ if (first_error.code == 13014 &&
353
390
  LCBT_SETTING(instance_, auth)->mode() == LCBAUTH_MODE_DYNAMIC) { // datastore.couchbase.insufficient_credentials
354
391
  auto result = request_credentials(LCBAUTH_REASON_AUTHENTICATION_FAILURE);
355
392
  bool credentials_found = result == LCBAUTH_RESULT_OK;
356
393
  lcb_log(LOGARGS(this, TRACE),
357
394
  LOGFMT "Invalidate credentials and retry request. creds: %s, rc: %s, code: %d, msg: %s", LOGID(this),
358
- credentials_found ? "ok" : "not_found", lcb_strerror_short(rc), first_error_code,
359
- first_error_message.c_str());
395
+ credentials_found ? "ok" : "not_found", lcb_strerror_short(rc), first_error.code,
396
+ first_error.message.c_str());
360
397
  return {credentials_found, default_backoff};
361
398
  }
362
- if (!first_error_message.empty()) {
399
+ if (!first_error.message.empty()) {
363
400
  for (const auto &magic_string : wtf_magic_strings) {
364
- if (first_error_message.find(magic_string) != std::string::npos) {
401
+ if (first_error.message.find(magic_string) != std::string::npos) {
365
402
  lcb_log(LOGARGS(this, TRACE),
366
403
  LOGFMT
367
404
  "Special error message detected. Will retry request. rc: %s (update to %s), code: %d, msg: %s",
368
405
  LOGID(this), lcb_strerror_short(rc), lcb_strerror_short(LCB_ERR_PREPARED_STATEMENT_FAILURE),
369
- first_error_code, first_error_message.c_str());
406
+ first_error.code, first_error.message.c_str());
370
407
  rc = LCB_ERR_PREPARED_STATEMENT_FAILURE;
371
408
  return {1, default_backoff};
372
409
  }
@@ -376,7 +413,7 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
376
413
  if (rc == LCB_SUCCESS) {
377
414
  return {0, 0};
378
415
  }
379
- return lcb_query_should_retry(instance_->settings, this, rc);
416
+ return lcb_query_should_retry(instance_->settings, this, rc, first_error.retry);
380
417
  }
381
418
 
382
419
  lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
@@ -426,7 +463,7 @@ lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
426
463
  lcb_log(LOGARGS(this, TRACE),
427
464
  LOGFMT "execute query: %.*s, idempotent=%s, timeout=%uus, grace_period=%uus, client_context_id=\"%s\"",
428
465
  LOGID(this), (int)body.size(), body.c_str(), idempotent_ ? "true" : "false", timeout,
429
- LCBT_SETTING(instance_, n1ql_grace_period), client_context_id.c_str());
466
+ LCBT_SETTING(instance_, n1ql_grace_period), client_context_id_.c_str());
430
467
  return rc;
431
468
  }
432
469
 
@@ -517,10 +554,10 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
517
554
  if (ccid.isNull()) {
518
555
  char buf[32];
519
556
  size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
520
- client_context_id.assign(buf, nbuf);
521
- json["client_context_id"] = client_context_id;
557
+ client_context_id_.assign(buf, nbuf);
558
+ json["client_context_id"] = client_context_id_;
522
559
  } else {
523
- client_context_id = ccid.asString();
560
+ client_context_id_ = ccid.asString();
524
561
  }
525
562
  if (json.isMember("readonly") && json["readonly"].asBool()) {
526
563
  idempotent_ = true;
@@ -554,8 +591,7 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
554
591
  }
555
592
  if (instance_->settings->tracer) {
556
593
  parent_span_ = cmd->parent_span();
557
- LCBTRACE_HTTP_START(instance_->settings, client_context_id.c_str(), parent_span_, LCBTRACE_TAG_SERVICE_N1QL,
558
- LCBTRACE_THRESHOLD_QUERY, span_);
594
+ span_ = lcb::trace::start_http_span_with_statement(instance_->settings, this, statement_);
559
595
  }
560
596
  }
561
597
 
@@ -27,6 +27,19 @@
27
27
  #include "capi/cmd_query.hh"
28
28
  #include "query_cache.hh"
29
29
 
30
+ /**
31
+ * @private
32
+ */
33
+ namespace lcb
34
+ {
35
+ struct query_error {
36
+ std::string message{};
37
+ uint32_t code{};
38
+ bool retry{false};
39
+ uint32_t reason_code{0};
40
+ };
41
+ } // namespace lcb
42
+
30
43
  /**
31
44
  * @private
32
45
  */
@@ -246,6 +259,32 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
246
259
  return LCB_SUCCESS;
247
260
  }
248
261
 
262
+ static lcbtrace_THRESHOLDOPTS service()
263
+ {
264
+ return LCBTRACE_THRESHOLD_QUERY;
265
+ }
266
+
267
+ static const std::string &operation_name()
268
+ {
269
+ static std::string name = LCBTRACE_OP_QUERY;
270
+ return name;
271
+ }
272
+
273
+ lcbtrace_SPAN *parent_span() const
274
+ {
275
+ return parent_span_;
276
+ }
277
+
278
+ const std::string &client_context_id() const
279
+ {
280
+ return client_context_id_;
281
+ }
282
+
283
+ int retries() const
284
+ {
285
+ return retries_;
286
+ }
287
+
249
288
  private:
250
289
  void on_backoff();
251
290
 
@@ -269,9 +308,8 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
269
308
  Json::Value json;
270
309
  /** String of the original statement. Cached here to avoid jsoncpp lookups */
271
310
  std::string statement_;
272
- std::string client_context_id;
273
- std::string first_error_message{};
274
- uint32_t first_error_code{};
311
+ std::string client_context_id_;
312
+ lcb::query_error first_error{};
275
313
 
276
314
  /** Whether we're retrying this */
277
315
  int retries_{0};
@@ -141,6 +141,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of(lcb_CMDCOUNTER *cmd, con
141
141
  return cmd->on_behalf_of(std::string(data, data_len));
142
142
  }
143
143
 
144
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of_extra_privilege(lcb_CMDCOUNTER *cmd, const char *privilege,
145
+ size_t privilege_len)
146
+ {
147
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
148
+ }
149
+
144
150
  static lcb_STATUS counter_validate(lcb_INSTANCE *instance, const lcb_CMDCOUNTER *cmd)
145
151
  {
146
152
  if (cmd->key().empty()) {
@@ -184,6 +190,12 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
184
190
  if (err != LCB_SUCCESS) {
185
191
  return err;
186
192
  }
193
+ for (const auto &privilege : cmd->extra_privileges()) {
194
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
195
+ if (err != LCB_SUCCESS) {
196
+ return err;
197
+ }
198
+ }
187
199
  }
188
200
 
189
201
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -237,7 +249,7 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
237
249
  }
238
250
  memcpy(SPAN_BUFFER(&packet->kh_span) + offset, &expiry, sizeof(expiry));
239
251
 
240
- LCBTRACE_KV_START(instance->settings, packet->opaque, cmd, LCBTRACE_OP_COUNTER, rdata->span);
252
+ rdata->span = lcb::trace::start_kv_span(instance->settings, packet, cmd);
241
253
  TRACE_ARITHMETIC_BEGIN(instance, &hdr, cmd);
242
254
  LCB_SCHED_ADD(instance, pipeline, packet);
243
255
  return LCB_SUCCESS;
@@ -112,6 +112,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of(lcb_CMDEXISTS *cmd, const
112
112
  return cmd->on_behalf_of(std::string(data, data_len));
113
113
  }
114
114
 
115
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of_extra_privilege(lcb_CMDEXISTS *cmd, const char *privilege,
116
+ size_t privilege_len)
117
+ {
118
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
119
+ }
120
+
115
121
  static lcb_STATUS exists_validate(lcb_INSTANCE *instance, const lcb_CMDEXISTS *cmd)
116
122
  {
117
123
  if (cmd->key().empty()) {
@@ -139,6 +145,12 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
139
145
  if (err != LCB_SUCCESS) {
140
146
  return err;
141
147
  }
148
+ for (const auto &privilege : cmd->extra_privileges()) {
149
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
150
+ if (err != LCB_SUCCESS) {
151
+ return err;
152
+ }
153
+ }
142
154
  }
143
155
 
144
156
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -153,7 +165,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
153
165
 
154
166
  hdr.request.opcode = PROTOCOL_BINARY_CMD_GET_META;
155
167
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
156
- hdr.request.bodylen = htonl(ntohs(hdr.request.keylen));
168
+ hdr.request.bodylen = ntohl(mcreq_get_key_size(&hdr));
157
169
  hdr.request.opaque = pkt->opaque;
158
170
  hdr.request.cas = 0;
159
171
 
@@ -168,7 +180,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
168
180
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
169
181
  }
170
182
 
171
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_EXISTS, pkt->u_rdata.reqdata.span);
183
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
172
184
  LCB_SCHED_ADD(instance, pipeline, pkt)
173
185
  TRACE_EXISTS_BEGIN(instance, &hdr, cmd);
174
186
  return LCB_SUCCESS;
@@ -129,6 +129,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of(lcb_CMDGET *cmd, const char
129
129
  return cmd->on_behalf_of(std::string(data, data_len));
130
130
  }
131
131
 
132
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of_extra_privilege(lcb_CMDGET *cmd, const char *privilege,
133
+ size_t privilege_len)
134
+ {
135
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
136
+ }
137
+
132
138
  static lcb_STATUS get_validate(lcb_INSTANCE *instance, const lcb_CMDGET *cmd)
133
139
  {
134
140
  if (cmd->key().empty()) {
@@ -159,6 +165,12 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
159
165
  if (err != LCB_SUCCESS) {
160
166
  return err;
161
167
  }
168
+ for (const auto &privilege : cmd->extra_privileges()) {
169
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
170
+ if (err != LCB_SUCCESS) {
171
+ return err;
172
+ }
173
+ }
162
174
  }
163
175
 
164
176
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -187,7 +199,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
187
199
 
188
200
  hdr.request.opcode = opcode;
189
201
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
190
- hdr.request.bodylen = htonl(extlen + ffextlen + ntohs(hdr.request.keylen));
202
+ hdr.request.bodylen = htonl(extlen + ffextlen + mcreq_get_key_size(&hdr));
191
203
  hdr.request.opaque = pkt->opaque;
192
204
  hdr.request.cas = 0;
193
205
 
@@ -209,7 +221,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
209
221
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, &expiry, sizeof(expiry));
210
222
  }
211
223
 
212
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_GET, rdata->span);
224
+ rdata->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
213
225
  LCB_SCHED_ADD(instance, pl, pkt)
214
226
  TRACE_GET_BEGIN(instance, &hdr, cmd);
215
227
  return LCB_SUCCESS;
@@ -144,6 +144,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of(lcb_CMDGETREPLICA *cm
144
144
  return cmd->on_behalf_of(std::string(data, data_len));
145
145
  }
146
146
 
147
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of_extra_privilege(lcb_CMDGETREPLICA *cmd,
148
+ const char *privilege, size_t privilege_len)
149
+ {
150
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
151
+ }
152
+
147
153
  struct RGetCookie : mc_REQDATAEX {
148
154
  RGetCookie(void *cookie, lcb_INSTANCE *instance, get_replica_mode, int vb);
149
155
  void decref()
@@ -349,20 +355,26 @@ static lcb_STATUS get_replica_schedule(lcb_INSTANCE *instance, std::shared_ptr<l
349
355
  return LCB_ERR_NO_MATCHING_SERVER;
350
356
  }
351
357
 
352
- /* Initialize the cookie */
353
- auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
354
- rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
355
- rck->deadline =
356
- rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
357
-
358
358
  std::vector<std::uint8_t> framing_extras;
359
359
  if (cmd->want_impersonation()) {
360
360
  lcb_STATUS err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
361
361
  if (err != LCB_SUCCESS) {
362
362
  return err;
363
363
  }
364
+ for (const auto &privilege : cmd->extra_privileges()) {
365
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
366
+ if (err != LCB_SUCCESS) {
367
+ return err;
368
+ }
369
+ }
364
370
  }
365
371
 
372
+ /* Initialize the cookie */
373
+ auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
374
+ rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
375
+ rck->deadline =
376
+ rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
377
+
366
378
  /* Initialize the packet */
367
379
  req.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
368
380
  req.request.opcode = PROTOCOL_BINARY_CMD_GET_REPLICA;
@@ -129,7 +129,7 @@ static void handle_observe_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_CALLBAC
129
129
  opc->remaining--;
130
130
  if (opc->remaining == 0) {
131
131
  TRACE_OBSERVE_END(instance, pkt);
132
- LCBTRACE_KV_FINISH(pl, pkt, resp, 0);
132
+ lcb::trace::finish_kv_span(pl, pkt, nullptr);
133
133
  delete opc;
134
134
  }
135
135
  }
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of(lcb_CMDREMOVE *cmd, const
117
117
  return cmd->on_behalf_of(std::string(data, data_len));
118
118
  }
119
119
 
120
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of_extra_privilege(lcb_CMDREMOVE *cmd, const char *privilege,
121
+ size_t privilege_len)
122
+ {
123
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
124
+ }
125
+
120
126
  static lcb_STATUS remove_validate(lcb_INSTANCE *instance, const lcb_CMDREMOVE *cmd)
121
127
  {
122
128
  if (cmd->key().empty()) {
@@ -159,6 +165,12 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
159
165
  if (err != LCB_SUCCESS) {
160
166
  return err;
161
167
  }
168
+ for (const auto &privilege : cmd->extra_privileges()) {
169
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
170
+ if (err != LCB_SUCCESS) {
171
+ return err;
172
+ }
173
+ }
162
174
  }
163
175
 
164
176
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -188,7 +200,7 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
188
200
  if (!framing_extras.empty()) {
189
201
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
190
202
  }
191
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_REMOVE, pkt->u_rdata.reqdata.span);
203
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
192
204
  TRACE_REMOVE_BEGIN(instance, &hdr, cmd);
193
205
  LCB_SCHED_ADD(instance, pl, pkt)
194
206
  return LCB_SUCCESS;
@@ -234,6 +234,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of(lcb_CMDSTORE *cmd, const c
234
234
  return cmd->on_behalf_of(std::string(data, data_len));
235
235
  }
236
236
 
237
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of_extra_privilege(lcb_CMDSTORE *cmd, const char *privilege,
238
+ size_t privilege_len)
239
+ {
240
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
241
+ }
242
+
237
243
  struct DurStoreCtx : mc_REQDATAEX {
238
244
  lcb_INSTANCE *instance;
239
245
  lcb_U16 persist_to;
@@ -400,6 +406,12 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
400
406
  if (err != LCB_SUCCESS) {
401
407
  return err;
402
408
  }
409
+ for (const auto &privilege : cmd->extra_privileges()) {
410
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
411
+ if (err != LCB_SUCCESS) {
412
+ return err;
413
+ }
414
+ }
403
415
  }
404
416
  auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
405
417
  hdr.request.magic = (ffextlen == 0) ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -485,7 +497,7 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
485
497
  if (cmd->is_replace_semantics()) {
486
498
  packet->flags |= MCREQ_F_REPLACE_SEMANTICS;
487
499
  }
488
- LCBTRACE_KVSTORE_START(instance->settings, packet->opaque, cmd, cmd->operation_name(), rdata->span);
500
+ rdata->span = lcb::trace::start_kv_span_with_durability(instance->settings, packet, cmd);
489
501
  LCB_SCHED_ADD(instance, pipeline, packet)
490
502
 
491
503
  TRACE_STORE_BEGIN(instance, &hdr, cmd);
@@ -409,6 +409,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of(lcb_CMDSUBDOC *cmd, const
409
409
  return cmd->on_behalf_of(std::string(data, data_len));
410
410
  }
411
411
 
412
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of_extra_privilege(lcb_CMDSUBDOC *cmd, const char *privilege,
413
+ size_t privilege_len)
414
+ {
415
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
416
+ }
417
+
412
418
  namespace SubdocCmdTraits
413
419
  {
414
420
  enum Options {
@@ -798,6 +804,12 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
798
804
  if (rc != LCB_SUCCESS) {
799
805
  return rc;
800
806
  }
807
+ for (const auto &privilege : cmd->extra_privileges()) {
808
+ rc = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
809
+ if (rc != LCB_SUCCESS) {
810
+ return rc;
811
+ }
812
+ }
801
813
  }
802
814
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
803
815
  auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
@@ -853,8 +865,7 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
853
865
  MCREQ_PKT_RDATA(pkt)->start +
854
866
  cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
855
867
  MCREQ_PKT_RDATA(pkt)->nsubreq = cmd->specs().specs().size();
856
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd,
857
- ctx.is_mutate() ? LCBTRACE_OP_MUTATEIN : LCBTRACE_OP_LOOKUPIN, MCREQ_PKT_RDATA(pkt)->span);
868
+ MCREQ_PKT_RDATA(pkt)->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
858
869
  LCB_SCHED_ADD(instance, pl, pkt)
859
870
  return LCB_SUCCESS;
860
871
  }
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of(lcb_CMDTOUCH *cmd, const c
117
117
  return cmd->on_behalf_of(std::string(data, data_len));
118
118
  }
119
119
 
120
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of_extra_privilege(lcb_CMDTOUCH *cmd, const char *privilege,
121
+ size_t privilege_len)
122
+ {
123
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
124
+ }
125
+
120
126
  static lcb_STATUS touch_validate(lcb_INSTANCE *instance, const lcb_CMDTOUCH *cmd)
121
127
  {
122
128
  if (cmd->key().empty()) {
@@ -142,6 +148,12 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
142
148
  if (err != LCB_SUCCESS) {
143
149
  return err;
144
150
  }
151
+ for (const auto &privilege : cmd->extra_privileges()) {
152
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
153
+ if (err != LCB_SUCCESS) {
154
+ return err;
155
+ }
156
+ }
145
157
  }
146
158
 
147
159
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -158,7 +170,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
158
170
  hdr.request.cas = 0;
159
171
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
160
172
  hdr.request.opaque = pkt->opaque;
161
- hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen + ntohs(hdr.request.keylen));
173
+ hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen + mcreq_get_key_size(&hdr));
162
174
 
163
175
  memcpy(SPAN_BUFFER(&pkt->kh_span), &hdr, sizeof(hdr));
164
176
  std::size_t offset = sizeof(hdr);
@@ -174,7 +186,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
174
186
  pkt->u_rdata.reqdata.deadline =
175
187
  pkt->u_rdata.reqdata.start +
176
188
  cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
177
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_TOUCH, pkt->u_rdata.reqdata.span);
189
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
178
190
  LCB_SCHED_ADD(instance, pl, pkt);
179
191
  TRACE_TOUCH_BEGIN(instance, &hdr, cmd);
180
192
  return LCB_SUCCESS;