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
@@ -0,0 +1,53 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2018-2020 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef LIBCOUCHBASE_UTILITIES_H
19
+ #define LIBCOUCHBASE_UTILITIES_H 1
20
+
21
+ #include "config.h"
22
+
23
+ #ifdef __cplusplus
24
+ #include <string>
25
+ #include <vector>
26
+
27
+ namespace lcb
28
+ {
29
+ namespace flexible_framing_extras
30
+ {
31
+ lcb_STATUS encode_impersonate_user(const std::string &username, std::vector<std::uint8_t> &flexible_framing_extras);
32
+ } // namespace flexible_framing_extras
33
+ } // namespace lcb
34
+
35
+ extern "C" {
36
+ #endif
37
+
38
+ /**
39
+ * Added to avoid triggering unexpected behaviour of strdup from stdlib.
40
+ * See https://stackoverflow.com/questions/8359966/strdup-returning-address-out-of-bounds
41
+ *
42
+ * All usages have to be replaced with std::string eventually.
43
+ *
44
+ * @private
45
+ */
46
+ LCB_INTERNAL_API
47
+ char *lcb_strdup(const char *);
48
+
49
+ #ifdef __cplusplus
50
+ }
51
+ #endif
52
+
53
+ #endif
@@ -25,6 +25,7 @@
25
25
  #include "json-inl.h"
26
26
  #include "hash.h"
27
27
  #include "crc32.h"
28
+ #include "utilities.h"
28
29
 
29
30
  #define STRINGIFY_(X) #X
30
31
  #define STRINGIFY(X) STRINGIFY_(X)
