libcouchbase 1.2.8 → 1.3.0

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