libcouchbase 1.0.4 → 1.1.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +11 -8
  3. data/ext/libcouchbase/CMakeLists.txt +1 -1
  4. data/ext/libcouchbase/README.markdown +38 -6
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +151 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -2
  7. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  8. data/ext/libcouchbase/cmake/source_files.cmake +1 -0
  9. data/ext/libcouchbase/contrib/cJSON/cJSON.c +686 -288
  10. data/ext/libcouchbase/contrib/cJSON/cJSON.h +0 -0
  11. data/ext/libcouchbase/contrib/cbsasl/src/hash.c +17 -17
  12. data/ext/libcouchbase/contrib/cliopts/cliopts.c +76 -0
  13. data/ext/libcouchbase/contrib/cliopts/cliopts.h +66 -15
  14. data/ext/libcouchbase/contrib/genhash/genhash.c +1 -2
  15. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4 -3
  16. data/ext/libcouchbase/example/instancepool/main.cc +12 -2
  17. data/ext/libcouchbase/example/libeventdirect/main.c +99 -25
  18. data/ext/libcouchbase/example/minimal/minimal.c +7 -5
  19. data/ext/libcouchbase/example/observe/durability.c +102 -0
  20. data/ext/libcouchbase/example/observe/observe.c +19 -6
  21. data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +1 -2
  22. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +6 -8
  23. data/ext/libcouchbase/include/libcouchbase/cntl.h +84 -64
  24. data/ext/libcouchbase/include/libcouchbase/couchbase.h +295 -78
  25. data/ext/libcouchbase/include/libcouchbase/deprecated.h +2 -2
  26. data/ext/libcouchbase/include/libcouchbase/error.h +1 -1
  27. data/ext/libcouchbase/include/libcouchbase/iops.h +9 -9
  28. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +2 -2
  29. data/ext/libcouchbase/include/libcouchbase/n1ql.h +69 -7
  30. data/ext/libcouchbase/include/libcouchbase/vbucket.h +17 -0
  31. data/ext/libcouchbase/include/libcouchbase/views.h +3 -3
  32. data/ext/libcouchbase/include/memcached/protocol_binary.h +62 -1
  33. data/ext/libcouchbase/packaging/deb/control +1 -1
  34. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +37 -36
  35. data/ext/libcouchbase/src/bootstrap.cc +22 -8
  36. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +1 -1
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -1
  38. data/ext/libcouchbase/src/bucketconfig/confmon.cc +13 -8
  39. data/ext/libcouchbase/src/callbacks.c +2 -0
  40. data/ext/libcouchbase/src/cntl.cc +28 -17
  41. data/ext/libcouchbase/src/dns-srv.cc +1 -2
  42. data/ext/libcouchbase/src/dump.cc +4 -0
  43. data/ext/libcouchbase/src/errmap.h +89 -16
  44. data/ext/libcouchbase/src/handler.cc +28 -11
  45. data/ext/libcouchbase/src/http/http-priv.h +4 -1
  46. data/ext/libcouchbase/src/http/http.cc +3 -0
  47. data/ext/libcouchbase/src/instance.cc +1 -1
  48. data/ext/libcouchbase/src/internal.h +1 -0
  49. data/ext/libcouchbase/src/lcbio/connect.cc +2 -3
  50. data/ext/libcouchbase/src/lcbio/manager.cc +2 -2
  51. data/ext/libcouchbase/src/lcbio/ssl.h +10 -0
  52. data/ext/libcouchbase/src/mc/mcreq.c +8 -0
  53. data/ext/libcouchbase/src/mcserver/mcserver.cc +14 -1
  54. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +0 -3
  55. data/ext/libcouchbase/src/n1ql/n1ql.cc +22 -29
  56. data/ext/libcouchbase/src/n1ql/params.cc +46 -1
  57. data/ext/libcouchbase/src/newconfig.cc +4 -4
  58. data/ext/libcouchbase/src/operations/durability-seqno.cc +4 -0
  59. data/ext/libcouchbase/src/operations/durability.cc +3 -0
  60. data/ext/libcouchbase/src/operations/ping.cc +315 -0
  61. data/ext/libcouchbase/src/operations/stats.cc +10 -0
  62. data/ext/libcouchbase/src/operations/subdoc.cc +13 -1
  63. data/ext/libcouchbase/src/retrychk.cc +1 -0
  64. data/ext/libcouchbase/src/settings.c +2 -0
  65. data/ext/libcouchbase/src/settings.h +13 -7
  66. data/ext/libcouchbase/src/ssl/ssl_c.c +28 -2
  67. data/ext/libcouchbase/src/ssl/ssl_common.c +3 -0
  68. data/ext/libcouchbase/src/ssl/ssl_e.c +15 -1
  69. data/ext/libcouchbase/src/ssl/ssl_iot_common.h +3 -1
  70. data/ext/libcouchbase/src/timings.c +0 -1
  71. data/ext/libcouchbase/src/vbucket/vbucket.c +49 -1
  72. data/ext/libcouchbase/tests/iotests/mock-environment.cc +58 -40
  73. data/ext/libcouchbase/tests/iotests/mock-environment.h +23 -4
  74. data/ext/libcouchbase/tests/iotests/mock-unit-test.h +8 -8
  75. data/ext/libcouchbase/tests/iotests/t_behavior.cc +5 -5
  76. data/ext/libcouchbase/tests/iotests/t_durability.cc +50 -0
  77. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +4 -2
  78. data/ext/libcouchbase/tests/iotests/t_errmap.cc +6 -3
  79. data/ext/libcouchbase/tests/iotests/t_lock.cc +5 -6
  80. data/ext/libcouchbase/tests/iotests/t_misc.cc +44 -0
  81. data/ext/libcouchbase/tests/iotests/t_serverops.cc +1 -0
  82. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +28 -0
  83. data/ext/libcouchbase/tests/iotests/t_views.cc +22 -10
  84. data/ext/libcouchbase/tools/CMakeLists.txt +21 -1
  85. data/ext/libcouchbase/tools/cbc-handlers.h +23 -3
  86. data/ext/libcouchbase/tools/cbc-n1qlback.cc +1 -1
  87. data/ext/libcouchbase/tools/cbc-pillowfight.cc +126 -26
  88. data/ext/libcouchbase/tools/cbc-proxy.cc +403 -0
  89. data/ext/libcouchbase/tools/cbc-subdoc.cc +826 -0
  90. data/ext/libcouchbase/tools/cbc.cc +149 -37
  91. data/ext/libcouchbase/tools/common/options.h +5 -2
  92. data/ext/libcouchbase/tools/linenoise/linenoise.c +15 -15
  93. data/lib/libcouchbase.rb +4 -0
  94. data/lib/libcouchbase/bucket.rb +51 -0
  95. data/lib/libcouchbase/connection.rb +100 -13
  96. data/lib/libcouchbase/ext/libcouchbase.rb +40 -0
  97. data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +13 -1
  98. data/lib/libcouchbase/ext/libcouchbase/enums.rb +2 -1
  99. data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +5 -0
  100. data/lib/libcouchbase/subdoc_request.rb +129 -0
  101. data/lib/libcouchbase/version.rb +1 -1
  102. data/spec/bucket_spec.rb +15 -1
  103. data/spec/connection_spec.rb +1 -1
  104. data/spec/subdoc_spec.rb +192 -0
  105. metadata +13 -4
  106. data/ext/libcouchbase/.travis.yml +0 -19