@@ -118,7 +119,7 @@ static int assign_dumy_server(lcbvb_CONFIG *cfg, lcbvb_SERVER *dst, const char *
118
119
  {
119
120
  int itmp;
120
121
  char *colon;
121
- if (!(dst->authority = strdup(s))) {
122
+ if (!(dst->authority = lcb_strdup(s))) {
122
123
  SET_ERRSTR(cfg, "Couldn't allocate authority string");
123
124
  goto GT_ERR;
124
125
  }
@@ -354,28 +355,28 @@ static int build_server_strings(lcbvb_CONFIG *cfg, lcbvb_SERVER *server)
354
355
  char tmpbuf[4096];
355
356
 
356
357
  copy_address(tmpbuf, sizeof(tmpbuf), server->hostname, server->svc.data);
357
- server->authority = strdup(tmpbuf);
358
+ server->authority = lcb_strdup(tmpbuf);
358
359
  if (!server->authority) {
359
360
  SET_ERRSTR(cfg, "Couldn't allocate authority");
360
361
  return 0;
361
362
  }
362
363
 
363
- server->svc.hoststrs[LCBVB_SVCTYPE_DATA] = strdup(server->authority);
364
+ server->svc.hoststrs[LCBVB_SVCTYPE_DATA] = lcb_strdup(server->authority);
364
365
  if (server->viewpath == NULL && server->svc.views && cfg->bname) {
365
366
  server->viewpath = malloc(strlen(cfg->bname) + 2);
366
367
  sprintf(server->viewpath, "/%s", cfg->bname);
367
368
  }
368
369
  if (server->querypath == NULL && server->svc.n1ql) {
369
- server->querypath = strdup("/query/service");
370
+ server->querypath = lcb_strdup("/query/service");
370
371
  }
371
372
  if (server->ftspath == NULL && server->svc.fts) {
372
- server->ftspath = strdup("/");
373
+ server->ftspath = lcb_strdup("/");
373
374
  }
374
375
  if (server->cbaspath == NULL && server->svc.cbas) {
375
- server->cbaspath = strdup("");
376
+ server->cbaspath = lcb_strdup("");
376
377
  }
377
378
  if (server->eventingpath == NULL && server->svc.eventing) {
378
- server->eventingpath = strdup("");
379
+ server->eventingpath = lcb_strdup("");
379
380
  }
380
381
  return 1;
381
382
  }
@@ -395,7 +396,7 @@ static int build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, c
395
396
  if (!get_jstr(js, "hostname", &htmp)) {
396
397
  htmp = "$HOST";
397
398
  }
398
- if (!(server->hostname = strdup(htmp))) {
399
+ if (!(server->hostname = lcb_strdup(htmp))) {
399
400
  SET_ERRSTR(cfg, "Couldn't allocate memory");
400
401
  goto GT_ERR;
401
402
  }
@@ -422,7 +423,7 @@ static int build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, c
422
423
  cJSON *jnetwork = cJSON_GetObjectItem(jaltaddr, *network);
423
424
  if (jnetwork && get_jstr(jnetwork, "hostname", &htmp)) {
424
425
  cJSON *jports;
425
- server->alt_hostname = strdup(htmp);
426
+ server->alt_hostname = lcb_strdup(htmp);
426
427
  jports = cJSON_GetObjectItem(jnetwork, "ports");
427
428
  if (jports && jports->type == cJSON_Object) {
428
429
  extract_services(cfg, jports, &server->alt_svc, 0);
@@ -481,7 +482,7 @@ static int build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
481
482
  }
482
483
 
483
484
  /** Hostname is the _rest_ API host, e.g. '8091' */
484
- if ((server->hostname = strdup(tmp)) == NULL) {
485
+ if ((server->hostname = lcb_strdup(tmp)) == NULL) {
485
486
  SET_ERRSTR(cfg, "Couldn't allocate hostname");
486
487
  goto GT_ERR;
487
488
  }
@@ -521,7 +522,7 @@ static int build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
521
522
  SET_ERRSTR(cfg, "Expected path in couchApiBase");
522
523
  goto GT_ERR;
523
524
  }
524
- server->viewpath = strdup(path_begin);
525
+ server->viewpath = lcb_strdup(path_begin);
525
526
  } else {
526
527
  server->svc.views = 0;
527
528
  }
@@ -559,7 +560,7 @@ static void guess_network(cJSON *jnodes, int nsrv, const char *source, char **ne
559
560
  cJSON *jhostname = cJSON_GetObjectItem(jsrv, "hostname");
560
561
  if (jhostname && jhostname->type == cJSON_String) {
561
562
  if (strcmp(jhostname->valuestring, source) == 0) {
562
- *network = strdup("default");
563
+ *network = lcb_strdup("default");
563
564
  return;
564
565
  }
565
566
  }
@@ -573,7 +574,7 @@ static void guess_network(cJSON *jnodes, int nsrv, const char *source, char **ne
573
574
  cJSON *jhostname = cJSON_GetObjectItem(cur, "hostname");
574
575
  if (jhostname && jhostname->type == cJSON_String) {
575
576
  if (strcmp(jhostname->valuestring, source) == 0) {
576
- *network = strdup(cur->string);
577
+ *network = lcb_strdup(cur->string);
577
578
  return;
578
579
  }
579
580
  }
@@ -582,7 +583,7 @@ static void guess_network(cJSON *jnodes, int nsrv, const char *source, char **ne
582
583
  }
583
584
  }
584
585
  }
585
- *network = strdup("default");
586
+ *network = lcb_strdup("default");
586
587
  }
587
588
 
588
589
  int lcbvb_load_json_ex(lcbvb_CONFIG *cfg, const char *data, const char *source, char **network)
@@ -604,7 +605,7 @@ int lcbvb_load_json_ex(lcbvb_CONFIG *cfg, const char *data, const char *source,
604
605
  }
605
606
 
606
607
  if (!is_cluster_cfg && get_jstr(cj, "name", &tmp)) {
607
- cfg->bname = strdup(tmp);
608
+ cfg->bname = lcb_strdup(tmp);
608
609
  cfg->bname_len = strlen(cfg->bname);
609
610
  }
610
611
 
@@ -618,7 +619,7 @@ int lcbvb_load_json_ex(lcbvb_CONFIG *cfg, const char *data, const char *source,
618
619
  }
619
620
 
620
621
  if (get_jstr(cj, "uuid", &tmp)) {
621
- cfg->buuid = strdup(tmp);
622
+ cfg->buuid = lcb_strdup(tmp);
622
623
  }
623
624
 
624
625
  if (!get_jint64(cj, "revEpoch", &cfg->revepoch)) {
@@ -824,7 +825,7 @@ void lcbvb_replace_host(lcbvb_CONFIG *cfg, const char *hoststr)
824
825
  }
825
826
  /* reassign authority */
826
827
  free(srv->authority);
827
- srv->authority = strdup(srv->svc.hoststrs[LCBVB_SVCTYPE_DATA]);
828
+ srv->authority = lcb_strdup(srv->svc.hoststrs[LCBVB_SVCTYPE_DATA]);
828
829
  }
829
830
  if (copy) {
830
831
  free(replacement);
@@ -1570,7 +1571,7 @@ const char *lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix, lcbvb_SVCTYPE svc,
1570
1571
  } else {
1571
1572
  snprintf(buf, sizeof(buf), "%s://%s:%d%s", prefix, hostname, port, path);
1572
1573
  }
1573
- *strp = strdup(buf);
1574
+ *strp = lcb_strdup(buf);
1574
1575
  }
