libcouchbase 0.0.7 → 0.0.8

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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/.gitignore +2 -0
  3. data/ext/libcouchbase/CMakeLists.txt +5 -7
  4. data/ext/libcouchbase/README.markdown +2 -2
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  7. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  10. data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
  11. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  12. data/ext/libcouchbase/cmake/source_files.cmake +34 -14
  13. data/ext/libcouchbase/configure.pl +1 -1
  14. data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
  15. data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
  16. data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
  17. data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
  18. data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
  19. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  20. data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
  21. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  22. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  23. data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  26. data/ext/libcouchbase/src/README.md +0 -2
  27. data/ext/libcouchbase/src/auth-priv.h +1 -0
  28. data/ext/libcouchbase/src/auth.cc +10 -0
  29. data/ext/libcouchbase/src/bootstrap.cc +216 -0
  30. data/ext/libcouchbase/src/bootstrap.h +50 -39
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
  37. data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
  38. data/ext/libcouchbase/src/cbft.cc +22 -27
  39. data/ext/libcouchbase/src/cntl.cc +24 -24
  40. data/ext/libcouchbase/src/connspec.cc +30 -1
  41. data/ext/libcouchbase/src/connspec.h +17 -0
  42. data/ext/libcouchbase/src/dns-srv.cc +143 -0
  43. data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
  44. data/ext/libcouchbase/src/getconfig.cc +73 -0
  45. data/ext/libcouchbase/src/handler.cc +84 -85
  46. data/ext/libcouchbase/src/hostlist.cc +0 -1
  47. data/ext/libcouchbase/src/hostlist.h +6 -1
  48. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  49. data/ext/libcouchbase/src/http/http.cc +9 -29
  50. data/ext/libcouchbase/src/http/http.h +1 -34
  51. data/ext/libcouchbase/src/http/http_io.cc +22 -26
  52. data/ext/libcouchbase/src/instance.cc +102 -28
  53. data/ext/libcouchbase/src/internal.h +47 -29
  54. data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
  55. data/ext/libcouchbase/src/jsparse/parser.h +91 -98
  56. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  57. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  58. data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
  59. data/ext/libcouchbase/src/lcbio/connect.h +9 -2
  60. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  61. data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
  62. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  63. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  64. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  65. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  66. data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
  67. data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
  68. data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
  69. data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
  70. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  71. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  72. data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
  73. data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
  74. data/ext/libcouchbase/src/nodeinfo.cc +4 -8
  75. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  76. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  77. data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
  78. data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
  79. data/ext/libcouchbase/src/operations/durability.cc +643 -0
  80. data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
  81. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  82. data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
  83. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
  84. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  85. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  86. data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
  87. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  88. data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
  89. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  90. data/ext/libcouchbase/src/packetutils.h +200 -137
  91. data/ext/libcouchbase/src/probes.d +1 -1
  92. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
  93. data/ext/libcouchbase/src/retryq.cc +394 -0
  94. data/ext/libcouchbase/src/retryq.h +116 -104
  95. data/ext/libcouchbase/src/settings.h +2 -1
  96. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  97. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  98. data/ext/libcouchbase/src/trace.h +8 -8
  99. data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
  100. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  101. data/ext/libcouchbase/src/views/docreq.h +24 -30
  102. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  103. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  104. data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
  105. data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
  106. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
  107. data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
  108. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  109. data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
  110. data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
  111. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  112. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  113. data/lib/libcouchbase/version.rb +1 -1
  114. metadata +36 -39
  115. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  116. data/ext/libcouchbase/src/bootstrap.c +0 -269
  117. data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
  118. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  119. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  120. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  121. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  122. data/ext/libcouchbase/src/getconfig.c +0 -100
  123. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  124. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  125. data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
  126. data/ext/libcouchbase/src/operations/durability.c +0 -668
  127. data/ext/libcouchbase/src/packetutils.c +0 -60
  128. data/ext/libcouchbase/src/retryq.c +0 -424
  129. data/ext/libcouchbase/src/simplestring.c +0 -211
  130. data/ext/libcouchbase/src/simplestring.h +0 -228
  131. data/ext/libcouchbase/src/ssobuf.h +0 -82
  132. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  133. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -19,9 +19,8 @@
19
19
  #define LCB_MCSERVER_NEGOTIATE_H
20
20
  #include <libcouchbase/couchbase.h>
21
21
  #include <lcbio/lcbio.h>
