libcouchbase 0.3.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- 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 +24 -1146
- 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 +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -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 +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- 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 +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- 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.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- 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.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- 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/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- 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/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- 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
|
File without changes
|
|
File without changes
|
|
@@ -22,14 +22,9 @@ struct BcastCookie : mc_REQDATAEX {
|
|
|
22
22
|
int remaining;
|
|
23
23
|
|
|
24
24
|
BcastCookie(lcb_CALLBACKTYPE type_,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
mc_REQDATAEX::procs = procs_;
|
|
29
|
-
mc_REQDATAEX::cookie = cookie_;
|
|
30
|
-
mc_REQDATAEX::start = gethrtime();
|
|
31
|
-
type = type_;
|
|
32
|
-
remaining = 0;
|
|
25
|
+
const mc_REQDATAPROCS* procs_, const void *cookie_)
|
|
26
|
+
: mc_REQDATAEX(cookie_, *procs_, gethrtime()),
|
|
27
|
+
type(type_), remaining(0) {
|
|
33
28
|
}
|
|
34
29
|
};
|
|
35
30
|
|
|
@@ -19,23 +19,30 @@
|
|
|
19
19
|
#include "trace.h"
|
|
20
20
|
#include "durability_internal.h"
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
mc_REQDATAEX base;
|
|
22
|
+
struct DurStoreCtx : mc_REQDATAEX {
|
|
24
23
|
lcb_t instance;
|
|
25
24
|
lcb_U16 persist_to;
|
|
26
25
|
lcb_U16 replicate_to;
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
static mc_REQDATAPROCS proctable;
|
|
28
|
+
|
|
29
|
+
DurStoreCtx(lcb_t instance_, lcb_U16 persist_, lcb_U16 replicate_,
|
|
30
|
+
const void *cookie_)
|
|
31
|
+
: mc_REQDATAEX(cookie_, proctable, gethrtime()),
|
|
32
|
+
instance(instance_), persist_to(persist_), replicate_to(replicate_) {
|
|
33
|
+
}
|
|
34
|
+
};
|
|
28
35
|
|
|
29
36
|
/** Observe stuff */
|
|
30
37
|
static void
|
|
31
|
-
handle_dur_storecb(mc_PIPELINE
|
|
38
|
+
handle_dur_storecb(mc_PIPELINE *, mc_PACKET *pkt,
|
|
32
39
|
lcb_error_t err, const void *arg)
|
|
33
40
|
{
|
|
34
41
|
lcb_RESPCALLBACK cb;
|
|
35
42
|
lcb_RESPSTOREDUR resp = { 0 };
|
|
36
43
|
lcb_CMDENDURE dcmd = { 0 };
|
|
37
44
|
const lcb_MUTATION_TOKEN *mt;
|
|
38
|
-
|
|
45
|
+
DurStoreCtx *dctx = static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
|
|
39
46
|
lcb_MULTICMD_CTX *mctx;
|
|
40
47
|
lcb_durability_opts_t opts = { 0 };
|
|
41
48
|
const lcb_RESPSTORE *sresp = (const lcb_RESPSTORE *)arg;
|
|
@@ -78,7 +85,7 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
|
|
|
78
85
|
|
|
79
86
|
if (err == LCB_SUCCESS) {
|
|
80
87
|
/* Everything OK? */
|
|
81
|
-
|
|
88
|
+
delete dctx;
|
|
82
89
|
return;
|
|
83
90
|
}
|
|
84
91
|
|
|
@@ -92,20 +99,15 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
|
|
|
92
99
|
resp.dur_resp = &dresp;
|
|
93
100
|
cb = lcb_find_callback(dctx->instance, LCB_CALLBACK_STOREDUR);
|
|
94
101
|
cb(dctx->instance, LCB_CALLBACK_STOREDUR, (const lcb_RESPBASE*)&resp);
|
|
95
|
-
|
|
102
|
+
delete dctx;
|
|
96
103
|
}
|
|
97
|
-
|
|
98
|
-
(void)pl;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
static void
|
|
102
|
-
|
|
103
|
-
{
|
|
104
|
-
DURSTORECTX *dctx = (void *)pkt->u_rdata.exdata;
|
|
105
|
-
free(dctx);
|
|
106
|
+
static void handle_dur_schedfail(mc_PACKET *pkt) {
|
|
107
|
+
delete static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
mc_REQDATAPROCS
|
|
110
|
+
mc_REQDATAPROCS DurStoreCtx::proctable = {
|
|
109
111
|
handle_dur_storecb,
|
|
110
112
|
handle_dur_schedfail
|
|
111
113
|
};
|
|
@@ -150,7 +152,7 @@ static int
|
|
|
150
152
|
can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
|
|
151
153
|
const lcb_VALBUF *vbuf, lcb_datatype_t datatype)
|
|
152
154
|
{
|
|
153
|
-
|
|
155
|
+
const lcb::Server *server = static_cast<const lcb::Server*>(pipeline);
|
|
154
156
|
int compressopts = LCBT_SETTING(instance, compressopts);
|
|
155
157
|
|
|
156
158
|
if (mcreq_compression_supported() == 0) {
|
|
@@ -163,7 +165,8 @@ can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
|
|
|
163
165
|
if ((compressopts & LCB_COMPRESS_OUT) == 0) {
|
|
164
166
|
return 0;
|
|
165
167
|
}
|
|
166
|
-
if (
|
|
168
|
+
if (server->supports_compression() == false &&
|
|
169
|
+
(compressopts & LCB_COMPRESS_FORCE) == 0) {
|
|
167
170
|
return 0;
|
|
168
171
|
}
|
|
169
172
|
if (datatype & LCB_VALUE_F_SNAPPYCOMP) {
|
|
@@ -178,7 +181,6 @@ do_store3(lcb_t instance, const void *cookie,
|
|
|
178
181
|
{
|
|
179
182
|
mc_PIPELINE *pipeline;
|
|
180
183
|
mc_PACKET *packet;
|
|
181
|
-
mc_REQDATA *rdata;
|
|
182
184
|
mc_CMDQUEUE *cq = &instance->cmdq;
|
|
183
185
|
int hsize;
|
|
184
186
|
int should_compress = 0;
|
|
@@ -256,8 +258,6 @@ do_store3(lcb_t instance, const void *cookie,
|
|
|
256
258
|
int duropts = 0;
|
|
257
259
|
lcb_U16 persist_u , replicate_u;
|
|
258
260
|
const lcb_CMDSTOREDUR *dcmd = (const lcb_CMDSTOREDUR *)cmd;
|
|
259
|
-
DURSTORECTX *dctx = calloc(1, sizeof(*dctx));
|
|
260
|
-
|
|
261
261
|
persist_u = dcmd->persist_to;
|
|
262
262
|
replicate_u = dcmd->replicate_to;
|
|
263
263
|
if (dcmd->replicate_to == -1 || dcmd->persist_to == -1) {
|
|
@@ -268,24 +268,19 @@ do_store3(lcb_t instance, const void *cookie,
|
|
|
268
268
|
if (err != LCB_SUCCESS) {
|
|
269
269
|
mcreq_wipe_packet(pipeline, packet);
|
|
270
270
|
mcreq_release_packet(pipeline, packet);
|
|
271
|
-
free(dctx);
|
|
272
271
|
return err;
|
|
273
272
|
}
|
|
274
273
|
|
|
275
|
-
dctx
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
packet->u_rdata.exdata = &dctx->base;
|
|
274
|
+
DurStoreCtx *dctx = new DurStoreCtx(instance, persist_u, replicate_u,
|
|
275
|
+
cookie);
|
|
276
|
+
packet->u_rdata.exdata = dctx;
|
|
279
277
|
packet->flags |= MCREQ_F_REQEXT;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
278
|
+
} else {
|
|
279
|
+
mc_REQDATA *rdata = MCREQ_PKT_RDATA(packet);
|
|
280
|
+
rdata->cookie = cookie;
|
|
281
|
+
rdata->start = gethrtime();
|
|
283
282
|
}
|
|
284
283
|
|
|
285
|
-
rdata = MCREQ_PKT_RDATA(packet);
|
|
286
|
-
rdata->cookie = cookie;
|
|
287
|
-
rdata->start = gethrtime();
|
|
288
|
-
|
|
289
284
|
scmd.message.body.expiration = htonl(cmd->exptime);
|
|
290
285
|
scmd.message.body.flags = htonl(flags);
|
|
291
286
|
hdr->request.magic = PROTOCOL_BINARY_REQ;
|
|
@@ -39,7 +39,9 @@ enum Options {
|
|
|
39
39
|
ALLOW_EXPIRY = 1<<1,
|
|
40
40
|
HAS_VALUE = 1<<2,
|
|
41
41
|
ALLOW_MKDIRP = 1<<3,
|
|
42
|
-
IS_LOOKUP = 1<<4
|
|
42
|
+
IS_LOOKUP = 1<<4,
|
|
43
|
+
// Must encapsulate in 'multi' spec
|
|
44
|
+
NO_STANDALONE = 1<<5
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
struct Traits {
|
|
@@ -51,13 +53,24 @@ struct Traits {
|
|
|
51
53
|
const uint8_t opcode;
|
|
52
54
|
|
|
53
55
|
inline bool valid() const {
|
|
54
|
-
return opcode !=
|
|
56
|
+
return opcode != PROTOCOL_BINARY_CMD_INVALID;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
inline unsigned mode() const {
|
|
58
60
|
return is_lookup ? LCB_SDMULTI_MODE_LOOKUP : LCB_SDMULTI_MODE_MUTATE;
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
inline bool chk_allow_empty_path(uint32_t options) const {
|
|
64
|
+
if (allow_empty_path) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (!is_lookup) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (options & LCB_SDSPEC_F_XATTRPATH) != 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
inline Traits(uint8_t op, unsigned options) :
|
|
62
75
|
allow_empty_path(options & EMPTY_PATH),
|
|
63
76
|
allow_expiry(options & ALLOW_EXPIRY),
|
|
@@ -109,7 +122,13 @@ static const Traits
|
|
|
109
122
|
Counter(PROTOCOL_BINARY_CMD_SUBDOC_COUNTER, ALLOW_EXPIRY|HAS_VALUE|ALLOW_MKDIRP);
|
|
110
123
|
|
|
111
124
|
static const Traits
|
|
112
|
-
|
|
125
|
+
GetDoc(PROTOCOL_BINARY_CMD_GET, IS_LOOKUP|EMPTY_PATH|NO_STANDALONE);
|
|
126
|
+
|
|
127
|
+
static const Traits
|
|
128
|
+
SetDoc(PROTOCOL_BINARY_CMD_SET, EMPTY_PATH|NO_STANDALONE);
|
|
129
|
+
|
|
130
|
+
static const Traits
|
|
131
|
+
Invalid(PROTOCOL_BINARY_CMD_INVALID, 0);
|
|
113
132
|
|
|
114
133
|
const Traits&
|
|
115
134
|
find(unsigned mode)
|
|
@@ -139,12 +158,28 @@ find(unsigned mode)
|
|
|
139
158
|
return Remove;
|
|
140
159
|
case LCB_SDCMD_COUNTER:
|
|
141
160
|
return Counter;
|
|
161
|
+
case LCB_SDCMD_GET_FULLDOC:
|
|
162
|
+
return GetDoc;
|
|
163
|
+
case LCB_SDCMD_SET_FULLDOC:
|
|
164
|
+
return SetDoc;
|
|
142
165
|
default:
|
|
143
166
|
return Invalid;
|
|
144
167
|
}
|
|
145
168
|
}
|
|
146
169
|
}
|
|
147
170
|
|
|
171
|
+
namespace SubdocPathFlags {
|
|
172
|
+
static const uint8_t MKDIR_P = 0x01;
|
|
173
|
+
static const uint8_t XATTR = 0x04;
|
|
174
|
+
static const uint8_t EXPAND_MACROS = 0x010;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
namespace SubdocDocFlags {
|
|
178
|
+
static const uint8_t MKDOC = 0x01;
|
|
179
|
+
static const uint8_t ADDDOC = 0x02;
|
|
180
|
+
static const uint8_t ACCESS_DELETED = 0x04;
|
|
181
|
+
}
|
|
182
|
+
|
|
148
183
|
static size_t
|
|
149
184
|
get_valbuf_size(const lcb_VALBUF& vb)
|
|
150
185
|
{
|
|
@@ -163,6 +198,36 @@ get_valbuf_size(const lcb_VALBUF& vb)
|
|
|
163
198
|
}
|
|
164
199
|
}
|
|
165
200
|
|
|
201
|
+
static uint8_t
|
|
202
|
+
make_path_flags(const uint32_t user) {
|
|
203
|
+
uint8_t flags = 0;
|
|
204
|
+
if (user & LCB_SDSPEC_F_MKINTERMEDIATES) {
|
|
205
|
+
flags |= SubdocPathFlags::MKDIR_P;
|
|
206
|
+
}
|
|
207
|
+
if (user & LCB_SDSPEC_F_XATTRPATH) {
|
|
208
|
+
flags |= SubdocPathFlags::XATTR;
|
|
209
|
+
}
|
|
210
|
+
if (user & LCB_SDSPEC_F_XATTR_MACROVALUES) {
|
|
211
|
+
flags |= SubdocPathFlags::XATTR | SubdocPathFlags::EXPAND_MACROS;
|
|
212
|
+
}
|
|
213
|
+
return flags;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static uint8_t
|
|
217
|
+
make_doc_flags(const uint32_t user) {
|
|
218
|
+
uint8_t flags = 0;
|
|
219
|
+
if (user & LCB_CMDSUBDOC_F_INSERT_DOC) {
|
|
220
|
+
flags |= SubdocDocFlags::ADDDOC;
|
|
221
|
+
}
|
|
222
|
+
if (user & LCB_CMDSUBDOC_F_UPSERT_DOC) {
|
|
223
|
+
flags |= SubdocDocFlags::MKDOC;
|
|
224
|
+
}
|
|
225
|
+
if (user & LCB_CMDSUBDOC_F_ACCESS_DELETED) {
|
|
226
|
+
flags |= SubdocDocFlags::ACCESS_DELETED;
|
|
227
|
+
}
|
|
228
|
+
return flags;
|
|
229
|
+
}
|
|
230
|
+
|
|
166
231
|
struct MultiBuilder {
|
|
167
232
|
MultiBuilder(const lcb_CMDSUBDOC *cmd_)
|
|
168
233
|
: cmd(cmd_), payload_size(0), mode(0) {
|
|
@@ -266,17 +331,10 @@ MultiBuilder::add_spec(const lcb_SDSPEC *spec)
|
|
|
266
331
|
// opcode
|
|
267
332
|
add_field(trait.opcode, 1);
|
|
268
333
|
// flags
|
|
269
|
-
|
|
270
|
-
if (spec->options & LCB_SDSPEC_F_MKINTERMEDIATES) {
|
|
271
|
-
sdflags = SUBDOC_FLAG_MKDIR_P;
|
|
272
|
-
}
|
|
273
|
-
if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
|
|
274
|
-
sdflags |= SUBDOC_FLAG_MKDOC;
|
|
275
|
-
}
|
|
276
|
-
add_field(sdflags, 1);
|
|
334
|
+
add_field(make_path_flags(spec->options), 1);
|
|
277
335
|
|
|
278
336
|
uint16_t npath = static_cast<uint16_t>(spec->path.contig.nbytes);
|
|
279
|
-
if (!npath && !trait.
|
|
337
|
+
if (!npath && !trait.chk_allow_empty_path(spec->options)) {
|
|
280
338
|
return LCB_EMPTY_PATH;
|
|
281
339
|
}
|
|
282
340
|
|
|
@@ -329,7 +387,8 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
329
387
|
if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
|
|
330
388
|
return LCB_EMPTY_KEY;
|
|
331
389
|
}
|
|
332
|
-
if (LCB_KEYBUF_IS_EMPTY(&spec->path) &&
|
|
390
|
+
if (LCB_KEYBUF_IS_EMPTY(&spec->path) &&
|
|
391
|
+
!traits.chk_allow_empty_path(spec->options)) {
|
|
333
392
|
return LCB_EMPTY_PATH;
|
|
334
393
|
}
|
|
335
394
|
|
|
@@ -367,14 +426,18 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
367
426
|
extlen = 7;
|
|
368
427
|
}
|
|
369
428
|
|
|
370
|
-
|
|
371
|
-
|
|
429
|
+
uint8_t docflags = make_doc_flags(cmd->cmdflags);
|
|
430
|
+
if (docflags) {
|
|
431
|
+
extlen++;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
protocol_binary_request_header hdr = {{0}};
|
|
372
435
|
mc_PACKET *packet;
|
|
373
436
|
mc_PIPELINE *pipeline;
|
|
374
437
|
|
|
375
438
|
rc = mcreq_basic_packet(&instance->cmdq,
|
|
376
439
|
(const lcb_CMDBASE*)cmd,
|
|
377
|
-
hdr, extlen, &packet, &pipeline, MCREQ_BASICPACKET_F_FALLBACKOK);
|
|
440
|
+
&hdr, extlen, &packet, &pipeline, MCREQ_BASICPACKET_F_FALLBACKOK);
|
|
378
441
|
|
|
379
442
|
if (rc != LCB_SUCCESS) {
|
|
380
443
|
return rc;
|
|
@@ -390,29 +453,36 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
390
453
|
MCREQ_PKT_RDATA(packet)->cookie = cookie;
|
|
391
454
|
MCREQ_PKT_RDATA(packet)->start = gethrtime();
|
|
392
455
|
|
|
393
|
-
hdr
|
|
394
|
-
hdr
|
|
395
|
-
hdr
|
|
396
|
-
hdr
|
|
397
|
-
hdr
|
|
398
|
-
hdr
|
|
399
|
-
|
|
456
|
+
hdr.request.magic = PROTOCOL_BINARY_REQ;
|
|
457
|
+
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
|
458
|
+
hdr.request.extlen = packet->extlen;
|
|
459
|
+
hdr.request.opaque = packet->opaque;
|
|
460
|
+
hdr.request.opcode = traits.opcode;
|
|
461
|
+
hdr.request.cas = lcb_htonll(cmd->cas);
|
|
462
|
+
hdr.request.bodylen = htonl(hdr.request.extlen +
|
|
463
|
+
ntohs(hdr.request.keylen) + get_value_size(packet));
|
|
464
|
+
|
|
465
|
+
memcpy(SPAN_BUFFER(&packet->kh_span), hdr.bytes, sizeof hdr.bytes);
|
|
400
466
|
|
|
401
|
-
|
|
402
|
-
|
|
467
|
+
char *extras = SPAN_BUFFER(&packet->kh_span) + MCREQ_PKT_BASESIZE;
|
|
468
|
+
// Path length:
|
|
469
|
+
uint16_t enc_pathlen = htons(spec->path.contig.nbytes);
|
|
470
|
+
memcpy(extras, &enc_pathlen, 2);
|
|
471
|
+
extras += 2;
|
|
403
472
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
|
|
408
|
-
request.message.extras.subdoc_flags |= SUBDOC_FLAG_MKDOC;
|
|
409
|
-
}
|
|
473
|
+
uint8_t path_flags = make_path_flags(spec->options);
|
|
474
|
+
memcpy(extras, &path_flags, 1);
|
|
475
|
+
extras += 1;
|
|
410
476
|
|
|
411
|
-
hdr->request.opcode = traits.opcode;
|
|
412
|
-
memcpy(SPAN_BUFFER(&packet->kh_span), request.bytes, sizeof request.bytes);
|
|
413
477
|
if (exptime) {
|
|
414
|
-
|
|
415
|
-
memcpy(
|
|
478
|
+
uint32_t enc_exptime = htonl(exptime);
|
|
479
|
+
memcpy(extras, &enc_exptime, 4);
|
|
480
|
+
extras += 4;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (docflags) {
|
|
484
|
+
memcpy(extras, &docflags, 1);
|
|
485
|
+
extras += 1;
|
|
416
486
|
}
|
|
417
487
|
|
|
418
488
|
LCB_SCHED_ADD(instance, pipeline, packet);
|
|
@@ -429,10 +499,17 @@ lcb_subdoc3(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
429
499
|
}
|
|
430
500
|
|
|
431
501
|
if (cmd->nspecs == 1) {
|
|
432
|
-
|
|
502
|
+
switch (cmd->specs[0].sdcmd) {
|
|
503
|
+
case LCB_SDCMD_GET_FULLDOC:
|
|
504
|
+
case LCB_SDCMD_SET_FULLDOC:
|
|
505
|
+
break;
|
|
506
|
+
default:
|
|
507
|
+
return sd3_single(instance, cookie, cmd);
|
|
508
|
+
}
|
|
433
509
|
}
|
|
434
510
|
|
|
435
|
-
uint32_t
|
|
511
|
+
uint32_t expiry = cmd->exptime;
|
|
512
|
+
uint8_t docflags = make_doc_flags(cmd->cmdflags);
|
|
436
513
|
lcb_error_t rc = LCB_SUCCESS;
|
|
437
514
|
|
|
438
515
|
MultiBuilder ctx(cmd);
|
|
@@ -440,7 +517,7 @@ lcb_subdoc3(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
440
517
|
*cmd->error_index = -1;
|
|
441
518
|
}
|
|
442
519
|
|
|
443
|
-
if (
|
|
520
|
+
if (expiry && !ctx.is_mutate()) {
|
|
444
521
|
return LCB_OPTIONS_CONFLICT;
|
|
445
522
|
}
|
|
446
523
|
|
|
@@ -456,7 +533,14 @@ lcb_subdoc3(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
456
533
|
|
|
457
534
|
mc_PIPELINE *pl;
|
|
458
535
|
mc_PACKET *pkt;
|
|
459
|
-
uint8_t extlen =
|
|
536
|
+
uint8_t extlen = 0;
|
|
537
|
+
if (expiry) {
|
|
538
|
+
extlen += 4;
|
|
539
|
+
}
|
|
540
|
+
if (docflags) {
|
|
541
|
+
extlen ++;
|
|
542
|
+
}
|
|
543
|
+
|
|
460
544
|
protocol_binary_request_header hdr;
|
|
461
545
|
|
|
462
546
|
if (cmd->error_index) {
|
|
@@ -497,9 +581,12 @@ lcb_subdoc3(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
|
497
581
|
hdr.request.bodylen = htonl(hdr.request.extlen +
|
|
498
582
|
ntohs(hdr.request.keylen) + ctx.payload_size);
|
|
499
583
|
memcpy(SPAN_BUFFER(&pkt->kh_span), hdr.bytes, sizeof hdr.bytes);
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
memcpy(SPAN_BUFFER(&pkt->kh_span) + 24, &
|
|
584
|
+
if (expiry) {
|
|
585
|
+
expiry = htonl(expiry);
|
|
586
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + 24, &expiry, 4);
|
|
587
|
+
}
|
|
588
|
+
if (docflags) {
|
|
589
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + 24 + (extlen -1), &docflags, 1);
|
|
503
590
|
}
|
|
504
591
|
|
|
505
592
|
MCREQ_PKT_RDATA(pkt)->cookie = cookie;
|
|
File without changes
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
#ifndef __cplusplus
|
|
28
28
|
typedef struct packet_info_st packet_info;
|
|
29
29
|
#else
|
|
30
|
+
#include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
|
|
30
31
|
namespace lcb {
|
|
31
32
|
class Server;
|
|
32
33
|
|
|
@@ -43,8 +44,8 @@ public:
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
MemcachedResponse(protocol_binary_command cmd, uint32_t opaque_,
|
|
46
|
-
protocol_binary_response_status code)
|
|
47
|
-
|
|
47
|
+
protocol_binary_response_status code)
|
|
48
|
+
: res(), payload(NULL), bufh(NULL) {
|
|
48
49
|
res.response.opcode = cmd;
|
|
49
50
|
res.response.opaque = opaque_;
|
|
50
51
|
res.response.status = htons(code);
|
|
@@ -211,6 +212,33 @@ public:
|
|
|
211
212
|
return bufh;
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
static lcb_error_t
|
|
216
|
+
parse_enhanced_error(const char *value, lcb_SIZE nvalue, char **err_ref, char **err_ctx)
|
|
217
|
+
{
|
|
218
|
+
if (value == NULL || nvalue == 0) {
|
|
219
|
+
return LCB_EINVAL;
|
|
220
|
+
}
|
|
221
|
+
Json::Value jval;
|
|
222
|
+
if (!Json::Reader().parse(value, value + nvalue, jval)) {
|
|
223
|
+
return LCB_EINVAL;
|
|
224
|
+
}
|
|
225
|
+
if (jval.empty()) {
|
|
226
|
+
return LCB_EINVAL;
|
|
227
|
+
}
|
|
228
|
+
Json::Value jerr = jval["error"];
|
|
229
|
+
if (jerr.empty()) {
|
|
230
|
+
return LCB_EINVAL;
|
|
231
|
+
}
|
|
232
|
+
std::string emsg;
|
|
233
|
+
if (!jerr["ref"].empty()) {
|
|
234
|
+
*err_ref = strdup(jerr["ref"].asString().c_str());
|
|
235
|
+
}
|
|
236
|
+
if (!jerr["context"].empty()) {
|
|
237
|
+
*err_ctx = strdup(jerr["context"].asString().c_str());
|
|
238
|
+
}
|
|
239
|
+
return LCB_SUCCESS;
|
|
240
|
+
}
|
|
241
|
+
|
|
214
242
|
protected:
|
|
215
243
|
/** The response header */
|
|
216
244
|
protocol_binary_response_header res;
|