1575
1576
 
1576
1577
  return *strp;
@@ -1617,24 +1618,24 @@ static void copy_service(const char *hostname, const lcbvb_SERVICES *src, lcbvb_
1617
1618
  *dst = *src;
1618
1619
  memset(&dst->hoststrs, 0, sizeof dst->hoststrs);
1619
1620
  if (src->views_base_) {
1620
- dst->views_base_ = strdup(src->views_base_);
1621
+ dst->views_base_ = lcb_strdup(src->views_base_);
1621
1622
  }
1622
1623
  if (src->query_base_) {
1623
- dst->query_base_ = strdup(src->query_base_);
1624
+ dst->query_base_ = lcb_strdup(src->query_base_);
1624
1625
  }
1625
1626
  if (src->fts_base_) {
1626
- dst->fts_base_ = strdup(src->fts_base_);
1627
+ dst->fts_base_ = lcb_strdup(src->fts_base_);
1627
1628
  }
1628
1629
  if (src->cbas_base_) {
1629
- dst->cbas_base_ = strdup(src->cbas_base_);
1630
+ dst->cbas_base_ = lcb_strdup(src->cbas_base_);
1630
1631
  }
1631
1632
  if (src->eventing_base_) {
1632
- dst->eventing_base_ = strdup(src->eventing_base_);
1633
+ dst->eventing_base_ = lcb_strdup(src->eventing_base_);
1633
1634
  }
1634
1635
  if (dst->data) {
1635
1636
  char buf[4096];
1636
1637
  copy_address(buf, sizeof(buf), hostname, dst->data);
1637
- dst->hoststrs[LCBVB_SVCTYPE_DATA] = strdup(buf);
1638
+ dst->hoststrs[LCBVB_SVCTYPE_DATA] = lcb_strdup(buf);
1638
1639
  }
1639
1640
  }
1640
1641
 
