libcouchbase 1.2.8 → 1.3.0

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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/README.md +16 -8
  4. data/ext/libcouchbase/CMakeLists.txt +34 -32
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
  7. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  10. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
  11. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  12. data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
  13. data/ext/libcouchbase/cmake/configure +8 -26
  14. data/ext/libcouchbase/cmake/defs.mk.in +2 -2
  15. data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
  16. data/ext/libcouchbase/cmake/source_files.cmake +11 -2
  17. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
  18. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
  19. data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
  20. data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
  21. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
  22. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
  23. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
  24. data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
  25. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
  26. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
  27. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
  28. data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
  29. data/ext/libcouchbase/example/crypto/.gitignore +2 -0
  30. data/ext/libcouchbase/example/crypto/Makefile +13 -0
  31. data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
  32. data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
  33. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
  34. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
  35. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
  36. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
  37. data/ext/libcouchbase/example/tracing/.gitignore +2 -0
  38. data/ext/libcouchbase/example/tracing/Makefile +8 -0
  39. data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
  40. data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
  41. data/ext/libcouchbase/example/tracing/tracing.c +439 -0
  42. data/ext/libcouchbase/example/tracing/views.c +444 -0
  43. data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
  44. data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
  45. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
  46. data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
  47. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
  48. data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
  49. data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
  50. data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
  51. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
  52. data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
  53. data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
  54. data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
  55. data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
  56. data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
  57. data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
  58. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
  59. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
  60. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
  61. data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
  62. data/ext/libcouchbase/src/auth-priv.h +36 -4
  63. data/ext/libcouchbase/src/auth.cc +66 -27
  64. data/ext/libcouchbase/src/bootstrap.cc +1 -1
  65. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
  66. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
  67. data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
  68. data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
  69. data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
  70. data/ext/libcouchbase/src/cbft.cc +48 -0
  71. data/ext/libcouchbase/src/cntl.cc +138 -2
  72. data/ext/libcouchbase/src/config_static.h +17 -0
  73. data/ext/libcouchbase/src/connspec.cc +54 -6
  74. data/ext/libcouchbase/src/connspec.h +9 -1
  75. data/ext/libcouchbase/src/crypto.cc +386 -0
  76. data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
  77. data/ext/libcouchbase/src/dump.cc +4 -0
  78. data/ext/libcouchbase/src/getconfig.cc +1 -2
  79. data/ext/libcouchbase/src/handler.cc +65 -27
  80. data/ext/libcouchbase/src/hostlist.cc +35 -7
  81. data/ext/libcouchbase/src/hostlist.h +7 -0
  82. data/ext/libcouchbase/src/http/http-priv.h +2 -0
  83. data/ext/libcouchbase/src/http/http.cc +77 -37
  84. data/ext/libcouchbase/src/http/http_io.cc +19 -2
  85. data/ext/libcouchbase/src/instance.cc +90 -17
  86. data/ext/libcouchbase/src/internal.h +5 -0
  87. data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
  88. data/ext/libcouchbase/src/lcbio/connect.h +27 -0
  89. data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
  90. data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
  91. data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
  92. data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
  93. data/ext/libcouchbase/src/lcbio/manager.h +2 -0
  94. data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
  95. data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
  96. data/ext/libcouchbase/src/logging.c +1 -1
  97. data/ext/libcouchbase/src/logging.h +2 -0
  98. data/ext/libcouchbase/src/mc/compress.cc +164 -0
  99. data/ext/libcouchbase/src/mc/compress.h +7 -12
  100. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
  101. data/ext/libcouchbase/src/mc/mcreq.c +11 -1
  102. data/ext/libcouchbase/src/mc/mcreq.h +35 -4
  103. data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
  104. data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
  105. data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
  106. data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
  107. data/ext/libcouchbase/src/mctx-helper.h +11 -0
  108. data/ext/libcouchbase/src/metrics.cc +132 -0
  109. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  110. data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
  111. data/ext/libcouchbase/src/newconfig.cc +9 -2
  112. data/ext/libcouchbase/src/operations/counter.cc +2 -1
  113. data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
  114. data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
  115. data/ext/libcouchbase/src/operations/durability.cc +24 -2
  116. data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
  117. data/ext/libcouchbase/src/operations/get.cc +4 -2
  118. data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
  119. data/ext/libcouchbase/src/operations/observe.cc +113 -62
  120. data/ext/libcouchbase/src/operations/ping.cc +246 -67
  121. data/ext/libcouchbase/src/operations/remove.cc +2 -1
  122. data/ext/libcouchbase/src/operations/store.cc +17 -14
  123. data/ext/libcouchbase/src/operations/touch.cc +3 -0
  124. data/ext/libcouchbase/src/packetutils.h +68 -4
  125. data/ext/libcouchbase/src/probes.d +132 -161
  126. data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
  127. data/ext/libcouchbase/src/retryq.cc +6 -2
  128. data/ext/libcouchbase/src/rnd.cc +68 -0
  129. data/ext/libcouchbase/src/rnd.h +39 -0
  130. data/ext/libcouchbase/src/settings.c +27 -0
  131. data/ext/libcouchbase/src/settings.h +67 -3
  132. data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
  133. data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
  134. data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
  135. data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
  136. data/ext/libcouchbase/src/trace.h +68 -61
  137. data/ext/libcouchbase/src/tracing/span.cc +289 -0
  138. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
  139. data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
  140. data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
  141. data/ext/libcouchbase/src/utilities.c +5 -0
  142. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
  143. data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
  144. data/ext/libcouchbase/src/views/docreq.cc +26 -1
  145. data/ext/libcouchbase/src/views/docreq.h +17 -0
  146. data/ext/libcouchbase/src/views/viewreq.cc +64 -1
  147. data/ext/libcouchbase/src/views/viewreq.h +21 -0
  148. data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
  149. data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
  150. data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
  151. data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
  152. data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
  153. data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
  154. data/ext/libcouchbase/tests/check-all.cc +6 -2
  155. data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
  156. data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
  157. data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
  158. data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
  159. data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
  160. data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
  161. data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
  162. data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
  163. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  164. data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
  165. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  166. data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
  167. data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
  168. data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
  169. data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
  170. data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
  171. data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
  172. data/ext/libcouchbase/tools/cbc.cc +113 -8
  173. data/ext/libcouchbase/tools/common/histogram.cc +1 -0
  174. data/ext/libcouchbase/tools/common/options.cc +28 -1
  175. data/ext/libcouchbase/tools/common/options.h +5 -0
  176. data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
  177. data/ext/libcouchbase/tools/docgen/loc.h +5 -4
  178. data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
  179. data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
  180. data/lib/libcouchbase/n1ql.rb +6 -1
  181. data/lib/libcouchbase/version.rb +1 -1
  182. data/spec/connection_spec.rb +6 -6
  183. metadata +38 -5
  184. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
  185. data/ext/libcouchbase/src/mc/compress.c +0 -90
  186. data/ext/libcouchbase/tools/common/my_inttypes.h +0 -22
