couchbase 1.3.2-x86-mingw32 → 1.3.3-x86-mingw32
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 +7 -0
- data/.travis.yml +1 -1
- data/RELEASE_NOTES.markdown +50 -0
- data/ext/couchbase_ext/arguments.c +27 -27
- data/ext/couchbase_ext/bucket.c +22 -16
- data/ext/couchbase_ext/couchbase_ext.c +132 -2
- data/ext/couchbase_ext/couchbase_ext.h +17 -0
- data/ext/couchbase_ext/extconf.rb +4 -3
- data/ext/couchbase_ext/get.c +23 -16
- data/ext/couchbase_ext/multithread_plugin.c +8 -2
- data/ext/couchbase_ext/utils.c +32 -2
- data/lib/couchbase.rb +39 -5
- data/lib/couchbase/version.rb +1 -1
- data/tasks/compile.rake +16 -11
- data/test/test_bucket.rb +14 -1
- metadata +6 -33
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 64c92cbfdb47cf90b52c5a3ddf6817b0b2f47824
|
4
|
+
data.tar.gz: 52b91ab4cad3bd75ca351b24f34a7cf3b68b7344
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1cc2d6eaf5fff25fa40b9d0ac9e389bd2cbc3561c6e98355d138c746db7004614d01e3e47ef5c1f2990657cfb68571bba12a19182c091c8c70f045320232fb66
|
7
|
+
data.tar.gz: db81527b9c87d8522e5b4e0c9712fbef06b53628d388757e0f5c60d12e9403afd71b10b4c8311073fbf178f79397b6c86775da28e02c6fb1f961e26dbaf3bfb6
|
data/.travis.yml
CHANGED
data/RELEASE_NOTES.markdown
CHANGED
@@ -3,6 +3,56 @@
|
|
3
3
|
This document is a list of user visible feature changes and important
|
4
4
|
bugfixes. Do not forget to update this doc in every important patch.
|
5
5
|
|
6
|
+
## 1.3.3 (2013-09-12)
|
7
|
+
|
8
|
+
* [major] RCBC-134 Allow application to use several connections with
|
9
|
+
thread-local singleton.
|
10
|
+
|
11
|
+
* [major] RCBC-135 Fixed invalid memory access which was detected by
|
12
|
+
using 'GC.stress = true' in tests.
|
13
|
+
|
14
|
+
* [major] RCBC-141 Initialize event indexes correctly. The plugin
|
15
|
+
didn't trace event callbacks, which might lead to invalid memory
|
16
|
+
access during rebalance, where libcouchbase creates/removes a lot of
|
17
|
+
events because of a fast-changing topology.
|
18
|
+
|
19
|
+
* [major] RCBC-137 Add selection options for new IO engines: select
|
20
|
+
and iocp.
|
21
|
+
|
22
|
+
* [major] When setting the username field, check for password
|
23
|
+
presence. Fixes segmentation fault in this code:
|
24
|
+
|
25
|
+
Couchbase.connect(:username => "default", :bucket => "default")
|
26
|
+
|
27
|
+
* [minor] Allow to determine the version of libcouchbase:
|
28
|
+
|
29
|
+
Couchbase.libcouchbase_version
|
30
|
+
|
31
|
+
* [major] RCBC-136 Build shared object for ruby 2.0 on windows. Also
|
32
|
+
fixes build script when using latest rake and rake-compiler.
|
33
|
+
|
34
|
+
* [minor] Fix deprecation warning on ruby 2.x. On newer versions it
|
35
|
+
should use `rb_thread_call_without_gvl()`.
|
36
|
+
|
37
|
+
ext/couchbase_ext/multithread_plugin.c: In function ‘loop_run_poll’:
|
38
|
+
ext/couchbase_ext/multithread_plugin.c:772:5: warning: ‘rb_thread_blocking_region’ is deprecated (declared at .../2.0.0-p247-dbg/include/ruby-2.0.0/ruby/intern.h:839) [-Wdeprecated-declarations]
|
39
|
+
rb_thread_blocking_region(loop_blocking_poll, args, RUBY_UBF_PROCESS, NULL);
|
40
|
+
|
41
|
+
* [major] Do not try to compile with plugins for Windows platform.
|
42
|
+
|
43
|
+
* [major] Force handle to be NULL on `lcb_create()` failure.
|
44
|
+
`lcb_create()` can leave garbage in the pointer even if the call
|
45
|
+
itself failed. This behaviour could lead to illegal memory access
|
46
|
+
on GC.
|
47
|
+
|
48
|
+
* [minor] Remove usage of `RARRAY_PTR` in favor of `rb_ary_entry`.
|
49
|
+
This improves performance significantly on Rubinius and also
|
50
|
+
improves compatibility with future CRuby 2.1 which introduces
|
51
|
+
generational garbage collection. This results in these arrays not
|
52
|
+
having to be rescanned in Rubinius and not marked as shady in
|
53
|
+
RBGCENC in CRuby 2.1.
|
54
|
+
For more discussion, also see: https://bugs.ruby-lang.org/issues/8399
|
55
|
+
|
6
56
|
## 1.3.2 (2013-07-10)
|
7
57
|
|
8
58
|
* [major] RCBC-133 Allow application to select the strategy of reading
|
@@ -130,14 +130,14 @@ cb_params_touch_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
130
130
|
rb_raise(rb_eArgError, "must be at least one key");
|
131
131
|
}
|
132
132
|
if (argc == 1) {
|
133
|
-
VALUE keys =
|
133
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
134
134
|
switch(TYPE(keys)) {
|
135
135
|
case T_ARRAY:
|
136
136
|
/* array of keys as a first argument */
|
137
137
|
params->cmd.touch.array = 1;
|
138
138
|
cb_params_touch_alloc(params, RARRAY_LEN(keys));
|
139
139
|
for (ii = 0; ii < params->cmd.touch.num; ++ii) {
|
140
|
-
cb_params_touch_init_item(params, ii,
|
140
|
+
cb_params_touch_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.touch.ttl);
|
141
141
|
}
|
142
142
|
break;
|
143
143
|
case T_HASH:
|
@@ -155,7 +155,7 @@ cb_params_touch_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
155
155
|
/* just list of arguments */
|
156
156
|
cb_params_touch_alloc(params, argc);
|
157
157
|
for (ii = 0; ii < params->cmd.touch.num; ++ii) {
|
158
|
-
cb_params_touch_init_item(params, ii,
|
158
|
+
cb_params_touch_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.touch.ttl);
|
159
159
|
}
|
160
160
|
}
|
161
161
|
}
|
@@ -215,14 +215,14 @@ cb_params_remove_parse_arguments(struct cb_params_st *params, int argc, VALUE ar
|
|
215
215
|
rb_raise(rb_eArgError, "must be at least one key");
|
216
216
|
}
|
217
217
|
if (argc == 1) {
|
218
|
-
VALUE keys =
|
218
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
219
219
|
switch(TYPE(keys)) {
|
220
220
|
case T_ARRAY:
|
221
221
|
/* array of keys as a first argument */
|
222
222
|
params->cmd.remove.array = 1;
|
223
223
|
cb_params_remove_alloc(params, RARRAY_LEN(keys));
|
224
224
|
for (ii = 0; ii < params->cmd.remove.num; ++ii) {
|
225
|
-
cb_params_remove_init_item(params, ii,
|
225
|
+
cb_params_remove_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.remove.cas);
|
226
226
|
}
|
227
227
|
break;
|
228
228
|
case T_HASH:
|
@@ -240,7 +240,7 @@ cb_params_remove_parse_arguments(struct cb_params_st *params, int argc, VALUE ar
|
|
240
240
|
/* just list of arguments */
|
241
241
|
cb_params_remove_alloc(params, argc);
|
242
242
|
for (ii = 0; ii < params->cmd.remove.num; ++ii) {
|
243
|
-
cb_params_remove_init_item(params, ii,
|
243
|
+
cb_params_remove_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.remove.cas);
|
244
244
|
}
|
245
245
|
}
|
246
246
|
}
|
@@ -344,7 +344,7 @@ cb_params_store_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
344
344
|
}
|
345
345
|
switch (argc) {
|
346
346
|
case 1:
|
347
|
-
keys =
|
347
|
+
keys = rb_ary_entry(argv, 0);
|
348
348
|
switch(TYPE(keys)) {
|
349
349
|
case T_HASH:
|
350
350
|
/* key-value pairs */
|
@@ -360,7 +360,7 @@ cb_params_store_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
360
360
|
case 2:
|
361
361
|
/* just key and value */
|
362
362
|
cb_params_store_alloc(params, 1);
|
363
|
-
cb_params_store_init_item(params, 0,
|
363
|
+
cb_params_store_init_item(params, 0, rb_ary_entry(argv, 0), rb_ary_entry(argv, 1),
|
364
364
|
params->cmd.store.flags, params->cmd.store.cas, params->cmd.store.ttl);
|
365
365
|
break;
|
366
366
|
default:
|
@@ -475,15 +475,15 @@ cb_params_get_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
|
475
475
|
rb_raise(rb_eArgError, "must be at least one key");
|
476
476
|
}
|
477
477
|
if (argc == 1) {
|
478
|
-
VALUE keys =
|
478
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
479
479
|
switch(TYPE(keys)) {
|
480
480
|
case T_ARRAY:
|
481
481
|
/* array of keys as a first argument */
|
482
482
|
params->cmd.get.array = 1;
|
483
483
|
cb_params_get_alloc(params, RARRAY_LEN(keys));
|
484
484
|
for (ii = 0; ii < params->cmd.get.num; ++ii) {
|
485
|
-
rb_ary_push(params->cmd.get.keys_ary,
|
486
|
-
cb_params_get_init_item(params, ii,
|
485
|
+
rb_ary_push(params->cmd.get.keys_ary, rb_ary_entry(keys, ii));
|
486
|
+
cb_params_get_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.get.ttl);
|
487
487
|
}
|
488
488
|
break;
|
489
489
|
case T_HASH:
|
@@ -505,8 +505,8 @@ cb_params_get_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
|
505
505
|
/* just list of arguments */
|
506
506
|
cb_params_get_alloc(params, argc);
|
507
507
|
for (ii = 0; ii < params->cmd.get.num; ++ii) {
|
508
|
-
rb_ary_push(params->cmd.get.keys_ary,
|
509
|
-
cb_params_get_init_item(params, ii,
|
508
|
+
rb_ary_push(params->cmd.get.keys_ary, rb_ary_entry(argv, ii));
|
509
|
+
cb_params_get_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.get.ttl);
|
510
510
|
}
|
511
511
|
}
|
512
512
|
}
|
@@ -589,14 +589,14 @@ cb_params_arith_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
589
589
|
rb_raise(rb_eArgError, "must be at least one key");
|
590
590
|
}
|
591
591
|
if (argc == 1) {
|
592
|
-
VALUE keys =
|
592
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
593
593
|
switch(TYPE(keys)) {
|
594
594
|
case T_ARRAY:
|
595
595
|
/* array of keys as a first argument */
|
596
596
|
params->cmd.arith.array = 1;
|
597
597
|
cb_params_arith_alloc(params, RARRAY_LEN(keys));
|
598
598
|
for (ii = 0; ii < params->cmd.arith.num; ++ii) {
|
599
|
-
cb_params_arith_init_item(params, ii,
|
599
|
+
cb_params_arith_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.arith.delta);
|
600
600
|
}
|
601
601
|
break;
|
602
602
|
case T_HASH:
|
@@ -613,7 +613,7 @@ cb_params_arith_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
613
613
|
/* just list of arguments */
|
614
614
|
cb_params_arith_alloc(params, argc);
|
615
615
|
for (ii = 0; ii < params->cmd.arith.num; ++ii) {
|
616
|
-
cb_params_arith_init_item(params, ii,
|
616
|
+
cb_params_arith_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.arith.delta);
|
617
617
|
}
|
618
618
|
}
|
619
619
|
}
|
@@ -643,14 +643,14 @@ cb_params_stats_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
643
643
|
lcb_size_t ii;
|
644
644
|
|
645
645
|
if (argc == 1) {
|
646
|
-
VALUE keys =
|
646
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
647
647
|
switch(TYPE(keys)) {
|
648
648
|
case T_ARRAY:
|
649
649
|
/* array of keys as a first argument */
|
650
650
|
params->cmd.stats.array = 1;
|
651
651
|
cb_params_stats_alloc(params, RARRAY_LEN(keys));
|
652
652
|
for (ii = 0; ii < params->cmd.stats.num; ++ii) {
|
653
|
-
cb_params_stats_init_item(params, ii,
|
653
|
+
cb_params_stats_init_item(params, ii, rb_ary_entry(keys, ii));
|
654
654
|
}
|
655
655
|
break;
|
656
656
|
default:
|
@@ -665,7 +665,7 @@ cb_params_stats_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
665
665
|
/* just list of arguments */
|
666
666
|
cb_params_stats_alloc(params, argc);
|
667
667
|
for (ii = 0; ii < params->cmd.stats.num; ++ii) {
|
668
|
-
cb_params_stats_init_item(params, ii,
|
668
|
+
cb_params_stats_init_item(params, ii, rb_ary_entry(argv, ii));
|
669
669
|
}
|
670
670
|
}
|
671
671
|
}
|
@@ -698,14 +698,14 @@ cb_params_observe_parse_arguments(struct cb_params_st *params, int argc, VALUE a
|
|
698
698
|
rb_raise(rb_eArgError, "must be at least one key");
|
699
699
|
}
|
700
700
|
if (argc == 1) {
|
701
|
-
VALUE keys =
|
701
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
702
702
|
switch(TYPE(keys)) {
|
703
703
|
case T_ARRAY:
|
704
704
|
/* array of keys as a first argument */
|
705
705
|
params->cmd.observe.array = 1;
|
706
706
|
cb_params_observe_alloc(params, RARRAY_LEN(keys));
|
707
707
|
for (ii = 0; ii < params->cmd.observe.num; ++ii) {
|
708
|
-
cb_params_observe_init_item(params, ii,
|
708
|
+
cb_params_observe_init_item(params, ii, rb_ary_entry(keys, ii));
|
709
709
|
}
|
710
710
|
break;
|
711
711
|
default:
|
@@ -717,7 +717,7 @@ cb_params_observe_parse_arguments(struct cb_params_st *params, int argc, VALUE a
|
|
717
717
|
/* just list of arguments */
|
718
718
|
cb_params_observe_alloc(params, argc);
|
719
719
|
for (ii = 0; ii < params->cmd.observe.num; ++ii) {
|
720
|
-
cb_params_observe_init_item(params, ii,
|
720
|
+
cb_params_observe_init_item(params, ii, rb_ary_entry(argv, ii));
|
721
721
|
}
|
722
722
|
}
|
723
723
|
}
|
@@ -771,7 +771,7 @@ cb_params_unlock_parse_options(struct cb_params_st *params, VALUE options)
|
|
771
771
|
cb_params_unlock_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
772
772
|
{
|
773
773
|
if (argc == 1) {
|
774
|
-
VALUE keys =
|
774
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
775
775
|
switch(TYPE(keys)) {
|
776
776
|
case T_HASH:
|
777
777
|
/* key-cas pairs */
|
@@ -847,7 +847,7 @@ do_params_build(VALUE ptr)
|
|
847
847
|
VALUE argv = params->args;
|
848
848
|
|
849
849
|
/* extract options */
|
850
|
-
if (argc > 1 && TYPE(
|
850
|
+
if (argc > 1 && TYPE(rb_ary_entry(argv, argc-1)) == T_HASH) {
|
851
851
|
opts = rb_ary_pop(argv);
|
852
852
|
--argc;
|
853
853
|
} else {
|
@@ -865,7 +865,7 @@ do_params_build(VALUE ptr)
|
|
865
865
|
case cb_cmd_remove:
|
866
866
|
params->cmd.remove.quiet = params->bucket->quiet;
|
867
867
|
if (argc == 2) {
|
868
|
-
int type = TYPE(
|
868
|
+
int type = TYPE(rb_ary_entry(argv, 1));
|
869
869
|
if (type == T_FIXNUM || type == T_BIGNUM) {
|
870
870
|
/* allow form delete("foo", 0xdeadbeef) */
|
871
871
|
--argc;
|
@@ -906,7 +906,7 @@ do_params_build(VALUE ptr)
|
|
906
906
|
params->cmd.arith.initial = params->bucket->default_arith_init;
|
907
907
|
params->cmd.arith.delta = 1;
|
908
908
|
params->cmd.arith.ttl = params->bucket->default_ttl;
|
909
|
-
if (argc == 2 && TYPE(
|
909
|
+
if (argc == 2 && TYPE(rb_ary_entry(argv, 1)) == T_FIXNUM) {
|
910
910
|
/* allow form incr("foo", 1) */
|
911
911
|
--argc;
|
912
912
|
params->cmd.arith.delta = NUM2ULL(rb_ary_pop(argv)) & INT64_MAX;
|
@@ -926,7 +926,7 @@ do_params_build(VALUE ptr)
|
|
926
926
|
case cb_cmd_unlock:
|
927
927
|
params->cmd.unlock.quiet = params->bucket->quiet;
|
928
928
|
if (argc == 2) {
|
929
|
-
int type = TYPE(
|
929
|
+
int type = TYPE(rb_ary_entry(argv, 1));
|
930
930
|
if (type == T_FIXNUM || type == T_BIGNUM) {
|
931
931
|
/* allow form unlock("foo", 0xdeadbeef) */
|
932
932
|
--argc;
|
data/ext/couchbase_ext/bucket.c
CHANGED
@@ -97,7 +97,9 @@ cb_bucket_mark(void *ptr)
|
|
97
97
|
rb_gc_mark(bucket->on_error_proc);
|
98
98
|
rb_gc_mark(bucket->on_connect_proc);
|
99
99
|
rb_gc_mark(bucket->key_prefix_val);
|
100
|
-
|
100
|
+
if (bucket->object_space) {
|
101
|
+
st_foreach(bucket->object_space, cb_bucket_mark_object_i, (st_data_t)bucket);
|
102
|
+
}
|
101
103
|
}
|
102
104
|
}
|
103
105
|
|
@@ -260,7 +262,12 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
260
262
|
if (arg != Qnil) {
|
261
263
|
if (arg == cb_sym_default) {
|
262
264
|
bucket->engine = cb_sym_default;
|
263
|
-
|
265
|
+
} else if (arg == cb_sym_select) {
|
266
|
+
bucket->engine = cb_sym_select;
|
267
|
+
#ifdef _WIN32
|
268
|
+
} else if (arg == cb_sym_iocp) {
|
269
|
+
bucket->engine = cb_sym_iocp;
|
270
|
+
#else
|
264
271
|
} else if (arg == cb_sym_libev) {
|
265
272
|
bucket->engine = cb_sym_libev;
|
266
273
|
} else if (arg == cb_sym_libevent) {
|
@@ -317,11 +324,7 @@ do_connect(struct cb_bucket_st *bucket)
|
|
317
324
|
struct lcb_create_st create_opts;
|
318
325
|
|
319
326
|
if (bucket->handle) {
|
320
|
-
|
321
|
-
lcb_destroy_io_ops(bucket->io);
|
322
|
-
bucket->handle = NULL;
|
323
|
-
bucket->io = NULL;
|
324
|
-
bucket->connected = 0;
|
327
|
+
cb_bucket_disconnect(bucket->self);
|
325
328
|
}
|
326
329
|
|
327
330
|
{
|
@@ -331,6 +334,12 @@ do_connect(struct cb_bucket_st *bucket)
|
|
331
334
|
|
332
335
|
if (bucket->engine == cb_sym_libevent) {
|
333
336
|
ciops.v.v0.type = LCB_IO_OPS_LIBEVENT;
|
337
|
+
} else if (bucket->engine == cb_sym_select) {
|
338
|
+
ciops.v.v0.type = LCB_IO_OPS_SELECT;
|
339
|
+
#ifdef _WIN32
|
340
|
+
} else if (bucket->engine == cb_sym_iocp) {
|
341
|
+
ciops.v.v0.type = LCB_IO_OPS_WINIOCP;
|
342
|
+
#endif
|
334
343
|
} else if (bucket->engine == cb_sym_libev) {
|
335
344
|
ciops.v.v0.type = LCB_IO_OPS_LIBEV;
|
336
345
|
} else if (bucket->engine == cb_sym_eventmachine) {
|
@@ -359,11 +368,12 @@ do_connect(struct cb_bucket_st *bucket)
|
|
359
368
|
create_opts.v.v1.type = bucket->type;
|
360
369
|
create_opts.v.v1.host = RTEST(bucket->node_list) ? RSTRING_PTR(bucket-> node_list) : RSTRING_PTR(bucket->authority);
|
361
370
|
create_opts.v.v1.user = RTEST(bucket->username) ? RSTRING_PTR(bucket->username) : NULL;
|
362
|
-
create_opts.v.v1.passwd = RTEST(bucket->
|
371
|
+
create_opts.v.v1.passwd = RTEST(bucket->password) ? RSTRING_PTR(bucket->password) : NULL;
|
363
372
|
create_opts.v.v1.bucket = RSTRING_PTR(bucket->bucket);
|
364
373
|
create_opts.v.v1.io = bucket->io;
|
365
374
|
err = lcb_create(&bucket->handle, &create_opts);
|
366
375
|
if (err != LCB_SUCCESS) {
|
376
|
+
bucket->handle = NULL;
|
367
377
|
rb_exc_raise(cb_check_error(err, "failed to create libcouchbase instance", Qnil));
|
368
378
|
}
|
369
379
|
lcb_set_cookie(bucket->handle, bucket);
|
@@ -388,10 +398,7 @@ do_connect(struct cb_bucket_st *bucket)
|
|
388
398
|
}
|
389
399
|
err = lcb_connect(bucket->handle);
|
390
400
|
if (err != LCB_SUCCESS) {
|
391
|
-
|
392
|
-
lcb_destroy_io_ops(bucket->io);
|
393
|
-
bucket->handle = NULL;
|
394
|
-
bucket->io = NULL;
|
401
|
+
cb_bucket_disconnect(bucket->self);
|
395
402
|
rb_exc_raise(cb_check_error(err, "failed to connect libcouchbase instance to server", Qnil));
|
396
403
|
}
|
397
404
|
bucket->exception = Qnil;
|
@@ -402,10 +409,7 @@ do_connect(struct cb_bucket_st *bucket)
|
|
402
409
|
if (!bucket->async) {
|
403
410
|
lcb_wait(bucket->handle);
|
404
411
|
if (bucket->exception != Qnil) {
|
405
|
-
|
406
|
-
lcb_destroy_io_ops(bucket->io);
|
407
|
-
bucket->handle = NULL;
|
408
|
-
bucket->io = NULL;
|
412
|
+
cb_bucket_disconnect(bucket->self);
|
409
413
|
rb_exc_raise(bucket->exception);
|
410
414
|
}
|
411
415
|
}
|
@@ -484,6 +488,8 @@ cb_bucket_alloc(VALUE klass)
|
|
484
488
|
* @option options [Symbol] :engine (:default) the IO engine to use
|
485
489
|
* Currently following engines are supported:
|
486
490
|
* :default :: Built-in engine (multi-thread friendly)
|
491
|
+
* :select :: select(2) IO plugin from libcouchbase
|
492
|
+
* :iocp :: "I/O Completion Ports" plugin from libcouchbase (windows only)
|
487
493
|
* :libevent :: libevent IO plugin from libcouchbase (optional)
|
488
494
|
* :libev :: libev IO plugin from libcouchbase (optional)
|
489
495
|
* :eventmachine :: EventMachine plugin (builtin, but requires EM gem and ruby 1.9+)
|
@@ -73,6 +73,7 @@ ID cb_sym_hostname;
|
|
73
73
|
ID cb_sym_http_request;
|
74
74
|
ID cb_sym_increment;
|
75
75
|
ID cb_sym_initial;
|
76
|
+
ID cb_sym_iocp;
|
76
77
|
ID cb_sym_key_prefix;
|
77
78
|
ID cb_sym_libev;
|
78
79
|
ID cb_sym_libevent;
|
@@ -97,6 +98,7 @@ ID cb_sym_put;
|
|
97
98
|
ID cb_sym_quiet;
|
98
99
|
ID cb_sym_replace;
|
99
100
|
ID cb_sym_replica;
|
101
|
+
ID cb_sym_select;
|
100
102
|
ID cb_sym_send_threshold;
|
101
103
|
ID cb_sym_set;
|
102
104
|
ID cb_sym_stats;
|
@@ -183,6 +185,16 @@ VALUE cb_eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x19 */
|
|
183
185
|
VALUE cb_eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x1a */
|
184
186
|
VALUE cb_eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x1b */
|
185
187
|
VALUE cb_eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
|
188
|
+
VALUE cb_eServerBug; /* LCB_SERVER_BUG = 0x1d */
|
189
|
+
VALUE cb_ePluginVersionMismatch; /* LCB_PLUGIN_VERSION_MISMATCH = 0x1e */
|
190
|
+
VALUE cb_eInvalidHostFormat; /* LCB_INVALID_HOST_FORMAT = 0x1f */
|
191
|
+
VALUE cb_eInvalidChar; /* LCB_INVALID_CHAR = 0x20 */
|
192
|
+
VALUE cb_eDurabilityTooMany; /* LCB_DURABILITY_ETOOMANY = 0x21 */
|
193
|
+
VALUE cb_eDuplicateCommands; /* LCB_DUPLICATE_COMMANDS = 0x22 */
|
194
|
+
VALUE cb_eNoMatchingServer; /* LCB_NO_MATCHING_SERVER = 0x23 */
|
195
|
+
VALUE cb_eBadEnvironment; /* LCB_BAD_ENVIRONMENT = 0x24 */
|
196
|
+
VALUE cb_eBusy; /* LCB_BUSY = 0x25 */
|
197
|
+
VALUE cb_eInvalidUsername; /* LCB_INVALID_USERNAME = 0x26 */
|
186
198
|
|
187
199
|
/* Default Strings */
|
188
200
|
VALUE cb_vStrDefault;
|
@@ -198,6 +210,14 @@ cb_intern_string(VALUE ar, const char *str)
|
|
198
210
|
return tmp;
|
199
211
|
}
|
200
212
|
|
213
|
+
static VALUE
|
214
|
+
cb_libcouchbase_version(VALUE self)
|
215
|
+
{
|
216
|
+
const char *ver = lcb_get_version(NULL);
|
217
|
+
(void)self;
|
218
|
+
return STR_NEW_CSTR(ver);
|
219
|
+
}
|
220
|
+
|
201
221
|
/* Ruby Extension initializer */
|
202
222
|
void
|
203
223
|
Init_couchbase_ext(void)
|
@@ -209,6 +229,15 @@ Init_couchbase_ext(void)
|
|
209
229
|
|
210
230
|
cb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
|
211
231
|
cb_mCouchbase = rb_define_module("Couchbase");
|
232
|
+
/* Document-method: libcouchbase_version
|
233
|
+
*
|
234
|
+
* @since 1.3.3
|
235
|
+
*
|
236
|
+
* Version of the libcouchbase library currently loaded
|
237
|
+
* @return [String]
|
238
|
+
*/
|
239
|
+
rb_define_singleton_method(cb_mCouchbase, "libcouchbase_version", cb_libcouchbase_version, 0);
|
240
|
+
|
212
241
|
cb_mTranscoder = rb_const_get(cb_mCouchbase, rb_intern("Transcoder"));
|
213
242
|
cb_mDocument = rb_const_get(cb_mTranscoder, rb_intern("Document"));
|
214
243
|
cb_mMarshal = rb_const_get(cb_mTranscoder, rb_intern("Marshal"));
|
@@ -436,12 +465,108 @@ Init_couchbase_ext(void)
|
|
436
465
|
/* Document-class: Couchbase::Error::DlsymFailed
|
437
466
|
* dlsym() failed
|
438
467
|
*
|
439
|
-
* Failed to locate the requested
|
468
|
+
* Failed to locate the requested symbol in the shared object
|
440
469
|
*
|
441
470
|
* @since 1.2.0
|
442
471
|
*/
|
443
472
|
cb_eDlsymFailedError = rb_define_class_under(cb_mError, "DlsymFailed", cb_eBaseError);
|
444
473
|
|
474
|
+
/* Document-class: Couchbase::Error::ServerBug
|
475
|
+
* Server Bug
|
476
|
+
*
|
477
|
+
* Unexpected usage of the server protocol, like unexpected
|
478
|
+
* response. If you've received this error code, please record your
|
479
|
+
* steps and file the issue at:
|
480
|
+
*
|
481
|
+
* http://www.couchbase.com/issues/browse/MB
|
482
|
+
*
|
483
|
+
* @since 1.3.3
|
484
|
+
*/
|
485
|
+
cb_eServerBug = rb_define_class_under(cb_mError, "ServerBug", cb_eBaseError);
|
486
|
+
|
487
|
+
/* Document-class: Couchbase::Error::PluginVersionMismatch
|
488
|
+
* Plugin Version Mismatch
|
489
|
+
*
|
490
|
+
* Libcouchbase cannot load the plugin because of version mismatch
|
491
|
+
*
|
492
|
+
* @since 1.3.3
|
493
|
+
*/
|
494
|
+
cb_ePluginVersionMismatch = rb_define_class_under(cb_mError, "PluginVersionMismatch", cb_eBaseError);
|
495
|
+
|
496
|
+
/* Document-class: Couchbase::Error::InvalidHostFormat
|
497
|
+
* Invalid Host Format
|
498
|
+
*
|
499
|
+
* The bootstrap hosts list use an invalid/unsupported format
|
500
|
+
*
|
501
|
+
* @since 1.3.3
|
502
|
+
*/
|
503
|
+
cb_eInvalidHostFormat = rb_define_class_under(cb_mError, "InvalidHostFormat", cb_eBaseError);
|
504
|
+
|
505
|
+
/* Document-class: Couchbase::Error::InvalidChar
|
506
|
+
* Invalid Character
|
507
|
+
*
|
508
|
+
* Invalid character used in the path component of an URL
|
509
|
+
*
|
510
|
+
* @since 1.3.3
|
511
|
+
*/
|
512
|
+
cb_eInvalidChar = rb_define_class_under(cb_mError, "InvalidChar", cb_eBaseError);
|
513
|
+
|
514
|
+
/* Document-class: Couchbase::Error::DurabilityTooMany
|
515
|
+
* Too Many Nodes
|
516
|
+
*
|
517
|
+
* Too many nodes were requested for the observe criteria
|
518
|
+
*
|
519
|
+
* @since 1.3.3
|
520
|
+
*/
|
521
|
+
cb_eDurabilityTooMany = rb_define_class_under(cb_mError, "DurabilityTooMany", cb_eBaseError);
|
522
|
+
|
523
|
+
/* Document-class: Couchbase::Error::DuplicateCommands
|
524
|
+
* Duplicate Commands
|
525
|
+
*
|
526
|
+
* The same key was passed multiple times in a command list
|
527
|
+
*
|
528
|
+
* @since 1.3.3
|
529
|
+
*/
|
530
|
+
cb_eDuplicateCommands = rb_define_class_under(cb_mError, "DuplicateCommands", cb_eBaseError);
|
531
|
+
|
532
|
+
/* Document-class: Couchbase::Error::NoMatchingServer
|
533
|
+
* No Matching Server
|
534
|
+
*
|
535
|
+
* The config says that there is no server yet at that
|
536
|
+
* position (-1 in the cluster topology map)
|
537
|
+
*
|
538
|
+
* @since 1.3.3
|
539
|
+
*/
|
540
|
+
cb_eNoMatchingServer = rb_define_class_under(cb_mError, "NoMatchingServer", cb_eBaseError);
|
541
|
+
|
542
|
+
/* Document-class: Couchbase::Error::BadEnvironment
|
543
|
+
* Busy
|
544
|
+
*
|
545
|
+
* An operation has not yet completed
|
546
|
+
*
|
547
|
+
* @since 1.3.3
|
548
|
+
*/
|
549
|
+
cb_eBadEnvironment = rb_define_class_under(cb_mError, "BadEnvironment", cb_eBaseError);
|
550
|
+
|
551
|
+
/* Document-class: Couchbase::Error::Busy
|
552
|
+
* Invalid Character
|
553
|
+
*
|
554
|
+
* Invalid character used in the path component of an URL
|
555
|
+
*
|
556
|
+
* @since 1.3.3
|
557
|
+
*/
|
558
|
+
cb_eBusy = rb_define_class_under(cb_mError, "Busy", cb_eBaseError);
|
559
|
+
|
560
|
+
/* Document-class: Couchbase::Error::InvalidUsername
|
561
|
+
* Invalid Username
|
562
|
+
*
|
563
|
+
* Administrator account must not be used to access the data
|
564
|
+
* in the bucket
|
565
|
+
*
|
566
|
+
* @since 1.3.3
|
567
|
+
*/
|
568
|
+
cb_eInvalidUsername = rb_define_class_under(cb_mError, "InvalidUsername", cb_eBaseError);
|
569
|
+
|
445
570
|
/* Document-class: Couchbase::Error::HTTP
|
446
571
|
* HTTP error with status code
|
447
572
|
*
|
@@ -484,7 +609,10 @@ Init_couchbase_ext(void)
|
|
484
609
|
* 0x1a :: LCB_CLIENT_ENOMEM (Out of memory on the client)
|
485
610
|
* 0x1b :: LCB_CLIENT_ETMPFAIL (Temporary failure on the client)
|
486
611
|
* 0x1c :: LCB_EBADHANDLE (Invalid handle type)
|
487
|
-
*
|
612
|
+
* 0x1d :: LCB_SERVER_BUG (Server bug)
|
613
|
+
* 0x1e :: LCB_PLUGIN_VERSION_MISMATCH (Plugin version mismatch)
|
614
|
+
* 0x1f :: LCB_INVALID_HOST_FORMAT (Invalid host format)
|
615
|
+
* 0x20 :: LCB_INVALID_CHAR (Invalid character)
|
488
616
|
*
|
489
617
|
* @since 1.0.0
|
490
618
|
*
|
@@ -1189,6 +1317,7 @@ Init_couchbase_ext(void)
|
|
1189
1317
|
cb_sym_http_request = ID2SYM(rb_intern("http_request"));
|
1190
1318
|
cb_sym_increment = ID2SYM(rb_intern("increment"));
|
1191
1319
|
cb_sym_initial = ID2SYM(rb_intern("initial"));
|
1320
|
+
cb_sym_iocp = ID2SYM(rb_intern("iocp"));
|
1192
1321
|
cb_sym_key_prefix = ID2SYM(rb_intern("key_prefix"));
|
1193
1322
|
cb_sym_libev = ID2SYM(rb_intern("libev"));
|
1194
1323
|
cb_sym_libevent = ID2SYM(rb_intern("libevent"));
|
@@ -1213,6 +1342,7 @@ Init_couchbase_ext(void)
|
|
1213
1342
|
cb_sym_quiet = ID2SYM(rb_intern("quiet"));
|
1214
1343
|
cb_sym_replace = ID2SYM(rb_intern("replace"));
|
1215
1344
|
cb_sym_replica = ID2SYM(rb_intern("replica"));
|
1345
|
+
cb_sym_select = ID2SYM(rb_intern("select"));
|
1216
1346
|
cb_sym_send_threshold = ID2SYM(rb_intern("send_threshold"));
|
1217
1347
|
cb_sym_set = ID2SYM(rb_intern("set"));
|
1218
1348
|
cb_sym_stats = ID2SYM(rb_intern("stats"));
|
@@ -22,6 +22,10 @@
|
|
22
22
|
#include <st.h>
|
23
23
|
#endif
|
24
24
|
|
25
|
+
#ifdef HAVE_RUBY_THREAD_H
|
26
|
+
#include <ruby/thread.h>
|
27
|
+
#endif
|
28
|
+
|
25
29
|
#include "couchbase_config.h"
|
26
30
|
#ifdef HAVE_RB_FIBER_YIELD
|
27
31
|
#define BUILD_EVENTMACHINE_PLUGIN
|
@@ -217,6 +221,7 @@ extern ID cb_sym_hostname;
|
|
217
221
|
extern ID cb_sym_http_request;
|
218
222
|
extern ID cb_sym_increment;
|
219
223
|
extern ID cb_sym_initial;
|
224
|
+
extern ID cb_sym_iocp;
|
220
225
|
extern ID cb_sym_key_prefix;
|
221
226
|
extern ID cb_sym_libev;
|
222
227
|
extern ID cb_sym_libevent;
|
@@ -241,6 +246,7 @@ extern ID cb_sym_put;
|
|
241
246
|
extern ID cb_sym_quiet;
|
242
247
|
extern ID cb_sym_replace;
|
243
248
|
extern ID cb_sym_replica;
|
249
|
+
extern ID cb_sym_select;
|
244
250
|
extern ID cb_sym_send_threshold;
|
245
251
|
extern ID cb_sym_set;
|
246
252
|
extern ID cb_sym_stats;
|
@@ -326,6 +332,17 @@ extern VALUE cb_eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x19 */
|
|
326
332
|
extern VALUE cb_eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x1a */
|
327
333
|
extern VALUE cb_eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x1b */
|
328
334
|
extern VALUE cb_eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
|
335
|
+
extern VALUE cb_eServerBug; /* LCB_SERVER_BUG = 0x1d */
|
336
|
+
extern VALUE cb_ePluginVersionMismatch; /* LCB_PLUGIN_VERSION_MISMATCH = 0x1e */
|
337
|
+
extern VALUE cb_eInvalidHostFormat; /* LCB_INVALID_HOST_FORMAT = 0x1f */
|
338
|
+
extern VALUE cb_eInvalidChar; /* LCB_INVALID_CHAR = 0x20 */
|
339
|
+
extern VALUE cb_eDurabilityTooMany; /* LCB_DURABILITY_ETOOMANY = 0x21 */
|
340
|
+
extern VALUE cb_eDuplicateCommands; /* LCB_DUPLICATE_COMMANDS = 0x22 */
|
341
|
+
extern VALUE cb_eNoMatchingServer; /* LCB_NO_MATCHING_SERVER = 0x23 */
|
342
|
+
extern VALUE cb_eBadEnvironment; /* LCB_BAD_ENVIRONMENT = 0x24 */
|
343
|
+
extern VALUE cb_eBusy; /* LCB_BUSY = 0x25 */
|
344
|
+
extern VALUE cb_eInvalidUsername; /* LCB_INVALID_USERNAME = 0x26 */
|
345
|
+
|
329
346
|
|
330
347
|
/* Default Strings */
|
331
348
|
extern VALUE cb_vStrDefault;
|
@@ -128,14 +128,14 @@ end
|
|
128
128
|
|
129
129
|
unless try_compile(<<-SRC)
|
130
130
|
#include <libcouchbase/couchbase.h>
|
131
|
+
#include <stdio.h>
|
131
132
|
|
132
133
|
int main() {
|
133
|
-
|
134
|
-
cmd.v.v1.strategy = 42;
|
134
|
+
printf("User not found: %d\\n", LCB_INVALID_USERNAME);
|
135
135
|
return 0;
|
136
136
|
}
|
137
137
|
SRC
|
138
|
-
die("You must install libcouchbase >= 2.
|
138
|
+
die("You must install libcouchbase >= 2.1.3\nSee http://www.couchbase.com/communities/c/ for more details")
|
139
139
|
end
|
140
140
|
|
141
141
|
have_library("couchbase", "lcb_verify_compiler_setup", "libcouchbase/couchbase.h") # just to add -lcouchbase properly
|
@@ -151,6 +151,7 @@ have_func("gethrtime")
|
|
151
151
|
have_func("rb_hash_lookup2")
|
152
152
|
have_func("rb_thread_fd_select")
|
153
153
|
have_func("rb_thread_blocking_region")
|
154
|
+
have_func("rb_thread_call_without_gvl")
|
154
155
|
have_func("poll", "poll.h")
|
155
156
|
have_func("ppoll", "poll.h")
|
156
157
|
have_func("rb_fiber_yield")
|
data/ext/couchbase_ext/get.c
CHANGED
@@ -36,19 +36,23 @@ cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_g
|
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
39
|
+
if (error == LCB_SUCCESS) {
|
40
|
+
flags = ULONG2NUM(resp->v.v0.flags);
|
41
|
+
cas = ULL2NUM(resp->v.v0.cas);
|
42
|
+
raw = STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes);
|
43
|
+
val = cb_decode_value(ctx->transcoder, raw, resp->v.v0.flags, ctx->transcoder_opts);
|
44
|
+
if (rb_obj_is_kind_of(val, rb_eStandardError)) {
|
45
|
+
VALUE exc_str = rb_funcall(val, cb_id_to_s, 0);
|
46
|
+
VALUE msg = rb_funcall(rb_mKernel, cb_id_sprintf, 3,
|
47
|
+
rb_str_new2("unable to convert value for key \"%s\": %s"), key, exc_str);
|
48
|
+
ctx->exception = rb_exc_new3(cb_eValueFormatError, msg);
|
49
|
+
rb_ivar_set(ctx->exception, cb_id_iv_operation, cb_sym_get);
|
50
|
+
rb_ivar_set(ctx->exception, cb_id_iv_key, key);
|
51
|
+
rb_ivar_set(ctx->exception, cb_id_iv_inner_exception, val);
|
52
|
+
val = Qnil;
|
53
|
+
}
|
54
|
+
} else {
|
55
|
+
val = flags = cas = Qnil;
|
52
56
|
}
|
53
57
|
if (bucket->async) { /* asynchronous */
|
54
58
|
if (ctx->proc != Qnil) {
|
@@ -291,11 +295,14 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
291
295
|
return rv; /* return as a hash {key => [value, flags, cas], ...} */
|
292
296
|
}
|
293
297
|
if (params.cmd.get.num > 1 || params.cmd.get.array) {
|
294
|
-
VALUE
|
298
|
+
VALUE keys, ret;
|
295
299
|
ret = rb_ary_new();
|
296
|
-
|
300
|
+
/* make sure ret is guarded so not invisible in a register
|
301
|
+
* when stack scanning */
|
302
|
+
RB_GC_GUARD(ret);
|
303
|
+
keys = params.cmd.get.keys_ary;
|
297
304
|
for (ii = 0; ii < params.cmd.get.num; ++ii) {
|
298
|
-
rb_ary_push(ret, rb_hash_aref(rv,
|
305
|
+
rb_ary_push(ret, rb_hash_aref(rv, rb_ary_entry(keys, ii)));
|
299
306
|
}
|
300
307
|
return ret; /* return as an array [value1, value2, ...] */
|
301
308
|
} else {
|
@@ -433,6 +433,7 @@ callbacks_push(rb_mt_callbacks *callbacks, rb_mt_event *event)
|
|
433
433
|
callbacks->capa = new_capa;
|
434
434
|
callbacks->events = new_events;
|
435
435
|
}
|
436
|
+
event->loop_index = callbacks->count;
|
436
437
|
callbacks->events[callbacks->count] = event;
|
437
438
|
callbacks->count++;
|
438
439
|
}
|
@@ -457,6 +458,8 @@ callbacks_run(rb_mt_callbacks *callbacks)
|
|
457
458
|
for(i = 0; i < callbacks->count; i++) {
|
458
459
|
rb_mt_event *cb = callbacks->events[i];
|
459
460
|
if (cb) {
|
461
|
+
cb->loop_index = -1;
|
462
|
+
callbacks->events[i] = NULL;
|
460
463
|
cb->handler(cb->socket, cb->actual_flags, cb->cb_data);
|
461
464
|
}
|
462
465
|
}
|
@@ -725,7 +728,7 @@ lp_arg_alloc(lp_arg **args)
|
|
725
728
|
return Data_Make_Struct(rb_cObject, lp_arg, 0, lp_arg_free, *args);
|
726
729
|
}
|
727
730
|
|
728
|
-
#
|
731
|
+
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
729
732
|
static VALUE
|
730
733
|
loop_blocking_poll(void *argp)
|
731
734
|
{
|
@@ -768,7 +771,10 @@ retry:
|
|
768
771
|
args->ts = HRTIME_INFINITY;
|
769
772
|
}
|
770
773
|
|
771
|
-
|
774
|
+
|
775
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
776
|
+
rb_thread_call_without_gvl((void *(*)(void*))loop_blocking_poll, args, RUBY_UBF_IO, 0);
|
777
|
+
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
772
778
|
rb_thread_blocking_region(loop_blocking_poll, args, RUBY_UBF_PROCESS, NULL);
|
773
779
|
#else
|
774
780
|
if (rb_thread_alone()) {
|
data/ext/couchbase_ext/utils.c
CHANGED
@@ -235,6 +235,36 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
|
|
235
235
|
case LCB_EBADHANDLE:
|
236
236
|
klass = cb_eBadHandleError;
|
237
237
|
break;
|
238
|
+
case LCB_SERVER_BUG:
|
239
|
+
klass = cb_eServerBug;
|
240
|
+
break;
|
241
|
+
case LCB_PLUGIN_VERSION_MISMATCH:
|
242
|
+
klass = cb_ePluginVersionMismatch;
|
243
|
+
break;
|
244
|
+
case LCB_INVALID_HOST_FORMAT:
|
245
|
+
klass = cb_eInvalidHostFormat;
|
246
|
+
break;
|
247
|
+
case LCB_INVALID_CHAR:
|
248
|
+
klass = cb_eInvalidChar;
|
249
|
+
break;
|
250
|
+
case LCB_DURABILITY_ETOOMANY:
|
251
|
+
klass = cb_eDurabilityTooMany;
|
252
|
+
break;
|
253
|
+
case LCB_DUPLICATE_COMMANDS:
|
254
|
+
klass = cb_eDuplicateCommands;
|
255
|
+
break;
|
256
|
+
case LCB_NO_MATCHING_SERVER:
|
257
|
+
klass = cb_eBadEnvironment;
|
258
|
+
break;
|
259
|
+
case LCB_BAD_ENVIRONMENT:
|
260
|
+
klass = cb_eBadEnvironment;
|
261
|
+
break;
|
262
|
+
case LCB_BUSY:
|
263
|
+
klass = cb_eBusyError;
|
264
|
+
break;
|
265
|
+
case LCB_INVALID_USERNAME:
|
266
|
+
klass = cb_eInvalidUsername;
|
267
|
+
break;
|
238
268
|
case LCB_ERROR:
|
239
269
|
/* fall through */
|
240
270
|
default:
|
@@ -375,8 +405,8 @@ do_encode(VALUE *args)
|
|
375
405
|
if (RARRAY_LEN(ret) != 2) {
|
376
406
|
rb_raise(rb_eArgError, "#dump method of transcoder should return two items");
|
377
407
|
}
|
378
|
-
*flags = NUM2ULONG(
|
379
|
-
return
|
408
|
+
*flags = NUM2ULONG(rb_ary_entry(ret, 1));
|
409
|
+
return rb_ary_entry(ret, 0);
|
380
410
|
}
|
381
411
|
|
382
412
|
static VALUE
|
data/lib/couchbase.rb
CHANGED
@@ -77,7 +77,7 @@ module Couchbase
|
|
77
77
|
|
78
78
|
# @private the thread local storage
|
79
79
|
def thread_storage
|
80
|
-
Thread.current[:couchbase] ||= { :pid => Process.pid }
|
80
|
+
Thread.current[:couchbase] ||= { :pid => Process.pid, :bucket => {} }
|
81
81
|
end
|
82
82
|
|
83
83
|
# @private resets thread local storage if process ids don't match
|
@@ -100,10 +100,42 @@ module Couchbase
|
|
100
100
|
# @example
|
101
101
|
# Couchbase.bucket.set("foo", "bar")
|
102
102
|
#
|
103
|
+
# @example Set connection options using Hash
|
104
|
+
# Couchbase.connection_options = {:node_list => ["example.com:8091"]}
|
105
|
+
# Couchbase.bucket("slot1").set("foo", "bar")
|
106
|
+
# Couchbase.bucket("slot1").bucket #=> "default"
|
107
|
+
# Couchbase.connection_options[:bucket] = "test"
|
108
|
+
# Couchbase.bucket("slot2").bucket #=> "test"
|
109
|
+
#
|
110
|
+
# @example Set connection options using URI
|
111
|
+
# Couchbase.connection_options = "http://example.com:8091/pools"
|
112
|
+
# Couchbase.bucket("slot1").set("foo", "bar")
|
113
|
+
# Couchbase.bucket("slot1").bucket #=> "default"
|
114
|
+
# Couchbase.connection_options = "http://example.com:8091/pools/buckets/test"
|
115
|
+
# Couchbase.bucket("slot2").bucket #=> "test"
|
116
|
+
#
|
117
|
+
# @example Use named slots to keep a connection
|
118
|
+
# Couchbase.connection_options = {
|
119
|
+
# :node_list => ["example.com", "example.org"],
|
120
|
+
# :bucket => "users"
|
121
|
+
# }
|
122
|
+
# Couchbase.bucket("users").set("john", {"balance" => 0})
|
123
|
+
# Couchbase.connection_options[:bucket] = "orders"
|
124
|
+
# Couchbase.bucket("other").set("john:1", {"products" => [42, 66]})
|
125
|
+
#
|
103
126
|
# @return [Bucket]
|
104
|
-
def bucket
|
127
|
+
def bucket(name = nil)
|
105
128
|
verify_connection!
|
106
|
-
|
129
|
+
name ||= case @connection_options
|
130
|
+
when Hash
|
131
|
+
@connection_options[:bucket]
|
132
|
+
when String
|
133
|
+
path = URI.parse(@connection_options).path
|
134
|
+
path[%r(^(/pools/([A-Za-z0-9_.-]+)(/buckets/([A-Za-z0-9_.-]+))?)?), 3] || "default"
|
135
|
+
else
|
136
|
+
"default"
|
137
|
+
end
|
138
|
+
thread_storage[:bucket][name] ||= connect(connection_options)
|
107
139
|
end
|
108
140
|
|
109
141
|
# Set a connection instance for current thread
|
@@ -111,10 +143,12 @@ module Couchbase
|
|
111
143
|
# @since 1.1.0
|
112
144
|
#
|
113
145
|
# @return [Bucket]
|
114
|
-
def bucket=(connection)
|
146
|
+
def bucket=(connection, name = nil)
|
115
147
|
verify_connection!
|
116
|
-
|
148
|
+
name ||= @connection_options && @connection_options[:bucket] || "default"
|
149
|
+
thread_storage[:bucket][name] = connection
|
117
150
|
end
|
151
|
+
alias set_bucket bucket=
|
118
152
|
|
119
153
|
end
|
120
154
|
|
data/lib/couchbase/version.rb
CHANGED
data/tasks/compile.rake
CHANGED
@@ -22,6 +22,14 @@ def gemspec
|
|
22
22
|
@clean_gemspec ||= eval(File.read(File.expand_path('../../couchbase.gemspec', __FILE__)))
|
23
23
|
end
|
24
24
|
|
25
|
+
version_router = lambda do |t|
|
26
|
+
File.open(t.name, 'wb') do |f|
|
27
|
+
f.write <<-RUBY
|
28
|
+
require "couchbase/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/couchbase_ext"
|
29
|
+
RUBY
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
# Setup compile tasks. Configuration can be passed via ENV.
|
26
34
|
# Example:
|
27
35
|
# rake compile with_libcouchbase_include=/opt/couchbase/include
|
@@ -33,13 +41,14 @@ end
|
|
33
41
|
#
|
34
42
|
Rake::ExtensionTask.new("couchbase_ext", gemspec) do |ext|
|
35
43
|
ext.cross_compile = true
|
36
|
-
ext.cross_platform =
|
44
|
+
ext.cross_platform = ENV['HOST'] || "i386-mingw32"
|
37
45
|
if ENV['RUBY_CC_VERSION']
|
38
46
|
ext.lib_dir = "lib/couchbase"
|
39
47
|
end
|
40
48
|
ext.cross_compiling do |spec|
|
41
49
|
spec.files.delete("lib/couchbase/couchbase_ext.so")
|
42
50
|
spec.files.push("lib/couchbase_ext.rb", Dir["lib/couchbase/1.{8,9}/couchbase_ext.so"])
|
51
|
+
file "#{ext.tmp_dir}/#{ext.cross_platform}/stage/lib/couchbase_ext.rb", &version_router
|
43
52
|
end
|
44
53
|
|
45
54
|
CLEAN.include "#{ext.lib_dir}/*.#{RbConfig::CONFIG['DLEXT']}"
|
@@ -84,12 +93,14 @@ namespace :ports do
|
|
84
93
|
directory "ports"
|
85
94
|
|
86
95
|
task :libcouchbase => ["ports"] do
|
87
|
-
recipe = MiniPortile.new "libcouchbase", "2.
|
96
|
+
recipe = MiniPortile.new "libcouchbase", "2.1.3"
|
88
97
|
recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
|
98
|
+
|
89
99
|
recipe.configure_options.push("--disable-debug",
|
90
100
|
"--disable-dependency-tracking",
|
91
101
|
"--disable-couchbasemock",
|
92
102
|
"--disable-cxx",
|
103
|
+
"--disable-plugins",
|
93
104
|
"--disable-examples",
|
94
105
|
"--disable-tools")
|
95
106
|
recipe.cook
|
@@ -97,19 +108,13 @@ namespace :ports do
|
|
97
108
|
end
|
98
109
|
end
|
99
110
|
|
100
|
-
file "lib/couchbase_ext.rb"
|
101
|
-
File.open("lib/couchbase_ext.rb", 'wb') do |f|
|
102
|
-
f.write <<-RUBY
|
103
|
-
require "couchbase/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/couchbase_ext"
|
104
|
-
RUBY
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
111
|
+
file "lib/couchbase_ext.rb", &version_router
|
108
112
|
task :cross => ["lib/couchbase_ext.rb", "ports:libcouchbase"]
|
109
113
|
|
110
114
|
desc "Package gem for windows"
|
111
115
|
task "package:windows" => :package do
|
112
116
|
sh("env RUBY_CC_VERSION=1.8.7 RBENV_VERSION=1.8.7-p370 rbenv exec bundle exec rake cross compile")
|
113
117
|
sh("env RUBY_CC_VERSION=1.9.2 RBENV_VERSION=1.9.2-p320 rbenv exec bundle exec rake cross compile")
|
114
|
-
sh("env RUBY_CC_VERSION=
|
118
|
+
sh("env RUBY_CC_VERSION=2.0.0 RBENV_VERSION=2.0.0-p247 rbenv exec bundle exec rake cross compile")
|
119
|
+
sh("env RUBY_CC_VERSION=1.8.7:1.9.2:2.0.0 RBENV_VERSION=1.9.2-p320 rbenv exec bundle exec rake cross native gem")
|
115
120
|
end
|
data/test/test_bucket.rb
CHANGED
@@ -119,6 +119,12 @@ class TestBucket < MiniTest::Test
|
|
119
119
|
def test_it_raises_error_with_wrong_credentials
|
120
120
|
with_mock do |mock|
|
121
121
|
assert_raises Couchbase::Error::Auth do
|
122
|
+
Couchbase.new(:hostname => mock.host,
|
123
|
+
:port => mock.port,
|
124
|
+
:bucket => 'default',
|
125
|
+
:password => 'wrong_password')
|
126
|
+
end
|
127
|
+
assert_raises Couchbase::Error::InvalidUsername do
|
122
128
|
Couchbase.new(:hostname => mock.host,
|
123
129
|
:port => mock.port,
|
124
130
|
:bucket => 'default',
|
@@ -130,7 +136,7 @@ class TestBucket < MiniTest::Test
|
|
130
136
|
|
131
137
|
def test_it_unable_to_connect_to_protected_buckets_with_wrong_credentials
|
132
138
|
with_mock(:buckets_spec => 'protected:secret') do |mock|
|
133
|
-
assert_raises Couchbase::Error::
|
139
|
+
assert_raises Couchbase::Error::InvalidUsername do
|
134
140
|
Couchbase.new(:hostname => mock.host,
|
135
141
|
:port => mock.port,
|
136
142
|
:bucket => 'protected',
|
@@ -234,4 +240,11 @@ class TestBucket < MiniTest::Test
|
|
234
240
|
end
|
235
241
|
end
|
236
242
|
|
243
|
+
def test_it_doesnt_try_to_destroy_handle_in_case_of_lcb_create_failure
|
244
|
+
assert_raises(Couchbase::Error::InvalidHostFormat) do
|
245
|
+
Couchbase.connect(:hostname => "foobar:baz")
|
246
|
+
end
|
247
|
+
GC.start # make sure it won't touch handle in finalizer
|
248
|
+
end
|
249
|
+
|
237
250
|
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
5
|
-
prerelease:
|
4
|
+
version: 1.3.3
|
6
5
|
platform: x86-mingw32
|
7
6
|
authors:
|
8
7
|
- Couchbase
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-09-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: yaji
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: multi_json
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: connection_pool
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rake
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ! '>='
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ! '>='
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: minitest
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ~>
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ~>
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,7 +83,6 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rake-compiler
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ! '>='
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ! '>='
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,7 +97,6 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: mini_portile
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ! '>='
|
116
102
|
- !ruby/object:Gem::Version
|
@@ -118,7 +104,6 @@ dependencies:
|
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ! '>='
|
124
109
|
- !ruby/object:Gem::Version
|
@@ -126,7 +111,6 @@ dependencies:
|
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: yajl-ruby
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ~>
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ~>
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,7 +125,6 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: active_support
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ! '>='
|
148
130
|
- !ruby/object:Gem::Version
|
@@ -150,7 +132,6 @@ dependencies:
|
|
150
132
|
type: :development
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ! '>='
|
156
137
|
- !ruby/object:Gem::Version
|
@@ -158,7 +139,6 @@ dependencies:
|
|
158
139
|
- !ruby/object:Gem::Dependency
|
159
140
|
name: eventmachine
|
160
141
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
142
|
requirements:
|
163
143
|
- - ! '>='
|
164
144
|
- !ruby/object:Gem::Version
|
@@ -166,7 +146,6 @@ dependencies:
|
|
166
146
|
type: :development
|
167
147
|
prerelease: false
|
168
148
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
149
|
requirements:
|
171
150
|
- - ! '>='
|
172
151
|
- !ruby/object:Gem::Version
|
@@ -269,36 +248,30 @@ files:
|
|
269
248
|
- test/test_version.rb
|
270
249
|
- lib/couchbase/1.8/couchbase_ext.so
|
271
250
|
- lib/couchbase/1.9/couchbase_ext.so
|
251
|
+
- lib/couchbase/2.0/couchbase_ext.so
|
272
252
|
- lib/couchbase_ext.rb
|
273
253
|
homepage: http://couchbase.org
|
274
254
|
licenses:
|
275
255
|
- ASL-2
|
256
|
+
metadata: {}
|
276
257
|
post_install_message:
|
277
258
|
rdoc_options: []
|
278
259
|
require_paths:
|
279
260
|
- lib
|
280
261
|
required_ruby_version: !ruby/object:Gem::Requirement
|
281
|
-
none: false
|
282
262
|
requirements:
|
283
263
|
- - ! '>='
|
284
264
|
- !ruby/object:Gem::Version
|
285
265
|
version: '0'
|
286
|
-
segments:
|
287
|
-
- 0
|
288
|
-
hash: 786073145375983008
|
289
266
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
290
|
-
none: false
|
291
267
|
requirements:
|
292
268
|
- - ! '>='
|
293
269
|
- !ruby/object:Gem::Version
|
294
270
|
version: '0'
|
295
|
-
segments:
|
296
|
-
- 0
|
297
|
-
hash: 786073145375983008
|
298
271
|
requirements: []
|
299
272
|
rubyforge_project:
|
300
|
-
rubygems_version:
|
273
|
+
rubygems_version: 2.0.7
|
301
274
|
signing_key:
|
302
|
-
specification_version:
|
275
|
+
specification_version: 4
|
303
276
|
summary: Couchbase ruby driver
|
304
277
|
test_files: []
|