couchbase 1.3.4-x64-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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +22 -0
  4. data/.yardopts +5 -0
  5. data/CONTRIBUTING.markdown +75 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +201 -0
  8. data/Makefile +3 -0
  9. data/README.markdown +649 -0
  10. data/RELEASE_NOTES.markdown +796 -0
  11. data/Rakefile +20 -0
  12. data/couchbase.gemspec +49 -0
  13. data/examples/chat-em/Gemfile +7 -0
  14. data/examples/chat-em/README.markdown +45 -0
  15. data/examples/chat-em/server.rb +82 -0
  16. data/examples/chat-goliath-grape/Gemfile +5 -0
  17. data/examples/chat-goliath-grape/README.markdown +50 -0
  18. data/examples/chat-goliath-grape/app.rb +67 -0
  19. data/examples/chat-goliath-grape/config/app.rb +20 -0
  20. data/examples/transcoders/Gemfile +3 -0
  21. data/examples/transcoders/README.markdown +59 -0
  22. data/examples/transcoders/cb-zcat +40 -0
  23. data/examples/transcoders/cb-zcp +45 -0
  24. data/examples/transcoders/gzip_transcoder.rb +49 -0
  25. data/examples/transcoders/options.rb +54 -0
  26. data/ext/couchbase_ext/.gitignore +4 -0
  27. data/ext/couchbase_ext/arguments.c +956 -0
  28. data/ext/couchbase_ext/arithmetic.c +307 -0
  29. data/ext/couchbase_ext/bucket.c +1370 -0
  30. data/ext/couchbase_ext/context.c +65 -0
  31. data/ext/couchbase_ext/couchbase_ext.c +1364 -0
  32. data/ext/couchbase_ext/couchbase_ext.h +644 -0
  33. data/ext/couchbase_ext/delete.c +163 -0
  34. data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
  35. data/ext/couchbase_ext/extconf.rb +168 -0
  36. data/ext/couchbase_ext/get.c +316 -0
  37. data/ext/couchbase_ext/gethrtime.c +129 -0
  38. data/ext/couchbase_ext/http.c +432 -0
  39. data/ext/couchbase_ext/multithread_plugin.c +1090 -0
  40. data/ext/couchbase_ext/observe.c +171 -0
  41. data/ext/couchbase_ext/plugin_common.c +171 -0
  42. data/ext/couchbase_ext/result.c +129 -0
  43. data/ext/couchbase_ext/stats.c +163 -0
  44. data/ext/couchbase_ext/store.c +542 -0
  45. data/ext/couchbase_ext/timer.c +192 -0
  46. data/ext/couchbase_ext/touch.c +186 -0
  47. data/ext/couchbase_ext/unlock.c +176 -0
  48. data/ext/couchbase_ext/utils.c +551 -0
  49. data/ext/couchbase_ext/version.c +142 -0
  50. data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
  51. data/lib/active_support/cache/couchbase_store.rb +430 -0
  52. data/lib/couchbase.rb +155 -0
  53. data/lib/couchbase/bucket.rb +457 -0
  54. data/lib/couchbase/cluster.rb +119 -0
  55. data/lib/couchbase/connection_pool.rb +58 -0
  56. data/lib/couchbase/constants.rb +12 -0
  57. data/lib/couchbase/result.rb +26 -0
  58. data/lib/couchbase/transcoder.rb +120 -0
  59. data/lib/couchbase/utils.rb +62 -0
  60. data/lib/couchbase/version.rb +21 -0
  61. data/lib/couchbase/view.rb +506 -0
  62. data/lib/couchbase/view_row.rb +272 -0
  63. data/lib/ext/multi_json_fix.rb +56 -0
  64. data/lib/rack/session/couchbase.rb +108 -0
  65. data/tasks/benchmark.rake +6 -0
  66. data/tasks/compile.rake +158 -0
  67. data/tasks/test.rake +100 -0
  68. data/tasks/util.rake +21 -0
  69. data/test/profile/.gitignore +1 -0
  70. data/test/profile/Gemfile +6 -0
  71. data/test/profile/benchmark.rb +195 -0
  72. data/test/setup.rb +178 -0
  73. data/test/test_arithmetic.rb +185 -0
  74. data/test/test_async.rb +316 -0
  75. data/test/test_bucket.rb +250 -0
  76. data/test/test_cas.rb +235 -0
  77. data/test/test_couchbase.rb +77 -0
  78. data/test/test_couchbase_connection_pool.rb +77 -0
  79. data/test/test_couchbase_rails_cache_store.rb +361 -0
  80. data/test/test_delete.rb +120 -0
  81. data/test/test_errors.rb +82 -0
  82. data/test/test_eventmachine.rb +70 -0
  83. data/test/test_format.rb +164 -0
  84. data/test/test_get.rb +407 -0
  85. data/test/test_stats.rb +57 -0
  86. data/test/test_store.rb +216 -0
  87. data/test/test_timer.rb +42 -0
  88. data/test/test_touch.rb +97 -0
  89. data/test/test_unlock.rb +119 -0
  90. data/test/test_utils.rb +58 -0
  91. data/test/test_version.rb +52 -0
  92. metadata +336 -0