@@ -16,13 +16,14 @@
16
16
 
17
17
  #define LCB_NO_DEPR_CXX_CTORS
18
18
 
19
- #include "common/my_inttypes.h"
20
19
  #include "config.h"
21
20
  #include <sys/types.h>
22
21
  #include <libcouchbase/couchbase.h>
23
22
  #include <libcouchbase/vbucket.h>
24
23
  #include <libcouchbase/api3.h>
25
24
  #include <libcouchbase/pktfwd.h>
25
+ #include <libcouchbase/n1ql.h>
26
+ #include <libcouchbase/cbft.h>
26
27
  #include <memcached/protocol_binary.h>
27
28
  #include <iostream>
28
29
  #include <iomanip>
@@ -61,6 +62,8 @@ static lcb_t instance = NULL;
61
62
  static struct event_base *evbase = NULL;
62
63
  static Histogram hg;
63
64
 
65
+ static char app_client_string[] = "cbc-proxy";
66
+
64
67
  #define LOGARGS(lvl) (instance)->settings, "proxy", LCB_LOG_##lvl, __FILE__, __LINE__
65
68
  #define CL_LOGFMT "<%s:%s> (cl=%p,fd=%d) "
66
69
  #define CL_LOGID(cl) cl->host, cl->port, (void *)cl, cl->fd
