couchbase 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.markdown +8 -0
- data/ext/couchbase_ext/couchbase_ext.c +173 -98
- data/lib/couchbase/bucket.rb +2 -2
- data/lib/couchbase/version.rb +1 -1
- data/test/test_cas.rb +8 -0
- metadata +4 -4
data/HISTORY.markdown
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 1.1.3 / 2012-07-27
|
2
|
+
|
3
|
+
* RCBC-59 Replicate flags in Bucket#cas operation
|
4
|
+
* calloc -> xcalloc, free -> xfree
|
5
|
+
* RCBC-64 Fix Couchbase::Bucket#dup
|
6
|
+
* Make object_space GC protector per-bucket object
|
7
|
+
* RCBC-60 Protect exceptions from GC
|
8
|
+
|
1
9
|
## 1.1.2 / 2012-06-05
|
2
10
|
|
3
11
|
* Upgrade libcouchbase dependency up to 1.0.4
|
@@ -64,6 +64,7 @@ typedef struct
|
|
64
64
|
uint32_t timeout;
|
65
65
|
VALUE exception; /* error delivered by error_callback */
|
66
66
|
VALUE on_error_proc; /* is using to deliver errors in async mode */
|
67
|
+
VALUE object_space;
|
67
68
|
} bucket_t;
|
68
69
|
|
69
70
|
typedef struct
|
@@ -93,7 +94,6 @@ struct key_traits
|
|
93
94
|
};
|
94
95
|
|
95
96
|
static VALUE mCouchbase, mError, mJSON, mURI, mMarshal, cBucket, cResult;
|
96
|
-
static VALUE object_space;
|
97
97
|
|
98
98
|
static ID sym_add,
|
99
99
|
sym_append,
|
@@ -142,6 +142,7 @@ static ID sym_add,
|
|
142
142
|
id_iv_node,
|
143
143
|
id_iv_operation,
|
144
144
|
id_iv_value,
|
145
|
+
id_dup,
|
145
146
|
id_load,
|
146
147
|
id_match,
|
147
148
|
id_parse,
|
@@ -183,6 +184,18 @@ static VALUE eTimeoutError; /*LIBCOUCHBASE_ETIMEDOUT = 0x16*/
|
|
183
184
|
static VALUE eConnectError; /*LIBCOUCHBASE_CONNECT_ERROR = 0x17*/
|
184
185
|
static VALUE eBucketNotFoundError; /*LIBCOUCHBASE_BUCKET_ENOENT = 0x18*/
|
185
186
|
|
187
|
+
static void
|
188
|
+
cb_gc_protect(bucket_t *bucket, VALUE val)
|
189
|
+
{
|
190
|
+
rb_hash_aset(bucket->object_space, val|1, val);
|
191
|
+
}
|
192
|
+
|
193
|
+
static void
|
194
|
+
cb_gc_unprotect(bucket_t *bucket, VALUE val)
|
195
|
+
{
|
196
|
+
rb_hash_delete(bucket->object_space, val|1);
|
197
|
+
}
|
198
|
+
|
186
199
|
static VALUE
|
187
200
|
cb_proc_call(VALUE recv, int argc, ...)
|
188
201
|
{
|
@@ -504,18 +517,18 @@ cb_args_scan_keys(long argc, VALUE argv, bucket_t *bucket, struct key_traits *tr
|
|
504
517
|
if (nn == 1 && TYPE(keys_ptr[0]) == T_HASH) {
|
505
518
|
/* hash of key-ttl pairs */
|
506
519
|
nn = RHASH_SIZE(keys_ptr[0]);
|
507
|
-
traits->keys =
|
508
|
-
traits->lens =
|
520
|
+
traits->keys = xcalloc(nn, sizeof(char *));
|
521
|
+
traits->lens = xcalloc(nn, sizeof(size_t));
|
509
522
|
traits->explicit_ttl = 1;
|
510
523
|
traits->mgat = 1;
|
511
|
-
traits->ttls =
|
524
|
+
traits->ttls = xcalloc(nn, sizeof(time_t));
|
512
525
|
rb_hash_foreach(keys_ptr[0], cb_extract_keys_i, (VALUE)traits);
|
513
526
|
} else {
|
514
527
|
/* the list of keys */
|
515
528
|
traits->nkeys = nn;
|
516
|
-
traits->keys =
|
517
|
-
traits->lens =
|
518
|
-
traits->ttls =
|
529
|
+
traits->keys = xcalloc(nn, sizeof(char *));
|
530
|
+
traits->lens = xcalloc(nn, sizeof(size_t));
|
531
|
+
traits->ttls = xcalloc(nn, sizeof(time_t));
|
519
532
|
for (ii = 0; ii < nn; ii++) {
|
520
533
|
key = unify_key(keys_ptr[ii]);
|
521
534
|
rb_ary_push(traits->keys_ary, key);
|
@@ -577,6 +590,7 @@ storage_callback(libcouchbase_t handle, const void *cookie,
|
|
577
590
|
rb_ivar_set(exc, id_iv_operation, o);
|
578
591
|
if (NIL_P(ctx->exception)) {
|
579
592
|
ctx->exception = exc;
|
593
|
+
cb_gc_protect(bucket, ctx->exception);
|
580
594
|
}
|
581
595
|
}
|
582
596
|
if (bucket->async) { /* asynchronous */
|
@@ -594,7 +608,7 @@ storage_callback(libcouchbase_t handle, const void *cookie,
|
|
594
608
|
|
595
609
|
if (bucket->seqno == 0) {
|
596
610
|
bucket->io->stop_event_loop(bucket->io);
|
597
|
-
|
611
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
598
612
|
}
|
599
613
|
(void)handle;
|
600
614
|
}
|
@@ -617,6 +631,7 @@ delete_callback(libcouchbase_t handle, const void *cookie,
|
|
617
631
|
rb_ivar_set(exc, id_iv_operation, sym_delete);
|
618
632
|
if (NIL_P(ctx->exception)) {
|
619
633
|
ctx->exception = exc;
|
634
|
+
cb_gc_protect(bucket, ctx->exception);
|
620
635
|
}
|
621
636
|
}
|
622
637
|
}
|
@@ -633,7 +648,7 @@ delete_callback(libcouchbase_t handle, const void *cookie,
|
|
633
648
|
}
|
634
649
|
if (bucket->seqno == 0) {
|
635
650
|
bucket->io->stop_event_loop(bucket->io);
|
636
|
-
|
651
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
637
652
|
}
|
638
653
|
(void)handle;
|
639
654
|
}
|
@@ -658,26 +673,27 @@ get_callback(libcouchbase_t handle, const void *cookie,
|
|
658
673
|
rb_ivar_set(exc, id_iv_operation, sym_get);
|
659
674
|
if (NIL_P(ctx->exception)) {
|
660
675
|
ctx->exception = exc;
|
676
|
+
cb_gc_protect(bucket, ctx->exception);
|
661
677
|
}
|
662
678
|
}
|
663
679
|
}
|
664
680
|
|
665
681
|
f = ULONG2NUM(flags);
|
666
682
|
c = ULL2NUM(cas);
|
683
|
+
v = Qnil;
|
667
684
|
if (nbytes != 0) {
|
668
685
|
v = decode_value(rb_str_new((const char*)bytes, nbytes), flags, ctx->force_format);
|
669
686
|
if (v == Qundef) {
|
687
|
+
if (ctx->exception != Qnil) {
|
688
|
+
cb_gc_unprotect(bucket, ctx->exception);
|
689
|
+
}
|
670
690
|
ctx->exception = rb_exc_new2(eValueFormatError, "unable to convert value");
|
671
691
|
rb_ivar_set(ctx->exception, id_iv_operation, sym_get);
|
672
692
|
rb_ivar_set(ctx->exception, id_iv_key, k);
|
673
|
-
|
674
|
-
}
|
675
|
-
} else {
|
676
|
-
if (flags_get_format(flags) == sym_plain) {
|
677
|
-
v = rb_str_new2("");
|
678
|
-
} else {
|
679
|
-
v = Qnil;
|
693
|
+
cb_gc_protect(bucket, ctx->exception);
|
680
694
|
}
|
695
|
+
} else if (flags_get_format(flags) == sym_plain) {
|
696
|
+
v = rb_str_new2("");
|
681
697
|
}
|
682
698
|
if (bucket->async) { /* asynchronous */
|
683
699
|
if (ctx->proc != Qnil) {
|
@@ -702,7 +718,7 @@ get_callback(libcouchbase_t handle, const void *cookie,
|
|
702
718
|
|
703
719
|
if (bucket->seqno == 0) {
|
704
720
|
bucket->io->stop_event_loop(bucket->io);
|
705
|
-
|
721
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
706
722
|
}
|
707
723
|
(void)handle;
|
708
724
|
}
|
@@ -721,6 +737,7 @@ flush_callback(libcouchbase_t handle, const void* cookie,
|
|
721
737
|
rb_ivar_set(exc, id_iv_operation, sym_flush);
|
722
738
|
if (NIL_P(ctx->exception)) {
|
723
739
|
ctx->exception = exc;
|
740
|
+
cb_gc_protect(bucket, ctx->exception);
|
724
741
|
}
|
725
742
|
success = Qfalse;
|
726
743
|
}
|
@@ -744,7 +761,7 @@ flush_callback(libcouchbase_t handle, const void* cookie,
|
|
744
761
|
bucket->seqno--;
|
745
762
|
if (bucket->seqno == 0) {
|
746
763
|
bucket->io->stop_event_loop(bucket->io);
|
747
|
-
|
764
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
748
765
|
}
|
749
766
|
}
|
750
767
|
|
@@ -766,6 +783,7 @@ version_callback(libcouchbase_t handle, const void *cookie,
|
|
766
783
|
rb_ivar_set(exc, id_iv_operation, sym_flush);
|
767
784
|
if (NIL_P(ctx->exception)) {
|
768
785
|
ctx->exception = exc;
|
786
|
+
cb_gc_protect(bucket, ctx->exception);
|
769
787
|
}
|
770
788
|
}
|
771
789
|
|
@@ -789,7 +807,7 @@ version_callback(libcouchbase_t handle, const void *cookie,
|
|
789
807
|
bucket->seqno--;
|
790
808
|
if (bucket->seqno == 0) {
|
791
809
|
bucket->io->stop_event_loop(bucket->io);
|
792
|
-
|
810
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
793
811
|
}
|
794
812
|
}
|
795
813
|
|
@@ -812,6 +830,7 @@ stat_callback(libcouchbase_t handle, const void* cookie,
|
|
812
830
|
rb_ivar_set(exc, id_iv_operation, sym_stats);
|
813
831
|
if (NIL_P(ctx->exception)) {
|
814
832
|
ctx->exception = exc;
|
833
|
+
cb_gc_protect(bucket, ctx->exception);
|
815
834
|
}
|
816
835
|
}
|
817
836
|
if (authority) {
|
@@ -841,7 +860,7 @@ stat_callback(libcouchbase_t handle, const void* cookie,
|
|
841
860
|
bucket->seqno--;
|
842
861
|
if (bucket->seqno == 0) {
|
843
862
|
bucket->io->stop_event_loop(bucket->io);
|
844
|
-
|
863
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
845
864
|
}
|
846
865
|
}
|
847
866
|
(void)handle;
|
@@ -864,6 +883,7 @@ touch_callback(libcouchbase_t handle, const void *cookie,
|
|
864
883
|
rb_ivar_set(exc, id_iv_operation, sym_touch);
|
865
884
|
if (NIL_P(ctx->exception)) {
|
866
885
|
ctx->exception = exc;
|
886
|
+
cb_gc_protect(bucket, ctx->exception);
|
867
887
|
}
|
868
888
|
}
|
869
889
|
}
|
@@ -884,7 +904,7 @@ touch_callback(libcouchbase_t handle, const void *cookie,
|
|
884
904
|
}
|
885
905
|
if (bucket->seqno == 0) {
|
886
906
|
bucket->io->stop_event_loop(bucket->io);
|
887
|
-
|
907
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
888
908
|
}
|
889
909
|
(void)handle;
|
890
910
|
}
|
@@ -920,6 +940,7 @@ arithmetic_callback(libcouchbase_t handle, const void *cookie,
|
|
920
940
|
}
|
921
941
|
if (NIL_P(ctx->exception)) {
|
922
942
|
ctx->exception = exc;
|
943
|
+
cb_gc_protect(bucket, ctx->exception);
|
923
944
|
}
|
924
945
|
}
|
925
946
|
v = ULL2NUM(value);
|
@@ -944,7 +965,7 @@ arithmetic_callback(libcouchbase_t handle, const void *cookie,
|
|
944
965
|
}
|
945
966
|
if (bucket->seqno == 0) {
|
946
967
|
bucket->io->stop_event_loop(bucket->io);
|
947
|
-
|
968
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
948
969
|
}
|
949
970
|
(void)handle;
|
950
971
|
}
|
@@ -980,13 +1001,13 @@ cb_bucket_free(void *ptr)
|
|
980
1001
|
if (bucket->handle) {
|
981
1002
|
libcouchbase_destroy(bucket->handle);
|
982
1003
|
}
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
1004
|
+
xfree(bucket->authority);
|
1005
|
+
xfree(bucket->hostname);
|
1006
|
+
xfree(bucket->pool);
|
1007
|
+
xfree(bucket->bucket);
|
1008
|
+
xfree(bucket->username);
|
1009
|
+
xfree(bucket->password);
|
1010
|
+
xfree(bucket);
|
990
1011
|
}
|
991
1012
|
}
|
992
1013
|
|
@@ -998,6 +1019,7 @@ cb_bucket_mark(void *ptr)
|
|
998
1019
|
if (bucket) {
|
999
1020
|
rb_gc_mark(bucket->exception);
|
1000
1021
|
rb_gc_mark(bucket->on_error_proc);
|
1022
|
+
rb_gc_mark(bucket->object_space);
|
1001
1023
|
}
|
1002
1024
|
}
|
1003
1025
|
|
@@ -1026,7 +1048,7 @@ do_scan_connection_options(bucket_t *bucket, int argc, VALUE *argv)
|
|
1026
1048
|
|
1027
1049
|
arg = rb_funcall(uri_obj, id_user, 0);
|
1028
1050
|
if (arg != Qnil) {
|
1029
|
-
|
1051
|
+
xfree(bucket->username);
|
1030
1052
|
bucket->username = strdup(RSTRING_PTR(arg));
|
1031
1053
|
if (bucket->username == NULL) {
|
1032
1054
|
rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
|
@@ -1035,7 +1057,7 @@ do_scan_connection_options(bucket_t *bucket, int argc, VALUE *argv)
|
|
1035
1057
|
|
1036
1058
|
arg = rb_funcall(uri_obj, id_password, 0);
|
1037
1059
|
if (arg != Qnil) {
|
1038
|
-
|
1060
|
+
xfree(bucket->password);
|
1039
1061
|
bucket->password = strdup(RSTRING_PTR(arg));
|
1040
1062
|
if (bucket->password == NULL) {
|
1041
1063
|
rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
|
@@ -1043,7 +1065,7 @@ do_scan_connection_options(bucket_t *bucket, int argc, VALUE *argv)
|
|
1043
1065
|
}
|
1044
1066
|
arg = rb_funcall(uri_obj, id_host, 0);
|
1045
1067
|
if (arg != Qnil) {
|
1046
|
-
|
1068
|
+
xfree(bucket->hostname);
|
1047
1069
|
bucket->hostname = strdup(RSTRING_PTR(arg));
|
1048
1070
|
if (bucket->hostname == NULL) {
|
1049
1071
|
rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
|
@@ -1059,45 +1081,45 @@ do_scan_connection_options(bucket_t *bucket, int argc, VALUE *argv)
|
|
1059
1081
|
re = rb_reg_new(path_re, sizeof(path_re) - 1, 0);
|
1060
1082
|
match = rb_funcall(re, id_match, 1, arg);
|
1061
1083
|
arg = rb_reg_nth_match(2, match);
|
1062
|
-
|
1084
|
+
xfree(bucket->pool);
|
1063
1085
|
bucket->pool = strdup(NIL_P(arg) ? "default" : RSTRING_PTR(arg));
|
1064
1086
|
arg = rb_reg_nth_match(4, match);
|
1065
|
-
|
1087
|
+
xfree(bucket->bucket);
|
1066
1088
|
bucket->bucket = strdup(NIL_P(arg) ? "default" : RSTRING_PTR(arg));
|
1067
1089
|
}
|
1068
1090
|
if (TYPE(opts) == T_HASH) {
|
1069
1091
|
arg = rb_hash_aref(opts, sym_hostname);
|
1070
1092
|
if (arg != Qnil) {
|
1071
1093
|
if (bucket->hostname) {
|
1072
|
-
|
1094
|
+
xfree(bucket->hostname);
|
1073
1095
|
}
|
1074
1096
|
bucket->hostname = strdup(StringValueCStr(arg));
|
1075
1097
|
}
|
1076
1098
|
arg = rb_hash_aref(opts, sym_pool);
|
1077
1099
|
if (arg != Qnil) {
|
1078
1100
|
if (bucket->pool) {
|
1079
|
-
|
1101
|
+
xfree(bucket->pool);
|
1080
1102
|
}
|
1081
1103
|
bucket->pool = strdup(StringValueCStr(arg));
|
1082
1104
|
}
|
1083
1105
|
arg = rb_hash_aref(opts, sym_bucket);
|
1084
1106
|
if (arg != Qnil) {
|
1085
1107
|
if (bucket->bucket) {
|
1086
|
-
|
1108
|
+
xfree(bucket->bucket);
|
1087
1109
|
}
|
1088
1110
|
bucket->bucket = strdup(StringValueCStr(arg));
|
1089
1111
|
}
|
1090
1112
|
arg = rb_hash_aref(opts, sym_username);
|
1091
1113
|
if (arg != Qnil) {
|
1092
1114
|
if (bucket->username) {
|
1093
|
-
|
1115
|
+
xfree(bucket->username);
|
1094
1116
|
}
|
1095
1117
|
bucket->username = strdup(StringValueCStr(arg));
|
1096
1118
|
}
|
1097
1119
|
arg = rb_hash_aref(opts, sym_password);
|
1098
1120
|
if (arg != Qnil) {
|
1099
1121
|
if (bucket->password) {
|
1100
|
-
|
1122
|
+
xfree(bucket->password);
|
1101
1123
|
}
|
1102
1124
|
bucket->password = strdup(StringValueCStr(arg));
|
1103
1125
|
}
|
@@ -1146,9 +1168,9 @@ do_scan_connection_options(bucket_t *bucket, int argc, VALUE *argv)
|
|
1146
1168
|
}
|
1147
1169
|
len = strlen(bucket->hostname) + 10;
|
1148
1170
|
if (bucket->authority) {
|
1149
|
-
|
1171
|
+
xfree(bucket->authority);
|
1150
1172
|
}
|
1151
|
-
bucket->authority =
|
1173
|
+
bucket->authority = xcalloc(len, sizeof(char));
|
1152
1174
|
if (bucket->authority == NULL) {
|
1153
1175
|
rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
|
1154
1176
|
}
|
@@ -1208,15 +1230,8 @@ do_connect(bucket_t *bucket)
|
|
1208
1230
|
}
|
1209
1231
|
}
|
1210
1232
|
|
1211
|
-
/*
|
1212
|
-
* Create and initialize new Bucket.
|
1213
|
-
*
|
1214
|
-
* @return [Bucket] new instance
|
1215
|
-
*
|
1216
|
-
* @see Bucket#initialize
|
1217
|
-
*/
|
1218
1233
|
static VALUE
|
1219
|
-
|
1234
|
+
cb_bucket_alloc(VALUE klass)
|
1220
1235
|
{
|
1221
1236
|
VALUE obj;
|
1222
1237
|
bucket_t *bucket;
|
@@ -1224,7 +1239,6 @@ cb_bucket_new(int argc, VALUE *argv, VALUE klass)
|
|
1224
1239
|
/* allocate new bucket struct and set it to zero */
|
1225
1240
|
obj = Data_Make_Struct(klass, bucket_t, cb_bucket_mark, cb_bucket_free,
|
1226
1241
|
bucket);
|
1227
|
-
rb_obj_call_init(obj, argc, argv);
|
1228
1242
|
return obj;
|
1229
1243
|
}
|
1230
1244
|
|
@@ -1295,6 +1309,7 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
1295
1309
|
bucket->default_format = sym_document;
|
1296
1310
|
bucket->on_error_proc = Qnil;
|
1297
1311
|
bucket->timeout = 0;
|
1312
|
+
bucket->object_space = rb_hash_new();
|
1298
1313
|
|
1299
1314
|
do_scan_connection_options(bucket, argc, argv);
|
1300
1315
|
do_connect(bucket);
|
@@ -1302,6 +1317,60 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
1302
1317
|
return self;
|
1303
1318
|
}
|
1304
1319
|
|
1320
|
+
/*
|
1321
|
+
* Initialize copy
|
1322
|
+
*
|
1323
|
+
* Initializes copy of the object, used by {Couchbase::Bucket#dup}
|
1324
|
+
*
|
1325
|
+
* @param orig [Couchbase::Bucket] the source for copy
|
1326
|
+
*
|
1327
|
+
* @return [Couchbase::Bucket]
|
1328
|
+
*/
|
1329
|
+
static VALUE
|
1330
|
+
cb_bucket_init_copy(VALUE copy, VALUE orig)
|
1331
|
+
{
|
1332
|
+
bucket_t *copy_b;
|
1333
|
+
bucket_t *orig_b;
|
1334
|
+
|
1335
|
+
if (copy == orig)
|
1336
|
+
return copy;
|
1337
|
+
|
1338
|
+
if (TYPE(orig) != T_DATA || TYPE(copy) != T_DATA ||
|
1339
|
+
RDATA(orig)->dfree != (RUBY_DATA_FUNC)cb_bucket_free) {
|
1340
|
+
rb_raise(rb_eTypeError, "wrong argument type");
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
copy_b = DATA_PTR(copy);
|
1344
|
+
orig_b = DATA_PTR(orig);
|
1345
|
+
|
1346
|
+
copy_b->port = orig_b->port;
|
1347
|
+
copy_b->authority = strdup(orig_b->authority);
|
1348
|
+
copy_b->hostname = strdup(orig_b->hostname);
|
1349
|
+
copy_b->pool = strdup(orig_b->pool);
|
1350
|
+
copy_b->bucket = strdup(orig_b->bucket);
|
1351
|
+
if (orig_b->username) {
|
1352
|
+
copy_b->username = strdup(orig_b->username);
|
1353
|
+
}
|
1354
|
+
if (orig_b->password) {
|
1355
|
+
copy_b->password = strdup(orig_b->password);
|
1356
|
+
}
|
1357
|
+
copy_b->async = orig_b->async;
|
1358
|
+
copy_b->quiet = orig_b->quiet;
|
1359
|
+
copy_b->seqno = orig_b->seqno;
|
1360
|
+
copy_b->default_format = orig_b->default_format;
|
1361
|
+
copy_b->default_flags = orig_b->default_flags;
|
1362
|
+
copy_b->default_ttl = orig_b->default_ttl;
|
1363
|
+
copy_b->timeout = orig_b->timeout;
|
1364
|
+
copy_b->exception = Qnil;
|
1365
|
+
if (orig_b->on_error_proc != Qnil) {
|
1366
|
+
copy_b->on_error_proc = rb_funcall(orig_b->on_error_proc, id_dup, 0);
|
1367
|
+
}
|
1368
|
+
|
1369
|
+
do_connect(copy_b);
|
1370
|
+
|
1371
|
+
return copy;
|
1372
|
+
}
|
1373
|
+
|
1305
1374
|
/*
|
1306
1375
|
* Reconnect the bucket
|
1307
1376
|
*
|
@@ -1492,7 +1561,7 @@ cb_bucket_hostname_get(VALUE self)
|
|
1492
1561
|
bucket_t *bucket = DATA_PTR(self);
|
1493
1562
|
if (bucket->handle) {
|
1494
1563
|
if (bucket->hostname) {
|
1495
|
-
|
1564
|
+
xfree(bucket->hostname);
|
1496
1565
|
bucket->hostname = NULL;
|
1497
1566
|
}
|
1498
1567
|
bucket->hostname = strdup(libcouchbase_get_host(bucket->handle));
|
@@ -1528,7 +1597,7 @@ cb_bucket_authority_get(VALUE self)
|
|
1528
1597
|
(void)cb_bucket_hostname_get(self);
|
1529
1598
|
(void)cb_bucket_port_get(self);
|
1530
1599
|
len = strlen(bucket->hostname) + 10;
|
1531
|
-
bucket->authority =
|
1600
|
+
bucket->authority = xcalloc(len, sizeof(char));
|
1532
1601
|
if (bucket->authority == NULL) {
|
1533
1602
|
rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
|
1534
1603
|
}
|
@@ -1691,7 +1760,7 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
1691
1760
|
k = unify_key(k);
|
1692
1761
|
key = RSTRING_PTR(k);
|
1693
1762
|
nkey = RSTRING_LEN(k);
|
1694
|
-
ctx =
|
1763
|
+
ctx = xcalloc(1, sizeof(context_t));
|
1695
1764
|
ctx->quiet = bucket->quiet;
|
1696
1765
|
if (ctx == NULL) {
|
1697
1766
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
@@ -1710,7 +1779,7 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
1710
1779
|
}
|
1711
1780
|
}
|
1712
1781
|
ctx->proc = proc;
|
1713
|
-
|
1782
|
+
cb_gc_protect(bucket, ctx->proc);
|
1714
1783
|
rv = rb_ary_new();
|
1715
1784
|
ctx->rv = &rv;
|
1716
1785
|
ctx->bucket = bucket;
|
@@ -1721,7 +1790,7 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
1721
1790
|
(const void *)key, nkey, cas);
|
1722
1791
|
exc = cb_check_error(err, "failed to schedule delete request", Qnil);
|
1723
1792
|
if (exc != Qnil) {
|
1724
|
-
|
1793
|
+
xfree(ctx);
|
1725
1794
|
rb_exc_raise(exc);
|
1726
1795
|
}
|
1727
1796
|
if (bucket->async) {
|
@@ -1732,8 +1801,9 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
1732
1801
|
bucket->io->run_event_loop(bucket->io);
|
1733
1802
|
}
|
1734
1803
|
exc = ctx->exception;
|
1735
|
-
|
1804
|
+
xfree(ctx);
|
1736
1805
|
if (exc != Qnil) {
|
1806
|
+
cb_gc_unprotect(bucket, exc);
|
1737
1807
|
rb_exc_raise(exc);
|
1738
1808
|
}
|
1739
1809
|
return rv;
|
@@ -1791,7 +1861,7 @@ cb_bucket_store(libcouchbase_storage_t cmd, int argc, VALUE *argv, VALUE self)
|
|
1791
1861
|
}
|
1792
1862
|
bytes = RSTRING_PTR(v);
|
1793
1863
|
nbytes = RSTRING_LEN(v);
|
1794
|
-
ctx =
|
1864
|
+
ctx = xcalloc(1, sizeof(context_t));
|
1795
1865
|
if (ctx == NULL) {
|
1796
1866
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
1797
1867
|
}
|
@@ -1799,7 +1869,7 @@ cb_bucket_store(libcouchbase_storage_t cmd, int argc, VALUE *argv, VALUE self)
|
|
1799
1869
|
ctx->rv = &rv;
|
1800
1870
|
ctx->bucket = bucket;
|
1801
1871
|
ctx->proc = proc;
|
1802
|
-
|
1872
|
+
cb_gc_protect(bucket, ctx->proc);
|
1803
1873
|
ctx->exception = Qnil;
|
1804
1874
|
seqno = bucket->seqno;
|
1805
1875
|
bucket->seqno++;
|
@@ -1807,7 +1877,7 @@ cb_bucket_store(libcouchbase_storage_t cmd, int argc, VALUE *argv, VALUE self)
|
|
1807
1877
|
(const void *)key, nkey, bytes, nbytes, flags, exp, cas);
|
1808
1878
|
exc = cb_check_error(err, "failed to schedule set request", Qnil);
|
1809
1879
|
if (exc != Qnil) {
|
1810
|
-
|
1880
|
+
xfree(ctx);
|
1811
1881
|
rb_exc_raise(exc);
|
1812
1882
|
}
|
1813
1883
|
if (bucket->async) {
|
@@ -1818,8 +1888,9 @@ cb_bucket_store(libcouchbase_storage_t cmd, int argc, VALUE *argv, VALUE self)
|
|
1818
1888
|
bucket->io->run_event_loop(bucket->io);
|
1819
1889
|
}
|
1820
1890
|
exc = ctx->exception;
|
1821
|
-
|
1891
|
+
xfree(ctx);
|
1822
1892
|
if (exc != Qnil) {
|
1893
|
+
cb_gc_unprotect(bucket, exc);
|
1823
1894
|
rb_exc_raise(exc);
|
1824
1895
|
}
|
1825
1896
|
if (bucket->exception != Qnil) {
|
@@ -1851,7 +1922,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
1851
1922
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
1852
1923
|
}
|
1853
1924
|
k = unify_key(k);
|
1854
|
-
ctx =
|
1925
|
+
ctx = xcalloc(1, sizeof(context_t));
|
1855
1926
|
if (ctx == NULL) {
|
1856
1927
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
1857
1928
|
}
|
@@ -1885,7 +1956,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
1885
1956
|
ctx->rv = &rv;
|
1886
1957
|
ctx->bucket = bucket;
|
1887
1958
|
ctx->proc = proc;
|
1888
|
-
|
1959
|
+
cb_gc_protect(bucket, ctx->proc);
|
1889
1960
|
ctx->exception = Qnil;
|
1890
1961
|
ctx->arithm = sign;
|
1891
1962
|
seqno = bucket->seqno;
|
@@ -1894,7 +1965,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
1894
1965
|
(const void *)key, nkey, delta, exp, create, initial);
|
1895
1966
|
exc = cb_check_error(err, "failed to schedule arithmetic request", k);
|
1896
1967
|
if (exc != Qnil) {
|
1897
|
-
|
1968
|
+
xfree(ctx);
|
1898
1969
|
rb_exc_raise(exc);
|
1899
1970
|
}
|
1900
1971
|
if (bucket->async) {
|
@@ -1905,8 +1976,9 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
|
|
1905
1976
|
bucket->io->run_event_loop(bucket->io);
|
1906
1977
|
}
|
1907
1978
|
exc = ctx->exception;
|
1908
|
-
|
1979
|
+
xfree(ctx);
|
1909
1980
|
if (exc != Qnil) {
|
1981
|
+
cb_gc_unprotect(bucket, exc);
|
1910
1982
|
rb_exc_raise(exc);
|
1911
1983
|
}
|
1912
1984
|
return rv;
|
@@ -2197,16 +2269,16 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
2197
2269
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
2198
2270
|
}
|
2199
2271
|
rb_funcall(args, id_flatten_bang, 0);
|
2200
|
-
traits =
|
2272
|
+
traits = xcalloc(1, sizeof(struct key_traits));
|
2201
2273
|
nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
|
2202
|
-
ctx =
|
2274
|
+
ctx = xcalloc(1, sizeof(context_t));
|
2203
2275
|
if (ctx == NULL) {
|
2204
2276
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
2205
2277
|
}
|
2206
2278
|
mgat = traits->mgat;
|
2207
2279
|
keys = traits->keys_ary;
|
2208
2280
|
ctx->proc = proc;
|
2209
|
-
|
2281
|
+
cb_gc_protect(bucket, ctx->proc);
|
2210
2282
|
ctx->bucket = bucket;
|
2211
2283
|
ctx->extended = traits->extended;
|
2212
2284
|
ctx->quiet = traits->quiet;
|
@@ -2219,13 +2291,13 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
2219
2291
|
err = libcouchbase_mget(bucket->handle, (const void *)ctx,
|
2220
2292
|
traits->nkeys, (const void * const *)traits->keys,
|
2221
2293
|
traits->lens, (traits->explicit_ttl) ? traits->ttls : NULL);
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2294
|
+
xfree(traits->keys);
|
2295
|
+
xfree(traits->lens);
|
2296
|
+
xfree(traits->ttls);
|
2297
|
+
xfree(traits);
|
2226
2298
|
exc = cb_check_error(err, "failed to schedule get request", Qnil);
|
2227
2299
|
if (exc != Qnil) {
|
2228
|
-
|
2300
|
+
xfree(ctx);
|
2229
2301
|
rb_exc_raise(exc);
|
2230
2302
|
}
|
2231
2303
|
if (bucket->async) {
|
@@ -2237,8 +2309,9 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
2237
2309
|
}
|
2238
2310
|
exc = ctx->exception;
|
2239
2311
|
extended = ctx->extended;
|
2240
|
-
|
2312
|
+
xfree(ctx);
|
2241
2313
|
if (exc != Qnil) {
|
2314
|
+
cb_gc_unprotect(bucket, exc);
|
2242
2315
|
rb_exc_raise(exc);
|
2243
2316
|
}
|
2244
2317
|
if (bucket->exception != Qnil) {
|
@@ -2344,14 +2417,14 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
|
|
2344
2417
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
2345
2418
|
}
|
2346
2419
|
rb_funcall(args, id_flatten_bang, 0);
|
2347
|
-
traits =
|
2420
|
+
traits = xcalloc(1, sizeof(struct key_traits));
|
2348
2421
|
nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
|
2349
|
-
ctx =
|
2422
|
+
ctx = xcalloc(1, sizeof(context_t));
|
2350
2423
|
if (ctx == NULL) {
|
2351
2424
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
2352
2425
|
}
|
2353
2426
|
ctx->proc = proc;
|
2354
|
-
|
2427
|
+
cb_gc_protect(bucket, ctx->proc);
|
2355
2428
|
ctx->bucket = bucket;
|
2356
2429
|
rv = rb_hash_new();
|
2357
2430
|
ctx->rv = &rv;
|
@@ -2361,12 +2434,12 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
|
|
2361
2434
|
err = libcouchbase_mtouch(bucket->handle, (const void *)ctx,
|
2362
2435
|
traits->nkeys, (const void * const *)traits->keys,
|
2363
2436
|
traits->lens, traits->ttls);
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2437
|
+
xfree(traits->keys);
|
2438
|
+
xfree(traits->lens);
|
2439
|
+
xfree(traits);
|
2367
2440
|
exc = cb_check_error(err, "failed to schedule touch request", Qnil);
|
2368
2441
|
if (exc != Qnil) {
|
2369
|
-
|
2442
|
+
xfree(ctx);
|
2370
2443
|
rb_exc_raise(exc);
|
2371
2444
|
}
|
2372
2445
|
if (bucket->async) {
|
@@ -2377,8 +2450,9 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
|
|
2377
2450
|
bucket->io->run_event_loop(bucket->io);
|
2378
2451
|
}
|
2379
2452
|
exc = ctx->exception;
|
2380
|
-
|
2453
|
+
xfree(ctx);
|
2381
2454
|
if (exc != Qnil) {
|
2455
|
+
cb_gc_unprotect(bucket, exc);
|
2382
2456
|
rb_exc_raise(exc);
|
2383
2457
|
}
|
2384
2458
|
if (bucket->exception != Qnil) {
|
@@ -2433,7 +2507,7 @@ cb_bucket_flush(VALUE self)
|
|
2433
2507
|
if (!bucket->async && rb_block_given_p()) {
|
2434
2508
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
2435
2509
|
}
|
2436
|
-
ctx =
|
2510
|
+
ctx = xcalloc(1, sizeof(context_t));
|
2437
2511
|
if (ctx == NULL) {
|
2438
2512
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
2439
2513
|
}
|
@@ -2446,13 +2520,13 @@ cb_bucket_flush(VALUE self)
|
|
2446
2520
|
} else {
|
2447
2521
|
ctx->proc = Qnil;
|
2448
2522
|
}
|
2449
|
-
|
2523
|
+
cb_gc_protect(bucket, ctx->proc);
|
2450
2524
|
seqno = bucket->seqno;
|
2451
2525
|
bucket->seqno++;
|
2452
2526
|
err = libcouchbase_flush(bucket->handle, (const void *)ctx);
|
2453
2527
|
exc = cb_check_error(err, "failed to schedule flush request", Qnil);
|
2454
2528
|
if (exc != Qnil) {
|
2455
|
-
|
2529
|
+
xfree(ctx);
|
2456
2530
|
rb_exc_raise(exc);
|
2457
2531
|
}
|
2458
2532
|
if (bucket->async) {
|
@@ -2463,8 +2537,9 @@ cb_bucket_flush(VALUE self)
|
|
2463
2537
|
bucket->io->run_event_loop(bucket->io);
|
2464
2538
|
}
|
2465
2539
|
exc = ctx->exception;
|
2466
|
-
|
2540
|
+
xfree(ctx);
|
2467
2541
|
if (exc != Qnil) {
|
2542
|
+
cb_gc_unprotect(bucket, exc);
|
2468
2543
|
rb_exc_raise(exc);
|
2469
2544
|
}
|
2470
2545
|
return rv;
|
@@ -2511,7 +2586,7 @@ cb_bucket_version(VALUE self)
|
|
2511
2586
|
if (!bucket->async && rb_block_given_p()) {
|
2512
2587
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
2513
2588
|
}
|
2514
|
-
ctx =
|
2589
|
+
ctx = xcalloc(1, sizeof(context_t));
|
2515
2590
|
if (ctx == NULL) {
|
2516
2591
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
2517
2592
|
}
|
@@ -2524,13 +2599,13 @@ cb_bucket_version(VALUE self)
|
|
2524
2599
|
} else {
|
2525
2600
|
ctx->proc = Qnil;
|
2526
2601
|
}
|
2527
|
-
|
2602
|
+
cb_gc_protect(bucket, ctx->proc);
|
2528
2603
|
seqno = bucket->seqno;
|
2529
2604
|
bucket->seqno++;
|
2530
2605
|
err = libcouchbase_server_versions(bucket->handle, (const void *)ctx);
|
2531
2606
|
exc = cb_check_error(err, "failed to schedule version request", Qnil);
|
2532
2607
|
if (exc != Qnil) {
|
2533
|
-
|
2608
|
+
xfree(ctx);
|
2534
2609
|
rb_exc_raise(exc);
|
2535
2610
|
}
|
2536
2611
|
if (bucket->async) {
|
@@ -2541,8 +2616,9 @@ cb_bucket_version(VALUE self)
|
|
2541
2616
|
bucket->io->run_event_loop(bucket->io);
|
2542
2617
|
}
|
2543
2618
|
exc = ctx->exception;
|
2544
|
-
|
2619
|
+
xfree(ctx);
|
2545
2620
|
if (exc != Qnil) {
|
2621
|
+
cb_gc_unprotect(bucket, exc);
|
2546
2622
|
rb_exc_raise(exc);
|
2547
2623
|
}
|
2548
2624
|
return rv;
|
@@ -2608,7 +2684,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
|
|
2608
2684
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
2609
2685
|
}
|
2610
2686
|
|
2611
|
-
ctx =
|
2687
|
+
ctx = xcalloc(1, sizeof(context_t));
|
2612
2688
|
if (ctx == NULL) {
|
2613
2689
|
rb_raise(eNoMemoryError, "failed to allocate memory for context");
|
2614
2690
|
}
|
@@ -2616,7 +2692,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
|
|
2616
2692
|
ctx->rv = &rv;
|
2617
2693
|
ctx->bucket = bucket;
|
2618
2694
|
ctx->proc = proc;
|
2619
|
-
|
2695
|
+
cb_gc_protect(bucket, ctx->proc);
|
2620
2696
|
ctx->exception = Qnil;
|
2621
2697
|
if (arg != Qnil) {
|
2622
2698
|
arg = unify_key(arg);
|
@@ -2632,7 +2708,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
|
|
2632
2708
|
key, nkey);
|
2633
2709
|
exc = cb_check_error(err, "failed to schedule stat request", Qnil);
|
2634
2710
|
if (exc != Qnil) {
|
2635
|
-
|
2711
|
+
xfree(ctx);
|
2636
2712
|
rb_exc_raise(exc);
|
2637
2713
|
}
|
2638
2714
|
if (bucket->async) {
|
@@ -2643,8 +2719,9 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
|
|
2643
2719
|
bucket->io->run_event_loop(bucket->io);
|
2644
2720
|
}
|
2645
2721
|
exc = ctx->exception;
|
2646
|
-
|
2722
|
+
xfree(ctx);
|
2647
2723
|
if (exc != Qnil) {
|
2724
|
+
cb_gc_unprotect(bucket, exc);
|
2648
2725
|
rb_exc_raise(exc);
|
2649
2726
|
}
|
2650
2727
|
if (bucket->exception != Qnil) {
|
@@ -3250,9 +3327,6 @@ Init_couchbase_ext(void)
|
|
3250
3327
|
* This class in charge of all stuff connected to communication with
|
3251
3328
|
* Couchbase. */
|
3252
3329
|
cBucket = rb_define_class_under(mCouchbase, "Bucket", rb_cObject);
|
3253
|
-
object_space = rb_hash_new();
|
3254
|
-
/* @private Hack to avoid GC in some cases */
|
3255
|
-
rb_define_const(cBucket, "OBJECT_SPACE", object_space);
|
3256
3330
|
|
3257
3331
|
/* 0x03: Bitmask for flag bits responsible for format */
|
3258
3332
|
rb_define_const(cBucket, "FMT_MASK", INT2FIX(FMT_MASK));
|
@@ -3272,9 +3346,9 @@ Init_couchbase_ext(void)
|
|
3272
3346
|
* http://dustin.github.com/2011/02/17/memcached-set.html */
|
3273
3347
|
rb_define_const(cBucket, "FMT_PLAIN", INT2FIX(FMT_PLAIN));
|
3274
3348
|
|
3275
|
-
|
3276
|
-
|
3349
|
+
rb_define_alloc_func(cBucket, cb_bucket_alloc);
|
3277
3350
|
rb_define_method(cBucket, "initialize", cb_bucket_init, -1);
|
3351
|
+
rb_define_method(cBucket, "initialize_copy", cb_bucket_init_copy, 1);
|
3278
3352
|
rb_define_method(cBucket, "inspect", cb_bucket_inspect, 0);
|
3279
3353
|
|
3280
3354
|
/* Document-method: seqno
|
@@ -3441,6 +3515,7 @@ Init_couchbase_ext(void)
|
|
3441
3515
|
id_arity = rb_intern("arity");
|
3442
3516
|
id_call = rb_intern("call");
|
3443
3517
|
id_dump = rb_intern("dump");
|
3518
|
+
id_dup = rb_intern("dup");
|
3444
3519
|
id_flatten_bang = rb_intern("flatten!");
|
3445
3520
|
id_has_key_p = rb_intern("has_key?");
|
3446
3521
|
id_host = rb_intern("host");
|
data/lib/couchbase/bucket.rb
CHANGED
@@ -57,12 +57,12 @@ module Couchbase
|
|
57
57
|
if async?
|
58
58
|
get(key, options) do |ret|
|
59
59
|
val = yield(ret) # get new value from caller
|
60
|
-
set(ret.key, val, :cas => ret.cas)
|
60
|
+
set(ret.key, val, :cas => ret.cas, :flags => ret.flags)
|
61
61
|
end
|
62
62
|
else
|
63
63
|
val, flags, ver = get(key, options)
|
64
64
|
val = yield(val) # get new value from caller
|
65
|
-
set(key, val, :cas => ver)
|
65
|
+
set(key, val, :cas => ver, :flags => flags)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
alias :compare_and_swap :cas
|
data/lib/couchbase/version.rb
CHANGED
data/test/test_cas.rb
CHANGED
@@ -56,4 +56,12 @@ class TestCas < MiniTest::Unit::TestCase
|
|
56
56
|
assert_equal expected, val
|
57
57
|
end
|
58
58
|
|
59
|
+
def test_flags_replication
|
60
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
|
61
|
+
:default_format => :document)
|
62
|
+
connection.set(uniq_id, "bar", :flags => 0x100)
|
63
|
+
connection.cas(uniq_id) { "baz" }
|
64
|
+
_, flags, _ = connection.get(uniq_id, :extended => true)
|
65
|
+
assert_equal 0x100, flags
|
66
|
+
end
|
59
67
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
@@ -198,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
198
198
|
version: '0'
|
199
199
|
segments:
|
200
200
|
- 0
|
201
|
-
hash:
|
201
|
+
hash: 4020867822083884443
|
202
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
203
|
none: false
|
204
204
|
requirements:
|
@@ -207,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
207
|
version: '0'
|
208
208
|
segments:
|
209
209
|
- 0
|
210
|
-
hash:
|
210
|
+
hash: 4020867822083884443
|
211
211
|
requirements: []
|
212
212
|
rubyforge_project:
|
213
213
|
rubygems_version: 1.8.24
|