22
- #ifdef __cplusplus
23
- extern "C" {
24
- #endif
22
+ #include <string>
23
+ #include <vector>
25
24
 
26
25
  /**
27
26
  * @file
@@ -37,83 +36,95 @@ extern "C" {
37
36
  */
38
37
 
39
38
  struct lcb_settings_st;
40
- typedef struct mc_SESSREQ *mc_pSESSREQ;
41
- typedef struct mc_SESSINFO *mc_pSESSINFO;
42
39
 
43
- /**
44
- * @brief Start negotiation on a connected socket
45
- *
46
- * This will start negotiation on the socket. Once complete (or an error has
47
- * taken place) the `callback` will be invoked with the result.
48
- *
49
- * @param sock A connected socket to use. Its reference count will be increased
50
- * @param settings A settings structure. Used for auth information as well as
51
- * logging
52
- * @param tmo Time in microseconds to wait until the negotiation is done
53
- * @param callback A callback to invoke when a result has been received
54
- * @param data User-defined pointer passed to the callback
55
- * @return A new handle which may be cancelled via mc_sessreq_cancel(). As with
56
- * other cancellable requests, once this handle is cancelled a callback will
57
- * not be received for it, and once the callback is received the handle may not
58
- * be cancelled as it will point to invalid memory.
59
- *
60
- * Once the socket has been negotiated successfuly, you may then use the
61
- * mc_sess_get() function to query the socket about various negotiation aspects
62
- *
63
- * @code{.c}
64
- * lcbio_CONNREQ creq;
65
- * mc_pSASLREQ req;
66
- * req = mc_sasl_start(sock, settings, tmo, callback, data);
67
- * LCBIO_CONNREQ_MKGENERIC(req, mc_sasl_cancel);
68
- * @endcode
69
- *
70
- * @see lcbio_connreq_cancel()
71
- * @see LCBIO_CONNREQ_MKGENERIC
72
- */
73
- mc_pSESSREQ
74
- mc_sessreq_start(
75
- lcbio_SOCKET *sock, struct lcb_settings_st *settings,
76
- uint32_t tmo, lcbio_CONNDONE_cb callback, void *data);
40
+ namespace lcb {
41
+ class SessionRequest {
42
+ public:
43
+ /**
44
+ * @brief Start negotiation on a connected socket
45
+ *
46
+ * This will start negotiation on the socket. Once complete (or an error has
47
+ * taken place) the `callback` will be invoked with the result.
48
+ *
49
+ * @param sock A connected socket to use. Its reference count will be increased
50
+ * @param settings A settings structure. Used for auth information as well as
51
+ * logging
52
+ * @param tmo Time in microseconds to wait until the negotiation is done
53
+ * @param callback A callback to invoke when a result has been received
54
+ * @param data User-defined pointer passed to the callback
55
+ * @return A new handle which may be cancelled via mc_sessreq_cancel(). As with
56
+ * other cancellable requests, once this handle is cancelled a callback will
57
+ * not be received for it, and once the callback is received the handle may not
58
+ * be cancelled as it will point to invalid memory.
59
+ *
60
+ * Once the socket has been negotiated successfuly, you may then use the
61
+ * mc_sess_get() function to query the socket about various negotiation aspects
62
+ *
63
+ * @code{.c}
64
+ * lcbio_CONNREQ creq;
65
+ * SessionRequest *req = SessionRequest::start(sock, settings, tmo, callback, data);
66
+ * LCBIO_CONNREQ_MKGENERIC(req, sessreq_cancel);
67
+ * @endcode
68
+ *
69
+ * @see lcb::sessreq_cancel()
70
+ * @see LCBIO_CONNREQ_MKGENERIC
71
+ */
72
+ static SessionRequest *start(lcbio_SOCKET *sock, lcb_settings_st *settings,
73
+ uint32_t tmo, lcbio_CONNDONE_cb callback,
74
+ void *data);
77
75
 
78
- /**
79
- * @brief Cancel a pending SASL negotiation request
80
- * @param handle The handle to cancel
81
- */
82
- void
83
- mc_sessreq_cancel(mc_pSESSREQ handle);
76
+ /**
77
+ * @brief Cancel a pending SASL negotiation request
78
+ * @param handle The handle to cancel
79
+ */
80
+ virtual void cancel() = 0;
81
+ virtual ~SessionRequest(){}
82
+ };
83
+ class SessionRequestImpl;
84
84
 
85
- /**
86
- * @brief Get an opaque handle representing the negotiated state of the socket
87
- * @param sock The negotiated socket
88
- * @return the `SASLINFO` structure if the socket is negotiated, or `NULL` if
89
- * the socket has not been negotiated.
90
- *
91
- * @see mc_sasl_getmech()
92
- */
93
- mc_pSESSINFO
94
- mc_sess_get(lcbio_SOCKET *sock);
85
+ extern "C" { void sessreq_cancel(SessionRequest *); }
95
86
 
96
- /**
97
- * @brief Get the mechanism employed for authentication
98
- * @param info pointer retrieved via mc_sasl_get()
99
- * @return A string indicating the mechanism used. This may be `PLAIN` or
100
- * `CRAM-MD5`.
101
- */
102
- const char *
103
- mc_sess_get_saslmech(mc_pSESSINFO info);
87
+ class SessionInfo : public lcbio_PROTOCTX {
88
+ public:
89
+ /**
90
+ * @brief Get an opaque handle representing the negotiated state of the socket
91
+ * @param sock The negotiated socket
92
+ * @return the `SASLINFO` structure if the socket is negotiated, or `NULL` if
93
+ * the socket has not been negotiated.
94
+ *
95
+ * @see get_mech()
96
+ */
97
+ static SessionInfo* get(lcbio_SOCKET*);
104
98
 
105
- /**
106
- * @brief Determine if a specific protocol feature is supported on the server
107
- * @param info info pointer returned via mc_sasl_get()
108
- * @param feature A feature ID
109
- * @return true if supported, false otherwise
110
- */
111
- int
112
- mc_sess_chkfeature(mc_pSESSINFO info, uint16_t feature);
99
+ /**
100
+ * @brief Get the mechanism employed for authentication
101
+ * @param info pointer retrieved via mc_sasl_get()
102
+ * @return A string indicating the mechanism used. This may be `PLAIN` or
103
+ * `CRAM-MD5`.
104
+ */
105
+ const std::string& get_mech() const {
106
+ return mech;
107
+ }
108
+
109
+ /**
110
+ * @brief Determine if a specific protocol feature is supported on the server
111
+ * @param info info pointer returned via mc_sasl_get()
112
+ * @param feature A feature ID
113
+ * @return true if supported, false otherwise
114
+ */
115
+ bool has_feature(uint16_t feature) const;
116
+
117
+ private:
118
+ SessionInfo();
119
+ friend class lcb::SessionRequestImpl;
120
+
121
+ std::string mech;
122
+ std::vector<uint16_t> server_features;
123
+ };
124
+
125
+
126
+ } // namespace
113
127
 
114
128
  /**@}*/
115
129
 
116
- #ifdef __cplusplus
117
- }
118
- #endif
119
130
  #endif
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright 2016 Couchbase, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #ifndef LCB_MCTX_HELPER_H
18
+ #define LCB_MCTX_HELPER_H
19
+ #include <libcouchbase/couchbase.h>
20
+
21
+ namespace lcb {
22
+
23
+ class MultiCmdContext : public lcb_MULTICMD_CTX {
24
+ protected:
25
+ virtual lcb_error_t MCTX_addcmd(const lcb_CMDBASE* cmd) = 0;
26
+ virtual lcb_error_t MCTX_done(const void *cookie) = 0;
27
+ virtual void MCTX_fail() = 0;
28
+
29
+ MultiCmdContext() {
30
+ lcb_MULTICMD_CTX::addcmd = dispatch_mctx_addcmd;
31
+ lcb_MULTICMD_CTX::done = dispatch_mctx_done;
32
+ lcb_MULTICMD_CTX::fail = dispatch_mctx_fail;
33
+ }
34
+
35
+ virtual ~MultiCmdContext() {}
36
+
37
+ private:
38
+ static lcb_error_t dispatch_mctx_addcmd(lcb_MULTICMD_CTX* ctx, const lcb_CMDBASE * cmd) {
39
+ return static_cast<MultiCmdContext*>(ctx)->MCTX_addcmd(cmd);
40
+ }
41
+ static lcb_error_t dispatch_mctx_done(lcb_MULTICMD_CTX* ctx, const void *cookie) {
42
+ return static_cast<MultiCmdContext*>(ctx)->MCTX_done(cookie);
43
+ }
44
+ static void dispatch_mctx_fail(lcb_MULTICMD_CTX* ctx) {
45
+ static_cast<MultiCmdContext*>(ctx)->MCTX_fail();
46
+ }
47
+ };
48
+
49
+ }
50
+
51
+ #endif
@@ -210,8 +210,7 @@ dispatch_common(lcb_t instance,
210
210
  // mind-numbing buffer copies. Maybe this can be done via a macro instead?
211
211
  class IndexSpec : public lcb_N1XSPEC {
212
212
  public:
213
- IndexSpec(const char *s, size_t n) {
214
- memset(static_cast<lcb_N1XSPEC*>(this), 0, sizeof (lcb_N1XSPEC));
213
+ IndexSpec(const char *s, size_t n) : lcb_N1XSPEC() {
215
214
  load_json(s, n);
216
215
  }
217
216
  inline IndexSpec(const lcb_N1XSPEC *spec);
@@ -142,10 +142,10 @@ struct lcb_N1QLCACHE_st {
142
142
  }
143
143
  };
144
144
 
145
- typedef struct lcb_N1QLREQ {
145
+ typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
146
146
  const lcb_RESPHTTP *cur_htresp;
147
147
  struct lcb_http_request_st *htreq;
148
- lcbjsp_PARSER *parser;
148
+ lcb::jsparse::Parser *parser;
149
149
  const void *cookie;
150
150
  lcb_N1QLCALLBACK callback;
151
151
  lcb_t instance;
@@ -155,6 +155,9 @@ typedef struct lcb_N1QLREQ {
155
155
  // How many rows were received. Used to avoid parsing the meta
156
156
  size_t nrows;
157
157
 
158
+ // Host for CBAS/Analytics query
159
+ std::string cbashost;
160
+
158
161
  /** The PREPARE query itself */
159
162
  struct lcb_N1QLREQ *prepare_req;
160
163
 
@@ -227,9 +230,28 @@ typedef struct lcb_N1QLREQ {
227
230
  */
228
231
  inline void fail_prepared(const lcb_RESPN1QL *orig, lcb_error_t err);
229
232
 
233
+ bool is_cbas() const {
234
+ return !cbashost.empty();
235
+ }
236
+
230
237
  inline lcb_N1QLREQ(lcb_t obj, const void *user_cookie, const lcb_CMDN1QL *cmd);
231
238
  inline ~lcb_N1QLREQ();
232
239
 
240
+ // Parser overrides:
241
+ void JSPARSE_on_row(const lcb::jsparse::Row& row) {
242
+ lcb_RESPN1QL resp = { 0 };
243
+ resp.row = static_cast<const char *>(row.row.iov_base);
244
+ resp.nrow = row.row.iov_len;
245
+ nrows++;
246
+ invoke_row(&resp, false);
247
+ }
248
+ void JSPARSE_on_error(const std::string&) {
249
+ lasterr = LCB_PROTOCOL_ERROR;
250
+ }
251
+ void JSPARSE_on_complete(const std::string&) {
252
+ // Nothing
253
+ }
254
+
233
255
  } N1QLREQ;
234
256
 
235
257
  static bool
@@ -330,8 +352,7 @@ N1QLREQ::maybe_retry()
330
352
  }
331
353
 
332
354
  was_retried = true;
333
-
334
- lcbjsp_get_postmortem(parser, &meta);
355
+ parser->get_postmortem(meta);
335
356
  if (!parse_json(static_cast<const char*>(meta.iov_base), meta.iov_len, root)) {
336
357
  return false; // Not JSON
337
358
  }
@@ -351,7 +372,7 @@ N1QLREQ::maybe_retry()
351
372
 
352
373
  } else {
353
374
  // We'll be parsing more rows later on..
354
- lcbjsp_reset(parser);
375
+ parser->reset();
355
376
  }
356
377
  return true;
357
378
  }
@@ -366,7 +387,7 @@ N1QLREQ::invoke_row(lcb_RESPN1QL *resp, bool is_last)
366
387
  lcb_IOV meta;
367
388
  resp->rflags |= LCB_RESP_F_FINAL;
368
389
  resp->rc = lasterr;
369
- lcbjsp_get_postmortem(parser, &meta);
390
+ parser->get_postmortem(meta);
370
391
  resp->row = static_cast<const char*>(meta.iov_base);
371
392
  resp->nrow = meta.iov_len;
372
393
  }