@@ -11,12 +11,17 @@
11
11
  #include <libcouchbase/n1ql.h>
12
12
  #include <limits>
13
13
  #include <stddef.h>
14
+ #include <errno.h>
14
15
  #include "common/options.h"
15
16
  #include "common/histogram.h"
16
17
  #include "cbc-handlers.h"
17
18
  #include "connspec.h"
18
19
  #include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
19
20
 
21
+ #ifndef LCB_NO_SSL
22
+ #include <openssl/crypto.h>
23
+ #endif
24
+
20
25
  using namespace cbc;
21
26
 
22
27
  using std::string;
@@ -34,11 +39,19 @@ string getRespKey(const lcb_RESPBASE* resp)
34
39
  }
35
40
 
36
41
  static void
37
- printKeyError(string& key, lcb_error_t err, const char *additional = NULL)
42
+ printKeyError(string& key, int cbtype, const lcb_RESPBASE *resp, const char *additional = NULL)
38
43
  {
39
- fprintf(stderr, "%-20s %s (0x%x)\n", key.c_str(), lcb_strerror(NULL, err), err);
44
+ fprintf(stderr, "%-20s %s (0x%x)\n", key.c_str(), lcb_strerror(NULL, resp->rc), resp->rc);
45
+ const char *ctx = lcb_resp_get_error_context(cbtype, resp);
46
+ if (ctx != NULL) {
47
+ fprintf(stderr, "%-20s %s\n", "", ctx);
48
+ }
49
+ const char *ref = lcb_resp_get_error_ref(cbtype, resp);
50
+ if (ref != NULL) {
51
+ fprintf(stderr, "%-20s Ref: %s\n", "", ref);
52
+ }
40
53
  if (additional) {
41
- fprintf(stderr, "%-20s%s\n", "", additional);
54
+ fprintf(stderr, "%-20s %s\n", "", additional);
42
55
  }
43
56
  }
