libcouchbase 1.0.4 → 1.1.0

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