couchbase 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ /* vim: ft=c et ts=8 sts=4 sw=4 cino=
2
+ *
3
+ * Copyright 2011, 2012 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "couchbase_ext.h"
19
+
20
+ static void
21
+ cb_context_mark(void *p, struct cb_bucket_st* bucket)
22
+ {
23
+ struct cb_context_st *ctx = p;
24
+ rb_gc_mark(ctx->proc);
25
+ rb_gc_mark(ctx->rv);
26
+ rb_gc_mark(ctx->exception);
27
+ rb_gc_mark(ctx->observe_options);
28
+ rb_gc_mark(ctx->force_format);
29
+ rb_gc_mark(ctx->operation);
30
+ rb_gc_mark(ctx->headers_val);
31
+ (void)bucket;
32
+ }
33
+
34
+ struct cb_context_st *
35
+ cb_context_alloc(struct cb_bucket_st* bucket)
36
+ {
37
+ struct cb_context_st *ctx = calloc(1, sizeof(*ctx));
38
+ if (ctx == NULL) {
39
+ rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
40
+ }
41
+ cb_gc_protect_ptr(bucket, ctx, cb_context_mark);
42
+ ctx->bucket = bucket;
43
+ ctx->exception = Qnil;
44
+ return ctx;
45
+ }
46
+
47
+ struct cb_context_st *
48
+ cb_context_alloc_common(struct cb_bucket_st *bucket, VALUE proc, size_t nqueries)
49
+ {
50
+ struct cb_context_st *ctx = cb_context_alloc(bucket);
51
+ ctx->proc = proc;
52
+ ctx->nqueries = nqueries;
53
+ if (!bucket->async) {
54
+ ctx->rv = rb_hash_new();
55
+ }
56
+ return ctx;
57
+ }
58
+
59
+ void
60
+ cb_context_free(struct cb_context_st *ctx)
61
+ {
62
+ cb_gc_unprotect_ptr(ctx->bucket, ctx);
63
+ free(ctx);
64
+ }
@@ -30,19 +30,23 @@ VALUE cb_mError;
30
30
  VALUE cb_mMarshal;
31
31
  VALUE cb_mMultiJson;
32
32
  VALUE cb_mURI;
33
+ VALUE em_m;
33
34
 
34
35
  /* Symbols */
35
36
  ID cb_sym_add;
36
37
  ID cb_sym_append;
37
38
  ID cb_sym_assemble_hash;
39
+ ID cb_sym_async;
38
40
  ID cb_sym_body;
39
41
  ID cb_sym_bucket;
40
42
  ID cb_sym_cas;
41
43
  ID cb_sym_chunked;
44
+ ID cb_sym_cluster;
45
+ ID cb_sym_connect;
42
46
  ID cb_sym_content_type;
43
47
  ID cb_sym_create;
44
- ID cb_sym_cluster;
45
48
  ID cb_sym_decrement;
49
+ ID cb_sym_default;
46
50
  ID cb_sym_default_arithmetic_init;
47
51
  ID cb_sym_default_flags;
48
52
  ID cb_sym_default_format;
@@ -52,7 +56,9 @@ ID cb_sym_delete;
52
56
  ID cb_sym_delta;
53
57
  ID cb_sym_development;
54
58
  ID cb_sym_document;
59
+ ID cb_sym_engine;
55
60
  ID cb_sym_environment;
61
+ ID cb_sym_eventmachine;
56
62
  ID cb_sym_extended;
57
63
  ID cb_sym_flags;
58
64
  ID cb_sym_format;
@@ -63,6 +69,8 @@ ID cb_sym_http_request;
63
69
  ID cb_sym_increment;
64
70
  ID cb_sym_initial;
65
71
  ID cb_sym_key_prefix;
72
+ ID cb_sym_libev;
73
+ ID cb_sym_libevent;
66
74
  ID cb_sym_lock;
67
75
  ID cb_sym_management;
68
76
  ID cb_sym_marshal;
@@ -95,8 +103,10 @@ ID cb_sym_unlock;
95
103
  ID cb_sym_username;
96
104
  ID cb_sym_version;