@@ -392,31 +413,13 @@ lcb_N1QLREQ::~lcb_N1QLREQ()
392
413
  }
393
414
 
394
415
  if (parser) {
395
- lcbjsp_free(parser);
416
+ delete parser;
396
417
  }
397
418
  if (prepare_req) {
398
419
  lcb_n1ql_cancel(instance, prepare_req);
399
420
  }
400
421
  }
401
422
 
402
- static void
403
- row_callback(lcbjsp_PARSER *parser, const lcbjsp_ROW *datum)
404
- {
405
- N1QLREQ *req = static_cast<N1QLREQ*>(parser->data);
406
- lcb_RESPN1QL resp = { 0 };
407
-
408
- if (datum->type == LCBJSP_TYPE_ROW) {
409
- resp.row = static_cast<const char*>(datum->row.iov_base);
410
- resp.nrow = datum->row.iov_len;
411
- req->nrows++;
412
- req->invoke_row(&resp, 0);
413
- } else if (datum->type == LCBJSP_TYPE_ERROR) {
414
- req->lasterr = resp.rc = LCB_PROTOCOL_ERROR;
415
- } else if (datum->type == LCBJSP_TYPE_COMPLETE) {
416
- /* Nothing */
417
- }
418
- }
419
-
420
423
  static void