@@ -152,9 +155,10 @@ struct client {
152
155
  struct bufferevent *bev;
153
156
  char host[NI_MAXHOST + 1];
154
157
  char port[NI_MAXSERV + 1];
158
+ long cnt;
155
159
  };
156
160
 
157
- static void dump_bytes(const struct client *cl, const char *msg, void *ptr, size_t len)
161
+ static void dump_bytes(const struct client *cl, const char *msg, const void *ptr, size_t len)
158
162
  {
159
163
  if (!config.isTrace()) {
160
164
  return;
@@ -246,6 +250,50 @@ static void pktfwd_callback(lcb_t, const void *cookie, lcb_error_t err, lcb_PKTF
246
250
  }
247
251
  }
248
252
 
253
+ extern "C" {
254
+ #define DEFINE_ROW_CALLBACK(cbname, resptype) \
255
+ static void cbname(lcb_t, int, const resptype *resp) \
256
+ { \
257
+ char key[100] = {0}; \
258
+ size_t nkey; \
259
+ struct client *cl = (struct client *)resp->cookie; \
260
+ \
261
+ protocol_binary_response_header header = {}; \
262
+ header.response.magic = PROTOCOL_BINARY_RES; \
263
+ header.response.opcode = PROTOCOL_BINARY_CMD_STAT; \
264
+ \
265
+ struct evbuffer *output = bufferevent_get_output(cl->bev); \
266
+ \
267
+ if (resp->rflags & LCB_RESP_F_FINAL) { \
268
+ memcpy(key, "meta", 4); \
269
+ } else { \
270
+ snprintf(key, sizeof(key), "row-%ld", cl->cnt++); \
271
+ } \
272
+ nkey = strlen(key); \
273
+ header.response.keylen = htons(nkey); \
274
+ header.response.bodylen = htonl(resp->nrow + nkey); \
275
+ \
276
+ evbuffer_expand(output, resp->nrow + sizeof(header.bytes)); \
277
+ dump_bytes(cl, "response", header.bytes, sizeof(header.bytes)); \
278
+ evbuffer_add(output, header.bytes, sizeof(header.bytes)); \
279
+ dump_bytes(cl, "response", key, nkey); \
280
+ evbuffer_add(output, key, nkey); \
281
+ dump_bytes(cl, "response", resp->row, resp->nrow); \
282
+ evbuffer_add(output, resp->row, resp->nrow); \
283
+ \
284
+ if (resp->rflags & LCB_RESP_F_FINAL) { \
285
+ header.response.keylen = 0; \
286
+ header.response.bodylen = 0; \
287
+ evbuffer_expand(output, sizeof(header.bytes)); \
288
+ dump_bytes(cl, "response", header.bytes, sizeof(header.bytes)); \
289
+ evbuffer_add(output, header.bytes, sizeof(header.bytes)); \
290
+ } \
291
+ }
292
+
293
+ DEFINE_ROW_CALLBACK(n1ql_callback, lcb_RESPN1QL)
294
+ DEFINE_ROW_CALLBACK(fts_callback, lcb_RESPFTS)
295
+ }
296
+
249
297
  static void conn_readcb(struct bufferevent *bev, void *cookie)
250
298
  {
251
299
  struct client *cl = (struct client *)cookie;
@@ -273,12 +321,67 @@ static void conn_readcb(struct bufferevent *bev, void *cookie)
273
321
  evbuffer_remove(input, pkt, pktlen);
274
322
 
275
323
  lcb_sched_enter(instance);
324
+ dump_bytes(cl, "request", pkt, pktlen);
325
+ if (header.request.opcode == PROTOCOL_BINARY_CMD_STAT) {
326
+ lcb_U8 extlen = ntohs(header.request.extlen);
327
+ lcb_U16 keylen = ntohs(header.request.keylen);
328
+ if (keylen < 5) {
329
+ goto FWD;
330
+ }
331
+ char *key = (char *)pkt + sizeof(header) + extlen;
332
+ lcb_error_t rc;
333
+ int cbas = memcmp(key, "cbas ", 5) == 0;
334
+ if (cbas || memcmp(key, "n1ql ", 5) == 0) {
335
+ lcb_N1QLPARAMS *nparams = lcb_n1p_new();
336
+
337
+ rc = lcb_n1p_setquery(nparams, key + 5, keylen - 5, LCB_N1P_QUERY_STATEMENT);
338
+ if (rc != LCB_SUCCESS) {
339
+ lcb_log(LOGARGS(INFO), CL_LOGFMT "failed to set query for %s", CL_LOGID(cl),
340
+ cbas ? "analytics" : "N1QL");
341
+ goto FWD;
342
+ }
343
+ lcb_CMDN1QL cmd = {0};
344
+ rc = lcb_n1p_mkcmd(nparams, &cmd);
345
+ if (rc != LCB_SUCCESS) {
346
+ lcb_log(LOGARGS(INFO), CL_LOGFMT "failed to generate %s command", CL_LOGID(cl),
347
+ cbas ? "analytics" : "N1QL");
348
+ goto FWD;
349
+ }
350
+ cmd.callback = n1ql_callback;
351
+ cl->cnt = 0;
352
+ if (cbas) {
353
+ cmd.cmdflags |= LCB_CMDN1QL_F_CBASQUERY;
354
+ }
355
+ rc = lcb_n1ql_query(instance, cl, &cmd);
356
+ if (rc != LCB_SUCCESS) {
357
+ lcb_log(LOGARGS(INFO), CL_LOGFMT "failed to schedule %s command", CL_LOGID(cl),
358
+ cbas ? "analytics" : "N1QL");
359
+ goto FWD;
360
+ }
361
+ lcb_n1p_free(nparams);
362
+ goto DONE;
363
+ } else if (memcmp(key, "fts ", 4) == 0) {
364
+ lcb_CMDFTS cmd = {0};
365
+ cmd.query = key + 4;
366
+ cmd.nquery = keylen - 4;
367
+ rc = lcb_fts_query(instance, cl, &cmd);
368
+ cmd.callback = fts_callback;
369
+ cl->cnt = 0;
370
+ if (rc != LCB_SUCCESS) {
371
+ lcb_log(LOGARGS(INFO), CL_LOGFMT "failed to schedule FTS command", CL_LOGID(cl));
372
+ goto FWD;
373
+ }
374
+ goto DONE;
375
+ }
376
+ }
377
+ FWD : {
276
378
  lcb_CMDPKTFWD cmd = {0};
277
379
  cmd.vb.vtype = LCB_KV_COPY;
278
380
  cmd.vb.u_buf.contig.bytes = pkt;
279
381
  cmd.vb.u_buf.contig.nbytes = pktlen;
280
- dump_bytes(cl, "request", pkt, pktlen);
281
382
  good_or_die(lcb_pktfwd3(instance, cl, &cmd), "Failed to forward packet");
383
+ }
384
+ DONE:
282
385
  lcb_sched_leave(instance);
283
386
  }
284
387
 
@@ -350,6 +453,26 @@ static void sigint_handler(int)
350
453
  }