97
105
  ID cb_sym_view;
106
+ ID cb_id_add_shutdown_hook;
98
107
  ID cb_id_arity;
99
108
  ID cb_id_call;
109
+ ID cb_id_create_timer;
100
110
  ID cb_id_delete;
101
111
  ID cb_id_dump;
102
112
  ID cb_id_dup;
@@ -120,6 +130,7 @@ ID cb_id_iv_time_to_replicate;
120
130
  ID cb_id_iv_value;
121
131
  ID cb_id_load;
122
132
  ID cb_id_match;
133
+ ID cb_id_next_tick;
123
134
  ID cb_id_observe_and_wait;
124
135
  ID cb_id_parse;
125
136
  ID cb_id_parse_body_bang;
@@ -170,11 +181,26 @@ VALUE cb_eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
170
181
  /* Default Strings */
171
182
  VALUE cb_vStrDefault;
172
183
  VALUE cb_vStrEmpty;
184
+ VALUE cb_vStrLocalhost;
185
+
186
+ static VALUE
187
+ cb_intern_string(VALUE ar, const char *str)
188
+ {
189
+ VALUE tmp = STR_NEW_CSTR(str);
190
+ rb_str_freeze(tmp);
191
+ rb_ary_push(ar, tmp);
192
+ return tmp;
193
+ }
173
194
 
174
195
  /* Ruby Extension initializer */
175
196
  void
176
197
  Init_couchbase_ext(void)