44
57
 
@@ -60,7 +73,7 @@ printKeyCasStatus(string& key, int cbtype, const lcb_RESPBASE *resp,
60
73
 
61
74
  extern "C" {
62
75
  static void
63
- get_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPGET *resp)
76
+ get_callback(lcb_t, lcb_CALLBACKTYPE cbtype, const lcb_RESPGET *resp)
64
77
  {
65
78
  string key = getRespKey((const lcb_RESPBASE *)resp);
66
79
  if (resp->rc == LCB_SUCCESS) {
@@ -71,7 +84,7 @@ get_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPGET *resp)
71
84
  fflush(stdout);
72
85
  fprintf(stderr, "\n");
73
86
  } else {
74
- printKeyError(key, resp->rc);
87
+ printKeyError(key, cbtype, (const lcb_RESPBASE *)resp);
75
88
  }
76
89
  }
77
90
 
@@ -96,13 +109,13 @@ store_callback(lcb_t, lcb_CALLBACKTYPE cbtype, const lcb_RESPBASE *resp)
96
109
  } else {
97
110
  sprintf(buf, "%s", "Store failed");
98
111
  }
99
- printKeyError(key, resp->rc, buf);
112
+ printKeyError(key, cbtype, resp);
100
113
  }
101
114
  } else {
102
115
  if (resp->rc == LCB_SUCCESS) {
103
116
  printKeyCasStatus(key, cbtype, resp, "Stored.");
104
117
  } else {
105
- printKeyError(key, resp->rc);
118
+ printKeyError(key, cbtype, resp);
106
119
  }
107
120
  }
108
121
  }
@@ -112,7 +125,7 @@ common_callback(lcb_t, int type, const lcb_RESPBASE *resp)
112
125
  {
113
126
  string key = getRespKey(resp);
114
127
  if (resp->rc != LCB_SUCCESS) {
115
- printKeyError(key, resp->rc);
128
+ printKeyError(key, type, resp);
116
129
  return;
117
130
  }
118
131
  switch (type) {
@@ -131,7 +144,7 @@ common_callback(lcb_t, int type, const lcb_RESPBASE *resp)
131
144
  }
132
145
 
133
146
  static void
134
- observe_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPOBSERVE *resp)
147
+ observe_callback(lcb_t, lcb_CALLBACKTYPE cbtype, const lcb_RESPOBSERVE *resp)
135
148
  {
136
149
  if (resp->nkey == 0) {
137
150
  return;
@@ -144,7 +157,7 @@ observe_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPOBSERVE *resp)
144
157
  resp->ismaster ? "Master" : "Replica",
145
158
  resp->status, resp->cas);
146
159
  } else {
147
- printKeyError(key, resp->rc);
160
+ printKeyError(key, cbtype, (const lcb_RESPBASE *)resp);
148
161
  }
149
162
  }
150
163
 
@@ -180,7 +193,7 @@ static void
180
193
  stats_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPSTATS *resp)
181
194
  {
182
195
  if (resp->rc != LCB_SUCCESS) {
183
- fprintf(stderr, "Got error %s (%d) in stats\n", lcb_strerror(NULL, resp->rc), resp->rc);
196
+ fprintf(stderr, "ERROR 0x%02X (%s)\n", resp->rc, lcb_strerror(NULL, resp->rc));
184
197
  return;
185
198
  }
186
199
  if (resp->server == NULL || resp->key == NULL) {
@@ -231,12 +244,24 @@ common_server_callback(lcb_t, int cbtype, const lcb_RESPSERVERBASE *sbase)
231
244
  }
232
245
  }
233
246
 