351
454
  }
352
455
 
456
+ static void diag_callback(lcb_t, int, const lcb_RESPBASE *rb)
457
+ {
458
+ const lcb_RESPDIAG *resp = (const lcb_RESPDIAG *)rb;
459
+ if (resp->rc != LCB_SUCCESS) {
460
+ fprintf(stderr, "failed: %s\n", lcb_strerror(NULL, resp->rc));
461
+ } else {
462
+ if (resp->njson) {
463
+ fprintf(stderr, "\n%.*s", (int)resp->njson, resp->json);
464
+ }
465
+ }
466
+ }
467
+
468
+ static void sigquit_handler(int)
469
+ {
470
+ lcb_CMDDIAG req = {};
471
+ req.options = LCB_PINGOPT_F_JSONPRETTY;
472
+ req.id = app_client_string;
473
+ lcb_diag(instance, NULL, &req);
474
+ }
475
+
353
476
  static void real_main(int argc, char **argv)
354
477
  {
355
478
  Parser parser;
@@ -372,8 +495,10 @@ static void real_main(int argc, char **argv)
372
495
 
373
496
  good_or_die(lcb_create(&instance, &cropts), "Failed to create connection");
374
497
  config.doCtls();
498
+ lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CLIENT_STRING, app_client_string);
375
499
  lcb_set_bootstrap_callback(instance, bootstrap_callback);
