libcouchbase 1.0.4 → 1.1.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/.travis.yml +11 -8
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/README.markdown +38 -6
- data/ext/libcouchbase/RELEASE_NOTES.markdown +151 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +686 -288
- data/ext/libcouchbase/contrib/cJSON/cJSON.h +0 -0
- data/ext/libcouchbase/contrib/cbsasl/src/hash.c +17 -17
- data/ext/libcouchbase/contrib/cliopts/cliopts.c +76 -0
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +66 -15
- data/ext/libcouchbase/contrib/genhash/genhash.c +1 -2
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4 -3
- data/ext/libcouchbase/example/instancepool/main.cc +12 -2
- data/ext/libcouchbase/example/libeventdirect/main.c +99 -25
- data/ext/libcouchbase/example/minimal/minimal.c +7 -5
- data/ext/libcouchbase/example/observe/durability.c +102 -0
- data/ext/libcouchbase/example/observe/observe.c +19 -6
- data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +1 -2
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +6 -8
- data/ext/libcouchbase/include/libcouchbase/cntl.h +84 -64
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +295 -78
- data/ext/libcouchbase/include/libcouchbase/deprecated.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/error.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +9 -9
- data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +69 -7
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +17 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +3 -3
- data/ext/libcouchbase/include/memcached/protocol_binary.h +62 -1
- data/ext/libcouchbase/packaging/deb/control +1 -1
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +37 -36
- data/ext/libcouchbase/src/bootstrap.cc +22 -8
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -1
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +13 -8
- data/ext/libcouchbase/src/callbacks.c +2 -0
- data/ext/libcouchbase/src/cntl.cc +28 -17
- data/ext/libcouchbase/src/dns-srv.cc +1 -2
- data/ext/libcouchbase/src/dump.cc +4 -0
- data/ext/libcouchbase/src/errmap.h +89 -16
- data/ext/libcouchbase/src/handler.cc +28 -11
- data/ext/libcouchbase/src/http/http-priv.h +4 -1
- data/ext/libcouchbase/src/http/http.cc +3 -0
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +1 -0
- data/ext/libcouchbase/src/lcbio/connect.cc +2 -3
- data/ext/libcouchbase/src/lcbio/manager.cc +2 -2
- data/ext/libcouchbase/src/lcbio/ssl.h +10 -0
- data/ext/libcouchbase/src/mc/mcreq.c +8 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +14 -1
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +0 -3
- data/ext/libcouchbase/src/n1ql/n1ql.cc +22 -29
- data/ext/libcouchbase/src/n1ql/params.cc +46 -1
- data/ext/libcouchbase/src/newconfig.cc +4 -4
- data/ext/libcouchbase/src/operations/durability-seqno.cc +4 -0
- data/ext/libcouchbase/src/operations/durability.cc +3 -0
- data/ext/libcouchbase/src/operations/ping.cc +315 -0
- data/ext/libcouchbase/src/operations/stats.cc +10 -0
- data/ext/libcouchbase/src/operations/subdoc.cc +13 -1
- data/ext/libcouchbase/src/retrychk.cc +1 -0
- data/ext/libcouchbase/src/settings.c +2 -0
- data/ext/libcouchbase/src/settings.h +13 -7
- data/ext/libcouchbase/src/ssl/ssl_c.c +28 -2
- data/ext/libcouchbase/src/ssl/ssl_common.c +3 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +15 -1
- data/ext/libcouchbase/src/ssl/ssl_iot_common.h +3 -1
- data/ext/libcouchbase/src/timings.c +0 -1
- data/ext/libcouchbase/src/vbucket/vbucket.c +49 -1
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +58 -40
- data/ext/libcouchbase/tests/iotests/mock-environment.h +23 -4
- data/ext/libcouchbase/tests/iotests/mock-unit-test.h +8 -8
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +5 -5
- data/ext/libcouchbase/tests/iotests/t_durability.cc +50 -0
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +4 -2
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +6 -3
- data/ext/libcouchbase/tests/iotests/t_lock.cc +5 -6
- data/ext/libcouchbase/tests/iotests/t_misc.cc +44 -0
- data/ext/libcouchbase/tests/iotests/t_serverops.cc +1 -0
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +28 -0
- data/ext/libcouchbase/tests/iotests/t_views.cc +22 -10
- data/ext/libcouchbase/tools/CMakeLists.txt +21 -1
- data/ext/libcouchbase/tools/cbc-handlers.h +23 -3
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +1 -1
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +126 -26
- data/ext/libcouchbase/tools/cbc-proxy.cc +403 -0
- data/ext/libcouchbase/tools/cbc-subdoc.cc +826 -0
- data/ext/libcouchbase/tools/cbc.cc +149 -37
- data/ext/libcouchbase/tools/common/options.h +5 -2
- data/ext/libcouchbase/tools/linenoise/linenoise.c +15 -15
- data/lib/libcouchbase.rb +4 -0
- data/lib/libcouchbase/bucket.rb +51 -0
- data/lib/libcouchbase/connection.rb +100 -13
- data/lib/libcouchbase/ext/libcouchbase.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +13 -1
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +2 -1
- data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +5 -0
- data/lib/libcouchbase/subdoc_request.rb +129 -0
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/bucket_spec.rb +15 -1
- data/spec/connection_spec.rb +1 -1
- data/spec/subdoc_spec.rb +192 -0
- metadata +13 -4
- data/ext/libcouchbase/.travis.yml +0 -19
|
File without changes
|
|
@@ -277,31 +277,31 @@ uint32_t cbsasl_hash(
|
|
|
277
277
|
a += k[0] + (((uint32_t)k[1]) << 16);
|
|
278
278
|
break;
|
|
279
279
|
case 11:
|
|
280
|
-
c += ((uint32_t)k8[10]) << 16; /*
|
|
280
|
+
c += ((uint32_t)k8[10]) << 16; /* fall through */
|
|
281
281
|
case 10:
|
|
282
|
-
c += k[4]; /*
|
|
282
|
+
c += k[4]; /* fall through */
|
|
283
283
|
b += k[2] + (((uint32_t)k[3]) << 16);
|
|
284
284
|
a += k[0] + (((uint32_t)k[1]) << 16);
|
|
285
285
|
break;
|
|
286
286
|
case 9 :
|
|
287
|
-
c += k8[8]; /*
|
|
287
|
+
c += k8[8]; /* fall through */
|
|
288
288
|
case 8 :
|
|
289
289
|
b += k[2] + (((uint32_t)k[3]) << 16);
|
|
290
290
|
a += k[0] + (((uint32_t)k[1]) << 16);
|
|
291
291
|
break;
|
|
292
292
|
case 7 :
|
|
293
|
-
b += ((uint32_t)k8[6]) << 16; /*
|
|
293
|
+
b += ((uint32_t)k8[6]) << 16; /* fall through */
|
|
294
294
|
case 6 :
|
|
295
295
|
b += k[2];
|
|
296
296
|
a += k[0] + (((uint32_t)k[1]) << 16);
|
|
297
297
|
break;
|
|
298
298
|
case 5 :
|
|
299
|
-
b += k8[4]; /*
|
|
299
|
+
b += k8[4]; /* fall through */
|
|
300
300
|
case 4 :
|
|
301
301
|
a += k[0] + (((uint32_t)k[1]) << 16);
|
|
302
302
|
break;
|
|
303
303
|
case 3 :
|
|
304
|
-
a += ((uint32_t)k8[2]) << 16; /*
|
|
304
|
+
a += ((uint32_t)k8[2]) << 16; /* fall through */
|
|
305
305
|
case 2 :
|
|
306
306
|
a += k[0];
|
|
307
307
|
break;
|
|
@@ -337,27 +337,27 @@ uint32_t cbsasl_hash(
|
|
|
337
337
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
|
338
338
|
switch (length) { /* all the case statements fall through */
|
|
339
339
|
case 12:
|
|
340
|
-
c += ((uint32_t)k[11]) << 24;
|
|
340
|
+
c += ((uint32_t)k[11]) << 24; /* fall through */
|
|
341
341
|
case 11:
|
|
342
|
-
c += ((uint32_t)k[10]) << 16;
|
|
342
|
+
c += ((uint32_t)k[10]) << 16; /* fall through */
|
|
343
343
|
case 10:
|
|
344
|
-
c += ((uint32_t)k[9]) << 8;
|
|
344
|
+
c += ((uint32_t)k[9]) << 8; /* fall through */
|
|
345
345
|
case 9 :
|
|
346
|
-
c += k[8];
|
|
346
|
+
c += k[8]; /* fall through */
|
|
347
347
|
case 8 :
|
|
348
|
-
b += ((uint32_t)k[7]) << 24;
|
|
348
|
+
b += ((uint32_t)k[7]) << 24; /* fall through */
|
|
349
349
|
case 7 :
|
|
350
|
-
b += ((uint32_t)k[6]) << 16;
|
|
350
|
+
b += ((uint32_t)k[6]) << 16; /* fall through */
|
|
351
351
|
case 6 :
|
|
352
|
-
b += ((uint32_t)k[5]) << 8;
|
|
352
|
+
b += ((uint32_t)k[5]) << 8; /* fall through */
|
|
353
353
|
case 5 :
|
|
354
|
-
b += k[4];
|
|
354
|
+
b += k[4]; /* fall through */
|
|
355
355
|
case 4 :
|
|
356
|
-
a += ((uint32_t)k[3]) << 24;
|
|
356
|
+
a += ((uint32_t)k[3]) << 24; /* fall through */
|
|
357
357
|
case 3 :
|
|
358
|
-
a += ((uint32_t)k[2]) << 16;
|
|
358
|
+
a += ((uint32_t)k[2]) << 16; /* fall through */
|
|
359
359
|
case 2 :
|
|
360
|
-
a += ((uint32_t)k[1]) << 8;
|
|
360
|
+
a += ((uint32_t)k[1]) << 8; /* fall through */
|
|
361
361
|
case 1 :
|
|
362
362
|
a += k[0];
|
|
363
363
|
break;
|
|
@@ -103,6 +103,66 @@ cliopts_list_clear(cliopts_list *l)
|
|
|
103
103
|
l->nalloc = 0;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
static void
|
|
107
|
+
add_pair_list_value(const char *src, size_t nsrc, cliopts_pair_list *l)
|
|
108
|
+
{
|
|
109
|
+
char *key = NULL, *val = NULL;
|
|
110
|
+
char *sep = memchr(src, '=', nsrc);
|
|
111
|
+
if (sep == NULL) {
|
|
112
|
+
key = malloc(nsrc + 1);
|
|
113
|
+
memcpy(key, src, nsrc);
|
|
114
|
+
key[nsrc] = '\0';
|
|
115
|
+
val = malloc(1);
|
|
116
|
+
val[0] = '\0';
|
|
117
|
+
} else {
|
|
118
|
+
char *pp = sep;
|
|
119
|
+
size_t nkey = sep - src;
|
|
120
|
+
size_t nval = nsrc - nkey - 1;
|
|
121
|
+
for (; pp > src; pp--, nkey--) {
|
|
122
|
+
if (*pp != ' ' && *pp != '\t' && *pp != '\0') {
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
key = malloc(nkey + 1);
|
|
127
|
+
memcpy(key, src, nkey);
|
|
128
|
+
key[nkey] = '\0';
|
|
129
|
+
val = malloc(nval + 1);
|
|
130
|
+
memcpy(val, sep + 1, nval);
|
|
131
|
+
val[nval] = '\0';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!l->nalloc) {
|
|
135
|
+
l->nalloc = 2;
|
|
136
|
+
l->keys = malloc(l->nalloc * sizeof(*l->keys));
|
|
137
|
+
l->values = malloc(l->nalloc * sizeof(*l->values));
|
|
138
|
+
} else {
|
|
139
|
+
l->nalloc *= 1.5;
|
|
140
|
+
l->keys = realloc(l->keys, sizeof(*l->keys) * l->nalloc);
|
|
141
|
+
l->values = realloc(l->values, sizeof(*l->values) * l->nalloc);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
l->keys[l->nvalues] = key;
|
|
145
|
+
l->values[l->nvalues] = val;
|
|
146
|
+
l->nvalues++;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
CLIOPTS_API
|
|
150
|
+
void
|
|
151
|
+
cliopts_pair_list_clear(cliopts_pair_list *l)
|
|
152
|
+
{
|
|
153
|
+
size_t ii;
|
|
154
|
+
for (ii = 0; ii < l->nvalues; ii++) {
|
|
155
|
+
free(l->keys[ii]);
|
|
156
|
+
free(l->values[ii]);
|
|
157
|
+
}
|
|
158
|
+
free(l->keys);
|
|
159
|
+
free(l->values);
|
|
160
|
+
l->keys = NULL;
|
|
161
|
+
l->values = NULL;
|
|
162
|
+
l->nvalues = 0;
|
|
163
|
+
l->nalloc = 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
106
166
|
/**
|
|
107
167
|
* Various extraction/conversion functions for numerics
|
|
108
168
|
*/
|
|
@@ -230,6 +290,7 @@ parse_value(struct cliopts_priv *ctx,
|
|
|
230
290
|
char *vp = malloc(vlen+1);
|
|
231
291
|
vp[vlen] = 0;
|
|
232
292
|
strcpy(vp, value);
|
|
293
|
+
free(*(char**)entry->dest);
|
|
233
294
|
*(char**)entry->dest = vp;
|
|
234
295
|
return WANT_OPTION;
|
|
235
296
|
}
|
|
@@ -238,6 +299,10 @@ parse_value(struct cliopts_priv *ctx,
|
|
|
238
299
|
add_list_value(value, vlen, (cliopts_list *)entry->dest);
|
|
239
300
|
return WANT_OPTION;
|
|
240
301
|
}
|
|
302
|
+
if (entry->ktype == CLIOPTS_ARGT_PAIR_LIST) {
|
|
303
|
+
add_pair_list_value(value, vlen, (cliopts_pair_list *)entry->dest);
|
|
304
|
+
return WANT_OPTION;
|
|
305
|
+
}
|
|
241
306
|
|
|
242
307
|
if (entry->ktype == CLIOPTS_ARGT_FLOAT) {
|
|
243
308
|
exfn = extract_float;
|
|
@@ -596,6 +661,17 @@ print_help(struct cliopts_priv *ctx, struct cliopts_extra_settings *settings)
|
|
|
596
661
|
}
|
|
597
662
|
break;
|
|
598
663
|
}
|
|
664
|
+
case CLIOPTS_ARGT_PAIR_LIST: {
|
|
665
|
+
size_t ii;
|
|
666
|
+
cliopts_pair_list *l = (cliopts_pair_list *)cur->dest;
|
|
667
|
+
for (ii = 0; ii < l->nvalues; ii++) {
|
|
668
|
+
fprintf(stderr, "'%s=%s'", l->keys[ii], l->values[ii]);
|
|
669
|
+
if (ii != l->nvalues-1) {
|
|
670
|
+
fprintf(stderr, ", ");
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
break;
|
|
674
|
+
}
|
|
599
675
|
case CLIOPTS_ARGT_FLOAT:
|
|
600
676
|
fprintf(stderr, "%0.2f", *(float*)cur->dest);
|
|
601
677
|
break;
|
|
@@ -47,7 +47,13 @@ typedef enum {
|
|
|
47
47
|
* string. You can use this option type to build -Doption=value style
|
|
48
48
|
* options which can be processed later on.
|
|
49
49
|
*/
|
|
50
|
-
CLIOPTS_ARGT_LIST
|
|
50
|
+
CLIOPTS_ARGT_LIST,
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Destination should be cliopts_pair_list. Argument type is assumed to be a
|
|
54
|
+
* string with '=' separator in form of KEY=VALUE.
|
|
55
|
+
*/
|
|
56
|
+
CLIOPTS_ARGT_PAIR_LIST
|
|
51
57
|
} cliopts_argtype_t;
|
|
52
58
|
|
|
53
59
|
typedef struct {
|
|
@@ -134,6 +140,19 @@ typedef struct {
|
|
|
134
140
|
size_t nalloc;
|
|
135
141
|
} cliopts_list;
|
|
136
142
|
|
|
143
|
+
typedef struct {
|
|
144
|
+
/** Array of string pointers. Allocated via standard malloc functions */
|
|
145
|
+
char **keys;
|
|
146
|
+
/** Number of valid entries */
|
|
147
|
+
size_t nkeys;
|
|
148
|
+
/** Array of string pointers. Allocated via standard malloc functions */
|
|
149
|
+
char **values;
|
|
150
|
+
/** Number of valid entries */
|
|
151
|
+
size_t nvalues;
|
|
152
|
+
/** Number of entries allocated */
|
|
153
|
+
size_t nalloc;
|
|
154
|
+
} cliopts_pair_list;
|
|
155
|
+
|
|
137
156
|
/**
|
|
138
157
|
* Clear a list of its contents
|
|
139
158
|
* @param l The list
|
|
@@ -142,6 +161,14 @@ CLIOPTS_API
|
|
|
142
161
|
void
|
|
143
162
|
cliopts_list_clear(cliopts_list *l);
|
|
144
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Clear a pair list of its contents
|
|
166
|
+
* @param l The pair list
|
|
167
|
+
*/
|
|
168
|
+
CLIOPTS_API
|
|
169
|
+
void
|
|
170
|
+
cliopts_pair_list_clear(cliopts_pair_list *l);
|
|
171
|
+
|
|
145
172
|
/**
|
|
146
173
|
* Parse options.
|
|
147
174
|
*
|
|
@@ -265,9 +292,9 @@ public:
|
|
|
265
292
|
TOption(TOption& other) {
|
|
266
293
|
*(cliopts_entry*)this = *(cliopts_entry*) &other;
|
|
267
294
|
innerVal = other.innerVal;
|
|
268
|
-
dest = &innerVal;
|
|
269
295
|
other.dest = NULL;
|
|
270
296
|
doCopy(other);
|
|
297
|
+
dest = &innerVal;
|
|
271
298
|
}
|
|
272
299
|
|
|
273
300
|
~TOption() {
|
|
@@ -292,6 +319,7 @@ public:
|
|
|
292
319
|
* @return the option object, for method chaining.
|
|
293
320
|
*/
|
|
294
321
|
inline Ttype& setDefault(const T& val) {
|
|
322
|
+
freeInnerVal();
|
|
295
323
|
innerVal = val;
|
|
296
324
|
return *this;
|
|
297
325
|
}
|
|
@@ -349,16 +377,7 @@ protected:
|
|
|
349
377
|
/** Called from within copy constructor */
|
|
350
378
|
inline void doCopy(TOption&) {}
|
|
351
379
|
|
|
352
|
-
inline void freeInnerVal() {
|
|
353
|
-
switch (ktype) {
|
|
354
|
-
case CLIOPTS_ARGT_LIST:
|
|
355
|
-
cliopts_list_clear((cliopts_list *)&innerVal);
|
|
356
|
-
break;
|
|
357
|
-
default:
|
|
358
|
-
/* nothing to do */
|
|
359
|
-
break;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
380
|
+
inline void freeInnerVal() {}
|
|
362
381
|
|
|
363
382
|
/** Create the default value for the option */
|
|
364
383
|
static inline Taccum createDefault() { return Taccum(); }
|
|
@@ -374,6 +393,11 @@ typedef TOption<std::vector<std::string>,
|
|
|
374
393
|
cliopts_list,
|
|
375
394
|
std::vector<std::string> > ListOption;
|
|
376
395
|
|
|
396
|
+
typedef TOption<std::vector<std::pair<std::string, std::string> >,
|
|
397
|
+
CLIOPTS_ARGT_PAIR_LIST,
|
|
398
|
+
cliopts_pair_list,
|
|
399
|
+
std::vector<std::pair<std::string, std::string> > > PairListOption;
|
|
400
|
+
|
|
377
401
|
typedef TOption<bool,
|
|
378
402
|
CLIOPTS_ARGT_NONE,
|
|
379
403
|
int> BoolOption;
|
|
@@ -408,18 +432,24 @@ template<> inline std::string& StringOption::const_result() {
|
|
|
408
432
|
template<> inline std::string StringOption::result() {
|
|
409
433
|
return const_result();
|
|
410
434
|
}
|
|
435
|
+
template<> inline void StringOption::freeInnerVal() {
|
|
436
|
+
free((void *)innerVal);
|
|
437
|
+
innerVal = NULL;
|
|
438
|
+
}
|
|
411
439
|
template<> inline StringOption& StringOption::setDefault(const std::string& s) {
|
|
412
440
|
priv = s;
|
|
413
|
-
|
|
441
|
+
freeInnerVal();
|
|
442
|
+
innerVal = strdup(priv.c_str());
|
|
414
443
|
return *this;
|
|
415
444
|
}
|
|
416
445
|
template<> inline void StringOption::doCopy(StringOption& other) {
|
|
417
446
|
priv = other.priv;
|
|
418
447
|
if (other.innerVal == other.priv.c_str()) {
|
|
419
|
-
|
|
448
|
+
freeInnerVal();
|
|
449
|
+
innerVal = strdup(priv.c_str());
|
|
420
450
|
}
|
|
421
451
|
}
|
|
422
|
-
template<> inline const char* StringOption::createDefault() { return
|
|
452
|
+
template<> inline const char* StringOption::createDefault() { return NULL; }
|
|
423
453
|
|
|
424
454
|
// LIST ROUTINES
|
|
425
455
|
template<> inline std::vector<std::string>& ListOption::const_result() {
|
|
@@ -433,6 +463,27 @@ template<> inline std::vector<std::string>& ListOption::const_result() {
|
|
|
433
463
|
template<> inline std::vector<std::string> ListOption::result() {
|
|
434
464
|
return const_result();
|
|
435
465
|
}
|
|
466
|
+
template<> inline void ListOption::freeInnerVal() { cliopts_list_clear(&innerVal); }
|
|
467
|
+
|
|
468
|
+
struct PairListDtor {
|
|
469
|
+
static void call(void *arg) {
|
|
470
|
+
cliopts_pair_list_clear((cliopts_pair_list *)arg);
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
// PAIR LIST ROUTINES
|
|
475
|
+
template<> inline std::vector<std::pair<std::string, std::string> >& PairListOption::const_result() {
|
|
476
|
+
if (priv.empty()) {
|
|
477
|
+
for (size_t ii = 0; ii < innerVal.nvalues; ii++) {
|
|
478
|
+
priv.push_back(std::make_pair(innerVal.keys[ii], innerVal.values[ii]));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return priv;
|
|
482
|
+
}
|
|
483
|
+
template<> inline std::vector<std::pair<std::string, std::string> > PairListOption::result() {
|
|
484
|
+
return const_result();
|
|
485
|
+
}
|
|
486
|
+
template<> inline void PairListOption::freeInnerVal() { cliopts_pair_list_clear(&innerVal); }
|
|
436
487
|
|
|
437
488
|
// BOOL ROUTINES
|
|
438
489
|
template<> inline BoolOption& BoolOption::setDefault(const bool& b) {
|
|
@@ -149,7 +149,6 @@ static struct genhash_entry_t *genhash_find_entry(genhash_t *h,
|
|
|
149
149
|
n = h->ops.hashfunc(k, klen) % h->size;
|
|
150
150
|
lcb_assert(n < h->size);
|
|
151
151
|
|
|
152
|
-
p = h->buckets[n];
|
|
153
152
|
for (p = h->buckets[n]; p && !h->ops.hasheq(k, klen, p->key, p->nkey); p = p->next);
|
|
154
153
|
return p;
|
|
155
154
|
}
|
|
@@ -181,7 +180,7 @@ enum update_type genhash_update(genhash_t *h, const void *k, lcb_size_t klen,
|
|
|
181
180
|
rv = MODIFICATION;
|
|
182
181
|
} else {
|
|
183
182
|
if (-1 == genhash_store(h, k, klen, v, vlen)) {
|
|
184
|
-
|
|
183
|
+
return ALLOC_FAILURE;
|
|
185
184
|
}
|
|
186
185
|
rv = NEW;
|
|
187
186
|
}
|
|
@@ -1275,7 +1275,8 @@ bool OurReader::readToken(Token& token) {
|
|
|
1275
1275
|
token.type_ = tokenString;
|
|
1276
1276
|
ok = readStringSingleQuote();
|
|
1277
1277
|
break;
|
|
1278
|
-
}
|
|
1278
|
+
}
|
|
1279
|
+
/* falls through */
|
|
1279
1280
|
case '/':
|
|
1280
1281
|
token.type_ = tokenComment;
|
|
1281
1282
|
ok = readComment();
|
|
@@ -2351,12 +2352,12 @@ RuntimeError::RuntimeError(std::string const& msg)
|
|
|
2351
2352
|
LogicError::LogicError(std::string const& msg)
|
|
2352
2353
|
: Exception(msg)
|
|
2353
2354
|
{}
|
|
2354
|
-
void throwRuntimeError(std::string const&
|
|
2355
|
+
void throwRuntimeError(std::string const& )
|
|
2355
2356
|
{
|
|
2356
2357
|
assert(false);
|
|
2357
2358
|
// throw RuntimeError(msg);
|
|
2358
2359
|
}
|
|
2359
|
-
void throwLogicError(std::string const&
|
|
2360
|
+
void throwLogicError(std::string const&)
|
|
2360
2361
|
{
|
|
2361
2362
|
assert(false);
|
|
2362
2363
|
// throw LogicError(msg);
|
|
@@ -70,7 +70,7 @@ pthr_func(void *arg) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
#define NUM_WORKERS 20
|
|
73
|
-
int main(
|
|
73
|
+
int main(int argc, char *argv[]) {
|
|
74
74
|
lcb_create_st options;
|
|
75
75
|
pthread_t workers[NUM_WORKERS];
|
|
76
76
|
Pool *pool;
|
|
@@ -79,7 +79,17 @@ int main(void) {
|
|
|
79
79
|
// set up the options to represent your cluster (hostname etc)
|
|
80
80
|
memset(&options, 0, sizeof options);
|
|
81
81
|
options.version = 3;
|
|
82
|
-
options.v.v3.connstr = "couchbase://localhost
|
|
82
|
+
options.v.v3.connstr = "couchbase://localhost";
|
|
83
|
+
if (argc > 1) {
|
|
84
|
+
options.v.v3.connstr = argv[1];
|
|
85
|
+
}
|
|
86
|
+
if (argc > 2) {
|
|
87
|
+
options.v.v3.passwd = argv[2];
|
|
88
|
+
}
|
|
89
|
+
if (argc > 3) {
|
|
90
|
+
options.v.v3.username = argv[3];
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
pool = new MyPool(options, 5);
|
|
84
94
|
|
|
85
95
|
err = pool->connect();
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* gcc -levent -lcouchbase main.c
|
|
20
|
+
*
|
|
21
|
+
* # perform STORE and 20 iterations of GET commands with interval 3 seconds
|
|
22
|
+
* ./a.out couchbase://localhost password Administrator 20 3
|
|
23
|
+
*/
|
|
24
|
+
|
|
18
25
|
#include <stdio.h>
|
|
19
26
|
#include <stdlib.h>
|
|
20
27
|
#include <string.h>
|
|
@@ -22,17 +29,29 @@
|
|
|
22
29
|
#include <libcouchbase/api3.h>
|
|
23
30
|
#include <event2/event.h>
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
const char key[] = "foo";
|
|
33
|
+
lcb_SIZE nkey = sizeof(key);
|
|
34
|
+
|
|
35
|
+
const char val[] = "{\"answer\":42}";
|
|
36
|
+
lcb_SIZE nval = sizeof(val);
|
|
37
|
+
|
|
38
|
+
int nreq = 1;
|
|
39
|
+
int nresp = 1;
|
|
40
|
+
int interval = 0;
|
|
41
|
+
struct event *timer = NULL;
|
|
42
|
+
|
|
43
|
+
static void bootstrap_callback(lcb_t instance, lcb_error_t err)
|
|
27
44
|
{
|
|
28
|
-
lcb_CMDSTORE cmd = {
|
|
45
|
+
lcb_CMDSTORE cmd = {0};
|
|
29
46
|
if (err != LCB_SUCCESS) {
|
|
30
47
|
fprintf(stderr, "ERROR: %s\n", lcb_strerror(instance, err));
|
|
31
48
|
exit(EXIT_FAILURE);
|
|
32
49
|
}
|
|
50
|
+
printf("successfully bootstrapped\n");
|
|
51
|
+
fflush(stdout);
|
|
33
52
|
/* Since we've got our configuration, let's go ahead and store a value */
|
|
34
|
-
LCB_CMD_SET_KEY(&cmd,
|
|
35
|
-
LCB_CMD_SET_VALUE(&cmd,
|
|
53
|
+
LCB_CMD_SET_KEY(&cmd, key, nkey);
|
|
54
|
+
LCB_CMD_SET_VALUE(&cmd, val, nval);
|
|
36
55
|
cmd.operation = LCB_SET;
|
|
37
56
|
err = lcb_store3(instance, NULL, &cmd);
|
|
38
57
|
if (err != LCB_SUCCESS) {
|
|
@@ -49,32 +68,68 @@ static void get_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
|
|
|
49
68
|
exit(EXIT_FAILURE);
|
|
50
69
|
}
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
printf("%d. retrieved the key 'foo', value: %.*s\n", nresp, (int)rg->nvalue, rg->value);
|
|
72
|
+
fflush(stdout);
|
|
73
|
+
nresp--;
|
|
74
|
+
if (nresp == 0) {
|
|
75
|
+
printf("stopping the loop\n");
|
|
76
|
+
event_base_loopbreak((void *)lcb_get_cookie(instance));
|
|
77
|
+
}
|
|
54
78
|
(void)cbtype;
|
|
55
79
|
}
|
|
56
80
|
|
|
57
|
-
static void
|
|
81
|
+
static void schedule_timer();
|
|
82
|
+
|
|
83
|
+
static void timer_callback(int fd, short event, void *arg)
|
|
58
84
|
{
|
|
85
|
+
lcb_t instance = arg;
|
|
59
86
|
lcb_error_t rc;
|
|
60
|
-
lcb_CMDGET gcmd =
|
|
87
|
+
lcb_CMDGET gcmd = {0};
|
|
61
88
|
|
|
62
|
-
|
|
63
|
-
fprintf(stderr, "Failed to store key: %s\n", lcb_strerror(instance, rb->rc));
|
|
64
|
-
exit(EXIT_FAILURE);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
LCB_CMD_SET_KEY(&gcmd, rb->key, rb->nkey);
|
|
89
|
+
LCB_CMD_SET_KEY(&gcmd, key, nkey);
|
|
68
90
|
rc = lcb_get3(instance, NULL, &gcmd);
|
|
69
91
|
if (rc != LCB_SUCCESS) {
|
|
70
92
|
fprintf(stderr, "Failed to schedule get request: %s\n", lcb_strerror(NULL, rc));
|
|
71
93
|
exit(EXIT_FAILURE);
|
|
72
94
|
}
|
|
95
|
+
(void)fd;
|
|
96
|
+
(void)event;
|
|
97
|
+
schedule_timer();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void schedule_timer()
|
|
101
|
+
{
|
|
102
|
+
struct timeval tv;
|
|
103
|
+
|
|
104
|
+
if (!nreq) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
tv.tv_sec = interval;
|
|
108
|
+
tv.tv_usec = 0;
|
|
109
|
+
evtimer_add(timer, &tv);
|
|
110
|
+
nreq--;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static void store_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
|
|
114
|
+
{
|
|
115
|
+
if (rb->rc != LCB_SUCCESS) {
|
|
116
|
+
fprintf(stderr, "Failed to store key: %s\n", lcb_strerror(instance, rb->rc));
|
|
117
|
+
exit(EXIT_FAILURE);
|
|
118
|
+
}
|
|
119
|
+
printf("stored key 'foo'\n");
|
|
120
|
+
fflush(stdout);
|
|
121
|
+
{
|
|
122
|
+
struct event_base *evbase = (struct event_base *)lcb_get_cookie(instance);
|
|
123
|
+
|
|
124
|
+
printf("try to get value %d times with %dsec interval\n", nreq, interval);
|
|
125
|
+
timer = evtimer_new(evbase, timer_callback, instance);
|
|
126
|
+
schedule_timer();
|
|
127
|
+
}
|
|
128
|
+
|
|
73
129
|
(void)cbtype;
|
|
74
130
|
}
|
|
75
131
|
|
|
76
|
-
static lcb_io_opt_t
|
|
77
|
-
create_libevent_io_ops(struct event_base *evbase)
|
|
132
|
+
static lcb_io_opt_t create_libevent_io_ops(struct event_base *evbase)
|
|
78
133
|
{
|
|
79
134
|
struct lcb_create_io_ops_st ciops;
|
|
80
135
|
lcb_io_opt_t ioops;
|
|
@@ -93,8 +148,7 @@ create_libevent_io_ops(struct event_base *evbase)
|
|
|
93
148
|
return ioops;
|
|
94
149
|
}
|
|
95
150
|
|
|
96
|
-
static lcb_t
|
|
97
|
-
create_libcouchbase_handle(lcb_io_opt_t ioops)
|
|
151
|
+
static lcb_t create_libcouchbase_handle(lcb_io_opt_t ioops, int argc, char **argv)
|
|
98
152
|
{
|
|
99
153
|
lcb_t instance;
|
|
100
154
|
lcb_error_t error;
|
|
@@ -103,8 +157,17 @@ create_libcouchbase_handle(lcb_io_opt_t ioops)
|
|
|
103
157
|
memset(&copts, 0, sizeof(copts));
|
|
104
158
|
|
|
105
159
|
/* If NULL, will default to localhost */
|
|
106
|
-
copts.
|
|
107
|
-
|
|
160
|
+
copts.version = 3;
|
|
161
|
+
if (argc > 1) {
|
|
162
|
+
copts.v.v3.connstr = argv[1];
|
|
163
|
+
}
|
|
164
|
+
if (argc > 2) {
|
|
165
|
+
copts.v.v3.passwd = argv[2];
|
|
166
|
+
}
|
|
167
|
+
if (argc > 3) {
|
|
168
|
+
copts.v.v3.username = argv[3];
|
|
169
|
+
}
|
|
170
|
+
copts.v.v3.io = ioops;
|
|
108
171
|
error = lcb_create(&instance, &copts);
|
|
109
172
|
|
|
110
173
|
if (error != LCB_SUCCESS) {
|
|
@@ -128,12 +191,18 @@ create_libcouchbase_handle(lcb_io_opt_t ioops)
|
|
|
128
191
|
|
|
129
192
|
/* This example shows how we can hook ourself into an external event loop.
|
|
130
193
|
* You may find more information in the blogpost: http://goo.gl/fCTrX */
|
|
131
|
-
int main(
|
|
194
|
+
int main(int argc, char **argv)
|
|
132
195
|
{
|
|
133
196
|
struct event_base *evbase = event_base_new();
|
|
134
197
|
lcb_io_opt_t ioops = create_libevent_io_ops(evbase);
|
|
135
|
-
lcb_t instance = create_libcouchbase_handle(ioops);
|
|
198
|
+
lcb_t instance = create_libcouchbase_handle(ioops, argc, argv);
|
|
136
199
|
|
|
200
|
+
if (argc > 4) {
|
|
201
|
+
nreq = nresp = atoi(argv[4]);
|
|
202
|
+
}
|
|
203
|
+
if (argc > 5) {
|
|
204
|
+
interval = atoi(argv[4]);
|
|
205
|
+
}
|
|
137
206
|
/*Store the event base as the user cookie in our instance so that
|
|
138
207
|
* we may terminate the program when we're done */
|
|
139
208
|
lcb_set_cookie(instance, evbase);
|
|
@@ -142,7 +211,12 @@ int main(void)
|
|
|
142
211
|
event_base_loop(evbase, 0);
|
|
143
212
|
|
|
144
213
|
/* Cleanup */
|
|
145
|
-
event_base_free(evbase);
|
|
146
214
|
lcb_destroy(instance);
|
|
147
|
-
|
|
215
|
+
if (timer) {
|
|
216
|
+
evtimer_del(timer);
|
|
217
|
+
}
|
|
218
|
+
lcb_destroy_io_ops(ioops);
|
|
219
|
+
event_base_free(evbase);
|
|
220
|
+
|
|
221
|
+
return EXIT_SUCCESS;
|
|
148
222
|
}
|