libcouchbase 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libcouchbase/.gitignore +2 -0
- data/ext/libcouchbase/CMakeLists.txt +5 -7
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +34 -14
- data/ext/libcouchbase/configure.pl +1 -1
- data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +1 -0
- data/ext/libcouchbase/src/auth.cc +10 -0
- data/ext/libcouchbase/src/bootstrap.cc +216 -0
- data/ext/libcouchbase/src/bootstrap.h +50 -39
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +24 -24
- data/ext/libcouchbase/src/connspec.cc +30 -1
- data/ext/libcouchbase/src/connspec.h +17 -0
- data/ext/libcouchbase/src/dns-srv.cc +143 -0
- data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
- data/ext/libcouchbase/src/getconfig.cc +73 -0
- data/ext/libcouchbase/src/handler.cc +84 -85
- data/ext/libcouchbase/src/hostlist.cc +0 -1
- data/ext/libcouchbase/src/hostlist.h +6 -1
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +9 -29
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +22 -26
- data/ext/libcouchbase/src/instance.cc +102 -28
- data/ext/libcouchbase/src/internal.h +47 -29
- data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
- data/ext/libcouchbase/src/jsparse/parser.h +91 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
- data/ext/libcouchbase/src/lcbio/connect.h +9 -2
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
- data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
- data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
- data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
- data/ext/libcouchbase/src/nodeinfo.cc +4 -8
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
- data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
- data/ext/libcouchbase/src/operations/durability.cc +643 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +200 -137
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
- data/ext/libcouchbase/src/retryq.cc +394 -0
- data/ext/libcouchbase/src/retryq.h +116 -104
- data/ext/libcouchbase/src/settings.h +2 -1
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/trace.h +8 -8
- data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
- data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
- data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
- data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- metadata +36 -39
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/getconfig.c +0 -100
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
- data/ext/libcouchbase/src/operations/durability.c +0 -668
- data/ext/libcouchbase/src/packetutils.c +0 -60
- data/ext/libcouchbase/src/retryq.c +0 -424
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- 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
|
-
#
|
23
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
*
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
void
|
83
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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),
|
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)->
|
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
|
-
|
139
|
+
lcb::Server *server)
|
140
140
|
{
|
141
|
-
size_t ii;
|
142
141
|
const char *old_datahost = lcbvb_get_hostport(oldconfig,
|
143
|
-
server->
|
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 *
|
188
|
+
iterwipe_cb(mc_CMDQUEUE *cq, mc_PIPELINE *oldpl, mc_PACKET *oldpkt, void *)
|
191
189
|
{
|
192
190
|
protocol_binary_request_header hdr;
|
193
|
-
|
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->
|
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((
|
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
|
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
|
-
|
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->
|
263
|
-
ppnew[newix] =
|
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
|
271
|
-
* structures for slots that don't have an existing
|
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] =
|
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
|
-
|
302
|
-
|
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 (
|
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,
|
308
|
+
void lcb_update_vbconfig(lcb_t instance, lcb_pCONFIGINFO config)
|
317
309
|
{
|
318
|
-
|
319
|
-
|
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
|
-
|
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
|
-
|
341
|
-
|
342
|
-
|
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
|
-
|
348
|
-
mc_PIPELINE
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|