177
198
  {
199
+ VALUE interned;
200
+
201
+ /* just a holder for EventMachine module */
202
+ em_m = 0;
203
+
178
204
  cb_mMultiJson = rb_const_get(rb_cObject, rb_intern("MultiJson"));
179
205
  cb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
180
206
  cb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
@@ -505,6 +531,7 @@ Init_couchbase_ext(void)
505
531
  */
506
532
  cb_cResult = rb_define_class_under(cb_mCouchbase, "Result", rb_cObject);
507
533
  rb_define_method(cb_cResult, "inspect", cb_result_inspect, 0);
534
+ rb_define_method(cb_cResult, "to_s", cb_result_inspect, 0);
508
535
  rb_define_method(cb_cResult, "success?", cb_result_success_p, 0);
509
536
  /* Document-method: operation
510
537
  *
@@ -535,6 +562,7 @@ Init_couchbase_ext(void)
535
562
  * @return [String]
536
563
  */
537
564
  rb_define_attr(cb_cResult, "value", 1, 0);
565
+ rb_define_alias(cb_cResult, "bucket", "value");
538
566
  cb_id_iv_value = rb_intern("@value");
539
567
  /* Document-method: cas
540
568
  *
@@ -816,27 +844,82 @@ Init_couchbase_ext(void)
816
844
  *
817
845
  * This callback is using to deliver exceptions in asynchronous mode.
818
846
  *
819
- * @yieldparam [Symbol] op The operation caused the error
820
- * @yieldparam [String] key The key which cause the error or +nil+
821
847
  * @yieldparam [Exception] exc The exception instance
822
848
  *
823
849
  * @example Using lambda syntax
824
- * connection = Couchbase.new(:async => true)
825
- * connection.on_error = lambda {|op, key, exc| ... }
850
+ * connection = Couchbase.connect
851
+ * connection.on_error = lambda {|exc| ... }
826
852
  * connection.run do |conn|
827
853
  * conn.set("foo", "bar")
828
854
  * end
829
855
  *
830
856
  * @example Using block syntax
831
- * connection = Couchbase.new(:async => true)
832
- * connection.on_error {|op, key, exc| ... }
833
- * ...
857
+ * connection = Couchbase.connect
858
+ * connection.on_error {|exc| ... }
859
+ * connection.run do |conn|
860
+ * conn.set("foo", "bar")
861
+ * end
834
862
  *
835
863
  * @return [Proc] the effective callback */
836
864
  /* rb_define_attr(cb_cBucket, "on_error", 1, 1); */
837
865
  rb_define_method(cb_cBucket, "on_error", cb_bucket_on_error_get, 0);
838
866
  rb_define_method(cb_cBucket, "on_error=", cb_bucket_on_error_set, 1);
839
867
 
868
+ /* Document-method: on_connect
869
+ * Connection callback for asynchronous mode.
870
+ *
871
+ * @since 1.3.0
872
+ *
873
+ * This callback used to notify that bucket instance is connected
874
+ * and ready to handle requests in asynchronous mode.
875
+ *
876
+ * @yieldparam [Result] result The result instance, with valid
877
+ * properties +#error+, +#success?+, +#operation+ and +#bucket+
878
+ *
879
+ * @example Using lambda syntax
880
+ * connection = Couchbase.new(:async => true)
881
+ * connection.on_connect = lambda do |ret|
882
+ * if ret.success?
883
+ * conn.set("foo", "bar")
884
+ * end
885
+ * end
886
+ * connection.run
887
+ *
888
+ * @example Using block syntax
889
+ * connection = Couchbase.new(:async => true)
890
+ * connection.run do |conn|
891
+ * connection.on_connect do |ret|
892
+ * if ret.success?
893
+ * conn.set("foo", "bar")
894
+ * end
895
+ * end
896
+ * end
897
+ *
898
+ * @example
899
+ * EM.run do
900
+ * pool = Pool.new
901
+ * connection = Couchbase.new(:engine => :eventmachine, :async => true)
902
+ * connection.on_connect do |result|
903
+ * unless result.success?
904
+ * $stderr.puts "Could not connect to CouchBase #{result.error}"
905
+ * else
906
+ * pool.add result.bucket
907
+ * end
908
+ * end
909
+ * end
910
+ *
911
+ * @example
912
+ * EM.run do
913
+ * pool = Pool.new
914
+ * connection = Couchbase.new(:engine => :eventmachine, :async => true)
915
+ * connection.on_connect = pool.method(:couchbase_connect_callback)
916
+ * end
917
+ *
918
+ * @return [Proc] the effective callback */
919
+ /* rb_define_attr(cb_cBucket, "on_connect", 1, 1); */
920
+ rb_define_method(cb_cBucket, "on_connect", cb_bucket_on_connect_get, 0);
921
+ rb_define_method(cb_cBucket, "on_connect=", cb_bucket_on_connect_set, 1);
922
+
840
923
  /* Document-method: url
841
924
  *
842
925
  * The config url for this connection.
@@ -994,8 +1077,10 @@ Init_couchbase_ext(void)
994
1077
  rb_define_method(cb_cTimer, "cancel", cb_timer_cancel, 0);
995
1078
 
996
1079
  /* Define cb_symbols */
1080
+ cb_id_add_shutdown_hook = rb_intern("add_shutdown_hook");
997
1081
  cb_id_arity = rb_intern("arity");
998
1082
  cb_id_call = rb_intern("call");
1083
+ cb_id_create_timer = rb_intern("create_timer");
999
1084
  cb_id_delete = rb_intern("delete");
1000
1085
  cb_id_dump = rb_intern("dump");
1001
1086
  cb_id_dup = rb_intern("dup");
@@ -1004,6 +1089,7 @@ Init_couchbase_ext(void)
1004
1089
  cb_id_host = rb_intern("host");
1005
1090
  cb_id_load = rb_intern("load");
1006
1091
  cb_id_match = rb_intern("match");
1092
+ cb_id_next_tick = rb_intern("next_tick");
1007
1093
  cb_id_observe_and_wait = rb_intern("observe_and_wait");
1008
1094
  cb_id_parse = rb_intern("parse");
1009
1095
  cb_id_parse_body_bang = rb_intern("parse_body!");
@@ -1019,14 +1105,17 @@ Init_couchbase_ext(void)
1019
1105
  cb_sym_add = ID2SYM(rb_intern("add"));
1020
1106
  cb_sym_append = ID2SYM(rb_intern("append"));
1021
1107
  cb_sym_assemble_hash = ID2SYM(rb_intern("assemble_hash"));
1108
+ cb_sym_async = ID2SYM(rb_intern("async"));
1022
1109
  cb_sym_body = ID2SYM(rb_intern("body"));
1023
1110
  cb_sym_bucket = ID2SYM(rb_intern("bucket"));
1024
1111
  cb_sym_cas = ID2SYM(rb_intern("cas"));
1025
1112
  cb_sym_chunked = ID2SYM(rb_intern("chunked"));
1026
1113
  cb_sym_cluster = ID2SYM(rb_intern("cluster"));
1114
+ cb_sym_connect = ID2SYM(rb_intern("connect"));
1027
1115
  cb_sym_content_type = ID2SYM(rb_intern("content_type"));
1028
1116
  cb_sym_create = ID2SYM(rb_intern("create"));
1029
1117
  cb_sym_decrement = ID2SYM(rb_intern("decrement"));
1118
+ cb_sym_default = ID2SYM(rb_intern("default"));
1030
1119
  cb_sym_default_arithmetic_init = ID2SYM(rb_intern("default_arithmetic_init"));
1031
1120
  cb_sym_default_flags = ID2SYM(rb_intern("default_flags"));
1032
1121
  cb_sym_default_format = ID2SYM(rb_intern("default_format"));
@@ -1035,7 +1124,9 @@ Init_couchbase_ext(void)
1035
1124
  cb_sym_delta = ID2SYM(rb_intern("delta"));
1036
1125
  cb_sym_development = ID2SYM(rb_intern("development"));
1037
1126
  cb_sym_document = ID2SYM(rb_intern("document"));
1127
+ cb_sym_engine = ID2SYM(rb_intern("engine"));
1038
1128
  cb_sym_environment = ID2SYM(rb_intern("environment"));
1129
+ cb_sym_eventmachine = ID2SYM(rb_intern("eventmachine"));
1039
1130
  cb_sym_extended = ID2SYM(rb_intern("extended"));
1040
1131
  cb_sym_flags = ID2SYM(rb_intern("flags"));
1041
1132
  cb_sym_format = ID2SYM(rb_intern("format"));
@@ -1046,6 +1137,8 @@ Init_couchbase_ext(void)
1046
1137
  cb_sym_increment = ID2SYM(rb_intern("increment"));
1047
1138
  cb_sym_initial = ID2SYM(rb_intern("initial"));
1048
1139
  cb_sym_key_prefix = ID2SYM(rb_intern("key_prefix"));
1140
+ cb_sym_libev = ID2SYM(rb_intern("libev"));
1141
+ cb_sym_libevent = ID2SYM(rb_intern("libevent"));
1049
1142
  cb_sym_lock = ID2SYM(rb_intern("lock"));
1050
1143
  cb_sym_management = ID2SYM(rb_intern("management"));
1051
1144
  cb_sym_marshal = ID2SYM(rb_intern("marshal"));
@@ -1079,10 +1172,9 @@ Init_couchbase_ext(void)
1079
1172
  cb_sym_version = ID2SYM(rb_intern("version"));
1080
1173
  cb_sym_view = ID2SYM(rb_intern("view"));
1081
1174
 
1082
- cb_vStrDefault = STR_NEW_CSTR("default");
1083
- rb_str_freeze(cb_vStrDefault);
1084
- rb_const_set(cb_mCouchbase, rb_intern("_STR_DEFAULT"), cb_vStrDefault);
1085
- cb_vStrEmpty = STR_NEW_CSTR("");
1086
- rb_str_freeze(cb_vStrEmpty);
1087
- rb_const_set(cb_mCouchbase, rb_intern("_STR_EMPTY"), cb_vStrEmpty);
1175
+ interned = rb_ary_new();
1176
+ rb_const_set(cb_mCouchbase, rb_intern("_INTERNED"), interned);
1177
+ cb_vStrDefault = cb_intern_string(interned, "default");
1178
+ cb_vStrEmpty = cb_intern_string(interned, "");
1179
+ cb_vStrLocalhost = cb_intern_string(interned, "localhost");
1088
1180
  }