376
500
  lcb_set_pktfwd_callback(instance, pktfwd_callback);
501
+ lcb_install_callback3(instance, LCB_CALLBACK_DIAG, diag_callback);
377
502
 
378
503
  good_or_die(lcb_connect(instance), "Failed to connect to cluster");
379
504
  if (config.useTimings()) {
@@ -388,6 +513,12 @@ static void real_main(int argc, char **argv)
388
513
  action.sa_flags = 0;
389
514
  sigaction(SIGINT, &action, NULL);
390
515
 
516
+ /* setup CTRL-\ handler */
517
+ sigemptyset(&action.sa_mask);
518
+ action.sa_handler = sigquit_handler;
519
+ action.sa_flags = 0;
520
+ sigaction(SIGQUIT, &action, NULL);
521
+
391
522
  event_base_dispatch(evbase);
392
523
  }
393
524
 
@@ -16,7 +16,6 @@
16
16
 
17
17
  #define LCB_NO_DEPR_CXX_CTORS
18
18
 
19
- #include "common/my_inttypes.h"
20
19
  #include "config.h"
21
20
  #include <sys/types.h>
22
21
  #include <libcouchbase/couchbase.h>
@@ -488,7 +487,7 @@ class UpsertHandler : public Handler
488
487
  }
489
488
  // currently it is not possible to upsert document without XATTRs
490
489
  // so lets allocate "_cbc" object with some useful stuff
491
- std::string ver = "\"libcouchbase/" LCB_VERSION_STRING "\"";
490
+ std::string ver = "\"" LCB_CLIENT_ID "\"";
492
491
  std::string path = "_cbc.version";
493
492
 
494
493
  std::string key = args[0];
@@ -1,5 +1,4 @@
1
1
  #define NOMINMAX
2
- #include "common/my_inttypes.h"
3
2
  #include <map>
4
3
  #include <sstream>
5
4
  #include <iostream>
@@ -21,6 +20,7 @@
21
20
  #ifndef LCB_NO_SSL
22
21
  #include <openssl/crypto.h>
23
22
  #endif
23
+ #include <snappy-stubs-public.h>
24
24
 
25
25
  using namespace cbc;
26
26
 
@@ -77,8 +77,17 @@ get_callback(lcb_t, lcb_CALLBACKTYPE cbtype, const lcb_RESPGET *resp)
77
77
  {
78
78
  string key = getRespKey((const lcb_RESPBASE *)resp);
79
79
  if (resp->rc == LCB_SUCCESS) {
80
- fprintf(stderr, "%-20s CAS=0x%" PRIx64 ", Flags=0x%x. Size=%lu\n",
81
- key.c_str(), resp->cas, resp->itmflags, (unsigned long)resp->nvalue);
80
+ fprintf(stderr, "%-20s CAS=0x%" PRIx64 ", Flags=0x%x, Size=%lu, Datatype=0x%02x",
81
+ key.c_str(), resp->cas, resp->itmflags, (unsigned long)resp->nvalue,
82
+ (int)resp->datatype);
83
+ if (resp->datatype) {
84
+ fprintf(stderr, "(");
85
+ if (resp->datatype & LCB_VALUE_F_JSON) {
86
+ fprintf(stderr, "JSON");
87
+ }
88
+ fprintf(stderr, ")");
89
+ }
90
+ fprintf(stderr, "\n");
82
91
  fflush(stderr);
83
92
  fwrite(resp->value, 1, resp->nvalue, stdout);
84
93
  fflush(stdout);
@@ -222,6 +231,34 @@ stats_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPSTATS *resp)
222
231
  fprintf(stdout, "\n");
223
232
  }