@@ -1656,12 +1657,12 @@ int lcbvb_genconfig_ex(lcbvb_CONFIG *vb, const char *name, const char *uuid, con
1656
1657
  vb->nvb = nvbuckets;
1657
1658
  vb->nrepl = nreplica;
1658
1659
  vb->nsrv = nservers;
1659
- vb->bname = strdup(name);
1660
+ vb->bname = lcb_strdup(name);
1660
1661
  if (vb->bname) {
1661
1662
  vb->bname_len = strlen(vb->bname);
1662
1663
  }
1663
1664
  if (uuid) {
1664
- vb->buuid = strdup(uuid);
1665
+ vb->buuid = lcb_strdup(uuid);
1665
1666
  }
1666
1667
 
1667
1668
  if (nreplica >= nservers) {
@@ -1713,21 +1714,21 @@ int lcbvb_genconfig_ex(lcbvb_CONFIG *vb, const char *name, const char *uuid, con
1713
1714
  const lcbvb_SERVER *src = servers + ii;
1714
1715
 
1715
1716
  *dst = *src;
1716
- dst->hostname = strdup(src->hostname);
1717
+ dst->hostname = lcb_strdup(src->hostname);
1717
1718
  if (src->viewpath) {
1718
- dst->viewpath = strdup(src->viewpath);
1719
+ dst->viewpath = lcb_strdup(src->viewpath);
1719
1720
  }
1720
1721
  if (src->querypath) {
1721
- dst->querypath = strdup(src->querypath);
1722
+ dst->querypath = lcb_strdup(src->querypath);
1722
1723
  }
1723
1724
  if (src->ftspath) {
1724
- dst->ftspath = strdup(src->ftspath);
1725
+ dst->ftspath = lcb_strdup(src->ftspath);
1725
1726
  }
1726
1727
  if (src->cbaspath) {
1727
- dst->cbaspath = strdup(src->cbaspath);
1728
+ dst->cbaspath = lcb_strdup(src->cbaspath);
1728
1729
  }
1729
1730
  if (src->eventingpath) {
1730
- dst->eventingpath = strdup(src->eventingpath);
1731
+ dst->eventingpath = lcb_strdup(src->eventingpath);
1731
1732
  }
1732
1733
 
1733
1734
  copy_service(src->hostname, &src->svc, &dst->svc);
@@ -1735,7 +1736,7 @@ int lcbvb_genconfig_ex(lcbvb_CONFIG *vb, const char *name, const char *uuid, con
1735
1736
  {
1736
1737
  char tmpbuf[MAX_AUTHORITY_SIZE] = {0};
1737
1738
  copy_address(tmpbuf, sizeof(tmpbuf), dst->hostname, dst->svc.data);
1738
- dst->authority = strdup(tmpbuf);
1739
+ dst->authority = lcb_strdup(tmpbuf);
1739
1740
  }
1740
1741
  }
1741
1742
 
@@ -80,8 +80,8 @@ void lcb_VIEW_HANDLE_::invoke_last(lcb_STATUS err)
80
80
  if (http_response_ && http_response_->ctx.response_code != 200 && http_response_->ctx.body_len) {
81
81
  // chances that were not able to parse response
82
82
  Json::Value meta;
83
- if (Json::Reader().parse(http_response_->ctx.body, http_response_->ctx.body + http_response_->ctx.body_len,
84
- meta)) {
83
+ if (Json::Reader(Json::Features::strictMode())
84
+ .parse(http_response_->ctx.body, http_response_->ctx.body + http_response_->ctx.body_len, meta)) {
85
85
  const Json::Value &error = meta["error"];
86
86
  if (error.isString()) {
87
87
  first_error_code_ = error.asString();
@@ -101,7 +101,10 @@ void lcb_VIEW_HANDLE_::invoke_last(lcb_STATUS err)
101
101
  resp.ctx.rc = LCB_ERR_VIEW_NOT_FOUND;
102
102
  }
103
103
 
104
- LCBTRACE_HTTP_FINISH(span_);
104
+ if (span_ != nullptr) {
105
+ lcb::trace::finish_http_span(span_, this);
106
+ span_ = nullptr;
107
+ }
105
108
  if (http_request_ != nullptr) {
106
109
  http_request_->span = nullptr;
107
110
  }
@@ -379,11 +382,16 @@ lcb_VIEW_HANDLE_::lcb_VIEW_HANDLE_(lcb_INSTANCE *instance, void *cookie, const l
379
382
  document_queue_->max_pending_response = cmd->max_concurrent_documents();
380
383
  }
381
384
  }
385
+ {
386
+ char buf[32];
387
+ size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
388
+ client_context_id_.assign(buf, nbuf);
389
+ }
382
390
 
383
391
  lcb_aspend_add(&instance_->pendops, LCB_PENDTYPE_COUNTER, nullptr);
384
392
  if (instance->settings->tracer) {
385
- LCBTRACE_HTTP_START(instance_->settings, nullptr, cmd->parent_span(), LCBTRACE_TAG_SERVICE_VIEW,
386
- LCBTRACE_THRESHOLD_VIEW, span_);
393
+ parent_span_ = cmd->parent_span();
394
+ span_ = lcb::trace::start_http_span(instance_->settings, this);
387
395
  }
388
396
  last_error_ = request_http(cmd);
389
397
  }
@@ -118,6 +118,32 @@ struct lcb_VIEW_HANDLE_ : lcb::jsparse::Parser::Actions {
118
118
  return http_request_;
119
119
  }
120
120
 
121
+ static lcbtrace_THRESHOLDOPTS service()
122
+ {
123
+ return LCBTRACE_THRESHOLD_VIEW;
124
+ }
125
+
126
+ static const std::string &operation_name()
127
+ {
128
+ static std::string name = LCBTRACE_OP_VIEW;
129
+ return name;
130
+ }
131
+
132
+ lcbtrace_SPAN *parent_span() const
133
+ {
134
+ return parent_span_;
135
+ }
136
+
137
+ const std::string &client_context_id() const
138
+ {
139
+ return client_context_id_;
140
+ }
141
+
142
+ int retries() const
143
+ {
144
+ return retries_;
145
+ }
146
+
121
147
  private:
122
148
  /** Current HTTP response to provide in callbacks */
123
149
  const lcb_RESPHTTP *http_response_{nullptr};
@@ -134,12 +160,15 @@ struct lcb_VIEW_HANDLE_ : lcb::jsparse::Parser::Actions {
134
160
  std::string query_params_{};
135
161
  std::string first_error_code_{};
136
162
  std::string first_error_message_{};
163
+ std::string client_context_id_{};
137
164
 
138
165
  unsigned refcount_{1};
139
166
  bool include_docs_{false};
140
167
  bool do_not_parse_rows_{false};
141
168
  bool spatial_{false};
169
+ int retries_{0};
142
170
 
143
171
  lcb_STATUS last_error_{LCB_SUCCESS};
172
+ lcbtrace_SPAN *parent_span_{nullptr};
144
173
  lcbtrace_SPAN *span_{nullptr};
145
174
  };
@@ -152,8 +152,29 @@ MACRO(DEFINE_MOCKTEST plugin test)
152
152
  --tests ${test}
153
153
  --verbose
154
154
  --
155
+ --gtest_filter="-ContaminatingUnitTest.*"
156
+ --gtest_throw_on_failure=1
155
157
  --gtest_print_time=1
156
158
  --gtest_output=xml:"${PROJECT_BINARY_DIR}/REPORT_${plugin}_${test}.xml")
159
+ SET_TESTS_PROPERTIES(check-${plugin}-${test} PROPERTIES LABELS "normal" )
160
+
161
+ ADD_TEST(
162
+ NAME
163
+ check-contaminating-${plugin}-${test}
164
+ COMMAND
165
+ $<TARGET_FILE:check-all>
166
+ --srcdir "${PROJECT_SOURCE_DIR}"
167
+ --testdir "$<TARGET_FILE_DIR:check-all>"
168
+ --libdir "$<TARGET_FILE_DIR:couchbase>"
169
+ --plugins ${plugin}
170
+ --tests ${test}
171
+ --verbose
172
+ --
173
+ --gtest_filter="ContaminatingUnitTest.*"
174
+ --gtest_throw_on_failure=1
175
+ --gtest_print_time=1
176
+ --gtest_output=xml:"${PROJECT_BINARY_DIR}/REPORT_${plugin}_${test}.xml")
177
+ SET_TESTS_PROPERTIES(check-contaminating-${plugin}-${test} PROPERTIES LABELS "contaminating" )
157
178
  ENDMACRO()
158
179
 
159
180
  # Since we need a plugin name, we'll use 'select'. However none of these
@@ -18,6 +18,9 @@
18
18
  #include "config.h"
19
19
  #include <gtest/gtest.h>
20
20
  #include <libcouchbase/couchbase.h>
21
+ #include <iotests/testutil.h>
22
+
23
+ #include "internal.h"
21
24
 
22
25
  class CtlTest : public ::testing::Test
23
26
  {
@@ -61,9 +64,9 @@ TEST_F(CtlTest, testStringCtls)
61
64
  {
62
65
  lcb_INSTANCE *instance;
63
66
  lcb_STATUS err;
64
- err = lcb_create(&instance, NULL);
67
+ err = lcb_create(&instance, nullptr);
65
68
  ASSERT_EQ(LCB_SUCCESS, err);
66
- ASSERT_FALSE(instance == NULL);
69
+ ASSERT_FALSE(instance == nullptr);
67
70
 
68
71
  // These are all U32
69
72
  PairMap ctlMap[] = {{"operation_timeout", LCB_CNTL_OP_TIMEOUT},
@@ -74,7 +77,7 @@ TEST_F(CtlTest, testStringCtls)
74
77
  {"error_thresh_delay", LCB_CNTL_CONFDELAY_THRESH},
75
78
  {"config_total_timeout", LCB_CNTL_CONFIGURATION_TIMEOUT},
76
79
  {"config_node_timeout", LCB_CNTL_CONFIG_NODE_TIMEOUT},
77
- {NULL, 0}};
80
+ {nullptr, 0}};
78
81
 
79
82
  for (PairMap *cur = ctlMap; cur->key; cur++) {
80
83
  err = lcb_cntl_string(instance, cur->key, "50");
@@ -111,3 +114,21 @@ TEST_F(CtlTest, testStringCtls)
111
114
 
112
115
  lcb_destroy(instance);
113
116
  }
117
+
118
+ TEST_F(CtlTest, testTimeDurationParsing)
119
+ {
120
+ lcb_INSTANCE *instance;
121
+ ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance, nullptr));
122
+ ASSERT_FALSE(instance == nullptr);
123
+
124
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cntl_string(instance, "analytics_timeout", "123.456"));
125
+ ASSERT_EQ(123456000, instance->settings->analytics_timeout);
126
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cntl_string(instance, "analytics_timeout", "42"));
127
+ ASSERT_EQ(42000000, instance->settings->analytics_timeout);
128
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cntl_string(instance, "analytics_timeout", "42us"));
129
+ ASSERT_EQ(42, instance->settings->analytics_timeout);
130
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cntl_string(instance, "analytics_timeout", "5s42us"));
131
+ ASSERT_EQ(5000042, instance->settings->analytics_timeout);
132
+
133
+ lcb_destroy(instance);
134
+ }
@@ -105,3 +105,11 @@ TEST_F(JsonParseTest, testN1QL)
105
105
  ASSERT_TRUE(validateJsonRows(JSON_n1ql_empty, sizeof(JSON_n1ql_empty), Parser::MODE_N1QL));