@@ -23,6 +23,9 @@
23
23
  #endif
24
24
 
25
25
  #include "couchbase_config.h"
26
+ #ifdef HAVE_RB_FIBER_YIELD
27
+ #define BUILD_EVENTMACHINE_PLUGIN
28
+ #endif
26
29
  #ifdef HAVE_STDINT_H
27
30
  #include <stdint.h>
28
31
  #endif
@@ -54,13 +57,20 @@ extern hrtime_t gethrtime(void);
54
57
  #ifndef HAVE_RB_HASH_LOOKUP2
55
58
  VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
56
59
  #endif
60
+ #ifndef HAVE_TYPE_ST_INDEX_T
61
+ typedef st_data_t st_index_t;
62
+ #endif
57
63
 
58
- #define cb_debug_object(OBJ) \
59
- rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
60
- rb_funcall(rb_stderr, rb_intern("print"), 1, STR_NEW_CSTR(" ")); \
61
- rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("class"), 0)); \
62
- rb_funcall(rb_stderr, rb_intern("print"), 1, STR_NEW_CSTR(" ")); \
63
- rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
64
+ #define cb_debug_object(OBJ) do { \
65
+ VALUE debug_args[6] = { \
66
+ rb_funcall(OBJ, rb_intern("object_id"), 0), \
67
+ STR_NEW_CSTR(" "), \
68
+ rb_funcall(OBJ, rb_intern("class"), 0), \
69
+ STR_NEW_CSTR(" "), \
70
+ rb_funcall(OBJ, rb_intern("inspect"), 0), \
71
+ STR_NEW_CSTR("\n") }; \
72
+ rb_funcall2(rb_stderr, rb_intern("print"), 6, debug_args); \
73
+ } while(0)
64
74
 