224
233
 
234
+ static void
235
+ watch_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPSTATS *resp)
236
+ {
237
+ if (resp->rc != LCB_SUCCESS) {
238
+ fprintf(stderr, "ERROR 0x%02X (%s)\n", resp->rc, lcb_strerror(NULL, resp->rc));
239
+ return;
240
+ }
241
+ if (resp->server == NULL || resp->key == NULL) {
242
+ return;
243
+ }
244
+
245
+ string key = getRespKey((const lcb_RESPBASE *)resp);
246
+ if (resp->nvalue > 0) {
247
+ char *nptr = NULL;
248
+ uint64_t val =
249
+ #ifdef _WIN32
250
+ _strtoi64
251
+ #else
252
+ strtoll
253
+ #endif
254
+ ((const char *)resp->value, &nptr, 10);
255
+ if (nptr != (const char *)resp->value) {
256
+ map<string, int64_t> *entry = reinterpret_cast< map<string, int64_t> *>(resp->cookie);
257
+ (*entry)[key] += val;
258
+ }
259
+ }
260
+ }
261
+
225
262
  static void
226
263
  common_server_callback(lcb_t, int cbtype, const lcb_RESPSERVERBASE *sbase)
227
264
  {
@@ -372,17 +409,17 @@ Handler::run()
372
409
  lcb_error_t err;
373
410
  err = lcb_create(&instance, &cropts);
374
411
  if (err != LCB_SUCCESS) {
375
- throw LcbError(err);
412
+ throw LcbError(err, "Failed to create instance");
376
413
  }
377
414
  params.doCtls(instance);
378
415
  err = lcb_connect(instance);
379
416
  if (err != LCB_SUCCESS) {
380
- throw LcbError(err);
417
+ throw LcbError(err, "Failed to connect instance");
381
418
  }
382
419
  lcb_wait(instance);
383
420
  err = lcb_get_bootstrap_status(instance);
384
421
  if (err != LCB_SUCCESS) {
385
- throw LcbError(err);
422
+ throw LcbError(err, "Failed to bootstrap instance");
386
423
  }
387
424
 
388
425
  if (params.useTimings()) {
@@ -508,8 +545,7 @@ SetHandler::addOptions()
508
545
  if (!hasFileList()) {
509
546
  parser.addOption(o_value);
510
547
  }
511
- // This may be enabled again if datatype support is re-added
512
- // parser.addOption(o_json);
548
+ parser.addOption(o_json);
513
549
  }
514
550
 
515
551
  lcb_storage_t
@@ -846,6 +882,22 @@ VersionHandler::run()
846
882
  } else {
847
883
  printf(" SSL: NOT SUPPORTED\n");
848
884
  }
