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