couchbase 3.2.0 → 3.2.4

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 (175) hide show
  1. package/README.md +24 -18
  2. package/binding.gyp +88 -85
  3. package/deps/lcb/CMakeLists.txt +1 -1
  4. package/deps/lcb/CONTRIBUTING.md +1 -1
  5. package/deps/lcb/README.markdown +2 -2
  6. package/deps/lcb/RELEASE_NOTES.markdown +99 -14
  7. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  8. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  9. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -7
  10. package/deps/lcb/doc/Doxyfile +1 -1
  11. package/deps/lcb/example/CMakeLists.txt +4 -4
  12. package/deps/lcb/example/libuvdirect/main.c +39 -12
  13. package/deps/lcb/example/minimal/durability.cc +149 -0
  14. package/deps/lcb/example/minimal/query.c +11 -9
  15. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  16. package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
  17. package/deps/lcb/include/libcouchbase/couchbase.h +80 -5
  18. package/deps/lcb/include/libcouchbase/error.h +2 -0
  19. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  20. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  21. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  22. package/deps/lcb/libcouchbase.gyp +347 -349
  23. package/deps/lcb/packaging/deb/control +1 -1
  24. package/deps/lcb/src/analytics/analytics_handle.cc +13 -5
  25. package/deps/lcb/src/analytics/analytics_handle.hh +29 -0
  26. package/deps/lcb/src/bootstrap.cc +6 -3
  27. package/deps/lcb/src/capi/cmd_analytics.cc +12 -1
  28. package/deps/lcb/src/capi/cmd_analytics.hh +30 -0
  29. package/deps/lcb/src/capi/cmd_counter.hh +23 -0
  30. package/deps/lcb/src/capi/cmd_exists.hh +24 -1
  31. package/deps/lcb/src/capi/cmd_get.hh +22 -0
  32. package/deps/lcb/src/capi/cmd_get_replica.hh +23 -0
  33. package/deps/lcb/src/capi/cmd_http.hh +7 -0
  34. package/deps/lcb/src/capi/cmd_query.cc +11 -1
  35. package/deps/lcb/src/capi/cmd_query.hh +31 -0
  36. package/deps/lcb/src/capi/cmd_remove.hh +23 -0
  37. package/deps/lcb/src/capi/cmd_search.cc +6 -0
  38. package/deps/lcb/src/capi/cmd_search.hh +23 -0
  39. package/deps/lcb/src/capi/cmd_store.hh +33 -21
  40. package/deps/lcb/src/capi/cmd_subdoc.hh +35 -0
  41. package/deps/lcb/src/capi/cmd_touch.hh +23 -0
  42. package/deps/lcb/src/capi/cmd_unlock.hh +23 -0
  43. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  44. package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
  45. package/deps/lcb/src/cntl.cc +45 -11
  46. package/deps/lcb/src/crypto.cc +2 -2
  47. package/deps/lcb/src/dns-srv.cc +5 -3
  48. package/deps/lcb/src/errmap.cc +5 -9
  49. package/deps/lcb/src/errmap.h +7 -3
  50. package/deps/lcb/src/handler.cc +24 -18
  51. package/deps/lcb/src/hostlist.h +2 -2
  52. package/deps/lcb/src/http/http-priv.h +2 -2
  53. package/deps/lcb/src/http/http.cc +5 -2
  54. package/deps/lcb/src/instance.cc +20 -11
  55. package/deps/lcb/src/internal.h +9 -0
  56. package/deps/lcb/src/lcbio/connect.cc +14 -2
  57. package/deps/lcb/src/lcbio/connect.h +2 -2
  58. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  59. package/deps/lcb/src/lcbio/ioutils.cc +9 -10
  60. package/deps/lcb/src/lcbio/manager.cc +1 -1
  61. package/deps/lcb/src/mcserver/mcserver.cc +9 -6
  62. package/deps/lcb/src/mcserver/negotiate.cc +39 -17
  63. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  64. package/deps/lcb/src/n1ql/query_handle.cc +41 -19
  65. package/deps/lcb/src/n1ql/query_handle.hh +28 -1
  66. package/deps/lcb/src/operations/counter.cc +18 -5
  67. package/deps/lcb/src/operations/exists.cc +25 -4
  68. package/deps/lcb/src/operations/get.cc +39 -19
  69. package/deps/lcb/src/operations/get_replica.cc +28 -8
  70. package/deps/lcb/src/operations/observe.cc +1 -1
  71. package/deps/lcb/src/operations/ping.cc +8 -8
  72. package/deps/lcb/src/operations/pktfwd.cc +2 -1
  73. package/deps/lcb/src/operations/remove.cc +39 -22
  74. package/deps/lcb/src/operations/store.cc +18 -5
  75. package/deps/lcb/src/operations/subdoc.cc +18 -6
  76. package/deps/lcb/src/operations/touch.cc +34 -16
  77. package/deps/lcb/src/operations/unlock.cc +24 -5
  78. package/deps/lcb/src/packetutils.h +3 -2
  79. package/deps/lcb/src/retryq.cc +24 -5
  80. package/deps/lcb/src/search/search.cc +1 -0
  81. package/deps/lcb/src/search/search_handle.cc +30 -8
  82. package/deps/lcb/src/search/search_handle.hh +29 -0
  83. package/deps/lcb/src/settings.cc +1 -1
  84. package/deps/lcb/src/ssl/ssl_common.c +6 -7
  85. package/deps/lcb/src/tracing/span.cc +47 -14
  86. package/deps/lcb/src/tracing/tracer.cc +11 -2
  87. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  88. package/deps/lcb/src/utilities.cc +43 -0
  89. package/deps/lcb/src/utilities.h +53 -0
  90. package/deps/lcb/src/vbucket/vbucket.c +34 -33
  91. package/deps/lcb/src/views/view_handle.cc +13 -5
  92. package/deps/lcb/src/views/view_handle.hh +29 -0
  93. package/deps/lcb/tests/CMakeLists.txt +21 -0
  94. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  95. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  96. package/deps/lcb/tests/basic/t_n1qlstrings.cc +73 -0
  97. package/deps/lcb/tests/iotests/mock-environment.cc +30 -1
  98. package/deps/lcb/tests/iotests/mock-environment.h +49 -0
  99. package/deps/lcb/tests/iotests/mock-unit-test.cc +104 -6
  100. package/deps/lcb/tests/iotests/mock-unit-test.h +34 -0
  101. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  102. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  103. package/deps/lcb/tests/iotests/t_get.cc +109 -7
  104. package/deps/lcb/tests/iotests/t_http.cc +9 -4
  105. package/deps/lcb/tests/iotests/t_lock.cc +18 -0
  106. package/deps/lcb/tests/iotests/t_mutate.cc +157 -63
  107. package/deps/lcb/tests/iotests/t_n1ql.cc +330 -33
  108. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  109. package/deps/lcb/tests/iotests/testutil.cc +168 -0
  110. package/deps/lcb/tests/iotests/testutil.h +116 -0
  111. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  112. package/deps/lcb/tests/mocksupport/server.c +0 -1
  113. package/deps/lcb/tests/mocksupport/timeout.c +2 -2
  114. package/deps/lcb/tools/cbc.cc +7 -0
  115. package/dist/analyticsindexmanager.js +512 -524
  116. package/dist/binding.d.ts +3 -0
  117. package/dist/bindingutilities.js +4 -0
  118. package/dist/bucket.js +1 -1
  119. package/dist/bucketmanager.d.ts +31 -1
  120. package/dist/bucketmanager.js +194 -186
  121. package/dist/cluster.d.ts +7 -0
  122. package/dist/cluster.js +48 -38
  123. package/dist/collection.js +11 -17
  124. package/dist/collectionmanager.js +181 -197
  125. package/dist/connection.d.ts +3 -1
  126. package/dist/connection.js +27 -16
  127. package/dist/couchbase.d.ts +1 -0
  128. package/dist/couchbase.js +3 -13
  129. package/dist/datastructures.js +239 -310
  130. package/dist/diagnosticsexecutor.js +70 -85
  131. package/dist/errors.d.ts +70 -0
  132. package/dist/errors.js +96 -2
  133. package/dist/eventingfunctionmanager.d.ts +804 -0
  134. package/dist/eventingfunctionmanager.js +993 -0
  135. package/dist/httpexecutor.d.ts +2 -1
  136. package/dist/httpexecutor.js +30 -37
  137. package/dist/queryindexmanager.js +240 -266
  138. package/dist/scope.js +10 -4
  139. package/dist/sdspecs.d.ts +1 -1
  140. package/dist/searchexecutor.js +3 -0
  141. package/dist/searchindexmanager.js +240 -271
  142. package/dist/searchquery.d.ts +17 -0
  143. package/dist/searchquery.js +22 -1
  144. package/dist/searchtypes.d.ts +7 -2
  145. package/dist/searchtypes.js +2 -2
  146. package/dist/usermanager.js +251 -264
  147. package/dist/utilities.d.ts +2 -0
  148. package/dist/utilities.js +7 -2
  149. package/dist/viewexecutor.js +1 -1
  150. package/dist/viewindexmanager.js +131 -150
  151. package/package.json +1 -1
  152. package/src/addondata.cpp +58 -0
  153. package/src/addondata.h +40 -0
  154. package/src/binding.cpp +3 -1
  155. package/src/cas.h +2 -2
  156. package/src/connection.cpp +25 -178
  157. package/src/connection.h +8 -65
  158. package/src/connection_ops.cpp +57 -34
  159. package/src/constants.cpp +3 -0
  160. package/src/instance.cpp +235 -0
  161. package/src/instance.h +102 -0
  162. package/src/{connection_callbacks.cpp → instance_callbacks.cpp} +34 -34
  163. package/src/logger.cpp +11 -1
  164. package/src/logger.h +3 -0
  165. package/src/metrics.cpp +10 -0
  166. package/src/metrics.h +3 -0
  167. package/src/mutationtoken.h +2 -2
  168. package/src/opbuilder.h +13 -15
  169. package/src/respreader.cpp +1 -0
  170. package/src/respreader.h +6 -4
  171. package/src/tracespan.h +11 -11
  172. package/src/tracing.cpp +11 -0
  173. package/src/tracing.h +3 -0
  174. package/src/valueparser.h +5 -0
  175. package/deps/lcb/example/observe/durability.c +0 -110