885
+ if (lcb_supports_feature(LCB_SUPPORTS_SNAPPY)) {
886
+ #define EXPAND(VAR) VAR ## 1
887
+ #define IS_EMPTY(VAR) EXPAND(VAR)
888
+
889
+ #if defined(SNAPPY_MAJOR) && (IS_EMPTY(SNAPPY_MAJOR) != 1)
890
+ printf(" Snappy: %d.%d.%d\n", SNAPPY_MAJOR, SNAPPY_MINOR, SNAPPY_PATCHLEVEL);
891
+ #else
892
+ printf(" Snappy: unknown\n");
893
+ #endif
894
+ } else {
895
+ printf(" Snappy: NOT SUPPORTED\n");
896
+ }
897
+ printf(" Tracing: %sSUPPORTED\n", lcb_supports_feature(LCB_SUPPORTS_TRACING) ? "" : "NOT ");
898
+ printf(" System: %s; %s\n", LCB_SYSTEM, LCB_SYSTEM_PROCESSOR);
899
+ printf(" CC: %s; %s\n", LCB_C_COMPILER, LCB_C_FLAGS);
900
+ printf(" CXX: %s; %s\n", LCB_CXX_COMPILER, LCB_CXX_FLAGS);
849
901
  }
850
902
 
851
903
  void
@@ -898,6 +950,57 @@ StatsHandler::run()
898
950
  lcb_wait(instance);
899
951
  }
900
952
 
953
+ void
954
+ WatchHandler::run()
955
+ {
956
+ Handler::run();
957
+ lcb_install_callback3(instance, LCB_CALLBACK_STATS, (lcb_RESPCALLBACK)watch_callback);
958
+ vector<string> keys = parser.getRestArgs();
959
+ if (keys.empty()) {
960
+ keys.push_back("cmd_total_ops");
961
+ keys.push_back("cmd_total_gets");
962
+ keys.push_back("cmd_total_sets");
963
+ }
964
+ int interval = o_interval.result();
965
+
966
+ map<string, int64_t> prev;
967
+
968
+ bool first = true;
969
+ while (true) {
970
+ map<string, int64_t> entry;
971
+ lcb_sched_enter(instance);
972
+ lcb_CMDSTATS cmd = { 0 };
973
+ lcb_error_t err = lcb_stats3(instance, (void *)&entry, &cmd);
974
+ if (err != LCB_SUCCESS) {
975
+ throw LcbError(err);
976
+ }
977
+ lcb_sched_leave(instance);
978
+ lcb_wait(instance);
979
+ if (first) {
980
+ for (vector<string>::iterator it = keys.begin(); it != keys.end(); ++it) {
981
+ fprintf(stderr, "%s: %" PRId64 "\n", it->c_str(), entry[*it]);
982
+ }
983
+ first = false;
984
+ } else {
985
+ #ifndef _WIN32
986
+ if (isatty(STDERR_FILENO)) {
987
+ fprintf(stderr, "\033[%dA", (int)keys.size());
988
+ }
989
+ #endif
990
+ for (vector<string>::iterator it = keys.begin(); it != keys.end(); ++it) {
991
+ fprintf(stderr, "%s: %" PRId64 "%20s\n", it->c_str(), (entry[*it] - prev[*it]) / interval, "");
992
+ }
993
+ }
994
+ prev = entry;
995
+ #ifdef _WIN32
996
+ Sleep(interval * 1000);
997
+ #else
998
+ sleep(interval);
999
+ #endif
1000
+ }
1001
+ }
1002
+
1003
+
901
1004
  void
902
1005
  VerbosityHandler::run()
903
1006
  {
@@ -1572,6 +1675,7 @@ static const char* optionsOrder[] = {
1572
1675
  "write-config",
1573
1676
  "strerror",
1574
1677
  "ping",
1678
+ "watch",
1575
1679
  NULL
1576
1680
  };
1577
1681
 
@@ -1640,6 +1744,7 @@ setupHandlers()
1640
1744
  handlers_s["rm"] = new RemoveHandler();
1641
1745
  handlers_s["cp"] = new SetHandler("cp");
1642
1746
  handlers_s["stats"] = new StatsHandler();
1747
+ handlers_s["watch"] = new WatchHandler();
1643
1748
  handlers_s["verbosity"] = new VerbosityHandler();
1644
1749
  handlers_s["ping"] = new PingHandler();
1645
1750
  handlers_s["mcflush"] = new McFlushHandler();
@@ -12,6 +12,7 @@ Histogram::install(lcb_t inst, FILE *out)
12
12
  rc = lcb_cntl(inst, LCB_CNTL_GET, LCB_CNTL_KVTIMINGS, &hg);
13
13
  assert(rc == LCB_SUCCESS);
14
14
  assert(hg != NULL);
15
+ (void)rc;
15
16
  }