@@ -0,0 +1,129 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2010, 2011 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
+ #ifndef HAVE_GETHRTIME
21
+
22
+ #include <stdlib.h>
23
+ #include <time.h>
24
+ #include <assert.h>
25
+
26
+ #ifdef HAVE_MACH_MACH_TIME_H
27
+ #include <mach/mach_time.h>
28
+ #endif
29
+
30
+ #ifdef HAVE_SYS_TIME_H
31
+ #include <sys/time.h>
32
+ #endif
33
+
34
+ /*
35
+ * OS X doesn't have clock_gettime, but for monotonic, we can build
36
+ * one with mach_absolute_time as shown below.
37
+ *
38
+ * Most of the idea came from
39
+ * http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/
40
+ */
41
+
42
+ #if defined(HAVE_MACH_ABSOLUTE_TIME) && !defined(HAVE_CLOCK_GETTIME)
43
+
44
+ #define CLOCK_MONOTONIC 192996728
45
+
46
+ static void mach_absolute_difference(uint64_t start, uint64_t end,
47
+ struct timespec *tp)
48
+ {
49
+ uint64_t difference = end - start;
50
+ static mach_timebase_info_data_t info = {0, 0};
51
+
52
+ if (info.denom == 0) {
53
+ mach_timebase_info(&info);
54
+ }
55
+
56
+ uint64_t elapsednano = difference * (info.numer / info.denom);
57
+
58
+ tp->tv_sec = elapsednano * 1e-9;
59
+ tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
60
+ }
61
+
62
+ static int clock_gettime(int which, struct timespec *tp)
63
+ {
64
+ assert(which == CLOCK_MONOTONIC);
65
+
66
+ static uint64_t epoch = 0;
67
+
68
+ if (epoch == 0) {
69
+ epoch = mach_absolute_time();
70
+ }
71
+
72
+ uint64_t now = mach_absolute_time();
73
+
74
+ mach_absolute_difference(epoch, now, tp);
75
+
76
+ return 0;
77
+ }
78
+
79
+ #define HAVE_CLOCK_GETTIME 1
80
+ #endif
81
+
82
+ hrtime_t gethrtime(void)
83
+ {
84
+ #ifdef HAVE_CLOCK_GETTIME
85
+ struct timespec tm;
86
+ if (clock_gettime(CLOCK_MONOTONIC, &tm) == -1) {
87
+ abort();
88
+ }
89
+ return (((hrtime_t)tm.tv_sec) * 1000000000) + (hrtime_t)tm.tv_nsec;
90
+ #elif HAVE_GETTIMEOFDAY
91
+
92
+ hrtime_t ret;
93
+ struct timeval tv;
94
+ if (gettimeofday(&tv, NULL) == -1) {
95
+ return (-1ULL);
96
+ }
97
+
98
+ ret = (hrtime_t)tv.tv_sec * 1000000000;
99
+ ret += tv.tv_usec * 1000;
100
+ return ret;
101
+ #elif defined(HAVE_QUERYPERFORMANCECOUNTER)
102
+ double ret;
103
+ // To fix the potential race condition for the local static variable,
104
+ // gethrtime should be called in a global static variable first.
105
+ // It will guarantee the local static variable will be initialized
106
+ // before any thread calls the function.
107
+ static LARGE_INTEGER pf = { 0 };
108
+ static double freq;
109
+ LARGE_INTEGER currtime;
110
+
111
+ if (pf.QuadPart == 0) {
112
+ if (QueryPerformanceFrequency(&pf)) {
113
+ assert(pf.QuadPart != 0);
114
+ freq = 1.0e9 / (double)pf.QuadPart;
115
+ } else {
116
+ abort();
117
+ }
118
+ }
119
+
120
+ QueryPerformanceCounter(&currtime);
121
+
122
+ ret = (double)currtime.QuadPart * freq ;
123
+ return (hrtime_t)ret;
124
+ #else
125
+ #error "I don't know how to build a highres clock..."
126
+ #endif
127
+ }
128
+
129
+ #endif
@@ -0,0 +1,432 @@
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
+ void
21
+ cb_http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
22
+ {
23
+ struct cb_context_st *ctx = (struct cb_context_st *)cookie;
24
+ struct cb_bucket_st *bucket = ctx->bucket;
25
+ VALUE key, val, res, exc;
26
+ lcb_http_status_t status;
27
+
28
+ ctx->request->completed = 1;
29
+
30
+ if (bucket->destroying) {
31
+ cb_context_free(ctx);
32
+ return;
33
+ }
34
+
35
+ key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
36
+ val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
37
+ exc = ctx->exception;
38
+ if (!RTEST(exc)) {
39
+ exc = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status);
40
+ if (exc != Qnil && val != Qnil) {
41
+ rb_ivar_set(exc, cb_id_iv_body, val);
42
+ }
43
+ }
44
+ if (RTEST(exc)) {
45
+ if (rb_obj_is_kind_of(exc, cb_eHTTPError)) {
46
+ rb_funcall(exc, cb_id_parse_body_bang, 0);
47
+ }
48
+ ctx->exception = exc;
49
+ }
50
+ status = resp->v.v0.status;
51
+ if (resp->v.v0.headers) {
52
+ cb_build_headers(ctx, resp->v.v0.headers);
53
+ ctx->headers_val = Qnil;
54
+ }
55
+ if (ctx->extended) {
56
+ res = rb_class_new_instance(0, NULL, cb_cResult);
57
+ rb_ivar_set(res, cb_id_iv_error, ctx->exception);
58
+ rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
59
+ rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
60
+ rb_ivar_set(res, cb_id_iv_key, key);
61
+ rb_ivar_set(res, cb_id_iv_value, val);
62
+ rb_ivar_set(res, cb_id_iv_completed, Qtrue);
63
+ rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
64
+ } else {
65
+ res = val;
66
+ }
67
+ if (ctx->proc != Qnil) {
68
+ cb_proc_call(bucket, ctx->proc, 1, res);
69
+ ctx->proc = Qnil;
70
+ }
71
+ if (!bucket->async && ctx->exception == Qnil) {
72
+ ctx->rv = res;
73
+ }
74
+ if (bucket->async) {
75
+ cb_context_free(ctx);
76
+ }
77
+ (void)handle;
78
+ (void)request;
79
+ }
80
+
81
+ void
82
+ cb_http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
83
+ {
84
+ struct cb_context_st *ctx = (struct cb_context_st *)cookie;
85
+ struct cb_bucket_st *bucket = ctx->bucket;
86
+ VALUE key, val, res;
87
+ lcb_http_status_t status;
88
+
89
+ key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
90
+ val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
91
+ status = resp->v.v0.status;
92
+ if (NIL_P(ctx->exception)) {
93
+ ctx->exception = cb_check_error_with_status(error,
94
+ "failed to execute HTTP request", key, resp->v.v0.status);
95
+ if (ctx->exception != Qnil) {
96
+ VALUE body_str = rb_ivar_get(ctx->exception, cb_id_iv_body);
97
+ if (NIL_P(body_str)) {
98
+ rb_ivar_set(ctx->exception, cb_id_iv_body, val);
99
+ } else {
100
+ rb_str_concat(body_str, val);
101
+ }
102
+ return;
103
+ }
104
+ }
105
+ if (resp->v.v0.headers) {
106
+ cb_build_headers(ctx, resp->v.v0.headers);
107
+ }
108
+ if (ctx->proc != Qnil) {
109
+ if (ctx->extended) {
110
+ res = rb_class_new_instance(0, NULL, cb_cResult);
111
+ rb_ivar_set(res, cb_id_iv_error, Qnil);
112
+ rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
113
+ rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
114
+ rb_ivar_set(res, cb_id_iv_key, key);
115
+ rb_ivar_set(res, cb_id_iv_value, val);
116
+ rb_ivar_set(res, cb_id_iv_completed, Qfalse);
117
+ rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
118
+ } else {
119
+ res = val;
120
+ }
121
+ cb_proc_call(bucket, ctx->proc, 1, res);
122
+ }
123
+ (void)handle;
124
+ (void)request;
125
+ }
126
+
127
+ void
128
+ cb_http_request_free(void *ptr)
129
+ {
130
+ struct cb_http_request_st *request = ptr;
131
+ if (request) {
132
+ request->running = 0;
133
+ if (TYPE(request->bucket_obj) == T_DATA
134
+ && RDATA(request->bucket_obj)->dfree == (RUBY_DATA_FUNC)cb_bucket_free
135
+ && !request->completed) {
136
+ lcb_cancel_http_request(request->bucket->handle, request->request);
137
+ }
138
+ free((char *)request->cmd.v.v0.content_type);
139
+ free((char *)request->cmd.v.v0.path);
140
+ free((char *)request->cmd.v.v0.body);
141
+ }
142
+ xfree(request);
143
+ }
144
+
145
+ void
146
+ cb_http_request_mark(void *ptr)
147
+ {
148
+ struct cb_http_request_st *request = ptr;
149
+ if (request) {
150
+ rb_gc_mark(request->on_body_callback);
151
+ }
152
+ }
153
+
154
+ VALUE
155
+ cb_http_request_alloc(VALUE klass)
156
+ {
157
+ VALUE obj;
158
+ struct cb_http_request_st *request;
159
+
160
+ /* allocate new bucket struct and set it to zero */
161
+ obj = Data_Make_Struct(klass, struct cb_http_request_st, cb_http_request_mark,
162
+ cb_http_request_free, request);
163
+ return obj;
164
+ }
165
+
166
+ /*
167
+ * Returns a string containing a human-readable representation of the
168
+ * CouchRequest.
169
+ *
170
+ * @since 1.2.0
171
+ *
172
+ * @return [String]
173
+ */
174
+ VALUE
175
+ cb_http_request_inspect(VALUE self)
176
+ {
177
+ VALUE str;
178
+ struct cb_http_request_st *req = DATA_PTR(self);
179
+ char buf[200];
180
+
181
+ str = rb_str_buf_new2("#<");
182
+ rb_str_buf_cat2(str, rb_obj_classname(self));
183
+ snprintf(buf, 20, ":%p \"", (void *)self);
184
+ rb_str_buf_cat2(str, buf);
185
+ rb_str_buf_cat2(str, req->cmd.v.v0.path);
186
+ snprintf(buf, 100, "\" chunked:%s>", req->cmd.v.v0.chunked ? "true" : "false");
187
+ rb_str_buf_cat2(str, buf);
188
+
189
+ return str;
190
+ }
191
+
192
+ /*
193
+ * Initialize new CouchRequest
194
+ *
195
+ * @since 1.2.0
196
+ *
197
+ * @return [Bucket::CouchRequest]
198
+ */
199
+ VALUE
200
+ cb_http_request_init(int argc, VALUE *argv, VALUE self)
201
+ {
202
+ struct cb_http_request_st *request = DATA_PTR(self);
203
+ VALUE bucket, path, opts, on_body, pp, arg;
204
+ rb_scan_args(argc, argv, "22", &bucket, &pp, &opts, &on_body);
205
+
206
+ if (NIL_P(on_body) && rb_block_given_p()) {
207
+ on_body = rb_block_proc();
208
+ }
209
+ if (CLASS_OF(bucket) != cb_cBucket) {
210
+ rb_raise(rb_eTypeError, "wrong argument type (expected Couchbase::Bucket)");
211
+ }
212
+ memset(&request->cmd, 0, sizeof(lcb_http_cmd_t));
213
+ request->type = LCB_HTTP_TYPE_VIEW;
214
+ request->on_body_callback = on_body;
215
+ request->bucket = DATA_PTR(bucket);
216
+ request->bucket_obj = bucket;
217
+ request->extended = Qfalse;
218
+ path = StringValue(pp); /* convert path to string */
219
+ request->cmd.v.v0.path = strdup(RSTRING_PTR(path));
220
+ request->cmd.v.v0.npath = RSTRING_LEN(path);
221
+ request->cmd.v.v0.method = LCB_HTTP_METHOD_GET;
222
+ request->cmd.v.v0.content_type = strdup("application/json");
223
+
224
+ if (opts != Qnil) {
225
+ Check_Type(opts, T_HASH);
226
+ request->extended = RTEST(rb_hash_aref(opts, cb_sym_extended));
227
+ request->cmd.v.v0.chunked = RTEST(rb_hash_aref(opts, cb_sym_chunked));
228
+ if ((arg = rb_hash_aref(opts, cb_sym_type)) != Qnil) {
229
+ if (arg == cb_sym_view) {
230
+ request->type = LCB_HTTP_TYPE_VIEW;
231
+ } else if (arg == cb_sym_management) {
232
+ request->type = LCB_HTTP_TYPE_MANAGEMENT;
233
+ } else {
234
+ rb_raise(rb_eArgError, "unsupported request type");
235
+ }
236
+ }
237
+ if ((arg = rb_hash_aref(opts, cb_sym_method)) != Qnil) {
238
+ if (arg == cb_sym_get) {
239
+ request->cmd.v.v0.method = LCB_HTTP_METHOD_GET;
240
+ } else if (arg == cb_sym_post) {
241
+ request->cmd.v.v0.method = LCB_HTTP_METHOD_POST;
242
+ } else if (arg == cb_sym_put) {
243
+ request->cmd.v.v0.method = LCB_HTTP_METHOD_PUT;
244
+ } else if (arg == cb_sym_delete) {
245
+ request->cmd.v.v0.method = LCB_HTTP_METHOD_DELETE;
246
+ } else {
247
+ rb_raise(rb_eArgError, "unsupported HTTP method");
248
+ }
249
+ }
250
+ if ((arg = rb_hash_aref(opts, cb_sym_body)) != Qnil) {
251
+ Check_Type(arg, T_STRING);
252
+ request->cmd.v.v0.body = strdup(RSTRING_PTR(arg));
253
+ request->cmd.v.v0.nbody = RSTRING_LEN(arg);
254
+ }
255
+ if ((arg = rb_hash_aref(opts, cb_sym_content_type)) != Qnil) {
256
+ Check_Type(arg, T_STRING);
257
+ free((char *)request->cmd.v.v0.content_type);
258
+ request->cmd.v.v0.content_type = strdup(RSTRING_PTR(arg));
259
+ }
260
+ }
261
+
262
+ return self;
263
+ }
264
+
265
+ /*
266
+ * Set +on_body+ callback
267
+ *
268
+ * @since 1.2.0
269
+ */
270
+ VALUE
271
+ cb_http_request_on_body(VALUE self)
272
+ {
273
+ struct cb_http_request_st *request = DATA_PTR(self);
274
+ VALUE old = request->on_body_callback;
275
+ if (rb_block_given_p()) {
276
+ request->on_body_callback = rb_block_proc();
277
+ }
278
+ return old;
279
+ }
280
+
281
+ /*
282
+ * Execute {Bucket::CouchRequest}
283
+ *
284
+ * @since 1.2.0
285
+ */
286
+ VALUE
287
+ cb_http_request_perform(VALUE self)
288
+ {
289
+ struct cb_http_request_st *req = DATA_PTR(self);
290
+ struct cb_context_st *ctx;
291
+ VALUE rv, exc;
292
+ lcb_error_t err;
293
+ struct cb_bucket_st *bucket = req->bucket;
294
+
295
+ if (!cb_bucket_connected_bang(bucket, cb_sym_http_request)) {
296
+ return Qnil;
297
+ }
298
+
299
+ ctx = cb_context_alloc(bucket);
300
+ ctx->rv = Qnil;
301
+ ctx->proc = rb_block_given_p() ? rb_block_proc() : req->on_body_callback;
302
+ ctx->extended = req->extended;
303
+ ctx->request = req;
304
+ ctx->headers_val = rb_hash_new();
305
+
306
+ err = lcb_make_http_request(bucket->handle, (const void *)ctx,
307
+ req->type, &req->cmd, &req->request);
308
+ exc = cb_check_error(err, "failed to schedule document request",
309
+ STR_NEW(req->cmd.v.v0.path, req->cmd.v.v0.npath));
310
+ if (exc != Qnil) {
311
+ lcb_cancel_http_request(bucket->handle, req->request);
312
+ rb_exc_raise(exc);
313
+ }
314
+ req->running = 1;
315
+ req->ctx = ctx;
316
+ if (bucket->async) {
317
+ return Qnil;
318
+ } else {
319
+ lcb_wait(bucket->handle);
320
+ if (req->completed) {
321
+ rv = ctx->rv;
322
+ exc = ctx->exception;
323
+ cb_context_free(ctx);
324
+ if (exc != Qnil) {
325
+ rb_exc_raise(exc);
326
+ }
327
+ return rv;
328
+ } else {
329
+ return Qnil;
330
+ }
331
+ }
332
+ return Qnil;
333
+ }
334
+
335
+ VALUE
336
+ cb_http_request_pause(VALUE self)
337
+ {
338
+ struct cb_http_request_st *req = DATA_PTR(self);
339
+ lcb_breakout(req->bucket->handle);
340
+ return Qnil;
341
+ }
342
+
343
+ VALUE
344
+ cb_http_request_continue(VALUE self)
345
+ {
346
+ VALUE exc, rv;
347
+ struct cb_http_request_st *req = DATA_PTR(self);
348
+
349
+ if (req->running) {
350
+ lcb_wait(req->bucket->handle);
351
+ if (req->completed) {
352
+ exc = req->ctx->exception;
353
+ rv = req->ctx->rv;
354
+ cb_context_free(req->ctx);
355
+ if (exc != Qnil) {
356
+ rb_exc_raise(exc);
357
+ }
358
+ return rv;
359
+ }
360
+ } else {
361
+ cb_http_request_perform(self);
362
+ }
363
+ return Qnil;
364
+ }
365
+
366
+ /* Document-method: path
367
+ *
368
+ * @since 1.2.0
369
+ *
370
+ * @return [String] the requested path
371
+ */
372
+ VALUE
373
+ cb_http_request_path_get(VALUE self)
374
+ {
375
+ struct cb_http_request_st *req = DATA_PTR(self);
376
+ return STR_NEW_CSTR(req->cmd.v.v0.path);
377
+ }
378
+
379
+ /* Document-method: chunked
380
+ *
381
+ * @since 1.2.0
382
+ *
383
+ * @return [Boolean] +false+ if library should collect whole response before
384
+ * yielding, +true+ if the client is ready to handle response in chunks.
385
+ */
386
+ VALUE
387
+ cb_http_request_chunked_get(VALUE self)
388
+ {
389
+ struct cb_http_request_st *req = DATA_PTR(self);
390
+ return req->cmd.v.v0.chunked ? Qtrue : Qfalse;
391
+ }
392
+
393
+ /* Document-method: extended
394
+ *
395
+ * @since 1.2.0
396
+ *
397
+ * @return [Boolean] if +false+ the callbacks should receive just the data,
398
+ * and {Couchbase::Result} instance otherwise.
399
+ */
400
+ VALUE
401
+ cb_http_request_extended_get(VALUE self)
402
+ {
403
+ struct cb_http_request_st *req = DATA_PTR(self);
404
+ return req->extended ? Qtrue : Qfalse;
405
+ }
406
+
407
+ /* Document-method: make_http_request(path, options = {})
408
+ *
409
+ * @since 1.2.0
410
+ *
411
+ * @param path [String]
412
+ * @param options [Hash]
413
+ * @option options [Boolean] :extended (false) set it to +true+ if the
414
+ * {Couchbase::Result} object needed. The response chunk will be
415
+ * accessible through +#value+ attribute.
416
+ * @yieldparam [String,Couchbase::Result] res the response chunk if the
417
+ * :extended option is +false+ and result object otherwise
418
+ *
419
+ * @return [Couchbase::Bucket::CouchRequest]
420
+ */
421
+ VALUE
422
+ cb_bucket_make_http_request(int argc, VALUE *argv, VALUE self)
423
+ {
424
+ VALUE args[4]; /* bucket, path, options, block */
425
+
426
+ args[0] = self;
427
+ rb_scan_args(argc, argv, "11&", &args[1], &args[2], &args[3]);
428
+
429
+ return rb_class_new_instance(4, args, cb_cCouchRequest);
430
+ }
431
+
432
+