couchbase 1.1.5-x86-mingw32 → 1.2.0.beta-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -1
- data/.travis.yml +12 -1
- data/HISTORY.markdown +112 -1
- data/README.markdown +149 -6
- data/couchbase.gemspec +5 -1
- data/ext/couchbase_ext/.gitignore +4 -0
- data/ext/couchbase_ext/arguments.c +973 -0
- data/ext/couchbase_ext/arithmetic.c +322 -0
- data/ext/couchbase_ext/bucket.c +1092 -0
- data/ext/couchbase_ext/couchbase_ext.c +618 -3247
- data/ext/couchbase_ext/couchbase_ext.h +519 -0
- data/ext/couchbase_ext/delete.c +167 -0
- data/ext/couchbase_ext/extconf.rb +24 -5
- data/ext/couchbase_ext/get.c +301 -0
- data/ext/couchbase_ext/gethrtime.c +124 -0
- data/ext/couchbase_ext/http.c +402 -0
- data/ext/couchbase_ext/observe.c +174 -0
- data/ext/couchbase_ext/result.c +126 -0
- data/ext/couchbase_ext/stats.c +169 -0
- data/ext/couchbase_ext/store.c +522 -0
- data/ext/couchbase_ext/timer.c +192 -0
- data/ext/couchbase_ext/touch.c +190 -0
- data/ext/couchbase_ext/unlock.c +180 -0
- data/ext/couchbase_ext/utils.c +471 -0
- data/ext/couchbase_ext/version.c +147 -0
- data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
- data/lib/active_support/cache/couchbase_store.rb +356 -0
- data/lib/couchbase.rb +24 -3
- data/lib/couchbase/bucket.rb +372 -9
- data/lib/couchbase/result.rb +26 -0
- data/lib/couchbase/utils.rb +59 -0
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase/view.rb +305 -0
- data/lib/couchbase/view_row.rb +230 -0
- data/lib/ext/multi_json_fix.rb +47 -0
- data/lib/rack/session/couchbase.rb +104 -0
- data/tasks/compile.rake +5 -14
- data/test/setup.rb +6 -2
- data/test/test_arithmetic.rb +32 -2
- data/test/test_async.rb +18 -4
- data/test/test_bucket.rb +11 -1
- data/test/test_cas.rb +13 -3
- data/test/test_couchbase_rails_cache_store.rb +294 -0
- data/test/test_delete.rb +60 -3
- data/test/test_format.rb +28 -17
- data/test/test_get.rb +91 -14
- data/test/test_store.rb +31 -1
- data/test/{test_flush.rb → test_timer.rb} +11 -18
- data/test/test_touch.rb +33 -5
- data/test/test_unlock.rb +120 -0
- data/test/test_utils.rb +26 -0
- metadata +102 -12
@@ -0,0 +1,124 @@
|
|
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
|
+
#include <stdlib.h>
|
20
|
+
#include <time.h>
|
21
|
+
#include <assert.h>
|
22
|
+
|
23
|
+
#ifdef HAVE_MACH_MACH_TIME_H
|
24
|
+
#include <mach/mach_time.h>
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#ifdef HAVE_SYS_TIME_H
|
28
|
+
#include <sys/time.h>
|
29
|
+
#endif
|
30
|
+
|
31
|
+
/*
|
32
|
+
* OS X doesn't have clock_gettime, but for monotonic, we can build
|
33
|
+
* one with mach_absolute_time as shown below.
|
34
|
+
*
|
35
|
+
* Most of the idea came from
|
36
|
+
* http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/
|
37
|
+
*/
|
38
|
+
|
39
|
+
#if defined(HAVE_MACH_ABSOLUTE_TIME) && !defined(HAVE_CLOCK_GETTIME)
|
40
|
+
|
41
|
+
#define CLOCK_MONOTONIC 192996728
|
42
|
+
|
43
|
+
static void mach_absolute_difference(uint64_t start, uint64_t end,
|
44
|
+
struct timespec *tp)
|
45
|
+
{
|
46
|
+
uint64_t difference = end - start;
|
47
|
+
static mach_timebase_info_data_t info = {0, 0};
|
48
|
+
|
49
|
+
if (info.denom == 0) {
|
50
|
+
mach_timebase_info(&info);
|
51
|
+
}
|
52
|
+
|
53
|
+
uint64_t elapsednano = difference * (info.numer / info.denom);
|
54
|
+
|
55
|
+
tp->tv_sec = elapsednano * 1e-9;
|
56
|
+
tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
|
57
|
+
}
|
58
|
+
|
59
|
+
static int clock_gettime(int which, struct timespec *tp)
|
60
|
+
{
|
61
|
+
assert(which == CLOCK_MONOTONIC);
|
62
|
+
|
63
|
+
static uint64_t epoch = 0;
|
64
|
+
|
65
|
+
if (epoch == 0) {
|
66
|
+
epoch = mach_absolute_time();
|
67
|
+
}
|
68
|
+
|
69
|
+
uint64_t now = mach_absolute_time();
|
70
|
+
|
71
|
+
mach_absolute_difference(epoch, now, tp);
|
72
|
+
|
73
|
+
return 0;
|
74
|
+
}
|
75
|
+
|
76
|
+
#define HAVE_CLOCK_GETTIME 1
|
77
|
+
#endif
|
78
|
+
|
79
|
+
hrtime_t gethrtime(void)
|
80
|
+
{
|
81
|
+
#ifdef HAVE_CLOCK_GETTIME
|
82
|
+
struct timespec tm;
|
83
|
+
if (clock_gettime(CLOCK_MONOTONIC, &tm) == -1) {
|
84
|
+
abort();
|
85
|
+
}
|
86
|
+
return (((hrtime_t)tm.tv_sec) * 1000000000) + (hrtime_t)tm.tv_nsec;
|
87
|
+
#elif HAVE_GETTIMEOFDAY
|
88
|
+
|
89
|
+
hrtime_t ret;
|
90
|
+
struct timeval tv;
|
91
|
+
if (gettimeofday(&tv, NULL) == -1) {
|
92
|
+
return (-1ULL);
|
93
|
+
}
|
94
|
+
|
95
|
+
ret = (hrtime_t)tv.tv_sec * 1000000000;
|
96
|
+
ret += tv.tv_usec * 1000;
|
97
|
+
return ret;
|
98
|
+
#elif defined(HAVE_QUERYPERFORMANCECOUNTER)
|
99
|
+
double ret;
|
100
|
+
// To fix the potential race condition for the local static variable,
|
101
|
+
// gethrtime should be called in a global static variable first.
|
102
|
+
// It will guarantee the local static variable will be initialized
|
103
|
+
// before any thread calls the function.
|
104
|
+
static LARGE_INTEGER pf = { 0 };
|
105
|
+
static double freq;
|
106
|
+
LARGE_INTEGER currtime;
|
107
|
+
|
108
|
+
if (pf.QuadPart == 0) {
|
109
|
+
if (QueryPerformanceFrequency(&pf)) {
|
110
|
+
assert(pf.QuadPart != 0);
|
111
|
+
freq = 1.0e9 / (double)pf.QuadPart;
|
112
|
+
} else {
|
113
|
+
abort();
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
QueryPerformanceCounter(&currtime);
|
118
|
+
|
119
|
+
ret = (double)currtime.QuadPart * freq ;
|
120
|
+
return (hrtime_t)ret;
|
121
|
+
#else
|
122
|
+
#error "I don't know how to build a highres clock..."
|
123
|
+
#endif
|
124
|
+
}
|
@@ -0,0 +1,402 @@
|
|
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
|
+
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 context_st *ctx = (struct context_st *)cookie;
|
24
|
+
struct bucket_st *bucket = ctx->bucket;
|
25
|
+
VALUE *rv = ctx->rv, key, val, res;
|
26
|
+
|
27
|
+
ctx->request->completed = 1;
|
28
|
+
key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
|
29
|
+
ctx->exception = cb_check_error_with_status(error,
|
30
|
+
"failed to execute HTTP request", key, resp->v.v0.status);
|
31
|
+
if (ctx->exception != Qnil) {
|
32
|
+
cb_gc_protect(bucket, ctx->exception);
|
33
|
+
}
|
34
|
+
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
35
|
+
if (resp->v.v0.headers) {
|
36
|
+
cb_build_headers(ctx, resp->v.v0.headers);
|
37
|
+
cb_gc_unprotect(bucket, ctx->headers_val);
|
38
|
+
}
|
39
|
+
if (ctx->extended) {
|
40
|
+
res = rb_class_new_instance(0, NULL, cResult);
|
41
|
+
rb_ivar_set(res, id_iv_error, ctx->exception);
|
42
|
+
rb_ivar_set(res, id_iv_operation, sym_http_request);
|
43
|
+
rb_ivar_set(res, id_iv_key, key);
|
44
|
+
rb_ivar_set(res, id_iv_value, val);
|
45
|
+
rb_ivar_set(res, id_iv_completed, Qtrue);
|
46
|
+
rb_ivar_set(res, id_iv_headers, ctx->headers_val);
|
47
|
+
} else {
|
48
|
+
res = val;
|
49
|
+
}
|
50
|
+
if (ctx->proc != Qnil) {
|
51
|
+
cb_proc_call(ctx->proc, 1, res);
|
52
|
+
}
|
53
|
+
if (!bucket->async && ctx->exception == Qnil) {
|
54
|
+
*rv = res;
|
55
|
+
}
|
56
|
+
(void)handle;
|
57
|
+
(void)request;
|
58
|
+
}
|
59
|
+
|
60
|
+
void
|
61
|
+
http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
|
62
|
+
{
|
63
|
+
struct context_st *ctx = (struct context_st *)cookie;
|
64
|
+
struct bucket_st *bucket = ctx->bucket;
|
65
|
+
VALUE key, val, res;
|
66
|
+
|
67
|
+
key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
|
68
|
+
ctx->exception = cb_check_error_with_status(error,
|
69
|
+
"failed to execute HTTP request", key, resp->v.v0.status);
|
70
|
+
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
71
|
+
if (ctx->exception != Qnil) {
|
72
|
+
cb_gc_protect(bucket, ctx->exception);
|
73
|
+
lcb_cancel_http_request(bucket->handle, request);
|
74
|
+
}
|
75
|
+
if (resp->v.v0.headers) {
|
76
|
+
cb_build_headers(ctx, resp->v.v0.headers);
|
77
|
+
}
|
78
|
+
if (ctx->proc != Qnil) {
|
79
|
+
if (ctx->extended) {
|
80
|
+
res = rb_class_new_instance(0, NULL, cResult);
|
81
|
+
rb_ivar_set(res, id_iv_error, ctx->exception);
|
82
|
+
rb_ivar_set(res, id_iv_operation, sym_http_request);
|
83
|
+
rb_ivar_set(res, id_iv_key, key);
|
84
|
+
rb_ivar_set(res, id_iv_value, val);
|
85
|
+
rb_ivar_set(res, id_iv_completed, Qfalse);
|
86
|
+
rb_ivar_set(res, id_iv_headers, ctx->headers_val);
|
87
|
+
} else {
|
88
|
+
res = val;
|
89
|
+
}
|
90
|
+
cb_proc_call(ctx->proc, 1, res);
|
91
|
+
}
|
92
|
+
(void)handle;
|
93
|
+
}
|
94
|
+
|
95
|
+
void
|
96
|
+
cb_http_request_free(void *ptr)
|
97
|
+
{
|
98
|
+
struct http_request_st *request = ptr;
|
99
|
+
if (request) {
|
100
|
+
request->running = 0;
|
101
|
+
if (TYPE(request->bucket_obj) == T_DATA
|
102
|
+
&& RDATA(request->bucket_obj)->dfree == (RUBY_DATA_FUNC)cb_bucket_free
|
103
|
+
&& !request->completed) {
|
104
|
+
lcb_cancel_http_request(request->bucket->handle, request->request);
|
105
|
+
}
|
106
|
+
xfree((char *)request->cmd.v.v0.content_type);
|
107
|
+
xfree((char *)request->cmd.v.v0.path);
|
108
|
+
xfree((char *)request->cmd.v.v0.body);
|
109
|
+
xfree(request);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
void
|
114
|
+
cb_http_request_mark(void *ptr)
|
115
|
+
{
|
116
|
+
struct http_request_st *request = ptr;
|
117
|
+
if (request) {
|
118
|
+
rb_gc_mark(request->on_body_callback);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
VALUE
|
123
|
+
cb_http_request_alloc(VALUE klass)
|
124
|
+
{
|
125
|
+
VALUE obj;
|
126
|
+
struct http_request_st *request;
|
127
|
+
|
128
|
+
/* allocate new bucket struct and set it to zero */
|
129
|
+
obj = Data_Make_Struct(klass, struct http_request_st, cb_http_request_mark,
|
130
|
+
cb_http_request_free, request);
|
131
|
+
return obj;
|
132
|
+
}
|
133
|
+
|
134
|
+
/*
|
135
|
+
* Returns a string containing a human-readable representation of the
|
136
|
+
* CouchRequest.
|
137
|
+
*
|
138
|
+
* @since 1.2.0
|
139
|
+
*
|
140
|
+
* @return [String]
|
141
|
+
*/
|
142
|
+
VALUE
|
143
|
+
cb_http_request_inspect(VALUE self)
|
144
|
+
{
|
145
|
+
VALUE str;
|
146
|
+
struct http_request_st *req = DATA_PTR(self);
|
147
|
+
char buf[200];
|
148
|
+
|
149
|
+
str = rb_str_buf_new2("#<");
|
150
|
+
rb_str_buf_cat2(str, rb_obj_classname(self));
|
151
|
+
snprintf(buf, 20, ":%p \"", (void *)self);
|
152
|
+
rb_str_buf_cat2(str, buf);
|
153
|
+
rb_str_buf_cat2(str, req->cmd.v.v0.path);
|
154
|
+
snprintf(buf, 100, "\" chunked:%s>", req->cmd.v.v0.chunked ? "true" : "false");
|
155
|
+
rb_str_buf_cat2(str, buf);
|
156
|
+
|
157
|
+
return str;
|
158
|
+
}
|
159
|
+
|
160
|
+
/*
|
161
|
+
* Initialize new CouchRequest
|
162
|
+
*
|
163
|
+
* @since 1.2.0
|
164
|
+
*
|
165
|
+
* @return [Bucket::CouchRequest]
|
166
|
+
*/
|
167
|
+
VALUE
|
168
|
+
cb_http_request_init(int argc, VALUE *argv, VALUE self)
|
169
|
+
{
|
170
|
+
struct http_request_st *request = DATA_PTR(self);
|
171
|
+
VALUE bucket, path, opts, on_body, pp, arg;
|
172
|
+
rb_scan_args(argc, argv, "22", &bucket, &pp, &opts, &on_body);
|
173
|
+
|
174
|
+
if (NIL_P(on_body) && rb_block_given_p()) {
|
175
|
+
on_body = rb_block_proc();
|
176
|
+
}
|
177
|
+
if (CLASS_OF(bucket) != cBucket) {
|
178
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected Couchbase::Bucket)");
|
179
|
+
}
|
180
|
+
memset(&request->cmd, 0, sizeof(lcb_http_cmd_t));
|
181
|
+
request->type = LCB_HTTP_TYPE_VIEW;
|
182
|
+
request->on_body_callback = on_body;
|
183
|
+
request->bucket = DATA_PTR(bucket);
|
184
|
+
request->bucket_obj = bucket;
|
185
|
+
request->extended = Qfalse;
|
186
|
+
path = StringValue(pp); /* convert path to string */
|
187
|
+
request->cmd.v.v0.path = strdup(RSTRING_PTR(path));
|
188
|
+
request->cmd.v.v0.npath = RSTRING_LEN(path);
|
189
|
+
request->cmd.v.v0.method = LCB_HTTP_METHOD_GET;
|
190
|
+
request->cmd.v.v0.content_type = strdup("application/json");
|
191
|
+
|
192
|
+
if (opts != Qnil) {
|
193
|
+
Check_Type(opts, T_HASH);
|
194
|
+
request->extended = RTEST(rb_hash_aref(opts, sym_extended));
|
195
|
+
request->cmd.v.v0.chunked = RTEST(rb_hash_aref(opts, sym_chunked));
|
196
|
+
if ((arg = rb_hash_aref(opts, sym_type)) != Qnil) {
|
197
|
+
if (arg == sym_view) {
|
198
|
+
request->type = LCB_HTTP_TYPE_VIEW;
|
199
|
+
} else if (arg == sym_management) {
|
200
|
+
request->type = LCB_HTTP_TYPE_MANAGEMENT;
|
201
|
+
} else {
|
202
|
+
rb_raise(rb_eArgError, "unsupported request type");
|
203
|
+
}
|
204
|
+
}
|
205
|
+
if ((arg = rb_hash_aref(opts, sym_method)) != Qnil) {
|
206
|
+
if (arg == sym_get) {
|
207
|
+
request->cmd.v.v0.method = LCB_HTTP_METHOD_GET;
|
208
|
+
} else if (arg == sym_post) {
|
209
|
+
request->cmd.v.v0.method = LCB_HTTP_METHOD_POST;
|
210
|
+
} else if (arg == sym_put) {
|
211
|
+
request->cmd.v.v0.method = LCB_HTTP_METHOD_PUT;
|
212
|
+
} else if (arg == sym_delete) {
|
213
|
+
request->cmd.v.v0.method = LCB_HTTP_METHOD_DELETE;
|
214
|
+
} else {
|
215
|
+
rb_raise(rb_eArgError, "unsupported HTTP method");
|
216
|
+
}
|
217
|
+
}
|
218
|
+
if ((arg = rb_hash_aref(opts, sym_body)) != Qnil) {
|
219
|
+
Check_Type(arg, T_STRING);
|
220
|
+
request->cmd.v.v0.body = strdup(RSTRING_PTR(arg));
|
221
|
+
request->cmd.v.v0.nbody = RSTRING_LEN(arg);
|
222
|
+
}
|
223
|
+
if ((arg = rb_hash_aref(opts, sym_content_type)) != Qnil) {
|
224
|
+
Check_Type(arg, T_STRING);
|
225
|
+
xfree((char *)request->cmd.v.v0.content_type);
|
226
|
+
request->cmd.v.v0.content_type = strdup(RSTRING_PTR(arg));
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
return self;
|
231
|
+
}
|
232
|
+
|
233
|
+
/*
|
234
|
+
* Set +on_body+ callback
|
235
|
+
*
|
236
|
+
* @since 1.2.0
|
237
|
+
*/
|
238
|
+
VALUE
|
239
|
+
cb_http_request_on_body(VALUE self)
|
240
|
+
{
|
241
|
+
struct http_request_st *request = DATA_PTR(self);
|
242
|
+
VALUE old = request->on_body_callback;
|
243
|
+
if (rb_block_given_p()) {
|
244
|
+
request->on_body_callback = rb_block_proc();
|
245
|
+
}
|
246
|
+
return old;
|
247
|
+
}
|
248
|
+
|
249
|
+
/*
|
250
|
+
* Execute {Bucket::CouchRequest}
|
251
|
+
*
|
252
|
+
* @since 1.2.0
|
253
|
+
*/
|
254
|
+
VALUE
|
255
|
+
cb_http_request_perform(VALUE self)
|
256
|
+
{
|
257
|
+
struct http_request_st *req = DATA_PTR(self);
|
258
|
+
struct context_st *ctx;
|
259
|
+
VALUE rv, exc;
|
260
|
+
lcb_error_t err;
|
261
|
+
struct bucket_st *bucket;
|
262
|
+
|
263
|
+
ctx = xcalloc(1, sizeof(struct context_st));
|
264
|
+
if (ctx == NULL) {
|
265
|
+
rb_raise(eClientNoMemoryError, "failed to allocate memory");
|
266
|
+
}
|
267
|
+
rv = Qnil;
|
268
|
+
ctx->rv = &rv;
|
269
|
+
ctx->bucket = bucket = req->bucket;
|
270
|
+
ctx->proc = rb_block_given_p() ? rb_block_proc() : req->on_body_callback;
|
271
|
+
ctx->extended = req->extended;
|
272
|
+
ctx->request = req;
|
273
|
+
ctx->headers_val = cb_gc_protect(bucket, rb_hash_new());
|
274
|
+
|
275
|
+
err = lcb_make_http_request(bucket->handle, (const void *)ctx,
|
276
|
+
req->type, &req->cmd, &req->request);
|
277
|
+
exc = cb_check_error(err, "failed to schedule document request",
|
278
|
+
STR_NEW(req->cmd.v.v0.path, req->cmd.v.v0.npath));
|
279
|
+
if (exc != Qnil) {
|
280
|
+
xfree(ctx);
|
281
|
+
rb_exc_raise(exc);
|
282
|
+
}
|
283
|
+
req->running = 1;
|
284
|
+
req->ctx = ctx;
|
285
|
+
if (bucket->async) {
|
286
|
+
return Qnil;
|
287
|
+
} else {
|
288
|
+
lcb_wait(bucket->handle);
|
289
|
+
if (req->completed) {
|
290
|
+
exc = ctx->exception;
|
291
|
+
xfree(ctx);
|
292
|
+
if (exc != Qnil) {
|
293
|
+
cb_gc_unprotect(bucket, exc);
|
294
|
+
rb_exc_raise(exc);
|
295
|
+
}
|
296
|
+
return rv;
|
297
|
+
} else {
|
298
|
+
return Qnil;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
return Qnil;
|
302
|
+
}
|
303
|
+
|
304
|
+
VALUE
|
305
|
+
cb_http_request_pause(VALUE self)
|
306
|
+
{
|
307
|
+
struct http_request_st *req = DATA_PTR(self);
|
308
|
+
req->bucket->io->stop_event_loop(req->bucket->io);
|
309
|
+
return Qnil;
|
310
|
+
}
|
311
|
+
|
312
|
+
VALUE
|
313
|
+
cb_http_request_continue(VALUE self)
|
314
|
+
{
|
315
|
+
VALUE exc, *rv;
|
316
|
+
struct http_request_st *req = DATA_PTR(self);
|
317
|
+
|
318
|
+
if (req->running) {
|
319
|
+
lcb_wait(req->bucket->handle);
|
320
|
+
if (req->completed) {
|
321
|
+
exc = req->ctx->exception;
|
322
|
+
rv = req->ctx->rv;
|
323
|
+
xfree(req->ctx);
|
324
|
+
if (exc != Qnil) {
|
325
|
+
cb_gc_unprotect(req->bucket, exc);
|
326
|
+
rb_exc_raise(exc);
|
327
|
+
}
|
328
|
+
return *rv;
|
329
|
+
}
|
330
|
+
} else {
|
331
|
+
cb_http_request_perform(self);
|
332
|
+
}
|
333
|
+
return Qnil;
|
334
|
+
}
|
335
|
+
|
336
|
+
/* Document-method: path
|
337
|
+
*
|
338
|
+
* @since 1.2.0
|
339
|
+
*
|
340
|
+
* @return [String] the requested path
|
341
|
+
*/
|
342
|
+
VALUE
|
343
|
+
cb_http_request_path_get(VALUE self)
|
344
|
+
{
|
345
|
+
struct http_request_st *req = DATA_PTR(self);
|
346
|
+
return STR_NEW_CSTR(req->cmd.v.v0.path);
|
347
|
+
}
|
348
|
+
|
349
|
+
/* Document-method: chunked
|
350
|
+
*
|
351
|
+
* @since 1.2.0
|
352
|
+
*
|
353
|
+
* @return [Boolean] +false+ if library should collect whole response before
|
354
|
+
* yielding, +true+ if the client is ready to handle response in chunks.
|
355
|
+
*/
|
356
|
+
VALUE
|
357
|
+
cb_http_request_chunked_get(VALUE self)
|
358
|
+
{
|
359
|
+
struct http_request_st *req = DATA_PTR(self);
|
360
|
+
return req->cmd.v.v0.chunked ? Qtrue : Qfalse;
|
361
|
+
}
|
362
|
+
|
363
|
+
/* Document-method: extended
|
364
|
+
*
|
365
|
+
* @since 1.2.0
|
366
|
+
*
|
367
|
+
* @return [Boolean] if +false+ the callbacks should receive just the data,
|
368
|
+
* and {Couchbase::Result} instance otherwise.
|
369
|
+
*/
|
370
|
+
VALUE
|
371
|
+
cb_http_request_extended_get(VALUE self)
|
372
|
+
{
|
373
|
+
struct http_request_st *req = DATA_PTR(self);
|
374
|
+
return req->extended ? Qtrue : Qfalse;
|
375
|
+
}
|
376
|
+
|
377
|
+
/* Document-method: make_http_request(path, options = {})
|
378
|
+
*
|
379
|
+
* @since 1.2.0
|
380
|
+
*
|
381
|
+
* @param path [String]
|
382
|
+
* @param options [Hash]
|
383
|
+
* @option options [Boolean] :extended (false) set it to +true+ if the
|
384
|
+
* {Couchbase::Result} object needed. The response chunk will be
|
385
|
+
* accessible through +#value+ attribute.
|
386
|
+
* @yieldparam [String,Couchbase::Result] res the response chunk if the
|
387
|
+
* :extended option is +false+ and result object otherwise
|
388
|
+
*
|
389
|
+
* @return [Couchbase::Bucket::CouchRequest]
|
390
|
+
*/
|
391
|
+
VALUE
|
392
|
+
cb_bucket_make_http_request(int argc, VALUE *argv, VALUE self)
|
393
|
+
{
|
394
|
+
VALUE args[4]; /* bucket, path, options, block */
|
395
|
+
|
396
|
+
args[0] = self;
|
397
|
+
rb_scan_args(argc, argv, "11&", &args[1], &args[2], &args[3]);
|
398
|
+
|
399
|
+
return rb_class_new_instance(4, args, cCouchRequest);
|
400
|
+
}
|
401
|
+
|
402
|
+
|