libcouchbase 0.0.7 → 0.0.8

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