106
106
  ASSERT_TRUE(validateBadParse(JSON_n1ql_bad, sizeof(JSON_n1ql_bad), Parser::MODE_N1QL));
107
107
  }
108
+
109
+ TEST_F(JsonParseTest, testInvalidJSON)
110
+ {
111
+ std::string input = "503 Service Unavailable";
112
+ Json::Value meta;
113
+ ASSERT_TRUE(Json::Reader().parse(input.c_str(), input.c_str() + input.size(), meta));
114
+ ASSERT_FALSE(Json::Reader(Json::Features::strictMode()).parse(input.c_str(), input.c_str() + input.size(), meta));
115
+ }
@@ -20,6 +20,7 @@
20
20
  #include <libcouchbase/couchbase.h>
21
21
 
22
22
  #include "n1ql/query_utils.hh"
23
+ #include "../iotests/testutil.h"
23
24
 
24
25
  class N1qLStringTests : public ::testing::Test
25
26
  {
@@ -35,3 +36,75 @@ TEST_F(N1qLStringTests, testParseTimeout)
35
36
  ASSERT_THROW(lcb_parse_golang_duration("124"), lcb_duration_parse_error);
36
37
  ASSERT_THROW(lcb_parse_golang_duration("99z"), lcb_duration_parse_error);
37
38
  }