247
+ static void
248
+ ping_callback(lcb_t, int, const lcb_RESPPING *resp)
249
+ {
250
+ if (resp->rc != LCB_SUCCESS) {
251
+ fprintf(stderr, "failed: %s\n", lcb_strerror(NULL, resp->rc));
252
+ } else {
253
+ if (resp->njson) {
254
+ printf("%.*s", (int)resp->njson, resp->json);
255
+ }
256
+ }
257
+ }
258
+
234
259
  static void
235
260
  arithmetic_callback(lcb_t, lcb_CALLBACKTYPE type, const lcb_RESPCOUNTER *resp)
236
261
  {
237
262
  string key = getRespKey((const lcb_RESPBASE *)resp);
238
263
  if (resp->rc != LCB_SUCCESS) {
239
- printKeyError(key, resp->rc);
264
+ printKeyError(key, type, (lcb_RESPBASE *)resp);
240
265
  } else {
241
266
  char buf[4096] = { 0 };
242
267
  sprintf(buf, "Current value is %" PRIu64 ".", resp->value);
@@ -403,21 +428,36 @@ GetHandler::run()
403
428
  lcb_install_callback3(instance, LCB_CALLBACK_GET, (lcb_RESPCALLBACK)get_callback);
404
429
  lcb_install_callback3(instance, LCB_CALLBACK_GETREPLICA, (lcb_RESPCALLBACK)get_callback);
405
430
  const vector<string>& keys = parser.getRestArgs();
406
- lcb_error_t err;
431
+ std::string replica_mode = o_replica.result();
407
432
 
408
433
  lcb_sched_enter(instance);
409
434
  for (size_t ii = 0; ii < keys.size(); ++ii) {
410
- lcb_CMDGET cmd = { 0 };
411
- const string& key = keys[ii];
412
- LCB_KREQ_SIMPLE(&cmd.key, key.c_str(), key.size());
413
- if (o_exptime.passed()) {
414
- cmd.exptime = o_exptime.result();
415
- }
416
- if (isLock()) {
417
- cmd.lock = 1;
435
+ lcb_error_t err;
436
+ if (o_replica.passed()) {
437
+ lcb_CMDGETREPLICA cmd = { 0 };
438
+ const string& key = keys[ii];
439
+ LCB_KREQ_SIMPLE(&cmd.key, key.c_str(), key.size());
440
+ if (replica_mode == "first") {
441
+ cmd.strategy = LCB_REPLICA_FIRST;
442
+ } else if (replica_mode == "all") {
443
+ cmd.strategy = LCB_REPLICA_ALL;
444
+ } else {
445
+ cmd.strategy = LCB_REPLICA_SELECT;
446
+ cmd.index = std::atoi(replica_mode.c_str());
447
+ }
448
+ err = lcb_rget3(instance, this, &cmd);
449
+ } else {
450
+ lcb_CMDGET cmd = { 0 };
451
+ const string& key = keys[ii];
452
+ LCB_KREQ_SIMPLE(&cmd.key, key.c_str(), key.size());
453
+ if (o_exptime.passed()) {
454
+ cmd.exptime = o_exptime.result();
455
+ }
456
+ if (isLock()) {
457
+ cmd.lock = 1;
458
+ }
459
+ err = lcb_get3(instance, this, &cmd);
418
460
  }
419
-
420
- err = lcb_get3(instance, this, &cmd);
421
461
  if (err != LCB_SUCCESS) {
422
462
  throw LcbError(err);
423
463
  }
@@ -763,11 +803,49 @@ VersionHandler::run()
763
803
  memset(&info, 0, sizeof info);
764
804
  err = lcb_cntl(NULL, LCB_CNTL_GET, LCB_CNTL_IOPS_DEFAULT_TYPES, &info);
765
805
  if (err == LCB_SUCCESS) {
766
- fprintf(stderr, " IO: Default=%s, Current=%s\n",
806
+ fprintf(stderr, " IO: Default=%s, Current=%s, Accessible=",
767
807
  iops_to_string(info.v.v0.os_default), iops_to_string(info.v.v0.effective));
768
808
  }
769
- printf(" SSL: .. %s\n",
770
- lcb_supports_feature(LCB_SUPPORTS_SSL) ? "SUPPORTED" : "NOT SUPPORTED");
809
+ {
810
+ size_t ii;
811
+ char buf[256] = {0}, *p = buf;
812
+ lcb_io_ops_type_t known_io[] = {
813
+ LCB_IO_OPS_WINIOCP,
814
+ LCB_IO_OPS_LIBEVENT,
815
+ LCB_IO_OPS_LIBUV,
816
+ LCB_IO_OPS_LIBEV,
817
+ LCB_IO_OPS_SELECT
818
+ };
819
+
820
+
821
+ for (ii = 0; ii < sizeof(known_io) / sizeof(known_io[0]); ii++) {
822
+ struct lcb_create_io_ops_st cio = {0};
823
+ lcb_io_opt_t io = NULL;
824
+
825
+ cio.v.v0.type = known_io[ii];
826
+ if (lcb_create_io_ops(&io, &cio) == LCB_SUCCESS) {
827
+ p += sprintf(p, "%s,", iops_to_string(known_io[ii]));
828
+ lcb_destroy_io_ops(io);
829
+ }
830
+ }
831
+ *(--p) = '\n';
832
+ fprintf(stderr, "%s", buf);
833
+ }
834
+
835
+ if (lcb_supports_feature(LCB_SUPPORTS_SSL)) {
836
+ #ifdef LCB_NO_SSL
837
+ printf(" SSL: SUPPORTED\n");
838
+ #else
839
+ #if defined(OPENSSL_VERSION)
840
+ printf(" SSL Runtime: %s\n", OpenSSL_version(OPENSSL_VERSION));
841
+ #elif defined(SSLEAY_VERSION)
842
+ printf(" SSL Runtime: %s\n", SSLeay_version(SSLEAY_VERSION));
843
+ #endif
844
+ printf(" SSL Headers: %s\n", OPENSSL_VERSION_TEXT);
845
+ #endif
846
+ } else {
847
+ printf(" SSL: NOT SUPPORTED\n");
848
+ }
771
849
  }
772
850
 
773
851
  void
@@ -852,6 +930,28 @@ VerbosityHandler::run()
852
930
  lcb_wait(instance);
853
931
  }
854
932
 
933
+ void
934
+ PingHandler::run()
935
+ {
936
+ Handler::run();
937
+
938
+ lcb_install_callback3(instance, LCB_CALLBACK_PING, (lcb_RESPCALLBACK)ping_callback);
939
+ lcb_CMDPING cmd = { 0 };
940
+ lcb_error_t err;
941
+ cmd.services = LCB_PINGSVC_F_KV | LCB_PINGSVC_F_N1QL | LCB_PINGSVC_F_VIEWS | LCB_PINGSVC_F_FTS;
942
+ cmd.options = LCB_PINGOPT_F_JSON | LCB_PINGOPT_F_JSONPRETTY;
943
+ if (o_details.passed()) {
944
+ cmd.options |= LCB_PINGOPT_F_JSONDETAILS;
945
+ }
946
+ lcb_sched_enter(instance);
947
+ err = lcb_ping3(instance, NULL, &cmd);
948
+ if (err != LCB_SUCCESS) {
949
+ throw LcbError(err);
950
+ }
951
+ lcb_sched_leave(instance);
952
+ lcb_wait(instance);
953
+ }
954
+
855
955
  void
856
956
  McFlushHandler::run()
857
957
  {
@@ -979,11 +1079,11 @@ extern "C" {
979
1079
  static void n1qlCallback(lcb_t, int, const lcb_RESPN1QL *resp)
980
1080
  {
981
1081
  if (resp->rflags & LCB_RESP_F_FINAL) {
982
- fprintf(stderr, "** N1QL Response finished\n");
1082
+ fprintf(stderr, "---> Query response finished\n");
983
1083
  if (resp->rc != LCB_SUCCESS) {
984
- fprintf(stderr, "N1QL query failed with library code 0x%x\n", resp->rc);
1084
+ fprintf(stderr, "---> Query failed with library code 0x%x (%s)\n", resp->rc, lcb_strerror(NULL, resp->rc));
985
1085
  if (resp->htresp) {
986
- fprintf(stderr, "Inner HTTP request failed with library code 0x%x and HTTP status %d\n",
1086
+ fprintf(stderr, "---> Inner HTTP request failed with library code 0x%x and HTTP status %d\n",
987
1087
  resp->htresp->rc, resp->htresp->htstatus);
988
1088
  }
989
1089
  }
@@ -1039,7 +1139,10 @@ N1qlHandler::run()
1039
1139
  if (o_prepare.passed()) {
1040
1140
  cmd.cmdflags |= LCB_CMDN1QL_F_PREPCACHE;
1041
1141
  }
1042
- fprintf(stderr, "Encoded query: %.*s\n", (int)cmd.nquery, cmd.query);
1142
+ if (o_analytics.passed()) {
1143
+ cmd.cmdflags |= LCB_CMDN1QL_F_CBASQUERY;
1144
+ }
1145
+ fprintf(stderr, "---> Encoded query: %.*s\n", (int)cmd.nquery, cmd.query);
1043
1146
  cmd.callback = n1qlCallback;
1044
1147
  rc = lcb_n1ql_query(instance, NULL, &cmd);
1045
1148
  if (rc != LCB_SUCCESS) {
@@ -1348,7 +1451,6 @@ ConnstrHandler::run()
1348
1451
  lcb_error_t err;
1349
1452
  const char *errmsg;
1350
1453
  lcb::Connspec spec;
1351
- memset(&spec, 0, sizeof spec);
1352
1454
  err = spec.parse(connstr_s.c_str(), &errmsg);
1353
1455
  if (err != LCB_SUCCESS) {
1354
1456
  throw BadArg(errmsg);
@@ -1362,6 +1464,8 @@ ConnstrHandler::run()
1362
1464
  if (spec.sslopts() & LCB_SSL_NOVERIFY) {
1363
1465
  sslOpts += "|NOVERIFY";
1364
1466
  }
1467
+ } else {
1468
+ sslOpts = "DISABLED";
1365
1469
  }
1366
1470
  printf("SSL: %s\n", sslOpts.c_str());
1367
1471
 
@@ -1455,7 +1559,7 @@ static const char* optionsOrder[] = {
1455
1559
  "version",
1456
1560
  "verbosity",
1457
1561
  "view",
1458
- "n1ql",
1562
+ "query",
1459
1563
  "admin",
1460
1564
  "bucket-create",
1461
1565
  "bucket-delete",
@@ -1467,6 +1571,7 @@ static const char* optionsOrder[] = {
1467
1571
  "connstr",
1468
1572
  "write-config",
1469
1573
  "strerror",
1574
+ "ping",
1470
1575
  NULL
1471
1576
  };
1472
1577
 
@@ -1536,6 +1641,7 @@ setupHandlers()
1536
1641
  handlers_s["cp"] = new SetHandler("cp");
1537
1642
  handlers_s["stats"] = new StatsHandler();
1538
1643
  handlers_s["verbosity"] = new VerbosityHandler();
1644
+ handlers_s["ping"] = new PingHandler();
1539
1645
  handlers_s["mcflush"] = new McFlushHandler();
1540
1646
  handlers_s["incr"] = new IncrHandler();
1541
1647
  handlers_s["decr"] = new DecrHandler();
@@ -1544,7 +1650,7 @@ setupHandlers()
1544
1650
  handlers_s["bucket-delete"] = new BucketDeleteHandler();
1545
1651
  handlers_s["bucket-flush"] = new BucketFlushHandler();
1546
1652
  handlers_s["view"] = new ViewsHandler();
1547
- handlers_s["n1ql"] = new N1qlHandler();
1653
+ handlers_s["query"] = new N1qlHandler();
1548
1654
  handlers_s["connstr"] = new ConnstrHandler();
1549
1655
  handlers_s["write-config"] = new WriteConfigHandler();
1550
1656
  handlers_s["strerror"] = new StrErrorHandler();
@@ -1561,6 +1667,7 @@ setupHandlers()
1561
1667
  }
1562
1668
 
1563
1669
  handlers["cat"] = handlers["get"];
1670
+ handlers["n1ql"] = handlers["query"];
1564
1671
  }
1565
1672
 
1566
1673
  #if _POSIX_VERSION >= 200112L
@@ -1604,7 +1711,8 @@ wrapExternalBinary(int argc, char **argv, const std::string& name)
1604
1711
  size_t cbc_pos = exePath.find("cbc");
1605
1712
 
1606
1713
  if (cbc_pos == string::npos) {
1607
- throw BadArg("Couldn't invoke " + name);
1714
+ fprintf(stderr, "Failed to invoke %s (%s)\n", name.c_str(), exePath.c_str());
1715
+ exit(EXIT_FAILURE);
1608
1716
  }
1609
1717
 
1610
1718
  exePath.replace(cbc_pos, 3, name);
@@ -1617,11 +1725,11 @@ wrapExternalBinary(int argc, char **argv, const std::string& name)
1617
1725
  }
1618
1726
  args.push_back((char*)NULL);
1619
1727
  execvp(exePath.c_str(), &args[0]);
1620
- perror(exePath.c_str());
1621
- throw BadArg("Couldn't execute " + name + " !");
1728
+ fprintf(stderr, "Failed to execute execute %s (%s): %s\n", name.c_str(), exePath.c_str(), strerror(errno));
1622
1729
  #else
1623
- throw BadArg("Can't wrap around " + name + " on non-POSIX environments");
1730
+ fprintf(stderr, "Can't wrap around %s on non-POSIX environments", name.c_str());
1624
1731
  #endif
1732
+ exit(EXIT_FAILURE);
1625
1733
  }
1626
1734
 
1627
1735
  static void cleanupHandlers()
@@ -1641,6 +1749,10 @@ int main(int argc, char **argv)
1641
1749
  wrapExternalBinary(argc, argv, "cbc-pillowfight");
1642
1750
  } else if (strcmp(argv[1], "n1qlback") == 0) {
1643
1751
  wrapExternalBinary(argc, argv, "cbc-n1qlback");
1752
+ } else if (strcmp(argv[1], "subdoc") == 0) {
1753
+ wrapExternalBinary(argc, argv, "cbc-subdoc");
1754
+ } else if (strcmp(argv[1], "proxy") == 0) {
1755
+ wrapExternalBinary(argc, argv, "cbc-proxy");
1644
1756
  }
1645
1757
  }
1646
1758
 
@@ -34,8 +34,11 @@ namespace cbc {
34
34
 
35
35
  class LcbError : public std::runtime_error {
36
36
  private:
37
- static std::string format_err(lcb_error_t err) {
37
+ static std::string format_err(lcb_error_t err, std::string msg) {
38
38
  std::stringstream ss;
39
+ if (!msg.empty()) {
40
+ ss << msg << ". ";
41
+ }
39
42
  ss << "libcouchbase error: " << lcb_strerror(NULL, err);
40
43
  ss << " (0x" << std::hex << err << ")";
41
44
  return ss.str();
@@ -43,7 +46,7 @@ private:
43
46
 
44
47
  public:
45
48
  lcb_error_t rc;
46
- LcbError(lcb_error_t code) : std::runtime_error(format_err(code)) {}
49
+ LcbError(lcb_error_t code, std::string msg = "") : std::runtime_error(format_err(code, msg)) {}
47
50
  };
48
51
 
49
52
  class BadArg : public std::runtime_error {
@@ -173,7 +173,6 @@ enum KEY_ACTION{
173
173
  };
174
174
 
175
175
  static void linenoiseAtExit(void);
176
- int linenoiseHistoryAdd(const char *line);
177
176
  static void refreshLine(struct linenoiseState *l);
178
177
 
179
178
  /* Debugging macro. */
@@ -192,7 +191,7 @@ FILE *lndebug_fp = NULL;
192
191
  fflush(lndebug_fp); \
193
192
  } while (0)
194
193
  #else
195
- #define lndebug(fmt, ...)
194
+ #define lndebug(...)
196
195
  #endif
197
196
 
198
197
  /* ======================= Low level terminal handling ====================== */
@@ -473,7 +472,7 @@ static void abFree(struct abuf *ab) {
473
472
 
474
473
  /* Helper of refreshSingleLine() and refreshMultiLine() to show hints
475
474
  * to the right of the prompt. */
476
- void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
475
+ static void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
477
476
  char seq[64];
478
477
  if (hintsCallback && plen+l->len < l->cols) {
479
478
  int color = -1, bold = 0;
@@ -635,7 +634,7 @@ static void refreshLine(struct linenoiseState *l) {
635
634
  /* Insert the character 'c' at cursor current position.
636
635
  *
637
636
  * On error writing to the terminal -1 is returned, otherwise 0. */
638
- int linenoiseEditInsert(struct linenoiseState *l, char c) {
637
+ static int linenoiseEditInsert(struct linenoiseState *l, char c) {
639
638
  if (l->len < l->buflen) {
640
639
  if (l->len == l->pos) {
641
640
  l->buf[l->pos] = c;
@@ -662,7 +661,7 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) {
662
661
  }
663
662
 
664
663
  /* Move cursor on the left. */
665
- void linenoiseEditMoveLeft(struct linenoiseState *l) {
664
+ static void linenoiseEditMoveLeft(struct linenoiseState *l) {
666
665
  if (l->pos > 0) {
667
666
  l->pos--;
668
667
  refreshLine(l);
@@ -670,7 +669,7 @@ void linenoiseEditMoveLeft(struct linenoiseState *l) {
670
669
  }
671
670
 
672
671
  /* Move cursor on the right. */
673
- void linenoiseEditMoveRight(struct linenoiseState *l) {
672
+ static void linenoiseEditMoveRight(struct linenoiseState *l) {
674
673
  if (l->pos != l->len) {
675
674
  l->pos++;
676
675
  refreshLine(l);
@@ -678,7 +677,7 @@ void linenoiseEditMoveRight(struct linenoiseState *l) {
678
677
  }
679
678
 
680
679
  /* Move cursor to the start of the line. */
681
- void linenoiseEditMoveHome(struct linenoiseState *l) {
680
+ static void linenoiseEditMoveHome(struct linenoiseState *l) {
682
681
  if (l->pos != 0) {
683
682
  l->pos = 0;
684
683
  refreshLine(l);
@@ -686,7 +685,7 @@ void linenoiseEditMoveHome(struct linenoiseState *l) {
686
685
  }
687
686
 
688
687
  /* Move cursor to the end of the line. */
689
- void linenoiseEditMoveEnd(struct linenoiseState *l) {
688
+ static void linenoiseEditMoveEnd(struct linenoiseState *l) {
690
689
  if (l->pos != l->len) {
691
690
  l->pos = l->len;
692
691
  refreshLine(l);
@@ -697,7 +696,7 @@ void linenoiseEditMoveEnd(struct linenoiseState *l) {
697
696
  * entry as specified by 'dir'. */
698
697
  #define LINENOISE_HISTORY_NEXT 0
699
698
  #define LINENOISE_HISTORY_PREV 1
700
- void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) {
699
+ static void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) {
701
700
  if (history_len > 1) {
702
701
  /* Update the current history entry before to
703
702
  * overwrite it with the next one. */
@@ -721,7 +720,7 @@ void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) {
721
720
 
722
721
  /* Delete the character at the right of the cursor without altering the cursor
723
722
  * position. Basically this is what happens with the "Delete" keyboard key. */
724
- void linenoiseEditDelete(struct linenoiseState *l) {
723
+ static void linenoiseEditDelete(struct linenoiseState *l) {
725
724
  if (l->len > 0 && l->pos < l->len) {
726
725
  memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1);
727
726
  l->len--;
@@ -731,7 +730,7 @@ void linenoiseEditDelete(struct linenoiseState *l) {
731
730
  }
732
731
 
733
732
  /* Backspace implementation. */
734
- void linenoiseEditBackspace(struct linenoiseState *l) {
733
+ static void linenoiseEditBackspace(struct linenoiseState *l) {
735
734
  if (l->pos > 0 && l->len > 0) {
736
735
  memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos);
737
736
  l->pos--;
@@ -743,7 +742,7 @@ void linenoiseEditBackspace(struct linenoiseState *l) {
743
742
 
744
743
  /* Delete the previosu word, maintaining the cursor at the start of the
745
744
  * current word. */
746
- void linenoiseEditDeletePrevWord(struct linenoiseState *l) {
745
+ static void linenoiseEditDeletePrevWord(struct linenoiseState *l) {
747
746
  size_t old_pos = l->pos;
748
747
  size_t diff;
749
748
 
@@ -804,11 +803,12 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
804
803
  * there was an error reading from fd. Otherwise it will return the
805
804
  * character that should be handled next. */
806
805
  if (c == 9 && completionCallback != NULL) {
807
- c = completeLine(&l);
806
+ int r = completeLine(&l);
808
807
  /* Return on errors */
809
- if (c < 0) return l.len;
808
+ if (r < 0) return l.len;
810
809
  /* Read next character when 0 */
811
- if (c == 0) continue;
810
+ if (r == 0) continue;
811
+ c = (char)r;
812
812
  }
813
813
 
814
814
  switch(c) {