421
424
  chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
422
425
  {
@@ -444,8 +447,7 @@ chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
444
447
  delete req;
445
448
  return;
446
449
  }
447
-
448
- lcbjsp_feed(req->parser, static_cast<const char*>(rh->body), rh->nbody);
450
+ req->parser->feed(static_cast<const char*>(rh->body), rh->nbody);
449
451
  }
450
452
 
451
453
  #define QUERY_PATH "/query/service"
@@ -512,7 +514,14 @@ N1QLREQ::issue_htreq(const std::string& body)
512
514
 
513
515
  htcmd.content_type = "application/json";
514
516
  htcmd.method = LCB_HTTP_METHOD_POST;
515
- htcmd.type = LCB_HTTP_TYPE_N1QL;
517
+
518
+ if (is_cbas()) {
519
+ htcmd.type = LCB_HTTP_TYPE_RAW;
520
+ htcmd.host = cbashost.c_str();
521
+ } else {
522
+ htcmd.type = LCB_HTTP_TYPE_N1QL;
523
+ }
524
+
516
525
  htcmd.cmdflags = LCB_CMDHTTP_F_STREAM|LCB_CMDHTTP_F_CASTMO;
517
526
  if (flags & F_CMDN1QL_CREDSAUTH) {
518
527
  htcmd.cmdflags |= LCB_CMDHTTP_F_NOUPASS;
@@ -522,7 +531,7 @@ N1QLREQ::issue_htreq(const std::string& body)
522
531
 
523
532
  lcb_error_t rc = lcb_http3(instance, this, &htcmd);
524
533
  if (rc == LCB_SUCCESS) {
525
- lcb_htreq_setcb(htreq, chunk_callback);
534
+ htreq->set_callback(chunk_callback);
526
535
  }
527
536
  return rc;
528
537
  }