39
+
40
+ TEST_F(N1qLStringTests, testQueryPositionalParams)
41
+ {
42
+ lcb_CMDQUERY *cmd = nullptr;
43
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_create(&cmd));
44
+
45
+ std::string statement = "SELECT 42 AS the_answer WHERE question IN (?, ?, ?) ";
46
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_statement(cmd, statement.c_str(), statement.size()));
47
+
48
+ const char *payload = nullptr;
49
+ size_t payload_len = 0;
50
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_encoded_payload(cmd, &payload, &payload_len));
51
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
52
+ ASSERT_EQ(R"({"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
53
+ std::string(payload, payload_len));
54
+
55
+ std::vector<std::string> question{"\"life\"", "\"Universe\"", "\"Everything\""};
56
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_positional_param(cmd, question[0].c_str(), question[0].size()));
57
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_positional_param(cmd, question[1].c_str(), question[1].size()));
58
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_positional_param(cmd, question[2].c_str(), question[2].size()));
59
+
60
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_encoded_payload(cmd, &payload, &payload_len));
61
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
62
+ ASSERT_EQ(
63
+ R"({"args":["life","Universe","Everything"],"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
64
+ std::string(payload, payload_len));
65
+
66
+ std::string questions{R"(["Universe", "life", "Everything"])"};
67
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_positional_params(cmd, questions.c_str(), questions.size()));
68
+
69
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_encoded_payload(cmd, &payload, &payload_len));
70
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
71
+ ASSERT_EQ(
72
+ R"({"args":["Universe","life","Everything"],"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
73
+ std::string(payload, payload_len));
74
+ }
75
+
76
+ TEST_F(N1qLStringTests, testAnalyticsPositionalParams)
77
+ {
78
+ lcb_CMDANALYTICS *cmd = nullptr;
79
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_create(&cmd));
80
+
81
+ std::string statement = "SELECT 42 AS the_answer WHERE question IN (?, ?, ?) ";
82
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_statement(cmd, statement.c_str(), statement.size()));
83
+
84
+ const char *payload = nullptr;
85
+ size_t payload_len = 0;
86
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_encoded_payload(cmd, &payload, &payload_len));
87
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
88
+ ASSERT_EQ(R"({"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
89
+ std::string(payload, payload_len));
90
+
91
+ std::vector<std::string> question{"\"life\"", "\"Universe\"", "\"Everything\""};
92
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_positional_param(cmd, question[0].c_str(), question[0].size()));
93
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_positional_param(cmd, question[1].c_str(), question[1].size()));
94
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_positional_param(cmd, question[2].c_str(), question[2].size()));
95
+
96
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_encoded_payload(cmd, &payload, &payload_len));
97
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
98
+ ASSERT_EQ(
99
+ R"({"args":["life","Universe","Everything"],"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
100
+ std::string(payload, payload_len));
101
+
102
+ std::string questions{R"(["Universe", "life", "Everything"])"};
103
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_positional_params(cmd, questions.c_str(), questions.size()));
104
+
105
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_encoded_payload(cmd, &payload, &payload_len));
106
+ ASSERT_TRUE(payload != nullptr && payload_len > 0);
107
+ ASSERT_EQ(
108
+ R"({"args":["Universe","life","Everything"],"statement":"SELECT 42 AS the_answer WHERE question IN (?, ?, ?) "})",
109
+ std::string(payload, payload_len));
110
+ }
@@ -21,6 +21,7 @@
21
21
  #include "mock-environment.h"