65
75
  #define CB_FMT_MASK 0x3
66
76
  #define CB_FMT_DOCUMENT 0x0
@@ -81,8 +91,12 @@ struct cb_bucket_st
81
91
  VALUE bucket;
82
92
  VALUE username;
83
93
  VALUE password;
94
+ VALUE engine;
84
95
  int async;
85
96
  int quiet;
97
+ uint8_t connected; /* non-zero if instance has been connected. it is possible to defer connection with :async option */
98
+ uint8_t running; /* non-zero if event loop is running */
99
+ uint8_t trigger_connect_cb_on_set; /* if non-zero, the on_connect callback will be triggered immediately after set */
86
100
  VALUE default_format; /* should update +default_flags+ on change */
87
101
  uint32_t default_flags;
88
102
  time_t default_ttl;
@@ -94,10 +108,13 @@ struct cb_bucket_st
94
108
  size_t nbytes; /* the number of bytes scheduled to be sent */
95
109
  VALUE exception; /* error delivered by error_callback */
96
110
  VALUE on_error_proc; /* is using to deliver errors in async mode */
111
+ VALUE on_connect_proc; /* used to notify that instance ready to handle requests in async mode */
97
112
  VALUE environment; /* sym_development or sym_production */
98
113
  VALUE key_prefix_val;
99
114
  VALUE node_list;
100
- VALUE object_space;
115
+ st_table *object_space;
116
+ char destroying;
117
+ char async_disconnect_hook_set;
101
118
  VALUE self; /* the pointer to bucket representation in ruby land */
102
119
  };
103
120
 
@@ -107,7 +124,7 @@ struct cb_context_st
107
124
  struct cb_bucket_st* bucket;
108
125
  int extended;
109
126
  VALUE proc;
110
- void *rv;
127
+ VALUE rv;
111
128
  VALUE exception;
112
129
  VALUE observe_options;
113
130
  VALUE force_format;
@@ -117,7 +134,6 @@ struct cb_context_st
117
134
  struct cb_http_request_st *request;
118
135
  int quiet;
119
136
  int arith; /* incr: +1, decr: -1, other: 0 */
120
- int http_cancel_on_error;
121
137
  size_t nqueries;
122
138
  };
123
139
 
@@ -156,19 +172,23 @@ extern VALUE cb_mError;
156
172
  extern VALUE cb_mMarshal;
157
173
  extern VALUE cb_mMultiJson;
158
174
  extern VALUE cb_mURI;
175
+ extern VALUE em_m;
159
176
 
160
177
  /* Symbols */
161
178
  extern ID cb_sym_add;