@@ -586,13 +595,12 @@ lcb_n1qlreq_parsetmo(const std::string& s)
586
595
 
587
596
  lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
588
597
  const void *user_cookie, const lcb_CMDN1QL *cmd)
589
- : cur_htresp(NULL), htreq(NULL), parser(lcbjsp_create(LCBJSP_MODE_N1QL)),
598
+ : cur_htresp(NULL), htreq(NULL),
599
+ parser(new lcb::jsparse::Parser(lcb::jsparse::Parser::MODE_N1QL, this)),
590
600
  cookie(user_cookie), callback(cmd->callback), instance(obj),
591
601
  lasterr(LCB_SUCCESS), flags(cmd->cmdflags), timeout(0),
592
602
  nrows(0), prepare_req(NULL), was_retried(false)
593
603
  {
594
- parser->data = this;
595
- parser->callback = row_callback;
596
604
  if (cmd->handle) {
597
605
  *cmd->handle = this;
598
606
  }
@@ -604,6 +612,22 @@ lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
604
612
  return;
605
613
  }
606
614
 
615
+ if (flags & LCB_CMDN1QL_F_CBASQUERY) {
616
+ if (!cmd->host) {
617
+ lasterr = LCB_EINVAL;
618
+ return;
619
+ }
620
+ cbashost.assign(cmd->host);
621
+ if (cbashost.empty()) {
622
+ lasterr = LCB_EINVAL;
623
+ return;
624
+ }
625
+ if (flags & LCB_CMDN1QL_F_PREPCACHE) {
626
+ lasterr = LCB_OPTIONS_CONFLICT;
627
+ return;
628
+ }
629
+ }
630
+
607
631
  const Json::Value& j_statement = json_const()["statement"];