22
22
  #include <sstream>
23
23
  #include "internal.h" /* settings from lcb_INSTANCE *for logging */
24
+ #include "testutil.h"
24
25
 
25
26
  #define LOGARGS(instance, lvl) instance->settings, "tests-ENV", LCB_LOG_##lvl, __FILE__, __LINE__
26
27
 
@@ -288,6 +289,7 @@ void MockEnvironment::createConnection(HandleWrap &handle, lcb_INSTANCE **instan
288
289
  }
289
290
 
290
291
  lcb_createopts_io(&options, io);
292
+
291
293
  lcb_STATUS err = lcb_create(instance, &options);
292
294
  ASSERT_EQ(LCB_SUCCESS, err);
293
295
  postCreate(*instance);
@@ -302,6 +304,26 @@ void MockEnvironment::createConnection(HandleWrap &handle, lcb_INSTANCE **instan
302
304
  {
303
305
  lcb_CREATEOPTS *options = nullptr;
304
306
  makeConnectParams(options, nullptr);
307
+
308
+ if (test_tracer.enabled()) {
309
+ lcb_createopts_tracer(options, test_tracer.lcb_tracer());
310
+ }
311
+
312
+ if (test_meter.enabled()) {
313
+ lcb_createopts_meter(options, test_meter.lcb_meter());
314
+ }
315
+
316
+ createConnection(handle, instance, options);
317
+ lcb_createopts_destroy(options);
318
+ }
319
+
320
+ void MockEnvironment::createConnection(HandleWrap &handle, lcb_INSTANCE **instance, const std::string &username,
321
+ const std::string &password)
322
+ {
323
+ lcb_CREATEOPTS *options = nullptr;
324
+ makeConnectParams(options, nullptr);
325
+
326
+ lcb_createopts_credentials(options, username.c_str(), username.size(), password.c_str(), password.size());
305
327
  createConnection(handle, instance, options);
306
328
  lcb_createopts_destroy(options);
307
329
  }
@@ -323,6 +345,10 @@ static void statsCallback(lcb_INSTANCE *instance, lcb_CALLBACK_TYPE, const lcb_R
323
345
  {
324
346
  MockEnvironment *me = nullptr;
325
347
  lcb_respstats_cookie(resp, (void **)&me);
348
+ if (me->getServerVersion() != MockEnvironment::VERSION_UNKNOWN) {
349
+ // ignore all subsequent responses
350
+ return;
351
+ }
326
352
  lcb_STATUS rc = lcb_respstats_status(resp);
327
353
  ASSERT_EQ(LCB_SUCCESS, rc) << lcb_strerror_short(rc);
328
354
 
@@ -542,6 +568,9 @@ void MockEnvironment::SetUp()
542
568
  featureRegistry.insert("replica_read");
543
569
  featureRegistry.insert("lock");
544
570
 
571
+ test_tracer = TestTracer();
572
+ test_meter = TestMeter();
573
+
545
574
  clearAndReset();
546
575
  }
547
576
 
@@ -591,7 +620,7 @@ MockCommand::MockCommand(Code code)
591
620
  std::string MockCommand::encode()
592
621
  {
593
622
  finalizePayload();
594
- return Json::FastWriter().write(command);
623
+ return Json::FastWriter().write(command) + "\n";
595
624
  }
596
625
 
597
626
  void MockKeyCommand::finalizePayload()