@@ -114,6 +114,12 @@ struct subdoc_spec_options {
114
114
  * This structure is provided in an array to the lcb_CMDSUBDOC::specs field.
115
115
  */
116
116
  struct subdoc_spec {
117
+ bool is_lookup() const
118
+ {
119
+ return opcode_ == subdoc_opcode::get || opcode_ == subdoc_opcode::get_count ||
120
+ opcode_ == subdoc_opcode::get_fulldoc || opcode_ == subdoc_opcode::exist;
121
+ }
122
+
117
123
  subdoc_opcode opcode() const
118
124
  {
119
125
  return opcode_;
@@ -216,11 +222,23 @@ struct lcb_SUBDOCSPECS_ {
216
222
  return specs_;
217
223
  }
218
224
 
225
+ bool is_lookup() const
226
+ {
227
+ return specs_.empty() || specs_[0].is_lookup();
228
+ }
229
+
219
230
  private:
220
231
  std::vector<subdoc_spec> specs_{};
221
232
  };
222
233
 
223
234
  struct lcb_CMDSUBDOC_ {
235
+ const std::string &operation_name() const
236
+ {
237
+ static std::string lookup_in_name = LCBTRACE_OP_LOOKUPIN;
238
+ static std::string mutate_in_name = LCBTRACE_OP_MUTATEIN;
239
+ return specs_.is_lookup() ? lookup_in_name : mutate_in_name;
240
+ }
241
+
224
242
  const subdoc_options &options() const
225
243
  {
226
244
  return options_;
@@ -421,6 +439,22 @@ struct lcb_CMDSUBDOC_ {
421
439
  return preserve_expiry_;
422
440
  }
423
441
 
442
+ lcb_STATUS on_behalf_of(std::string user)
443
+ {
444
+ impostor_ = std::move(user);
445
+ return LCB_SUCCESS;
446
+ }
447
+
448
+ bool want_impersonation() const
449
+ {
450
+ return !impostor_.empty();
451
+ }
452
+
453
+ const std::string &impostor() const
454
+ {
455
+ return impostor_;
456
+ }
457
+
424
458
  private:
425
459
  lcb::collection_qualifier collection_{};
426
460
  std::chrono::microseconds timeout_{0};
@@ -434,6 +468,7 @@ struct lcb_CMDSUBDOC_ {
434
468
  subdoc_options options_{};
435
469
  lcb_SUBDOCSPECS_ specs_{};
436
470
  bool preserve_expiry_{false};
471
+ std::string impostor_{};
437
472
  };
438
473
 
439
474
  /**
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDTOUCH_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_TOUCH;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS expiry(std::uint32_t expiry)
32
38
  {
33
39
  expiry_ = expiry;
@@ -126,6 +132,22 @@ struct lcb_CMDTOUCH_ {
126
132
  return cookie_;
127
133
  }
128
134
 
135
+ lcb_STATUS on_behalf_of(std::string user)
136
+ {
137
+ impostor_ = std::move(user);
138
+ return LCB_SUCCESS;
139
+ }
140
+
141
+ bool want_impersonation() const
142
+ {
143
+ return !impostor_.empty();
144
+ }
145
+
146
+ const std::string &impostor() const
147
+ {
148
+ return impostor_;
149
+ }
150
+
129
151
  private:
130
152
  lcb::collection_qualifier collection_{};
131
153
  std::chrono::microseconds timeout_{0};
@@ -134,6 +156,7 @@ struct lcb_CMDTOUCH_ {
134
156
  lcbtrace_SPAN *parent_span_{nullptr};
135
157
  void *cookie_{nullptr};
136
158
  std::string key_{};
159
+ std::string impostor_{};
137
160
  };
138
161
 
139
162
  /**
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDUNLOCK_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_UNLOCK;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS cas(std::uint64_t cas)
32
38
  {
33
39
  if (cas == 0) {
@@ -129,6 +135,22 @@ struct lcb_CMDUNLOCK_ {
129
135
  return cookie_;
130
136
  }
131
137
 
138
+ lcb_STATUS on_behalf_of(std::string user)
139
+ {
140
+ impostor_ = std::move(user);
141
+ return LCB_SUCCESS;
142
+ }
143
+
144
+ bool want_impersonation() const
145
+ {
146
+ return !impostor_.empty();
147
+ }
148
+
149
+ const std::string &impostor() const
150
+ {
151
+ return impostor_;
152
+ }
153
+
132
154
  private:
133
155
  lcb::collection_qualifier collection_{};
134
156
  std::chrono::microseconds timeout_{0};
@@ -137,6 +159,7 @@ struct lcb_CMDUNLOCK_ {
137
159
  void *cookie_{nullptr};
138
160
  std::string key_{};
139
161
  std::uint64_t cas_{};
162
+ std::string impostor_{};
140
163
  };
141
164
 
142
165
  /**
@@ -47,6 +47,12 @@ struct lcb_VIEW_ERROR_CONTEXT_ {
47
47
 
48
48
  /** @private */
49
49
  struct lcb_CMDVIEW_ {
50
+ static const std::string &operation_name()
51
+ {
52
+ static std::string name = LCBTRACE_OP_VIEW;
53
+ return name;
54
+ }
55
+
50
56
  bool view_or_design_document_empty() const
51
57
  {
52
58
  return view_name_.empty() || design_document_name_.empty();
@@ -135,8 +135,8 @@ struct collection_qualifier {
135
135
  return true;
136
136
  }
137
137
 
138
- std::string scope_{};
139
- std::string collection_{};
138
+ std::string scope_{"_default"};
139
+ std::string collection_{"_default"};
140
140
  std::string spec_{};
141
141
  std::uint32_t resolved_collection_id_{0};
142
142
  bool resolved_{false};
@@ -21,6 +21,7 @@
21
21
  #include <lcbio/iotable.h>
22
22
  #include <mcserver/negotiate.h>
23
23
  #include <lcbio/ssl.h>
24
+ #include "n1ql/query_utils.hh"
24
25
 
25
26
  #define LOGARGS(instance, lvl) instance->settings, "cntl", LCB_LOG_##lvl, __FILE__, __LINE__
26
27
 
@@ -238,7 +239,35 @@ HANDLER(select_bucket_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, select
238
239
 
239
240
  HANDLER(log_redaction_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, log_redaction))}
240
241
 
241
- HANDLER(enable_tracing_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, use_tracing))}
242
+ HANDLER(enable_tracing_handler)
243
+ {
244
+ if (mode == LCB_CNTL_GET) {
245
+ RETURN_GET_ONLY(int, instance->settings->use_tracing)
246
+ } else if (mode == LCB_CNTL_SET) {
247
+ if (arg == nullptr) {
248
+ return LCB_ERR_INVALID_ARGUMENT;
249
+ }
250
+ int enabled = *(static_cast<int *>(arg));
251
+ if (enabled) {
252
+ if (instance->settings->use_tracing) {
253
+ /* do nothing */
254
+ return LCB_SUCCESS;
255
+ }
256
+ instance->settings->tracer = lcbtrace_new(instance, LCBTRACE_F_THRESHOLD);
257
+ instance->settings->use_tracing = true;
258
+ return LCB_SUCCESS;
259
+ } else {
260
+ if (instance->settings->use_tracing) {
261
+ lcbtrace_destroy(instance->settings->tracer);
262
+ instance->settings->tracer = nullptr;
263
+ instance->settings->use_tracing = false;
264
+ }
265
+ return LCB_SUCCESS;
266
+ }
267
+ } else {
268
+ return LCB_ERR_CONTROL_UNSUPPORTED_MODE;
269
+ }
270
+ }
242
271
 
243
272
  HANDLER(enable_errmap_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, use_errmap))}
244
273
 
@@ -354,7 +383,7 @@ HANDLER(force_sasl_mech_handler)
354
383
  free(instance->settings->sasl_mech_force);
355
384
  if (arg) {
356
385
  const char *s = reinterpret_cast<const char *>(arg);
357
- instance->settings->sasl_mech_force = strdup(s);
386
+ instance->settings->sasl_mech_force = lcb_strdup(s);
358
387
  for (char *p = instance->settings->sasl_mech_force; *p != '\0'; p++) {
359
388
  if (*p == ',') {
360
389
  *p = ' ';
@@ -553,7 +582,7 @@ HANDLER(client_string_handler)
553
582
  free(LCBT_SETTING(instance, client_string));
554
583
  LCBT_SETTING(instance, client_string) = nullptr;
555
584
  if (val) {
556
- char *p, *buf = strdup(val);
585
+ char *p, *buf = lcb_strdup(val);
557
586
  for (p = buf; *p != '\0'; p++) {
558
587
  switch (*p) {
559
588
  case '\n':
@@ -709,7 +738,7 @@ HANDLER(network_handler)
709
738
  free(LCBT_SETTING(instance, network));
710
739
  LCBT_SETTING(instance, network) = nullptr;
711
740
  if (val) {
712
- LCBT_SETTING(instance, network) = strdup(val);
741
+ LCBT_SETTING(instance, network) = lcb_strdup(val);
713
742
  }
714
743
  } else {
715
744
  *(const char **)arg = LCBT_SETTING(instance, network);
@@ -858,14 +887,19 @@ typedef struct {
858
887
 
859
888
  static lcb_STATUS convert_timevalue(const char *arg, u_STRCONVERT *u)
860
889
  {
861
- double dtmp;
862
- char *end = nullptr;
863
- errno = 0;
864
- dtmp = std::strtod(arg, &end);
865
- if (errno == ERANGE || end == arg) {
866
- return LCB_ERR_CONTROL_INVALID_ARGUMENT;
890
+ try {
891
+ auto tmo_ns = lcb_parse_golang_duration(arg);
892
+ u->u32 = static_cast<std::uint32_t>(std::chrono::duration_cast<std::chrono::microseconds>(tmo_ns).count());
893
+ } catch (const lcb_duration_parse_error &) {
894
+ double dtmp;
895
+ char *end = nullptr;
896
+ errno = 0;
897
+ dtmp = std::strtod(arg, &end);
898
+ if (errno == ERANGE || end == arg) {
899
+ return LCB_ERR_CONTROL_INVALID_ARGUMENT;
900
+ }
901
+ u->u32 = static_cast<std::uint32_t>(dtmp * (double)1000000);
867
902
  }
868
- u->u32 = static_cast<std::uint32_t>(dtmp * (double)1000000);
869
903
  return LCB_SUCCESS;
870
904
  }
871
905
 
@@ -221,7 +221,7 @@ lcb_STATUS lcbcrypto_encrypt_fields(lcb_INSTANCE *instance, lcbcrypto_CMDENCRYPT
221
221
  }
222
222
  if (changed) {
223
223
  std::string doc = Json::FastWriter().write(jdoc);
224
- cmd->out = strdup(doc.c_str());
224
+ cmd->out = lcb_strdup(doc.c_str());
225
225
  cmd->nout = strlen(cmd->out);
226
226
  }
227
227
  return LCB_SUCCESS;
@@ -383,7 +383,7 @@ lcb_STATUS lcbcrypto_decrypt_fields(lcb_INSTANCE *instance, lcbcrypto_CMDDECRYPT
383
383
  }
384
384
  if (changed) {
385
385
  std::string doc = Json::FastWriter().write(jdoc);
386
- cmd->out = strdup(doc.c_str());
386
+ cmd->out = lcb_strdup(doc.c_str());
387
387
  cmd->nout = strlen(cmd->out);
388
388
  }
389
389
  return LCB_SUCCESS;
@@ -105,9 +105,11 @@ lcb_STATUS lcb::dnssrv_query(const char *addr, Hostlist &hs)
105
105
  }
106
106
 
107
107
  for (cur = root; cur; cur = cur->pNext) {
108
- // Use the ASCII version of the DNS lookup structure
109
- const DNS_SRV_DATAA *srv = &cur->Data.SRV;
110
- hs.add(srv->pNameTarget, srv->wPort);
108
+ if(cur->wType == DNS_TYPE_SRV) {
109
+ // Use the ASCII version of the DNS lookup structure
110
+ const DNS_SRV_DATAA *srv = &cur->Data.SRV;
111
+ hs.add(srv->pNameTarget, srv->wPort);
112
+ }
111
113
  }
112
114
  DnsRecordListFree(root, DnsFreeRecordList);
113
115
  return LCB_SUCCESS;
@@ -131,8 +131,7 @@ ErrorMap::ParseStatus ErrorMap::parse(const char *s, size_t n, std::string &errm
131
131
  return PARSE_ERROR;
132
132
  }
133
133
 
134
- Json::Value::const_iterator ii = errsJson.begin();
135
- for (; ii != errsJson.end(); ++ii) {
134
+ for (Json::Value::const_iterator ii = errsJson.begin(); ii != errsJson.end(); ++ii) {
136
135
  // Key is the version in hex
137
136
  unsigned ec = 0;
138
137
  if (sscanf(ii.key().asCString(), "%x", &ec) != 1) {
@@ -155,14 +154,11 @@ ErrorMap::ParseStatus ErrorMap::parse(const char *s, size_t n, std::string &errm
155
154
  return PARSE_ERROR;
156
155
  }
157
156
 
158
- Json::Value::const_iterator jj = attrs.begin();
159
- for (; jj != attrs.end(); ++jj) {
160
- ErrorAttribute attr = getAttribute(jj->asString());
161
- if (attr == INVALID_ATTRIBUTE) {
162
- errmsg = "unknown attribute received";
163
- return UNKNOWN_VERSION;
157
+ for (const auto &jj : attrs) {
158
+ ErrorAttribute attr = getAttribute(jj.asString());
159
+ if (attr != INVALID_ATTRIBUTE) {
160
+ error.attributes.insert(attr);
164
161
  }
165
- error.attributes.insert(attr);
166
162
  }
167
163
  if (error.hasAttribute(AUTO_RETRY)) {
168
164
  const Json::Value &retryJson = errorJson["retry"];
@@ -124,7 +124,11 @@ enum ErrorAttribute {
124
124
  * This attribute means that the error is related to operating on \
125
125
  * a soft-deleted document. \
126
126
  */ \
127
- X(ITEM_DELETED, "item-deleted")
127
+ X(ITEM_DELETED, "item-deleted") \
128
+ /** \
129
+ * The error is related to rate limitation for the client (version 2) \
130
+ */ \
131
+ X(ITEM_RATE_LIMIT, "rate-limit")
128
132
 
129
133
  #define X(c, s) c,
130
134
  LCB_XERRMAP_ATTRIBUTES(X)
@@ -221,7 +225,7 @@ struct Error {
221
225
  uint16_t code;
222
226
  std::string shortname;
223
227
  std::string description;
224
- std::set< ErrorAttribute > attributes;
228
+ std::set<ErrorAttribute> attributes;
225
229
  SpecWrapper retry;
226
230
 
227
231
  Error() : code(-1) {}
@@ -280,7 +284,7 @@ class ErrorMap
280
284
  private:
281
285
  static const uint32_t MAX_VERSION;
282
286
  ErrorMap(const ErrorMap &);
283
- typedef std::map< uint16_t, Error > MapType;
287
+ typedef std::map<uint16_t, Error> MapType;
284
288
  MapType errors;
285
289
  uint32_t revision{0};
286
290
  uint32_t version{0};
@@ -157,6 +157,13 @@ lcb_STATUS lcb_map_error(lcb_INSTANCE *instance, int in)
157
157
  return LCB_ERR_DURABILITY_AMBIGUOUS;
158
158
  case PROTOCOL_BINARY_RESPONSE_LOCKED:
159
159
  return LCB_ERR_DOCUMENT_LOCKED;
160
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
161
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
162
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
163
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
164
+ return LCB_ERR_RATE_LIMITED;
165
+ case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
166
+ return LCB_ERR_QUOTA_LIMITED;
160
167
  default:
161
168
  if (instance != nullptr) {
162
169
  return instance->callbacks.errmap(instance, in);
@@ -269,20 +276,19 @@ void init_resp(lcb_INSTANCE *instance, mc_PIPELINE *pipeline, const MemcachedRes
269
276
  resp->ctx.key.assign(key, key_len);
270
277
  }
271
278
 
272
- auto *server = static_cast<lcb::Server *>(pipeline);
279
+ const auto *server = static_cast<lcb::Server *>(pipeline);
273
280
  const lcb_host_t *remote = server->curhost;
274
281
  if (remote) {
275
- std::stringstream ss;
282
+ resp->ctx.endpoint.reserve(sizeof(remote->host) + sizeof(remote->port) + 3);
276
283
  if (remote->ipv6) {
277
- ss << '[';
284
+ resp->ctx.endpoint.append("[");
278
285
  }
279
- ss << remote->host;
286
+ resp->ctx.endpoint.append(remote->host);
280
287
  if (remote->ipv6) {
281
- ss << ']';
288
+ resp->ctx.endpoint.append("]");
282
289
  }
283
- ss << ':';
284
- ss << remote->port;
285
- resp->ctx.endpoint = ss.str();
290
+ resp->ctx.endpoint.append(":");
291
+ resp->ctx.endpoint.append(remote->port);
286
292
  }
287
293
  }
288
294
 
@@ -421,7 +427,7 @@ static void H_get(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *
421
427
 
422
428
  void *freeptr = nullptr;
423
429
  maybe_decompress(o, response, &resp, &freeptr);
424
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
430
+ lcb::trace::finish_kv_span(pipeline, request, response);
425
431
  TRACE_GET_END(o, request, response, &resp);
426
432
  record_kv_op_latency("get", o, request);
427
433
  if (request->flags & MCREQ_F_REQEXT) {
@@ -455,7 +461,7 @@ static void H_exists(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
455
461
  resp.seqno = lcb_ntohll(resp.seqno);
456
462
  }
457
463
  }
458
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
464
+ lcb::trace::finish_kv_span(pipeline, request, response);
459
465
  TRACE_EXISTS_END(root, request, response, &resp);
460
466
  record_kv_op_latency("exists", root, request);
461
467
  invoke_callback(request, root, &resp, LCB_CALLBACK_EXISTS);
@@ -555,7 +561,7 @@ static void H_subdoc(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
555
561
  handle_error_info(response, resp);
556
562
  }
557
563
  }
558
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
564
+ lcb::trace::finish_kv_span(pipeline, request, response);
559
565
 
560
566
  if (cbtype == LCB_CALLBACK_SDLOOKUP) {
561
567
  record_kv_op_latency("lookup_in", o, request);
@@ -689,7 +695,7 @@ static void H_delete(mc_PIPELINE *pipeline, mc_PACKET *packet, MemcachedResponse
689
695
  init_resp(root, pipeline, response, packet, immerr, &resp);
690
696
  handle_error_info(response, resp);
691
697
  handle_mutation_token(root, response, packet, &resp.mt);
692
- LCBTRACE_KV_FINISH(pipeline, packet, resp, response->duration());
698
+ lcb::trace::finish_kv_span(pipeline, packet, response);
693
699
  TRACE_REMOVE_END(root, packet, response, &resp);
694
700
  record_kv_op_latency("remove", root, packet);
695
701
  invoke_callback(packet, root, &resp, LCB_CALLBACK_REMOVE);
@@ -797,7 +803,7 @@ static void H_observe_seqno(mc_PIPELINE *pipeline, mc_PACKET *request, Memcached
797
803
  /* Get the server for this command. Note that since this is a successful
798
804
  * operation, the server is never a dummy */
799
805
  }
800
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
806
+ lcb::trace::finish_kv_span(pipeline, request, response);
801
807
  invoke_callback(request, root, &resp, LCB_CALLBACK_OBSEQNO);
802
808
  }
803
809
 
@@ -829,7 +835,7 @@ static void H_store(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
829
835
  resp.rflags |= LCB_RESP_F_EXTDATA | LCB_RESP_F_FINAL;
830
836
  handle_mutation_token(root, response, request, &resp.mt);
831
837
  TRACE_STORE_END(root, request, response, &resp);
832
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
838
+ lcb::trace::finish_kv_span(pipeline, request, response);
833
839
  record_kv_op_latency_store(root, request, &resp);
834
840
  if (request->flags & MCREQ_F_REQEXT) {
835
841
  request->u_rdata.exdata->procs->handler(pipeline, request, LCB_CALLBACK_STORE, immerr, &resp);
@@ -854,7 +860,7 @@ static void H_arithmetic(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRes
854
860
  }
855
861
  resp.rflags |= LCB_RESP_F_FINAL;
856
862
  resp.ctx.cas = response->cas();
857
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
863
+ lcb::trace::finish_kv_span(pipeline, request, response);
858
864
  TRACE_ARITHMETIC_END(root, request, response, &resp);
859
865
  record_kv_op_latency("arithmetic", root, request);
860
866
  invoke_callback(request, root, &resp, LCB_CALLBACK_COUNTER);
@@ -941,7 +947,7 @@ static void H_noop(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
941
947
  {
942
948
  lcb_INSTANCE *root = get_instance(pipeline);
943
949
  lcb_RESPNOOP resp{};
944
- mc_REQDATAEX *exdata = request->u_rdata.exdata;
950
+ const mc_REQDATAEX *exdata = request->u_rdata.exdata;
945
951
 
946
952
  make_error(root, &resp, response, immerr, request);
947
953
 
@@ -955,7 +961,7 @@ static void H_touch(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
955
961
  init_resp(root, pipeline, response, request, immerr, &resp);
956
962
  handle_error_info(response, resp);
957
963
  resp.rflags |= LCB_RESP_F_FINAL;
958
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
964
+ lcb::trace::finish_kv_span(pipeline, request, response);
959
965
  TRACE_TOUCH_END(root, request, response, &resp);
960
966
  record_kv_op_latency("touch", root, request);
961
967
  invoke_callback(request, root, &resp, LCB_CALLBACK_TOUCH);
@@ -968,7 +974,7 @@ static void H_unlock(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
968
974
  init_resp(root, pipeline, response, request, immerr, &resp);
969
975
  handle_error_info(response, resp);
970
976
  resp.rflags |= LCB_RESP_F_FINAL;
971
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
977
+ lcb::trace::finish_kv_span(pipeline, request, response);
972
978
  TRACE_UNLOCK_END(root, request, response, &resp);
973
979
  record_kv_op_latency("unlock", root, request);
974
980
  invoke_callback(request, root, &resp, LCB_CALLBACK_UNLOCK);
@@ -134,8 +134,8 @@ struct Hostlist {
134
134
  return hosts[ix_];
135
135
  }
136
136
 
137
- std::vector<lcb_host_t> hosts;
138
- std::vector<const char *> hoststrs;
137
+ std::vector< lcb_host_t > hosts;
138
+ std::vector< const char * > hoststrs;
139
139
  };
140
140
  } // namespace lcb
141
141
  typedef lcb::Hostlist *hostlist_t;
@@ -36,8 +36,8 @@ namespace http
36
36
 
37
37
  // Simple object for header key and value
38
38
  struct Header {
39
- std::string key;
40
- std::string value;
39
+ std::string key{};
40
+ std::string value{};
41
41
  Header(const std::string &key_, const std::string &value_) : key(key_), value(value_) {}
42
42
  };
43
43
 
@@ -81,14 +81,14 @@ LIBCOUCHBASE_API int lcb_resphttp_is_final(const lcb_RESPHTTP *resp)
81
81
 
82
82
  LIBCOUCHBASE_API lcb_STATUS lcb_cmdhttp_create(lcb_CMDHTTP **cmd, lcb_HTTP_TYPE type)
83
83
  {
84
- *cmd = (lcb_CMDHTTP *)calloc(1, sizeof(lcb_CMDHTTP));
84
+ *cmd = new lcb_CMDHTTP{};
85
85
  (*cmd)->type = type;
86
86
  return LCB_SUCCESS;
87
87
  }
88
88
 
89
89
  LIBCOUCHBASE_API lcb_STATUS lcb_cmdhttp_destroy(lcb_CMDHTTP *cmd)
90
90
  {
91
- free(cmd);
91
+ delete cmd;
92
92
  return LCB_SUCCESS;
93
93
  }
94
94
 
@@ -729,6 +729,9 @@ Request::Request(lcb_INSTANCE *instance_, const void *cookie, const lcb_CMDHTTP
729
729
  callback(lcb_find_callback(instance, LCB_CALLBACK_HTTP)), io(instance->iotable), ioctx(nullptr), timer(nullptr),
730
730
  parser(nullptr), user_timeout(cmd->cmdflags & LCB_CMDHTTP_F_CASTMO ? cmd->cas : 0)
731
731
  {
732
+ for (const auto &pair : cmd->headers_) {
733
+ request_headers.emplace_back(Header(pair.first, pair.second));
734
+ }
732
735
  }
733
736
 
734
737
  Request::~Request()
@@ -322,12 +322,12 @@ static lcb_STATUS setup_ssl(lcb_INSTANCE *obj, const Connspec &params)
322
322
 
323
323
  if (lcb_getenv_nonempty("LCB_SSL_CACERT", optbuf, sizeof optbuf)) {
324
324
  lcb_log(LOGARGS(obj, INFO), "SSL CA certificate %s specified on environment", optbuf);
325
- settings->certpath = strdup(optbuf);
325
+ settings->certpath = lcb_strdup(optbuf);
326
326
  }
327
327
 
328
328
  if (lcb_getenv_nonempty("LCB_SSL_KEY", optbuf, sizeof optbuf)) {
329
329
  lcb_log(LOGARGS(obj, INFO), "SSL key %s specified on environment", optbuf);
330
- settings->keypath = strdup(optbuf);
330
+ settings->keypath = lcb_strdup(optbuf);
331
331
  }
332
332
 
333
333
  if (lcb_getenv_nonempty("LCB_SSL_MODE", optbuf, sizeof optbuf)) {
@@ -343,15 +343,15 @@ static lcb_STATUS setup_ssl(lcb_INSTANCE *obj, const Connspec &params)
343
343
  }
344
344
 
345
345
  if (settings->truststorepath == nullptr && !params.truststorepath().empty()) {
346
- settings->truststorepath = strdup(params.truststorepath().c_str());
346
+ settings->truststorepath = lcb_strdup(params.truststorepath().c_str());
347
347
  }
348
348
 
349
349
  if (settings->certpath == nullptr && !params.certpath().empty()) {
350
- settings->certpath = strdup(params.certpath().c_str());
350
+ settings->certpath = lcb_strdup(params.certpath().c_str());
351
351
  }
352
352
 
353
353
  if (settings->keypath == nullptr && !params.keypath().empty()) {
354
- settings->keypath = strdup(params.keypath().c_str());
354
+ settings->keypath = lcb_strdup(params.keypath().c_str());
355
355
  }
356
356
 
357
357
  if (env_policy == -1) {
@@ -484,10 +484,10 @@ lcb_STATUS lcb_create(lcb_INSTANCE **instance, const lcb_CREATEOPTS *options)
484
484
 
485
485
  if (spec.bucket().empty()) {
486
486
  if (type == LCB_TYPE_BUCKET) {
487
- settings->bucket = strdup("default");
487
+ settings->bucket = lcb_strdup("default");
488
488
  }
489
489
  } else {
490
- settings->bucket = strdup(spec.bucket().c_str());
490
+ settings->bucket = lcb_strdup(spec.bucket().c_str());
491
491
  }
492
492
 
493
493
  if (!spec.username().empty()) {
@@ -635,6 +635,7 @@ static void do_pool_shutdown(io::Pool *pool)
635
635
  LIBCOUCHBASE_API
636
636
  void lcb_destroy(lcb_INSTANCE *instance)
637
637
  {
638
+ instance->destroying = 1;
638
639
  #define DESTROY(fn, fld) \
639
640
  if (instance->fld) { \
640
641
  fn(instance->fld); \
@@ -665,10 +666,10 @@ void lcb_destroy(lcb_INSTANCE *instance)
665
666
  }
666
667
 
667
668
  if ((pendq = po->items[LCB_PENDTYPE_HTTP])) {
668
- for (it = pendq->begin(); it != pendq->end(); ++it) {
669
- auto *htreq = reinterpret_cast<http::Request *>(*it);
670
- htreq->block_callback();
671
- htreq->finish(LCB_ERR_GENERIC);
669
+ std::vector<void *> requests(pendq->begin(), pendq->end());
670
+ for (void *request : requests) {
671
+ auto *htreq = reinterpret_cast<http::Request *>(request);
672
+ htreq->finish(LCB_ERR_REQUEST_CANCELED);
672
673
  }
673
674
  }
674
675
 
@@ -717,6 +718,14 @@ void lcb_destroy(lcb_INSTANCE *instance)
717
718
  } while (!sd.stopped);
718
719
  }
719
720
 
721
+ // Once we are done destroying the instance, we need to manually disconnect
722
+ // the logger from the settings since further work may proceed in the background
723
+ // with some forms of IO backend, but once lcb_destroy is invoked, the logger
724
+ // may no longer be valid from the application side.
725
+ if (instance->settings && instance->settings->logger) {
726
+ instance->settings->logger = nullptr;
727
+ }
728
+
720
729
  DESTROY(lcbio_table_unref, iotable)
721
730
  DESTROY(lcb_settings_unref, settings)
722
731
  DESTROY(lcb_histogram_destroy, kv_timings)
@@ -17,6 +17,10 @@
17
17
  #ifndef LIBCOUCHBASE_INTERNAL_H
18
18
  #define LIBCOUCHBASE_INTERNAL_H 1
19
19
 
20
+ #ifndef NOMINMAX
21
+ #define NOMINMAX
22
+ #endif
23
+
20
24
  /* System/Standard includes */
21
25
  #include "config.h"
22
26
  #include <errno.h>
@@ -55,6 +59,7 @@
55
59
  #include "tracing/tracing-internal.h"
56
60
 
57
61
  #include "hostlist.h"
62
+ #include "utilities.h"
58
63
 
59
64
  #ifdef __cplusplus
60
65
  #include <functional>
@@ -132,6 +137,7 @@ struct lcb_st {
132
137
  lcbio_pTIMER dtor_timer; /**< Asynchronous destruction timer */
133
138
  lcb_BTYPE btype; /**< Type of the bucket */
134
139
  lcb_COLLCACHE *collcache; /**< Collection cache */
140
+ int destroying; /**< Are we in lcb_destroy() ?*/
135
141
 
136
142
  #ifdef __cplusplus
137
143
  typedef std::map<std::string, lcbcrypto_PROVIDER *> lcb_ProviderMap;
@@ -179,6 +185,9 @@ struct lcb_st {
179
185
  */
180
186
  inline lcb_STATUS bootstrap(unsigned options)
181
187
  {
188
+ if (destroying) {
189
+ return LCB_ERR_REQUEST_CANCELED;
190
+ }
182
191
  if (!bs_state) {
183
192
  bs_state = new lcb::Bootstrap(this);
184
193
  }