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
@@ -53,7 +53,7 @@ void Bootstrap::config_callback(EventType event, ConfigInfo *info) {
53
53
 
54
54
  tm.cancel();
55
55
 
56
- lcb_log(LOGARGS(instance, DEBUG), "Instance configured!");
56
+ lcb_log(LOGARGS(instance, DEBUG), "Instance configured");
57
57
 
58
58
  if (info->get_origin() != CLCONFIG_FILE) {
59
59
  /* Set the timestamp for the current config to control throttling,
@@ -88,14 +88,28 @@ void Bootstrap::config_callback(EventType event, ConfigInfo *info) {
88
88
  state = S_BOOTSTRAPPED;
89
89
  lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
90
90
 
91
- if (instance->type == LCB_TYPE_BUCKET &&
92
- LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA &&
91
+ if (instance->type == LCB_TYPE_BUCKET) {
92
+ if (LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA &&
93
93
  instance->cur_configinfo->get_origin() != CLCONFIG_MCRAW) {
94
+ lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets");
95
+ instance->settings->bc_http_stream_time = -1;
96
+ instance->confmon->set_active(CLCONFIG_HTTP, true);
97
+ instance->confmon->set_active(CLCONFIG_CCCP, false);
98
+ }
94
99
 
95
- lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets");
96
- instance->settings->bc_http_stream_time = -1;
97
- instance->confmon->set_active(CLCONFIG_HTTP, true);
98
- instance->confmon->set_active(CLCONFIG_CCCP, false);
100
+ /* infer bucket type using distribution and capabilities set */
101
+ switch (LCBVB_DISTTYPE(LCBT_VBCONFIG(instance))) {
102
+ case LCBVB_DIST_VBUCKET:
103
+ if (LCBVB_CAPS(LCBT_VBCONFIG(instance)) & LCBVB_CAP_COUCHAPI) {
104
+ instance->btype = LCB_BTYPE_COUCHBASE;
105
+ } else {
106
+ instance->btype = LCB_BTYPE_EPHEMERAL;
107
+ }
108
+ break;
109
+ case LCBVB_DIST_KETAMA:
110
+ instance->btype = LCB_BTYPE_MEMCACHED;
111
+ break;
112
+ }
99
113
  }
100
114
  instance->callbacks.bootstrap(instance, LCB_SUCCESS);
101
115
 
@@ -127,7 +141,7 @@ void Bootstrap::check_bgpoll() {
127
141
 
128
142
  void Bootstrap::bgpoll() {
129
143
  lcb_log(LOGARGS(parent, TRACE), "Background-polling for new configuration");
130
- bootstrap(BS_REFRESH_THROTTLE);
144
+ bootstrap(BS_REFRESH_ALWAYS);
131
145
  check_bgpoll();
132
146
  }
133
147
 
@@ -140,7 +140,7 @@ CccpProvider::schedule_next_request(lcb_error_t err, bool can_rollover)
140
140
  lcb::Server* server = instance->find_server(*next_host);
141
141
  if (server) {
142
142
  cmdcookie = new CccpCookie(this);
143
- lcb_log(LOGARGS(this, INFO), "Re-Issuing CCCP Command on server struct %p (%s:%s)", (void*)server, next_host->host, next_host->port);
143
+ lcb_log(LOGARGS(this, DEBUG), "Re-Issuing CCCP Command on server struct %p (%s:%s)", (void*)server, next_host->host, next_host->port);
144
144
  timer.rearm(settings().config_node_timeout);
145
145
  instance->request_config(cmdcookie, server);
146
146
 
@@ -128,7 +128,6 @@ process_chunk(HttpProvider *http, const void *buf, unsigned nbuf)
128
128
  /* reissue the request; but wait for it to drain */
129
129
  lcb_log(LOGARGS(http, WARN), LOGFMT "Got 404 on config stream. Assuming terse URI not supported on cluster", LOGID(http));
130
130
  http->try_nexturi = 1;
131
- err = LCB_SUCCESS;
132
131
  goto GT_CHECKDONE;
133
132
  }
134
133
  } else if (resp.status == 401) {
@@ -147,7 +147,7 @@ int Confmon::do_set_next(ConfigInfo *new_config, bool notify_miss)
147
147
  ca = config->vbc;
148
148
  cb = new_config->vbc;
149
149
 
150
- lcb_log(LOGARGS(this, INFO), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(new_config->get_origin()), ca->revid, cb->revid);
150
+ lcb_log(LOGARGS(this, DEBUG), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(new_config->get_origin()), ca->revid, cb->revid);
151
151
  if (notify_miss) {
152
152
  invoke_listeners(CLCONFIG_EVENT_GOT_ANY_CONFIG, new_config);
153
153
  }
@@ -198,6 +198,9 @@ void Confmon::provider_failed(Provider *provider, lcb_error_t reason) {
198
198
  } else {
199
199
  last_error = reason;
200
200
  }
201
+ if (reason == LCB_AUTH_ERROR) {
202
+ goto GT_ERROR;
203
+ }
201
204
  }
202
205
 
203
206
  if (settings->conntype == LCB_TYPE_CLUSTER && provider->type == CLCONFIG_HTTP) {
@@ -211,13 +214,7 @@ void Confmon::provider_failed(Provider *provider, lcb_error_t reason) {
211
214
  }
212
215
 
213
216
  cur_provider = next_active(cur_provider);
214
-
215
- if (!cur_provider) {
216
- LOG(this, TRACE, "Maximum provider reached. Resetting index");
217
- invoke_listeners(CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
218
- cur_provider = first_active();
219
- stop();
220
- } else {
217
+ if (cur_provider) {
221
218
  uint32_t interval = 0;
222
219
  if (config) {
223
220
  /* Not first */
@@ -226,7 +223,15 @@ void Confmon::provider_failed(Provider *provider, lcb_error_t reason) {
226
223
  lcb_log(LOGARGS(this, DEBUG), "Will try next provider in %uus", interval);
227
224
  state |= CONFMON_S_ITERGRACE;
228
225
  as_start.rearm(interval);
226
+ return;
227
+ } else {
228
+ LOG(this, TRACE, "Maximum provider reached. Resetting index");
229
229
  }
230
+
231
+ GT_ERROR:
232
+ invoke_listeners(CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
233
+ cur_provider = first_active();
234
+ stop();
230
235
  }
231
236
 
232
237
  void Confmon::provider_got_config(Provider *, ConfigInfo *config_) {
@@ -354,6 +354,8 @@ lcb_strcbtype(int cbtype)
354
354
  return "SDMUTATE";
355
355
  case LCB_CALLBACK_SDLOOKUP:
356
356
  return "SDLOOKUP";
357
+ case LCB_CALLBACK_NOOP:
358
+ return "NOOP";
357
359
  default:
358
360
  return "UNKNOWN";
359
361
  }
@@ -1,6 +1,6 @@
1
1
  /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright 2010-2012 Couchbase, Inc.
3
+ * Copyright 2010-2017 Couchbase, Inc.
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
21
21
  #include <mcserver/negotiate.h>
22
22
  #include <lcbio/ssl.h>
23
23
 
24
+ #define LOGARGS(instance, lvl) instance->settings, "cntl", LCB_LOG_##lvl, __FILE__, __LINE__
25
+
24
26
  #define CNTL__MODE_SETSTRING 0x1000
25
27
 
26
28
  /* Basic definition/declaration for handlers */
@@ -157,6 +159,9 @@ HANDLER(compmode_handler) {
157
159
  HANDLER(bucketname_handler) {
158
160
  RETURN_GET_ONLY(const char*, LCBT_SETTING(instance, bucket))
159
161
  }
162
+ HANDLER(buckettype_handler) {
163
+ RETURN_GET_ONLY(lcb_BTYPE, static_cast<lcb_BTYPE>(instance->btype))
164
+ }
160
165
  HANDLER(schedflush_handler) {
161
166
  RETURN_GET_SET(int, LCBT_SETTING(instance, sched_implicit_flush))
162
167
  }
@@ -197,6 +202,11 @@ HANDLER(send_hello_handler) {
197
202
  RETURN_GET_SET(int, LCBT_SETTING(instance, send_hello));
198
203
  }
199
204
  HANDLER(config_poll_interval_handler) {
205
+ lcb_U32 *user = reinterpret_cast<lcb_U32*>(arg);
206
+ if (mode == LCB_CNTL_SET && *user > 0 && *user < LCB_CONFIG_POLL_INTERVAL_FLOOR) {
207
+ lcb_log(LOGARGS(instance, ERROR), "Interval for background poll is too low: %dus (min: %dus)", *user, LCB_CONFIG_POLL_INTERVAL_FLOOR);
208
+ return LCB_ECTL_BADARG;
209
+ }
200
210
  lcb_error_t rv = timeout_common(mode, instance, cmd, arg);
201
211
  if (rv == LCB_SUCCESS &&
202
212
  (mode == LCB_CNTL_SET || CNTL__MODE_SETSTRING) &&
@@ -614,7 +624,8 @@ static ctl_handler handlers[] = {
614
624
  select_bucket_handler, /* LCB_CNTL_SELECT_BUCKET */
615
625
  tcp_keepalive_handler, /* LCB_CNTL_TCP_KEEPALIVE */
616
626
  config_poll_interval_handler, /* LCB_CNTL_CONFIG_POLL_INTERVAL */
617
- send_hello_handler /* LCB_CNTL_SEND_HELLO */
627
+ send_hello_handler, /* LCB_CNTL_SEND_HELLO */
628
+ buckettype_handler /* LCB_CNTL_BUCKETTYPE */
618
629
  };
619
630
 
620
631
  /* Union used for conversion to/from string functions */
@@ -638,7 +649,7 @@ typedef struct {
638
649
  ctl_str_cb converter;
639
650
  } cntl_OPCODESTRS;
640
651
 
641
- static lcb_error_t convert_timeout(const char *arg, u_STRCONVERT *u) {
652
+ static lcb_error_t convert_timevalue(const char *arg, u_STRCONVERT *u) {
642
653
  int rv;
643
654
  unsigned long tmp;
644
655
 
@@ -673,7 +684,7 @@ static lcb_error_t convert_int(const char *arg, u_STRCONVERT *u) {
673
684
  }
674
685
 
675
686
  static lcb_error_t convert_u32(const char *arg, u_STRCONVERT *u) {
676
- return convert_timeout(arg, u);
687
+ return convert_timevalue(arg, u);
677
688
  }
678
689
  static lcb_error_t convert_float(const char *arg, u_STRCONVERT *u) {
679
690
  double d;
@@ -729,19 +740,19 @@ static lcb_error_t convert_retrymode(const char *arg, u_STRCONVERT *u) {
729
740
  }
730
741
 
731
742
  static cntl_OPCODESTRS stropcode_map[] = {
732
- {"operation_timeout", LCB_CNTL_OP_TIMEOUT, convert_timeout},
733
- {"timeout", LCB_CNTL_OP_TIMEOUT, convert_timeout},
734
- {"views_timeout", LCB_CNTL_VIEW_TIMEOUT, convert_timeout},
735
- {"n1ql_timeout", LCB_CNTL_N1QL_TIMEOUT, convert_timeout},
736
- {"durability_timeout", LCB_CNTL_DURABILITY_TIMEOUT, convert_timeout},
737
- {"durability_interval", LCB_CNTL_DURABILITY_INTERVAL, convert_timeout},
738
- {"http_timeout", LCB_CNTL_HTTP_TIMEOUT, convert_timeout},
743
+ {"operation_timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
744
+ {"timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
745
+ {"views_timeout", LCB_CNTL_VIEW_TIMEOUT, convert_timevalue},
746
+ {"n1ql_timeout", LCB_CNTL_N1QL_TIMEOUT, convert_timevalue},
747
+ {"durability_timeout", LCB_CNTL_DURABILITY_TIMEOUT, convert_timevalue},
748
+ {"durability_interval", LCB_CNTL_DURABILITY_INTERVAL, convert_timevalue},
749
+ {"http_timeout", LCB_CNTL_HTTP_TIMEOUT, convert_timevalue},
739
750
  {"randomize_nodes", LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS, convert_intbool},
740
751
  {"sasl_mech_force", LCB_CNTL_FORCE_SASL_MECH, convert_passthru},
741
752
  {"error_thresh_count", LCB_CNTL_CONFERRTHRESH, convert_SIZE},
742
- {"error_thresh_delay", LCB_CNTL_CONFDELAY_THRESH, convert_timeout},
743
- {"config_total_timeout", LCB_CNTL_CONFIGURATION_TIMEOUT, convert_timeout},
744
- {"config_node_timeout", LCB_CNTL_CONFIG_NODE_TIMEOUT, convert_timeout},
753
+ {"error_thresh_delay", LCB_CNTL_CONFDELAY_THRESH, convert_timevalue},
754
+ {"config_total_timeout", LCB_CNTL_CONFIGURATION_TIMEOUT, convert_timevalue},
755
+ {"config_node_timeout", LCB_CNTL_CONFIG_NODE_TIMEOUT, convert_timevalue},
745
756
  {"compression", LCB_CNTL_COMPRESSION_OPTS, convert_compression},
746
757
  {"console_log_level", LCB_CNTL_CONLOGGER_LEVEL, convert_u32},
747
758
  {"config_cache", LCB_CNTL_CONFIGCACHE, convert_passthru },
@@ -752,7 +763,7 @@ static cntl_OPCODESTRS stropcode_map[] = {
752
763
  {"sync_dtor", LCB_CNTL_SYNCDESTROY, convert_intbool },
753
764
  {"_reinit_connstr", LCB_CNTL_REINIT_CONNSTR },
754
765
  {"retry_backoff", LCB_CNTL_RETRY_BACKOFF, convert_float },
755
- {"retry_interval", LCB_CNTL_RETRY_INTERVAL, convert_timeout},
766
+ {"retry_interval", LCB_CNTL_RETRY_INTERVAL, convert_timevalue},
756
767
  {"http_poolsize", LCB_CNTL_HTTP_POOLSIZE, convert_SIZE },
757
768
  {"vbguess_persist", LCB_CNTL_VBGUESS_PERSIST, convert_intbool },
758
769
  {"unsafe_optimize", LCB_CNTL_UNSAFE_OPTIMIZE, convert_intbool },
@@ -763,13 +774,13 @@ static cntl_OPCODESTRS stropcode_map[] = {
763
774
  {"readj_ts_wait", LCB_CNTL_RESET_TIMEOUT_ON_WAIT, convert_intbool },
764
775
  {"console_log_file", LCB_CNTL_CONLOGGER_FP, NULL },
765
776
  {"client_string", LCB_CNTL_CLIENT_STRING, convert_passthru},
766
- {"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timeout},
777
+ {"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timevalue},
767
778
  {"bucket_cred", LCB_CNTL_BUCKET_CRED, NULL},
768
779
  {"read_chunk_size", LCB_CNTL_READ_CHUNKSIZE, convert_u32},
769
780
  {"enable_errmap", LCB_CNTL_ENABLE_ERRMAP, convert_intbool},
770
781
  {"select_bucket", LCB_CNTL_SELECT_BUCKET, convert_intbool},
771
782
  {"tcp_keepalive", LCB_CNTL_TCP_KEEPALIVE, convert_intbool},
772
- {"config_poll_interval", LCB_CNTL_CONFIG_POLL_INTERVAL, convert_timeout},
783
+ {"config_poll_interval", LCB_CNTL_CONFIG_POLL_INTERVAL, convert_timevalue},
773
784
  {"send_hello", LCB_CNTL_SEND_HELLO, convert_intbool},
774
785
  {NULL, -1}
775
786
  };
@@ -10,14 +10,13 @@
10
10
 
11
11
  #ifdef HAVE_ARPA_NAMESER_H
12
12
  #include <arpa/nameser.h>
13
- #if __NAMESER < 19991006
13
+ #if defined(__NAMESER) && __NAMESER < 19991006
14
14
  #undef HAVE_RES_SEARCH
15
15
  #endif /* __NAMESER < NNN */
16
16
  #endif /* HAVE_ARPA_NAMESER_H */
17
17
 
18
18
  #if defined(HAVE_ARPA_NAMESER_H) && defined(HAVE_RES_SEARCH)
19
19
  #define CAN_SRV_LOOKUP
20
- #include <cstdio>
21
20
  #include <sys/types.h>
22
21
  #include <netinet/in.h>
23
22
  #include <resolv.h>
@@ -31,7 +31,11 @@ lcb_dump(lcb_t instance, FILE *fp, lcb_U32 flags)
31
31
  fp = stderr;
32
32
  }
33
33
  fprintf(fp, "Dumping state for lcb_t=%p\n", (void*)instance);
34
+ if (instance == NULL) {
35
+ return;
36
+ }
34
37
  fprintf(fp, "Settings=%p\n", (void*)instance->settings);
38
+ fprintf(fp, "BucketType=%d\n", instance->btype);
35
39
 
36
40
  if (instance->cur_configinfo) {
37
41
  lcb::clconfig::ConfigInfo *cfg = instance->cur_configinfo;
@@ -14,22 +14,95 @@ namespace errmap {
14
14
 
15
15
  enum ErrorAttribute {
16
16
  #define LCB_XERRMAP_ATTRIBUTES(X) \
17
- X(TEMPORARY, "temp") \
18
- X(SUBDOC, "subdoc") \
19
- X(RETRY_NOW, "retry-now") \
20
- X(RETRY_LATER, "retry-later") \
21
- X(INVALID_INPUT, "invalid-input") \
22
- X(NOT_ENABLED, "support") \
23
- X(AUTH, "auth") \
24
- X(CONN_STATE_INVALIDATED, "conn-state-invalidated") \
25
- X(CONSTRAINT_FAILURE, "item-only") \
26
- X(RETRY_EXP_BACKOFF, "retry-exp-backoff") \
27
- X(RETRY_LINEAR_BACKOFF, "retry-linear-backoff") \
28
- X(INTERNAL, "internal") \
29
- X(DCP, "dcp") \
30
- X(FETCH_CONFIG, "fetch-config") \
31
- X(SPECIAL_HANDLING, "special-handling") \
32
- X(AUTO_RETRY, "auto-retry")
17
+ /** \
18
+ * This error is transient. Note that this does not mean the \
19
+ * error is retriable. \
20
+ */ \
21
+ X(TEMPORARY, "temp") \
22
+ /** \
23
+ * The error is related to the subdocument subsystem. \
24
+ */ \
25
+ X(SUBDOC, "subdoc") \
26
+ /** \
27
+ * The operation may be retried immediately. \
28
+ */ \
29
+ X(RETRY_NOW, "retry-now") \
30
+ /** \
31
+ * The operation may be retried after some time. \
32
+ */ \
33
+ X(RETRY_LATER, "retry-later") \
34
+ /** \
35
+ * This attribute means that a user's input was invalid because it \
36
+ * violates the semantics of the operation, or exceeds some \
37
+ * predefined limit. \
38
+ */ \
39
+ X(INVALID_INPUT, "invalid-input") \
40
+ /** \
41
+ * The operation is not supported, possibly because the of server \
42
+ * version, bucket type, or current user. \
43
+ */ \
44
+ X(NOT_ENABLED, "support") \
45
+ /** \
46
+ * The operation failed because the client failed to authenticate \
47
+ * or is not authorized to perform this operation. Note that this \
48
+ * error in itself does not mean the connection is invalid, unless \
49
+ * conn-state-invalidated is also present. \
50
+ */ \
51
+ X(AUTH, "auth") \
52
+ /** \
53
+ * The current connection is no longer valid. The client must \
54
+ * reconnect to the server. Note that the presence of other \
55
+ * attributes may indicate an alternate remedy to fixing the \
56
+ * connection without a disconnect, but without special remedial \
57
+ * action a disconnect is needed. \
58
+ */ \
59
+ X(CONN_STATE_INVALIDATED, "conn-state-invalidated") \
60
+ /** \
61
+ * This attribute means that the error is related to a constraint \
62
+ * failure regarding the item itself, i.e. the item does not exist, \
63
+ * already exists, or its current value makes the current operation \
64
+ * impossible. Retrying the operation when the item's value or \
65
+ * status has changed may succeed. \
66
+ */ \
67
+ X(CONSTRAINT_FAILURE, "item-only") \
68
+ /** \
69
+ * This is an internal error in the server. \
70
+ */ \
71
+ X(INTERNAL, "internal") \
72
+ /** \
73
+ * The error is related to the DCP subsystem. \
74
+ */ \
75
+ X(DCP, "dcp") \
76
+ /** \
77
+ * The client's cluster map may be outdated and requires updating. \
78
+ * The client should obtain a newer configuration. \
79
+ */ \
80
+ X(FETCH_CONFIG, "fetch-config") \
81
+ /** \
82
+ * This error code must be handled specially. If it is not handled, \
83
+ * the connection must be dropped. \
84
+ */ \
85
+ X(SPECIAL_HANDLING, "special-handling") \
86
+ /** \
87
+ * Use retry specifications from the server \
88
+ */ \
89
+ X(AUTO_RETRY, "auto-retry") \
90
+ /** \
91
+ * The operation was successful for those situations \
92
+ * where the error code is indicating successful (i.e. subdoc \
93
+ * operations carried out on a deleted document) \
94
+ */ \
95
+ X(SUCCESS, "success") \
96
+ /** \
97
+ * This attribute specifies that the requested item is currently \
98
+ * locked. \
99
+ */ \
100
+ X(ITEM_LOCKED, "item-locked") \
101
+ /** \
102
+ * This attribute means that the error is related to operating on \
103
+ * a soft-deleted document. \
104
+ */ \
105
+ X(ITEM_DELETED, "item-deleted") \
33
106
 
34
107
  #define X(c, s) c,
35
108
  LCB_XERRMAP_ATTRIBUTES(X)
@@ -437,6 +437,8 @@ H_subdoc(mc_PIPELINE *pipeline, mc_PACKET *request,
437
437
  response->opcode() == PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION) {
438
438
  if (w.resp.rc == LCB_SUCCESS || w.resp.rc == LCB_SUBDOC_MULTI_FAILURE) {
439
439
  w.resp.responses = response;
440
+ } else {
441
+ handle_error_info(response, &w);
440
442
  }
441
443
  } else {
442
444
  /* Single response */
@@ -446,6 +448,8 @@ H_subdoc(mc_PIPELINE *pipeline, mc_PACKET *request,
446
448
  } else if (LCB_EIFSUBDOC(w.resp.rc)) {
447
449
  w.resp.responses = response;
448
450
  w.resp.rc = LCB_SUBDOC_MULTI_FAILURE;
451
+ } else {
452
+ handle_error_info(response, &w);
449
453
  }
450
454
  }
451
455
  invoke_callback(request, o, &w.resp, cbtype);
@@ -808,6 +812,19 @@ H_version(mc_PIPELINE *pipeline, mc_PACKET *request,
808
812
  exdata->procs->handler(pipeline, request, resp.rc, &resp);
809
813
  }
810
814
 
815
+ static void
816
+ H_noop(mc_PIPELINE *pipeline, mc_PACKET *request,
817
+ MemcachedResponse *response, lcb_error_t immerr)
818
+ {
819
+ lcb_t root = get_instance(pipeline);
820
+ lcb_RESPNOOP resp = { 0 };
821
+ mc_REQDATAEX *exdata = request->u_rdata.exdata;
822
+
823
+ make_error(root, &resp, response, immerr);
824
+
825
+ exdata->procs->handler(pipeline, request, resp.rc, &resp);
826
+ }
827
+
811
828
  static void
812
829
  H_touch(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response,
813
830
  lcb_error_t immerr)
@@ -852,7 +869,7 @@ H_config(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response,
852
869
  lcb_error_t immerr)
853
870
  {
854
871
  /** We just jump to the normal config handler */
855
- lcb_RESPBASE dummy;
872
+ lcb_RESPBASE dummy = {0};
856
873
  mc_REQDATAEX *exdata = request->u_rdata.exdata;
857
874
  make_error(get_instance(pipeline), &dummy, response, immerr);
858
875
 
@@ -960,10 +977,8 @@ mcreq_dispatch_response(
960
977
  case PROTOCOL_BINARY_CMD_VERBOSITY:
961
978
  INVOKE_OP(H_verbosity);
962
979
 
963
- #if 0
964
980
  case PROTOCOL_BINARY_CMD_NOOP:
965
981
  INVOKE_OP(H_noop);
966
- #endif
967
982
 
968
983
  case PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG:
969
984
  INVOKE_OP(H_config);
@@ -1010,12 +1025,14 @@ lcb_resp_get_mutation_token(int cbtype, const lcb_RESPBASE *rb)
1010
1025
  }
1011
1026
 
1012
1027
  #define ERRINFO_CALLBACKS(X) \
1013
- X(GET) \
1014
- X(STORE) \
1015
- X(COUNTER) \
1016
- X(TOUCH) \
1017
- X(REMOVE) \
1018
- X(UNLOCK) \
1028
+ X(LCB_CALLBACK_GET, lcb_RESPGET) \
1029
+ X(LCB_CALLBACK_STORE, lcb_RESPSTORE) \
1030
+ X(LCB_CALLBACK_COUNTER, lcb_RESPCOUNTER) \
1031
+ X(LCB_CALLBACK_TOUCH, lcb_RESPTOUCH) \
1032
+ X(LCB_CALLBACK_REMOVE, lcb_RESPREMOVE) \
1033
+ X(LCB_CALLBACK_UNLOCK, lcb_RESPUNLOCK) \
1034
+ X(LCB_CALLBACK_SDLOOKUP, lcb_RESPSUBDOC) \
1035
+ X(LCB_CALLBACK_SDMUTATE, lcb_RESPSUBDOC) \
1019
1036
 
1020
1037
 
1021
1038
  LIBCOUCHBASE_API
@@ -1026,7 +1043,7 @@ lcb_resp_get_error_context(int cbtype, const lcb_RESPBASE *rb)
1026
1043
  return NULL;
1027
1044
  }
1028
1045
 
1029
- #define X(NAME) if (cbtype == LCB_CALLBACK_##NAME) { return ResponsePack<lcb_RESP##NAME>::get_err_ctx(rb); }
1046
+ #define X(CBTYPE, RESP) if (cbtype == CBTYPE) { return ResponsePack<RESP>::get_err_ctx(rb); }
1030
1047
  ERRINFO_CALLBACKS(X);
1031
1048
  #undef X
1032
1049
  return NULL;
@@ -1040,7 +1057,7 @@ lcb_resp_get_error_ref(int cbtype, const lcb_RESPBASE *rb)
1040
1057
  return NULL;
1041
1058
  }
1042
1059
 
1043
- #define X(NAME) if (cbtype == LCB_CALLBACK_##NAME) { return ResponsePack<lcb_RESP##NAME>::get_err_ref(rb); }
1060
+ #define X(CBTYPE, RESP) if (cbtype == CBTYPE) { return ResponsePack<RESP>::get_err_ref(rb); }
1044
1061
  ERRINFO_CALLBACKS(X);
1045
1062
  #undef X
1046
1063
  return NULL;