couchbase 1.2.0.z.beta5 → 1.2.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.
- data/RELEASE_NOTES.markdown +513 -0
- data/couchbase.gemspec +0 -1
- data/ext/couchbase_ext/arguments.c +50 -147
- data/ext/couchbase_ext/arithmetic.c +6 -17
- data/ext/couchbase_ext/bucket.c +97 -111
- data/ext/couchbase_ext/couchbase_ext.c +10 -0
- data/ext/couchbase_ext/couchbase_ext.h +20 -9
- data/ext/couchbase_ext/delete.c +6 -8
- data/ext/couchbase_ext/extconf.rb +6 -0
- data/ext/couchbase_ext/get.c +7 -9
- data/ext/couchbase_ext/http.c +20 -19
- data/ext/couchbase_ext/multithread_plugin.c +1201 -0
- data/ext/couchbase_ext/observe.c +10 -10
- data/ext/couchbase_ext/stats.c +6 -8
- data/ext/couchbase_ext/store.c +8 -10
- data/ext/couchbase_ext/timer.c +1 -1
- data/ext/couchbase_ext/touch.c +6 -8
- data/ext/couchbase_ext/unlock.c +6 -8
- data/ext/couchbase_ext/utils.c +75 -5
- data/ext/couchbase_ext/version.c +6 -8
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase/view.rb +6 -2
- data/lib/ext/multi_json_fix.rb +3 -0
- data/lib/rack/session/couchbase.rb +8 -5
- data/tasks/compile.rake +1 -1
- data/tasks/test.rake +0 -1
- data/tasks/util.rake +1 -1
- data/test/setup.rb +5 -2
- data/test/test_async.rb +2 -2
- metadata +11 -29
- data/HISTORY.markdown +0 -268
data/couchbase.gemspec
CHANGED
@@ -46,6 +46,5 @@ Gem::Specification.new do |s|
|
|
46
46
|
s.add_development_dependency 'yard-xml'
|
47
47
|
s.add_development_dependency 'mini_portile'
|
48
48
|
s.add_development_dependency 'yajl-ruby', '~> 1.1.0'
|
49
|
-
s.add_development_dependency RUBY_VERSION =~ /^1\.9/ ? 'debugger' : 'ruby-debug'
|
50
49
|
s.add_development_dependency 'active_support'
|
51
50
|
end
|
@@ -19,23 +19,37 @@
|
|
19
19
|
|
20
20
|
/* TOUCH */
|
21
21
|
|
22
|
+
#define _alloc_data_for_s(type, _type, size, items, ptr) do {\
|
23
|
+
lcb_size_t ii; \
|
24
|
+
\
|
25
|
+
params->cmd.type.num = size; \
|
26
|
+
params->cmd.type.items = calloc(size, sizeof(_type)); \
|
27
|
+
if (params->cmd.type.items == NULL) { \
|
28
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments"); \
|
29
|
+
} \
|
30
|
+
params->cmd.type.ptr = calloc(size, sizeof(_type *)); \
|
31
|
+
if (params->cmd.type.ptr == NULL) { \
|
32
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments"); \
|
33
|
+
} \
|
34
|
+
for (ii = 0; ii < size; ++ii) { \
|
35
|
+
params->cmd.type.ptr[ii] = params->cmd.type.items + ii; \
|
36
|
+
} \
|
37
|
+
} while(0)
|
38
|
+
|
39
|
+
#define _alloc_data_for(type, _type) _alloc_data_for_s(type, _type, size, items, ptr)
|
40
|
+
|
41
|
+
|
42
|
+
#define _release_data_for_s(type, items, ptr) \
|
43
|
+
free(params->cmd.type.items); \
|
44
|
+
free(params->cmd.type.ptr);
|
45
|
+
|
46
|
+
#define _release_data_for(type) _release_data_for_s(type, items, ptr)
|
47
|
+
|
48
|
+
|
22
49
|
static void
|
23
50
|
cb_params_touch_alloc(struct cb_params_st *params, lcb_size_t size)
|
24
51
|
{
|
25
|
-
|
26
|
-
|
27
|
-
params->cmd.touch.num = size;
|
28
|
-
params->cmd.touch.items = xcalloc(size, sizeof(lcb_touch_cmd_t));
|
29
|
-
if (params->cmd.touch.items == NULL) {
|
30
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
31
|
-
}
|
32
|
-
params->cmd.touch.ptr = xcalloc(size, sizeof(lcb_touch_cmd_t *));
|
33
|
-
if (params->cmd.touch.ptr == NULL) {
|
34
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
35
|
-
}
|
36
|
-
for (ii = 0; ii < size; ++ii) {
|
37
|
-
params->cmd.touch.ptr[ii] = params->cmd.touch.items + ii;
|
38
|
-
}
|
52
|
+
_alloc_data_for(touch, lcb_touch_cmd_t);
|
39
53
|
}
|
40
54
|
|
41
55
|
static void
|
@@ -68,8 +82,9 @@ cb_params_touch_parse_options(struct cb_params_st *params, VALUE options)
|
|
68
82
|
if (tmp != Qnil) {
|
69
83
|
params->cmd.touch.ttl = NUM2ULONG(tmp);
|
70
84
|
}
|
71
|
-
|
72
|
-
|
85
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
86
|
+
if (tmp != Qundef) {
|
87
|
+
params->cmd.touch.quiet = RTEST(tmp);
|
73
88
|
}
|
74
89
|
}
|
75
90
|
|
@@ -118,20 +133,7 @@ cb_params_touch_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
118
133
|
static void
|
119
134
|
cb_params_remove_alloc(struct cb_params_st *params, lcb_size_t size)
|
120
135
|
{
|
121
|
-
|
122
|
-
|
123
|
-
params->cmd.remove.num = size;
|
124
|
-
params->cmd.remove.items = xcalloc(size, sizeof(lcb_remove_cmd_t));
|
125
|
-
if (params->cmd.remove.items == NULL) {
|
126
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
127
|
-
}
|
128
|
-
params->cmd.remove.ptr = xcalloc(size, sizeof(lcb_remove_cmd_t *));
|
129
|
-
if (params->cmd.remove.ptr == NULL) {
|
130
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
131
|
-
}
|
132
|
-
for (ii = 0; ii < size; ++ii) {
|
133
|
-
params->cmd.remove.ptr[ii] = params->cmd.remove.items + ii;
|
134
|
-
}
|
136
|
+
_alloc_data_for(remove, lcb_remove_cmd_t);
|
135
137
|
}
|
136
138
|
|
137
139
|
static void
|
@@ -160,8 +162,9 @@ cb_params_remove_parse_options(struct cb_params_st *params, VALUE options)
|
|
160
162
|
if (NIL_P(options)) {
|
161
163
|
return;
|
162
164
|
}
|
163
|
-
|
164
|
-
|
165
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
166
|
+
if (tmp != Qundef) {
|
167
|
+
params->cmd.remove.quiet = RTEST(tmp);
|
165
168
|
}
|
166
169
|
tmp = rb_hash_aref(options, cb_sym_cas);
|
167
170
|
if (tmp != Qnil) {
|
@@ -213,20 +216,7 @@ cb_params_remove_parse_arguments(struct cb_params_st *params, int argc, VALUE ar
|
|
213
216
|
static void
|
214
217
|
cb_params_store_alloc(struct cb_params_st *params, lcb_size_t size)
|
215
218
|
{
|
216
|
-
|
217
|
-
|
218
|
-
params->cmd.store.num = size;
|
219
|
-
params->cmd.store.items = xcalloc(size, sizeof(lcb_store_cmd_t));
|
220
|
-
if (params->cmd.store.items == NULL) {
|
221
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
222
|
-
}
|
223
|
-
params->cmd.store.ptr = xcalloc(size, sizeof(lcb_store_cmd_t *));
|
224
|
-
if (params->cmd.store.ptr == NULL) {
|
225
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
226
|
-
}
|
227
|
-
for (ii = 0; ii < size; ++ii) {
|
228
|
-
params->cmd.store.ptr[ii] = params->cmd.store.items + ii;
|
229
|
-
}
|
219
|
+
_alloc_data_for(store, lcb_store_cmd_t);
|
230
220
|
}
|
231
221
|
|
232
222
|
static void
|
@@ -345,33 +335,10 @@ cb_params_store_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
345
335
|
static void
|
346
336
|
cb_params_get_alloc(struct cb_params_st *params, lcb_size_t size)
|
347
337
|
{
|
348
|
-
lcb_size_t ii;
|
349
|
-
|
350
|
-
params->cmd.get.num = size;
|
351
338
|
if (params->cmd.get.replica) {
|
352
|
-
|
353
|
-
if (params->cmd.get.items_gr == NULL) {
|
354
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
355
|
-
}
|
356
|
-
params->cmd.get.ptr = xcalloc(size, sizeof(lcb_get_replica_cmd_t *));
|
357
|
-
if (params->cmd.get.ptr_gr == NULL) {
|
358
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
359
|
-
}
|
360
|
-
for (ii = 0; ii < size; ++ii) {
|
361
|
-
params->cmd.get.ptr_gr[ii] = params->cmd.get.items_gr + ii;
|
362
|
-
}
|
339
|
+
_alloc_data_for_s(get, lcb_get_replica_cmd_t, size, items_gr, ptr_gr);
|
363
340
|
} else {
|
364
|
-
|
365
|
-
if (params->cmd.get.items == NULL) {
|
366
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
367
|
-
}
|
368
|
-
params->cmd.get.ptr = xcalloc(size, sizeof(lcb_get_cmd_t *));
|
369
|
-
if (params->cmd.get.ptr == NULL) {
|
370
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
371
|
-
}
|
372
|
-
for (ii = 0; ii < size; ++ii) {
|
373
|
-
params->cmd.get.ptr[ii] = params->cmd.get.items + ii;
|
374
|
-
}
|
341
|
+
_alloc_data_for(get, lcb_get_cmd_t);
|
375
342
|
}
|
376
343
|
}
|
377
344
|
|
@@ -413,8 +380,9 @@ cb_params_get_parse_options(struct cb_params_st *params, VALUE options)
|
|
413
380
|
params->cmd.get.replica = RTEST(rb_hash_aref(options, cb_sym_replica));
|
414
381
|
params->cmd.get.extended = RTEST(rb_hash_aref(options, cb_sym_extended));
|
415
382
|
params->cmd.get.assemble_hash = RTEST(rb_hash_aref(options, cb_sym_assemble_hash));
|
416
|
-
|
417
|
-
|
383
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
384
|
+
if (tmp != Qundef) {
|
385
|
+
params->cmd.get.quiet = RTEST(tmp);
|
418
386
|
}
|
419
387
|
tmp = rb_hash_aref(options, cb_sym_format);
|
420
388
|
if (tmp != Qnil) {
|
@@ -485,20 +453,7 @@ cb_params_get_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
|
485
453
|
static void
|
486
454
|
cb_params_arith_alloc(struct cb_params_st *params, lcb_size_t size)
|
487
455
|
{
|
488
|
-
|
489
|
-
|
490
|
-
params->cmd.arith.num = size;
|
491
|
-
params->cmd.arith.items = xcalloc(size, sizeof(lcb_arithmetic_cmd_t));
|
492
|
-
if (params->cmd.arith.items == NULL) {
|
493
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
494
|
-
}
|
495
|
-
params->cmd.arith.ptr = xcalloc(size, sizeof(lcb_arithmetic_cmd_t *));
|
496
|
-
if (params->cmd.arith.ptr == NULL) {
|
497
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
498
|
-
}
|
499
|
-
for (ii = 0; ii < size; ++ii) {
|
500
|
-
params->cmd.arith.ptr[ii] = params->cmd.arith.items + ii;
|
501
|
-
}
|
456
|
+
_alloc_data_for(arith, lcb_arithmetic_cmd_t);
|
502
457
|
}
|
503
458
|
|
504
459
|
static void
|
@@ -602,20 +557,7 @@ cb_params_arith_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
602
557
|
static void
|
603
558
|
cb_params_stats_alloc(struct cb_params_st *params, lcb_size_t size)
|
604
559
|
{
|
605
|
-
|
606
|
-
|
607
|
-
params->cmd.stats.num = size;
|
608
|
-
params->cmd.stats.items = xcalloc(size, sizeof(lcb_server_stats_cmd_t));
|
609
|
-
if (params->cmd.stats.items == NULL) {
|
610
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
611
|
-
}
|
612
|
-
params->cmd.stats.ptr = xcalloc(size, sizeof(lcb_server_stats_cmd_t *));
|
613
|
-
if (params->cmd.stats.ptr == NULL) {
|
614
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
615
|
-
}
|
616
|
-
for (ii = 0; ii < size; ++ii) {
|
617
|
-
params->cmd.stats.ptr[ii] = params->cmd.stats.items + ii;
|
618
|
-
}
|
560
|
+
_alloc_data_for(stats, lcb_server_stats_cmd_t);
|
619
561
|
}
|
620
562
|
|
621
563
|
static void
|
@@ -667,20 +609,7 @@ cb_params_stats_parse_arguments(struct cb_params_st *params, int argc, VALUE arg
|
|
667
609
|
static void
|
668
610
|
cb_params_observe_alloc(struct cb_params_st *params, lcb_size_t size)
|
669
611
|
{
|
670
|
-
|
671
|
-
|
672
|
-
params->cmd.observe.num = size;
|
673
|
-
params->cmd.observe.items = xcalloc(size, sizeof(lcb_observe_cmd_t));
|
674
|
-
if (params->cmd.observe.items == NULL) {
|
675
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
676
|
-
}
|
677
|
-
params->cmd.observe.ptr = xcalloc(size, sizeof(lcb_observe_cmd_t *));
|
678
|
-
if (params->cmd.observe.ptr == NULL) {
|
679
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
680
|
-
}
|
681
|
-
for (ii = 0; ii < size; ++ii) {
|
682
|
-
params->cmd.observe.ptr[ii] = params->cmd.observe.items + ii;
|
683
|
-
}
|
612
|
+
_alloc_data_for(observe, lcb_observe_cmd_t);
|
684
613
|
}
|
685
614
|
|
686
615
|
static void
|
@@ -730,20 +659,7 @@ cb_params_observe_parse_arguments(struct cb_params_st *params, int argc, VALUE a
|
|
730
659
|
static void
|
731
660
|
cb_params_unlock_alloc(struct cb_params_st *params, lcb_size_t size)
|
732
661
|
{
|
733
|
-
|
734
|
-
|
735
|
-
params->cmd.unlock.num = size;
|
736
|
-
params->cmd.unlock.items = xcalloc(size, sizeof(lcb_unlock_cmd_t));
|
737
|
-
if (params->cmd.unlock.items == NULL) {
|
738
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
739
|
-
}
|
740
|
-
params->cmd.unlock.ptr = xcalloc(size, sizeof(lcb_unlock_cmd_t *));
|
741
|
-
if (params->cmd.unlock.ptr == NULL) {
|
742
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
743
|
-
}
|
744
|
-
for (ii = 0; ii < size; ++ii) {
|
745
|
-
params->cmd.unlock.ptr[ii] = params->cmd.unlock.items + ii;
|
746
|
-
}
|
662
|
+
_alloc_data_for(unlock, lcb_unlock_cmd_t);
|
747
663
|
}
|
748
664
|
|
749
665
|
static void
|
@@ -776,8 +692,9 @@ cb_params_unlock_parse_options(struct cb_params_st *params, VALUE options)
|
|
776
692
|
if (tmp != Qnil) {
|
777
693
|
params->cmd.unlock.cas = NUM2ULL(tmp);
|
778
694
|
}
|
779
|
-
|
780
|
-
|
695
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
696
|
+
if (tmp != Qundef) {
|
697
|
+
params->cmd.unlock.quiet = RTEST(tmp);
|
781
698
|
}
|
782
699
|
}
|
783
700
|
|
@@ -808,15 +725,7 @@ cb_params_unlock_parse_arguments(struct cb_params_st *params, int argc, VALUE ar
|
|
808
725
|
cb_params_version_alloc(struct cb_params_st *params)
|
809
726
|
{
|
810
727
|
params->cmd.version.num = 1;
|
811
|
-
|
812
|
-
if (params->cmd.version.items == NULL) {
|
813
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
814
|
-
}
|
815
|
-
params->cmd.version.ptr = xcalloc(1, sizeof(lcb_server_version_cmd_t *));
|
816
|
-
if (params->cmd.version.ptr == NULL) {
|
817
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments");
|
818
|
-
}
|
819
|
-
params->cmd.version.ptr[0] = params->cmd.version.items;
|
728
|
+
_alloc_data_for_s(version, lcb_server_version_cmd_t, 1, items, ptr);
|
820
729
|
}
|
821
730
|
|
822
731
|
|
@@ -824,15 +733,10 @@ cb_params_version_alloc(struct cb_params_st *params)
|
|
824
733
|
void
|
825
734
|
cb_params_destroy(struct cb_params_st *params)
|
826
735
|
{
|
827
|
-
#define _release_data_for(type) \
|
828
|
-
xfree(params->cmd.type.items); \
|
829
|
-
xfree(params->cmd.type.ptr);
|
830
|
-
|
831
736
|
switch (params->type) {
|
832
737
|
case cb_cmd_get:
|
833
738
|
_release_data_for(get);
|
834
|
-
|
835
|
-
xfree(params->cmd.get.ptr_gr);
|
739
|
+
_release_data_for_s(get, items_gr, ptr_gr);
|
836
740
|
break;
|
837
741
|
case cb_cmd_touch:
|
838
742
|
_release_data_for(touch);
|
@@ -859,7 +763,6 @@ cb_params_destroy(struct cb_params_st *params)
|
|
859
763
|
_release_data_for(unlock);
|
860
764
|
break;
|
861
765
|
}
|
862
|
-
#undef _release_data_for
|
863
766
|
}
|
864
767
|
|
865
768
|
struct build_params_st
|
@@ -35,18 +35,7 @@ cb_arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, cons
|
|
35
35
|
if (exc != Qnil) {
|
36
36
|
rb_ivar_set(exc, cb_id_iv_cas, cas);
|
37
37
|
rb_ivar_set(exc, cb_id_iv_operation, o);
|
38
|
-
|
39
|
-
if (bucket->on_error_proc != Qnil) {
|
40
|
-
cb_proc_call(bucket->on_error_proc, 3, o, key, exc);
|
41
|
-
} else {
|
42
|
-
if (NIL_P(bucket->exception)) {
|
43
|
-
bucket->exception = exc;
|
44
|
-
}
|
45
|
-
}
|
46
|
-
}
|
47
|
-
if (NIL_P(ctx->exception)) {
|
48
|
-
ctx->exception = cb_gc_protect(bucket, exc);
|
49
|
-
}
|
38
|
+
ctx->exception = cb_gc_protect(bucket, exc);
|
50
39
|
}
|
51
40
|
val = ULL2NUM(resp->v.v0.value);
|
52
41
|
if (bucket->async) { /* asynchronous */
|
@@ -57,7 +46,7 @@ cb_arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, cons
|
|
57
46
|
rb_ivar_set(res, cb_id_iv_key, key);
|
58
47
|
rb_ivar_set(res, cb_id_iv_value, val);
|
59
48
|
rb_ivar_set(res, cb_id_iv_cas, cas);
|
60
|
-
cb_proc_call(ctx->proc, 1, res);
|
49
|
+
cb_proc_call(bucket, ctx->proc, 1, res);
|
61
50
|
}
|
62
51
|
} else { /* synchronous */
|
63
52
|
if (NIL_P(exc)) {
|
@@ -71,7 +60,7 @@ cb_arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, cons
|
|
71
60
|
if (ctx->nqueries == 0) {
|
72
61
|
cb_gc_unprotect(bucket, ctx->proc);
|
73
62
|
if (bucket->async) {
|
74
|
-
|
63
|
+
free(ctx);
|
75
64
|
}
|
76
65
|
}
|
77
66
|
(void)handle;
|
@@ -98,7 +87,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
98
87
|
params.bucket = bucket;
|
99
88
|
params.cmd.arith.sign = sign;
|
100
89
|
cb_params_build(¶ms, RARRAY_LEN(args), args);
|
101
|
-
ctx =
|
90
|
+
ctx = calloc(1, sizeof(struct cb_context_st));
|
102
91
|
if (ctx == NULL) {
|
103
92
|
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
|
104
93
|
}
|
@@ -113,7 +102,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
113
102
|
cb_params_destroy(¶ms);
|
114
103
|
exc = cb_check_error(err, "failed to schedule arithmetic request", Qnil);
|
115
104
|
if (exc != Qnil) {
|
116
|
-
|
105
|
+
free(ctx);
|
117
106
|
rb_exc_raise(exc);
|
118
107
|
}
|
119
108
|
bucket->nbytes += params.npayload;
|
@@ -126,7 +115,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
126
115
|
lcb_wait(bucket->handle);
|
127
116
|
}
|
128
117
|
exc = ctx->exception;
|
129
|
-
|
118
|
+
free(ctx);
|
130
119
|
if (exc != Qnil) {
|
131
120
|
cb_gc_unprotect(bucket, exc);
|
132
121
|
rb_exc_raise(exc);
|
data/ext/couchbase_ext/bucket.c
CHANGED
@@ -36,15 +36,8 @@ cb_bucket_free(void *ptr)
|
|
36
36
|
lcb_destroy(bucket->handle);
|
37
37
|
lcb_destroy_io_ops(bucket->io);
|
38
38
|
}
|
39
|
-
xfree(bucket->authority);
|
40
|
-
xfree(bucket->hostname);
|
41
|
-
xfree(bucket->pool);
|
42
|
-
xfree(bucket->bucket);
|
43
|
-
xfree(bucket->username);
|
44
|
-
xfree(bucket->password);
|
45
|
-
xfree(bucket->key_prefix);
|
46
|
-
xfree(bucket);
|
47
39
|
}
|
40
|
+
xfree(bucket);
|
48
41
|
}
|
49
42
|
|
50
43
|
void
|
@@ -53,6 +46,12 @@ cb_bucket_mark(void *ptr)
|
|
53
46
|
struct cb_bucket_st *bucket = ptr;
|
54
47
|
|
55
48
|
if (bucket) {
|
49
|
+
rb_gc_mark(bucket->authority);
|
50
|
+
rb_gc_mark(bucket->hostname);
|
51
|
+
rb_gc_mark(bucket->pool);
|
52
|
+
rb_gc_mark(bucket->bucket);
|
53
|
+
rb_gc_mark(bucket->username);
|
54
|
+
rb_gc_mark(bucket->password);
|
56
55
|
rb_gc_mark(bucket->exception);
|
57
56
|
rb_gc_mark(bucket->on_error_proc);
|
58
57
|
rb_gc_mark(bucket->key_prefix_val);
|
@@ -64,7 +63,7 @@ cb_bucket_mark(void *ptr)
|
|
64
63
|
do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
65
64
|
{
|
66
65
|
VALUE uri, opts, arg;
|
67
|
-
|
66
|
+
char port_s[8];
|
68
67
|
|
69
68
|
if (rb_scan_args(argc, argv, "02", &uri, &opts) > 0) {
|
70
69
|
if (TYPE(uri) == T_HASH && argc == 1) {
|
@@ -85,28 +84,16 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
85
84
|
|
86
85
|
arg = rb_funcall(uri_obj, cb_id_user, 0);
|
87
86
|
if (arg != Qnil) {
|
88
|
-
|
89
|
-
bucket->username = strdup(RSTRING_PTR(arg));
|
90
|
-
if (bucket->username == NULL) {
|
91
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for Bucket");
|
92
|
-
}
|
87
|
+
bucket->username = rb_str_dup_frozen(StringValue(arg));
|
93
88
|
}
|
94
89
|
|
95
90
|
arg = rb_funcall(uri_obj, cb_id_password, 0);
|
96
91
|
if (arg != Qnil) {
|
97
|
-
|
98
|
-
bucket->password = strdup(RSTRING_PTR(arg));
|
99
|
-
if (bucket->password == NULL) {
|
100
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for Bucket");
|
101
|
-
}
|
92
|
+
bucket->password = rb_str_dup_frozen(StringValue(arg));
|
102
93
|
}
|
103
94
|
arg = rb_funcall(uri_obj, cb_id_host, 0);
|
104
95
|
if (arg != Qnil) {
|
105
|
-
|
106
|
-
bucket->hostname = strdup(RSTRING_PTR(arg));
|
107
|
-
if (bucket->hostname == NULL) {
|
108
|
-
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for Bucket");
|
109
|
-
}
|
96
|
+
bucket->hostname = rb_str_dup_frozen(StringValue(arg));
|
110
97
|
} else {
|
111
98
|
rb_raise(rb_eArgError, "invalid URI: missing hostname");
|
112
99
|
}
|
@@ -118,11 +105,11 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
118
105
|
re = rb_reg_new(path_re, sizeof(path_re) - 1, 0);
|
119
106
|
match = rb_funcall(re, cb_id_match, 1, arg);
|
120
107
|
arg = rb_reg_nth_match(2, match);
|
121
|
-
|
122
|
-
bucket->pool
|
108
|
+
bucket->pool = NIL_P(arg) ? cb_vStrDefault : rb_str_dup_frozen(StringValue(arg));
|
109
|
+
rb_str_freeze(bucket->pool);
|
123
110
|
arg = rb_reg_nth_match(4, match);
|
124
|
-
|
125
|
-
bucket->bucket
|
111
|
+
bucket->bucket = NIL_P(arg) ? cb_vStrDefault : rb_str_dup_frozen(StringValue(arg));
|
112
|
+
rb_str_freeze(bucket->bucket);
|
126
113
|
}
|
127
114
|
if (TYPE(opts) == T_HASH) {
|
128
115
|
arg = rb_hash_aref(opts, cb_sym_type);
|
@@ -135,43 +122,37 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
135
122
|
}
|
136
123
|
arg = rb_hash_aref(opts, cb_sym_node_list);
|
137
124
|
if (arg != Qnil) {
|
138
|
-
VALUE tt;
|
139
|
-
xfree(bucket->node_list);
|
140
125
|
Check_Type(arg, T_ARRAY);
|
141
|
-
|
142
|
-
bucket->node_list
|
126
|
+
bucket->node_list = rb_ary_join(arg, STR_NEW_CSTR(";"));
|
127
|
+
rb_str_freeze(bucket->node_list);
|
143
128
|
}
|
144
129
|
arg = rb_hash_aref(opts, cb_sym_hostname);
|
145
130
|
if (arg != Qnil) {
|
146
|
-
|
147
|
-
bucket->hostname = strdup(StringValueCStr(arg));
|
131
|
+
bucket->hostname = rb_str_dup_frozen(StringValue(arg));
|
148
132
|
}
|
149
133
|
arg = rb_hash_aref(opts, cb_sym_pool);
|
150
134
|
if (arg != Qnil) {
|
151
|
-
|
152
|
-
bucket->pool = strdup(StringValueCStr(arg));
|
135
|
+
bucket->pool = rb_str_dup_frozen(StringValue(arg));
|
153
136
|
}
|
154
137
|
arg = rb_hash_aref(opts, cb_sym_bucket);
|
155
138
|
if (arg != Qnil) {
|
156
|
-
|
157
|
-
bucket->bucket = strdup(StringValueCStr(arg));
|
139
|
+
bucket->bucket = rb_str_dup_frozen(StringValue(arg));
|
158
140
|
}
|
159
141
|
arg = rb_hash_aref(opts, cb_sym_username);
|
160
142
|
if (arg != Qnil) {
|
161
|
-
|
162
|
-
bucket->username = strdup(StringValueCStr(arg));
|
143
|
+
bucket->username = rb_str_dup_frozen(StringValue(arg));
|
163
144
|
}
|
164
145
|
arg = rb_hash_aref(opts, cb_sym_password);
|
165
146
|
if (arg != Qnil) {
|
166
|
-
|
167
|
-
bucket->password = strdup(StringValueCStr(arg));
|
147
|
+
bucket->password = rb_str_dup_frozen(StringValue(arg));
|
168
148
|
}
|
169
149
|
arg = rb_hash_aref(opts, cb_sym_port);
|
170
150
|
if (arg != Qnil) {
|
171
151
|
bucket->port = (uint16_t)NUM2UINT(arg);
|
172
152
|
}
|
173
|
-
|
174
|
-
|
153
|
+
arg = rb_hash_lookup2(opts, cb_sym_quiet, Qundef);
|
154
|
+
if (arg != Qundef) {
|
155
|
+
bucket->quiet = RTEST(arg);
|
175
156
|
}
|
176
157
|
arg = rb_hash_aref(opts, cb_sym_timeout);
|
177
158
|
if (arg != Qnil) {
|
@@ -217,9 +198,7 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
217
198
|
}
|
218
199
|
arg = rb_hash_aref(opts, cb_sym_key_prefix);
|
219
200
|
if (arg != Qnil) {
|
220
|
-
|
221
|
-
bucket->key_prefix = strdup(StringValueCStr(arg));
|
222
|
-
bucket->key_prefix_val = STR_NEW_CSTR(bucket->key_prefix);
|
201
|
+
bucket->key_prefix_val = rb_str_dup_frozen(StringValue(arg));
|
223
202
|
}
|
224
203
|
arg = rb_hash_aref(opts, cb_sym_default_arithmetic_init);
|
225
204
|
if (arg != Qnil) {
|
@@ -232,19 +211,16 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
232
211
|
opts = Qnil;
|
233
212
|
}
|
234
213
|
}
|
235
|
-
if (bucket->password && bucket->username
|
236
|
-
bucket->username =
|
214
|
+
if (RTEST(bucket->password) && !RTEST(bucket->username)) {
|
215
|
+
bucket->username = bucket->bucket;
|
237
216
|
}
|
238
|
-
len = strlen(bucket->hostname) + 10;
|
239
217
|
if (bucket->default_observe_timeout < 2) {
|
240
218
|
rb_raise(rb_eArgError, "default_observe_timeout is too low");
|
241
219
|
}
|
242
|
-
|
243
|
-
bucket->authority =
|
244
|
-
|
245
|
-
|
246
|
-
}
|
247
|
-
snprintf(bucket->authority, len, "%s:%u", bucket->hostname, bucket->port);
|
220
|
+
snprintf(port_s, sizeof(port_s), ":%u", bucket->port);
|
221
|
+
bucket->authority = rb_str_dup(bucket->hostname);
|
222
|
+
rb_str_cat2(bucket->authority, port_s);
|
223
|
+
rb_str_freeze(bucket->authority);
|
248
224
|
}
|
249
225
|
|
250
226
|
static void
|
@@ -259,7 +235,21 @@ do_connect(struct cb_bucket_st *bucket)
|
|
259
235
|
bucket->handle = NULL;
|
260
236
|
bucket->io = NULL;
|
261
237
|
}
|
238
|
+
|
239
|
+
#ifndef _WIN32
|
240
|
+
{
|
241
|
+
struct lcb_create_io_ops_st ciops;
|
242
|
+
memset(&ciops, 0, sizeof(ciops));
|
243
|
+
ciops.version = 1;
|
244
|
+
ciops.v.v1.sofile = NULL;
|
245
|
+
ciops.v.v1.symbol = "cb_create_ruby_mt_io_opts";
|
246
|
+
ciops.v.v1.cookie = NULL;
|
247
|
+
|
248
|
+
err = lcb_create_io_ops(&bucket->io, &ciops);
|
249
|
+
}
|
250
|
+
#else
|
262
251
|
err = lcb_create_io_ops(&bucket->io, NULL);
|
252
|
+
#endif
|
263
253
|
if (err != LCB_SUCCESS) {
|
264
254
|
rb_exc_raise(cb_check_error(err, "failed to create IO instance", Qnil));
|
265
255
|
}
|
@@ -267,10 +257,10 @@ do_connect(struct cb_bucket_st *bucket)
|
|
267
257
|
memset(&create_opts, 0, sizeof(struct lcb_create_st));
|
268
258
|
create_opts.version = 1;
|
269
259
|
create_opts.v.v1.type = bucket->type;
|
270
|
-
create_opts.v.v1.host = bucket->node_list ? bucket-> node_list : bucket->authority;
|
271
|
-
create_opts.v.v1.user = bucket->username;
|
272
|
-
create_opts.v.v1.passwd = bucket->password;
|
273
|
-
create_opts.v.v1.bucket = bucket->bucket;
|
260
|
+
create_opts.v.v1.host = RTEST(bucket->node_list) ? RSTRING_PTR(bucket-> node_list) : RSTRING_PTR(bucket->authority);
|
261
|
+
create_opts.v.v1.user = RTEST(bucket->username) ? RSTRING_PTR(bucket->username) : NULL;
|
262
|
+
create_opts.v.v1.passwd = RTEST(bucket->username) ? RSTRING_PTR(bucket->password) : NULL;
|
263
|
+
create_opts.v.v1.bucket = RSTRING_PTR(bucket->bucket);
|
274
264
|
create_opts.v.v1.io = bucket->io;
|
275
265
|
err = lcb_create(&bucket->handle, &create_opts);
|
276
266
|
if (err != LCB_SUCCESS) {
|
@@ -416,10 +406,14 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
416
406
|
bucket->self = self;
|
417
407
|
bucket->exception = Qnil;
|
418
408
|
bucket->type = LCB_TYPE_BUCKET;
|
419
|
-
bucket->hostname =
|
409
|
+
bucket->hostname = rb_str_new2("localhost");
|
420
410
|
bucket->port = 8091;
|
421
|
-
bucket->pool =
|
422
|
-
bucket->
|
411
|
+
bucket->pool = cb_vStrDefault;
|
412
|
+
rb_str_freeze(bucket->pool);
|
413
|
+
bucket->bucket = cb_vStrDefault;
|
414
|
+
rb_str_freeze(bucket->bucket);
|
415
|
+
bucket->username = Qnil;
|
416
|
+
bucket->password = Qnil;
|
423
417
|
bucket->async = 0;
|
424
418
|
bucket->quiet = 0;
|
425
419
|
bucket->default_ttl = 0;
|
@@ -429,11 +423,9 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
429
423
|
bucket->on_error_proc = Qnil;
|
430
424
|
bucket->timeout = 0;
|
431
425
|
bucket->environment = cb_sym_production;
|
432
|
-
bucket->key_prefix = NULL;
|
433
426
|
bucket->key_prefix_val = Qnil;
|
434
|
-
bucket->node_list =
|
427
|
+
bucket->node_list = Qnil;
|
435
428
|
bucket->object_space = rb_hash_new();
|
436
|
-
bucket->node_list = NULL;
|
437
429
|
|
438
430
|
do_scan_connection_options(bucket, argc, argv);
|
439
431
|
do_connect(bucket);
|
@@ -469,19 +461,12 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
|
|
469
461
|
|
470
462
|
copy_b->self = copy_b->self;
|
471
463
|
copy_b->port = orig_b->port;
|
472
|
-
copy_b->authority =
|
473
|
-
copy_b->hostname =
|
474
|
-
copy_b->pool =
|
475
|
-
copy_b->bucket =
|
476
|
-
|
477
|
-
|
478
|
-
}
|
479
|
-
if (orig_b->password) {
|
480
|
-
copy_b->password = strdup(orig_b->password);
|
481
|
-
}
|
482
|
-
if (orig_b->key_prefix) {
|
483
|
-
copy_b->key_prefix = strdup(orig_b->key_prefix);
|
484
|
-
}
|
464
|
+
copy_b->authority = orig_b->authority;
|
465
|
+
copy_b->hostname = orig_b->hostname;
|
466
|
+
copy_b->pool = orig_b->pool;
|
467
|
+
copy_b->bucket = orig_b->bucket;
|
468
|
+
copy_b->username = orig_b->username;
|
469
|
+
copy_b->password = orig_b->password;
|
485
470
|
copy_b->async = orig_b->async;
|
486
471
|
copy_b->quiet = orig_b->quiet;
|
487
472
|
copy_b->default_format = orig_b->default_format;
|
@@ -493,9 +478,7 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
|
|
493
478
|
if (orig_b->on_error_proc != Qnil) {
|
494
479
|
copy_b->on_error_proc = rb_funcall(orig_b->on_error_proc, cb_id_dup, 0);
|
495
480
|
}
|
496
|
-
|
497
|
-
copy_b->key_prefix_val = rb_funcall(orig_b->key_prefix_val, cb_id_dup, 0);
|
498
|
-
}
|
481
|
+
copy_b->key_prefix_val = orig_b->key_prefix_val;
|
499
482
|
|
500
483
|
do_connect(copy_b);
|
501
484
|
|
@@ -724,8 +707,7 @@ cb_bucket_key_prefix_set(VALUE self, VALUE val)
|
|
724
707
|
{
|
725
708
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
726
709
|
|
727
|
-
bucket->
|
728
|
-
bucket->key_prefix_val = STR_NEW_CSTR(bucket->key_prefix);
|
710
|
+
bucket->key_prefix_val = rb_str_dup_frozen(StringValue(val));
|
729
711
|
|
730
712
|
return bucket->key_prefix_val;
|
731
713
|
}
|
@@ -740,14 +722,16 @@ cb_bucket_key_prefix_set(VALUE self, VALUE val)
|
|
740
722
|
cb_bucket_hostname_get(VALUE self)
|
741
723
|
{
|
742
724
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
725
|
+
|
743
726
|
if (bucket->handle) {
|
744
|
-
|
745
|
-
|
746
|
-
if (bucket->hostname
|
747
|
-
|
727
|
+
const char * host = lcb_get_host(bucket->handle);
|
728
|
+
unsigned long len = RSTRING_LEN(bucket->hostname);
|
729
|
+
if (len != strlen(host) || strncmp(RSTRING_PTR(bucket->hostname), host, len) != 0) {
|
730
|
+
bucket->hostname = STR_NEW_CSTR(host);
|
731
|
+
rb_str_freeze(bucket->hostname);
|
748
732
|
}
|
749
733
|
}
|
750
|
-
return
|
734
|
+
return bucket->hostname;
|
751
735
|
}
|
752
736
|
|
753
737
|
/* Document-method: port
|
@@ -776,17 +760,19 @@ cb_bucket_port_get(VALUE self)
|
|
776
760
|
cb_bucket_authority_get(VALUE self)
|
777
761
|
{
|
778
762
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
bucket->
|
785
|
-
|
786
|
-
|
763
|
+
VALUE old_hostname = bucket->hostname;
|
764
|
+
uint16_t old_port = bucket->port;
|
765
|
+
VALUE hostname = cb_bucket_hostname_get(self);
|
766
|
+
cb_bucket_port_get(self);
|
767
|
+
|
768
|
+
if (hostname != old_hostname || bucket->port != old_port) {
|
769
|
+
char port_s[8];
|
770
|
+
snprintf(port_s, sizeof(port_s), ":%u", bucket->port);
|
771
|
+
bucket->authority = rb_str_dup(hostname);
|
772
|
+
rb_str_cat2(bucket->authority, port_s);
|
773
|
+
rb_str_freeze(bucket->authority);
|
787
774
|
}
|
788
|
-
|
789
|
-
return STR_NEW_CSTR(bucket->authority);
|
775
|
+
return bucket->authority;
|
790
776
|
}
|
791
777
|
|
792
778
|
/* Document-method: bucket
|
@@ -799,7 +785,7 @@ cb_bucket_authority_get(VALUE self)
|
|
799
785
|
cb_bucket_bucket_get(VALUE self)
|
800
786
|
{
|
801
787
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
802
|
-
return
|
788
|
+
return bucket->bucket;
|
803
789
|
}
|
804
790
|
|
805
791
|
/* Document-method: pool
|
@@ -812,7 +798,7 @@ cb_bucket_bucket_get(VALUE self)
|
|
812
798
|
cb_bucket_pool_get(VALUE self)
|
813
799
|
{
|
814
800
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
815
|
-
return
|
801
|
+
return bucket->pool;
|
816
802
|
}
|
817
803
|
|
818
804
|
/* Document-method: username
|
@@ -826,7 +812,7 @@ cb_bucket_pool_get(VALUE self)
|
|
826
812
|
cb_bucket_username_get(VALUE self)
|
827
813
|
{
|
828
814
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
829
|
-
return
|
815
|
+
return bucket->username;
|
830
816
|
}
|
831
817
|
|
832
818
|
/* Document-method: password
|
@@ -839,7 +825,7 @@ cb_bucket_username_get(VALUE self)
|
|
839
825
|
cb_bucket_password_get(VALUE self)
|
840
826
|
{
|
841
827
|
struct cb_bucket_st *bucket = DATA_PTR(self);
|
842
|
-
return
|
828
|
+
return bucket->password;
|
843
829
|
}
|
844
830
|
|
845
831
|
/* Document-method: environment
|
@@ -921,11 +907,11 @@ cb_bucket_url_get(VALUE self)
|
|
921
907
|
|
922
908
|
(void)cb_bucket_authority_get(self);
|
923
909
|
str = rb_str_buf_new2("http://");
|
924
|
-
|
910
|
+
rb_str_append(str, bucket->authority);
|
925
911
|
rb_str_buf_cat2(str, "/pools/");
|
926
|
-
|
912
|
+
rb_str_append(str, bucket->pool);
|
927
913
|
rb_str_buf_cat2(str, "/buckets/");
|
928
|
-
|
914
|
+
rb_str_append(str, bucket->bucket);
|
929
915
|
rb_str_buf_cat2(str, "/");
|
930
916
|
return str;
|
931
917
|
}
|
@@ -951,11 +937,11 @@ cb_bucket_inspect(VALUE self)
|
|
951
937
|
(void)cb_bucket_authority_get(self);
|
952
938
|
rb_str_buf_cat2(str, buf);
|
953
939
|
rb_str_buf_cat2(str, "http://");
|
954
|
-
|
940
|
+
rb_str_append(str, bucket->authority);
|
955
941
|
rb_str_buf_cat2(str, "/pools/");
|
956
|
-
|
942
|
+
rb_str_append(str, bucket->pool);
|
957
943
|
rb_str_buf_cat2(str, "/buckets/");
|
958
|
-
|
944
|
+
rb_str_append(str, bucket->bucket);
|
959
945
|
rb_str_buf_cat2(str, "/");
|
960
946
|
snprintf(buf, 150, "\" default_format=:%s, default_flags=0x%x, quiet=%s, connected=%s, timeout=%u",
|
961
947
|
rb_id2name(SYM2ID(bucket->default_format)),
|
@@ -964,7 +950,7 @@ cb_bucket_inspect(VALUE self)
|
|
964
950
|
bucket->handle ? "true" : "false",
|
965
951
|
bucket->timeout);
|
966
952
|
rb_str_buf_cat2(str, buf);
|
967
|
-
if (bucket->
|
953
|
+
if (RTEST(bucket->key_prefix_val)) {
|
968
954
|
rb_str_buf_cat2(str, ", key_prefix=");
|
969
955
|
rb_str_append(str, rb_inspect(bucket->key_prefix_val));
|
970
956
|
}
|
@@ -1010,7 +996,7 @@ do_run(VALUE *args)
|
|
1010
996
|
}
|
1011
997
|
}
|
1012
998
|
bucket->async = 1;
|
1013
|
-
cb_proc_call(proc, 1, self);
|
999
|
+
cb_proc_call(bucket, proc, 1, self);
|
1014
1000
|
do_loop(bucket);
|
1015
1001
|
if (bucket->exception != Qnil) {
|
1016
1002
|
exc = bucket->exception;
|