608
632
  if (j_statement.isString()) {
609
633
  statement = j_statement.asString();
@@ -25,7 +25,7 @@
25
25
  #define LOG(instance, lvlbase, msg) lcb_log(instance->settings, "newconfig", LCB_LOG_##lvlbase, __FILE__, __LINE__, msg)
26
26
 
27
27
  #define SERVER_FMT "%s:%s (%p)"
28
- #define SERVER_ARGS(s) (s)->curhost->host, (s)->curhost->port, (void *)s
28
+ #define SERVER_ARGS(s) (s)->get_host().host, (s)->get_host().port, (void *)s
29
29
 
30
30
  typedef struct lcb_GUESSVB_st {
31
31
  time_t last_update; /**< Last time this vBucket was heuristically set */
@@ -106,8 +106,8 @@ lcb_vbguess_remap(lcb_t instance, int vbid, int bad)
106
106
  lcb_GUESSVB *guess = guesses + vbid;
107
107
  int newix = lcbvb_nmv_remap_ex(LCBT_VBCONFIG(instance), vbid, bad, 1);
108
108
  if (!guesses) {
109
- guesses = instance->vbguess = calloc(
110
- LCBT_VBCONFIG(instance)->nvb, sizeof *guesses);
109
+ guesses = instance->vbguess = reinterpret_cast<lcb_GUESSVB*>(calloc(
110
+ LCBT_VBCONFIG(instance)->nvb, sizeof *guesses));
111
111
  }
112
112
  if (newix > -1 && newix != bad) {
113
113
  guess->newix = newix;
@@ -136,18 +136,17 @@ lcb_vbguess_remap(lcb_t instance, int vbid, int bad)
136
136
  */
137
137
  static int
138
138
  find_new_data_index(lcbvb_CONFIG *oldconfig, lcbvb_CONFIG* newconfig,
139
- mc_SERVER *server)
139
+ lcb::Server *server)
140
140
  {
141
- size_t ii;
142
141
  const char *old_datahost = lcbvb_get_hostport(oldconfig,
143
- server->pipeline.index, LCBVB_SVCTYPE_DATA, LCBVB_SVCMODE_PLAIN);
142
+ server->get_index(), LCBVB_SVCTYPE_DATA, LCBVB_SVCMODE_PLAIN);
144
143
 
145
144
  if (!old_datahost) {
146
145
  /* Old server had no data service */
147
146
  return -1;
148
147
  }
149
148
 
150
- for (ii = 0; ii < LCBVB_NSERVERS(newconfig); ii++) {
149
+ for (size_t ii = 0; ii < LCBVB_NSERVERS(newconfig); ii++) {
151
150
  const char *new_datahost = lcbvb_get_hostport(newconfig, ii,
152
151
  LCBVB_SVCTYPE_DATA, LCBVB_SVCMODE_PLAIN);
153
152
  if (new_datahost && strcmp(new_datahost, old_datahost) == 0) {
@@ -160,15 +159,14 @@ find_new_data_index(lcbvb_CONFIG *oldconfig, lcbvb_CONFIG* newconfig,
160
159
  static void
161
160
  log_vbdiff(lcb_t instance, lcbvb_CONFIGDIFF *diff)
162
161
  {
163
- char **curserver;
164
162
  lcb_log(LOGARGS(instance, INFO), "Config Diff: [ vBuckets Modified=%d ], [Sequence Changed=%d]", diff->n_vb_changes, diff->sequence_changed);
165
163
  if (diff->servers_added) {
166
- for (curserver = diff->servers_added; *curserver; curserver++) {
164
+ for (char **curserver = diff->servers_added; *curserver; curserver++) {
167
165
  lcb_log(LOGARGS(instance, INFO), "Detected server %s added", *curserver);
168
166
  }
169
167
  }
170
168
  if (diff->servers_removed) {
171
- for (curserver = diff->servers_removed; *curserver; curserver++) {
169
+ for (char **curserver = diff->servers_removed; *curserver; curserver++) {
172
170
  lcb_log(LOGARGS(instance, INFO), "Detected server %s removed", *curserver);
173
171
  }
174
172
  }
@@ -187,19 +185,15 @@ log_vbdiff(lcb_t instance, lcbvb_CONFIGDIFF *diff)
187
185
  * another server.
188
186
  */
189
187
  static int
190
- iterwipe_cb(mc_CMDQUEUE *cq, mc_PIPELINE *oldpl, mc_PACKET *oldpkt, void *arg)
188
+ iterwipe_cb(mc_CMDQUEUE *cq, mc_PIPELINE *oldpl, mc_PACKET *oldpkt, void *)
191
189
  {
192
190
  protocol_binary_request_header hdr;
193
- mc_SERVER *srv = (mc_SERVER *)oldpl;
194
- mc_PIPELINE *newpl;
195
- mc_PACKET *newpkt;
191
+ lcb::Server *srv = static_cast<lcb::Server *>(oldpl);
196
192
  int newix;
197
193
 
198
- (void)arg;
199
-
200
194
  mcreq_read_hdr(oldpkt, &hdr);
201
195
 
202
- if (!lcb_should_retry(srv->settings, oldpkt, LCB_MAX_ERROR)) {
196
+ if (!lcb_should_retry(srv->get_settings(), oldpkt, LCB_MAX_ERROR)) {
203
197
  return MCREQ_KEEP_PACKET;
204
198
  }
205
199
 
@@ -222,23 +216,23 @@ iterwipe_cb(mc_CMDQUEUE *cq, mc_PIPELINE *oldpl, mc_PACKET *oldpkt, void *arg)
222
216
  }
223
217
 
224
218
 
225
- newpl = cq->pipelines[newix];
219
+ mc_PIPELINE *newpl = cq->pipelines[newix];
226
220
  if (newpl == oldpl || newpl == NULL) {
227
221
  return MCREQ_KEEP_PACKET;
228
222
  }
229
223
 
230
- lcb_log(LOGARGS((lcb_t)cq->cqdata, DEBUG), "Remapped packet %p (SEQ=%u) from "SERVER_FMT " to " SERVER_FMT,
231
- (void*)oldpkt, oldpkt->opaque, SERVER_ARGS((mc_SERVER*)oldpl), SERVER_ARGS((mc_SERVER*)newpl));
224
+ lcb_log(LOGARGS((lcb_t)cq->cqdata, DEBUG), "Remapped packet %p (SEQ=%u) from " SERVER_FMT " to " SERVER_FMT,
225
+ (void*)oldpkt, oldpkt->opaque, SERVER_ARGS((lcb::Server*)oldpl), SERVER_ARGS((lcb::Server*)newpl));
232
226
 
233
227
  /** Otherwise, copy over the packet and find the new vBucket to map to */
234
- newpkt = mcreq_renew_packet(oldpkt);
228
+ mc_PACKET *newpkt = mcreq_renew_packet(oldpkt);
235
229
  newpkt->flags &= ~MCREQ_STATE_FLAGS;
236
230
  mcreq_reenqueue_packet(newpl, newpkt);
237
231
  mcreq_packet_handled(oldpl, oldpkt);
238
232
  return MCREQ_REMOVE_PACKET;
239
233
  }
240
234
 
241
- static int
235
+ static void
242
236
  replace_config(lcb_t instance, lcbvb_CONFIG *oldconfig, lcbvb_CONFIG *newconfig)
243
237
  {
244
238
  mc_CMDQUEUE *cq = &instance->cmdq;
@@ -248,7 +242,7 @@ replace_config(lcb_t instance, lcbvb_CONFIG *oldconfig, lcbvb_CONFIG *newconfig)
248
242
  assert(LCBT_VBCONFIG(instance) == newconfig);
249
243
 
250
244
  nnew = LCBVB_NSERVERS(newconfig);
251
- ppnew = calloc(nnew, sizeof(*ppnew));
245
+ ppnew = reinterpret_cast<mc_PIPELINE**>(calloc(nnew, sizeof(*ppnew)));
252
246
  ppold = mcreq_queue_take_pipelines(cq, &nold);
253
247
 
254
248
  /**
@@ -256,26 +250,25 @@ replace_config(lcb_t instance, lcbvb_CONFIG *oldconfig, lcbvb_CONFIG *newconfig)
256
250
  * and place it inside the new list.
257
251
  */
258
252
  for (ii = 0; ii < nold; ii++) {
259
- mc_SERVER *cur = (mc_SERVER *)ppold[ii];
253
+ lcb::Server *cur = static_cast<lcb::Server *>(ppold[ii]);
260
254
  int newix = find_new_data_index(oldconfig, newconfig, cur);
261
255
  if (newix > -1) {
262
- cur->pipeline.index = newix;
263
- ppnew[newix] = &cur->pipeline;
256
+ cur->set_new_index(newix);
257
+ ppnew[newix] = cur;
264
258
  ppold[ii] = NULL;
265
- lcb_log(LOGARGS(instance, INFO), "Reusing server "SERVER_FMT". OldIndex=%d. NewIndex=%d", SERVER_ARGS(cur), ii, newix);
259
+ lcb_log(LOGARGS(instance, INFO), "Reusing server " SERVER_FMT ". OldIndex=%d. NewIndex=%d", SERVER_ARGS(cur), ii, newix);
266
260
  }
267
261
  }
268
262
 
269
263
  /**
270
- * Once we've moved the kept servers to the new list, allocate new mc_SERVER
271
- * structures for slots that don't have an existing mc_SERVER. We must do
264
+ * Once we've moved the kept servers to the new list, allocate new lcb::Server
265
+ * structures for slots that don't have an existing lcb::Server. We must do
272
266
  * this before add_pipelines() is called, so that there are no holes inside
273
267
  * ppnew
274
268
  */
275
269
  for (ii = 0; ii < nnew; ii++) {
276
270
  if (!ppnew[ii]) {
277
- ppnew[ii] = (mc_PIPELINE *)mcserver_alloc(instance, ii);
278
- ppnew[ii]->index = ii;
271
+ ppnew[ii] = new lcb::Server(instance, ii);
279
272
  }
280
273
  }
281
274
 
@@ -298,31 +291,28 @@ replace_config(lcb_t instance, lcbvb_CONFIG *oldconfig, lcbvb_CONFIG *newconfig)
298
291
  }
299
292
 
300
293
  mcreq_iterwipe(cq, ppold[ii], iterwipe_cb, NULL);
301
- mcserver_fail_chain((mc_SERVER *)ppold[ii], LCB_MAP_CHANGED);
302
- mcserver_close((mc_SERVER *)ppold[ii]);
294
+ static_cast<lcb::Server*>(ppold[ii])->purge(LCB_MAP_CHANGED);
295
+ static_cast<lcb::Server*>(ppold[ii])->close();
303
296
  }
304
297
 
305
298
  for (ii = 0; ii < nnew; ii++) {
306
- if (mcserver_has_pending((mc_SERVER*)ppnew[ii])) {
299
+ if (static_cast<lcb::Server*>(ppnew[ii])->has_pending()) {
307
300
  ppnew[ii]->flush_start(ppnew[ii]);
308
301
  }
309
302
  }
310
303
 
311
304
  free(ppnew);
312
305
  free(ppold);
313
- return LCB_CONFIGURATION_CHANGED;
314
306
  }
315
307
 
316
- void lcb_update_vbconfig(lcb_t instance, clconfig_info *config)
308
+ void lcb_update_vbconfig(lcb_t instance, lcb_pCONFIGINFO config)
317
309
  {
318
- lcb_size_t ii;
319
- int change_status;
320
- clconfig_info *old_config;
310
+ lcb_configuration_t change_status;
311
+ lcb::clconfig::ConfigInfo *old_config = instance->cur_configinfo;
321
312
  mc_CMDQUEUE *q = &instance->cmdq;
322
313
 
323
- old_config = instance->cur_configinfo;
324
314
  instance->cur_configinfo = config;
325
- lcb_clconfig_incref(config);
315
+ config->incref();
326
316
  q->config = instance->cur_configinfo->vbc;
327
317
  q->cqdata = instance;
328
318
 
@@ -337,49 +327,31 @@ void lcb_update_vbconfig(lcb_t instance, clconfig_info *config)
337
327
  /* Apply the vb guesses */
338
328
  lcb_vbguess_newconfig(instance, config->vbc, instance->vbguess);
339
329
 
340
- change_status = replace_config(instance, old_config->vbc, config->vbc);
341
- if (change_status == -1) {
342
- LOG(instance, ERR, "Couldn't replace config");
343
- return;
344
- }
345
- lcb_clconfig_decref(old_config);
330
+ replace_config(instance, old_config->vbc, config->vbc);
331
+ old_config->decref();
332
+ change_status = LCB_CONFIGURATION_CHANGED;
346
333
  } else {
347
- unsigned nservers;
348
- mc_PIPELINE **servers;
349
- nservers = VB_NSERVERS(config->vbc);
350
- if ((servers = malloc(sizeof(*servers) * nservers)) == NULL) {
351
- assert(servers);
352
- lcb_log(LOGARGS(instance, FATAL), "Couldn't allocate memory for new server list! (n=%u)", nservers);
353
- return;
354
- }
334
+ size_t nservers = VB_NSERVERS(config->vbc);
335
+ std::vector<mc_PIPELINE*> servers;
355
336
 
356
- for (ii = 0; ii < nservers; ii++) {
357
- mc_SERVER *srv;
358
- if ((srv = mcserver_alloc(instance, ii)) == NULL) {
359
- assert(srv);
360
- lcb_log(LOGARGS(instance, FATAL), "Couldn't allocate memory for server instance!");
361
- return;
362
- }
363
- servers[ii] = &srv->pipeline;
337
+ for (size_t ii = 0; ii < nservers; ii++) {
338
+ servers.push_back(new lcb::Server(instance, ii));
364
339
  }
365
340
 
366
- mcreq_queue_add_pipelines(q, servers, nservers, config->vbc);
341
+ mcreq_queue_add_pipelines(q, &servers[0], nservers, config->vbc);
367
342
  change_status = LCB_CONFIGURATION_NEW;
368
- free(servers);
369
343
  }
370
344
 
371
345
  /* Update the list of nodes here for server list */
372
- hostlist_clear(instance->ht_nodes);
373
- for (ii = 0; ii < LCBVB_NSERVERS(config->vbc); ++ii) {
346
+ instance->ht_nodes->clear();
347
+ for (size_t ii = 0; ii < LCBVB_NSERVERS(config->vbc); ++ii) {
374
348
  const char *hp = lcbvb_get_hostport(config->vbc, ii,
375
349
  LCBVB_SVCTYPE_MGMT, LCBVB_SVCMODE_PLAIN);
376
350
  if (hp) {
377
- hostlist_add_stringz(instance->ht_nodes, hp, LCB_CONFIG_HTTP_PORT);
351
+ instance->ht_nodes->add(hp, LCB_CONFIG_HTTP_PORT);
378
352
  }
379
353
  }
380
354
 
381
355
  instance->callbacks.configuration(instance, change_status);
382
356
  lcb_maybe_breakout(instance);
383
357
  }
384
-
385
-