16
17
 
17
18
  void
@@ -77,9 +77,11 @@ ConnParams::ConnParams() :
77
77
  o_transport.description("Bootstrap protocol").argdesc("HTTP|CCCP|ALL").setDefault("ALL");
78
78
  o_configcache.description("Path to cached configuration");
79
79
  o_ssl.description("Enable SSL settings").argdesc("ON|OFF|NOVERIFY").setDefault("off");
80
- o_certpath.description("Path to server certificate");
80
+ o_certpath.description("Path to server SSL certificate");
81
+ o_keypath.description("Path to client SSL private key");
81
82
  o_verbose.description("Set debugging output (specify multiple times for greater verbosity");
82
83
  o_dump.description("Dump verbose internal state after operations are done");
84
+ o_compress.description("Turn on compression of outgoing data (second time to force compression)").setDefault(false);
83
85
 
84
86
  o_cparams.description("Additional options for connection. "
85
87
  "Use -Dtimeout=SECONDS for KV operation timeout");
@@ -218,6 +220,8 @@ ConnParams::loadFileDefaults()
218
220
  o_connstr.setDefault(value).setPassed();
219
221
  } else if (key == "certpath") {
220
222
  o_certpath.setDefault(value).setPassed();
223
+ } else if (key == "keypath") {
224
+ o_keypath.setDefault(value).setPassed();
221
225
  } else if (key == "ssl") {
222
226
  o_ssl.setDefault(value).setPassed();
223
227
  } else {
@@ -259,7 +263,9 @@ ConnParams::writeConfig(const string& s)
259
263
  writeOption(f, o_user, "user");
260
264
  writeOption(f, o_passwd, "password");
261
265
  writeOption(f, o_ssl, "ssl");
266
+ writeOption(f, o_truststorepath, "truststorepath");
262
267
  writeOption(f, o_certpath, "certpath");
268
+ writeOption(f, o_keypath, "keypath");
263
269
 
264
270
  if (o_timeout.passed()) {
265
271
  f << "timeout=" << std::dec << o_timeout.result() << endl;
@@ -317,11 +323,21 @@ ConnParams::fillCropts(lcb_create_st& cropts)
317
323
  fprintf(stderr, " Specifying the default port (8091) has no effect\n");
318
324
  }
319
325
 
326
+ if (o_truststorepath.passed()) {
327
+ connstr += "truststorepath=";
328
+ connstr += o_truststorepath.result();
329
+ connstr += '&';
330
+ }
320
331
  if (o_certpath.passed()) {
321
332
  connstr += "certpath=";
322
333
  connstr += o_certpath.result();
323
334
  connstr += '&';
324
335
  }
336
+ if (o_keypath.passed()) {
337
+ connstr += "keypath=";
338
+ connstr += o_keypath.result();
339
+ connstr += '&';
340
+ }
325
341
  if (o_ssl.passed()) {
326
342
  connstr += "ssl=";
327
343
  connstr += o_ssl.result();
@@ -417,6 +433,17 @@ ConnParams::doCtls(lcb_t instance)
417
433
 
418
434
  // Set the detailed error codes option
419
435
  doSctl<int>(instance, LCB_CNTL_DETAILED_ERRCODES, 1);
436
+
437
+ {
438
+ int opts = LCB_COMPRESS_IN;
439
+ if (o_compress.passed()) {
440
+ opts |= LCB_COMPRESS_OUT;
441
+ if (o_compress.numSpecified() > 1) {
442
+ opts |= LCB_COMPRESS_FORCE;
443
+ }
444
+ }
445
+ doPctl(instance, LCB_CNTL_COMPRESSION_OPTS, &opts);
446
+ }
420
447
  } catch (lcb_error_t &err) {
421
448
  return err;
422
449
  }