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
@@ -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;