couchbase 3.2.0 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
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
  }