162
179
  extern ID cb_sym_append;
163
180
  extern ID cb_sym_assemble_hash;
181
+ extern ID cb_sym_async;
164
182
  extern ID cb_sym_body;
165
183
  extern ID cb_sym_bucket;
166
184
  extern ID cb_sym_cas;
167
185
  extern ID cb_sym_chunked;
168
186
  extern ID cb_sym_cluster;
187
+ extern ID cb_sym_connect;
169
188
  extern ID cb_sym_content_type;
170
189
  extern ID cb_sym_create;
171
190
  extern ID cb_sym_decrement;
191
+ extern ID cb_sym_default;
172
192
  extern ID cb_sym_default_arithmetic_init;
173
193
  extern ID cb_sym_default_flags;
174
194
  extern ID cb_sym_default_format;
@@ -178,7 +198,9 @@ extern ID cb_sym_delete;
178
198
  extern ID cb_sym_delta;
179
199
  extern ID cb_sym_development;
180
200
  extern ID cb_sym_document;
201
+ extern ID cb_sym_engine;
181
202
  extern ID cb_sym_environment;
203
+ extern ID cb_sym_eventmachine;
182
204
  extern ID cb_sym_extended;
183
205
  extern ID cb_sym_flags;
184
206
  extern ID cb_sym_format;
@@ -189,6 +211,8 @@ extern ID cb_sym_http_request;
189
211
  extern ID cb_sym_increment;
190
212
  extern ID cb_sym_initial;
191
213
  extern ID cb_sym_key_prefix;
214
+ extern ID cb_sym_libev;
215
+ extern ID cb_sym_libevent;
192
216
  extern ID cb_sym_lock;
193
217
  extern ID cb_sym_management;
194
218
  extern ID cb_sym_marshal;
@@ -221,8 +245,10 @@ extern ID cb_sym_unlock;
221
245
  extern ID cb_sym_username;
222
246
  extern ID cb_sym_version;
223
247
  extern ID cb_sym_view;
248
+ extern ID cb_id_add_shutdown_hook;
224
249
  extern ID cb_id_arity;
225
250
  extern ID cb_id_call;
251
+ extern ID cb_id_create_timer;
226
252
  extern ID cb_id_delete;
227
253
  extern ID cb_id_dump;
228
254
  extern ID cb_id_dup;
@@ -246,6 +272,7 @@ extern ID cb_id_iv_time_to_replicate;
246
272
  extern ID cb_id_iv_value;
247
273
  extern ID cb_id_load;
248
274
  extern ID cb_id_match;
275
+ extern ID cb_id_next_tick;
249
276
  extern ID cb_id_observe_and_wait;
250
277
  extern ID cb_id_parse;
251
278
  extern ID cb_id_parse_body_bang;
@@ -295,12 +322,15 @@ extern VALUE cb_eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
295
322
  /* Default Strings */
296
323
  extern VALUE cb_vStrDefault;
297
324
  extern VALUE cb_vStrEmpty;
325
+ extern VALUE cb_vStrLocalhost;
298
326
 
327
+ typedef void (*mark_f)(void *, struct cb_bucket_st*);
299
328
  void cb_strip_key_prefix(struct cb_bucket_st *bucket, VALUE key);
300
329
  VALUE cb_check_error(lcb_error_t rc, const char *msg, VALUE key);
301
330
  VALUE cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key, lcb_http_status_t status);
302
- VALUE cb_gc_protect(struct cb_bucket_st *bucket, VALUE val);
303
- VALUE cb_gc_unprotect(struct cb_bucket_st *bucket, VALUE val);
331
+ int cb_bucket_connected_bang(struct cb_bucket_st *bucket, VALUE operation);
332
+ void cb_gc_protect_ptr(struct cb_bucket_st *bucket, void *ptr, mark_f mark_func);
333
+ void cb_gc_unprotect_ptr(struct cb_bucket_st *bucket, void *ptr);
304
334
  VALUE cb_proc_call(struct cb_bucket_st *bucket, VALUE recv, int argc, ...);
305
335
  int cb_first_value_i(VALUE key, VALUE value, VALUE arg);
306
336
  void cb_build_headers(struct cb_context_st *ctx, const char * const *headers);
@@ -325,6 +355,10 @@ void cb_http_data_callback(lcb_http_request_t request, lcb_t handle, const void
325
355
  void cb_observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_observe_resp_t *resp);
326
356
  void cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_resp_t *resp);
327
357
 
358
+ struct cb_context_st *cb_context_alloc(struct cb_bucket_st *bucket);
359
+ struct cb_context_st *cb_context_alloc_common(struct cb_bucket_st *bucket, VALUE proc, size_t nqueries);
360
+ void cb_context_free(struct cb_context_st *ctx);
361
+
328
362
  VALUE cb_bucket_alloc(VALUE klass);
329
363
  void cb_bucket_free(void *ptr);
330
364
  VALUE cb_bucket_init_copy(VALUE copy, VALUE orig);
@@ -360,6 +394,8 @@ VALUE cb_bucket_default_format_get(VALUE self);
360
394
  VALUE cb_bucket_default_format_set(VALUE self, VALUE val);
361
395
  VALUE cb_bucket_on_error_set(VALUE self, VALUE val);
362
396
  VALUE cb_bucket_on_error_get(VALUE self);
397
+ VALUE cb_bucket_on_connect_set(VALUE self, VALUE val);
398
+ VALUE cb_bucket_on_connect_get(VALUE self);
363
399
  VALUE cb_bucket_timeout_get(VALUE self);
364
400
  VALUE cb_bucket_timeout_set(VALUE self, VALUE val);
365
401
  VALUE cb_bucket_key_prefix_get(VALUE self);
@@ -535,12 +571,45 @@ struct cb_params_st
535
571
  size_t idx;
536
572
  /* the approximate size of the data to be sent */
537
573
  size_t npayload;
574
+ VALUE ensurance;
575
+ VALUE args;
538
576
  };
539
577
 
540
578
  void cb_params_destroy(struct cb_params_st *params);
541
- void cb_params_build(struct cb_params_st *params, int argc, VALUE argv);
579
+ void cb_params_build(struct cb_params_st *params);
542
580
 
581
+ /* common plugin functions */
582
+ lcb_ssize_t cb_io_recv(struct lcb_io_opt_st *iops, lcb_socket_t sock, void *buffer, lcb_size_t len, int flags);
583
+ lcb_ssize_t cb_io_recvv(struct lcb_io_opt_st *iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov);
584
+ lcb_ssize_t cb_io_send(struct lcb_io_opt_st *iops, lcb_socket_t sock, const void *msg, lcb_size_t len, int flags);
585
+ lcb_ssize_t cb_io_sendv(struct lcb_io_opt_st *iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov);
586
+ lcb_socket_t cb_io_socket(struct lcb_io_opt_st *iops, int domain, int type, int protocol);
587
+ void cb_io_close(struct lcb_io_opt_st *iops, lcb_socket_t sock);
588
+ int cb_io_connect(struct lcb_io_opt_st *iops, lcb_socket_t sock, const struct sockaddr *name, unsigned int namelen);
589
+
590
+ /* plugin init functions */
543
591
  LIBCOUCHBASE_API
544
592
  lcb_error_t cb_create_ruby_mt_io_opts(int version, lcb_io_opt_t *io, void *arg);
593
+
594
+ /* shortcut functions */
595
+ static inline VALUE
596
+ rb_funcall_0(VALUE self, ID method)
597
+ {
598
+ return rb_funcall2(self, method, 0, NULL);
599
+ }
600
+
601
+ static inline VALUE
602
+ rb_funcall_1(VALUE self, ID method, VALUE arg)
603
+ {
604
+ return rb_funcall2(self, method, 1, &arg);
605
+ }
606
+
607
+ static inline VALUE
608
+ rb_funcall_2(VALUE self, ID method, VALUE arg1, VALUE arg2)
609
+ {
610
+ VALUE args[2] = {arg1, arg2};
611
+ return rb_funcall2(self, method, 2, args);
612
+ }
613
+
545
614
  #endif
546
615