couchbase 1.2.0.beta-x86-mingw32 → 1.2.0-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/.travis.yml +1 -1
- data/Makefile +3 -0
- data/README.markdown +15 -4
- data/RELEASE_NOTES.markdown +513 -0
- data/couchbase.gemspec +0 -1
- data/ext/couchbase_ext/arguments.c +161 -244
- data/ext/couchbase_ext/arithmetic.c +29 -37
- data/ext/couchbase_ext/bucket.c +252 -219
- data/ext/couchbase_ext/couchbase_ext.c +540 -417
- data/ext/couchbase_ext/couchbase_ext.h +218 -191
- data/ext/couchbase_ext/delete.c +30 -27
- data/ext/couchbase_ext/extconf.rb +15 -3
- data/ext/couchbase_ext/get.c +45 -37
- data/ext/couchbase_ext/http.c +95 -74
- data/ext/couchbase_ext/multithread_plugin.c +1201 -0
- data/ext/couchbase_ext/observe.c +42 -37
- data/ext/couchbase_ext/result.c +17 -20
- data/ext/couchbase_ext/stats.c +30 -28
- data/ext/couchbase_ext/store.c +46 -39
- data/ext/couchbase_ext/timer.c +11 -11
- data/ext/couchbase_ext/touch.c +30 -27
- data/ext/couchbase_ext/unlock.c +30 -27
- data/ext/couchbase_ext/utils.c +166 -89
- data/ext/couchbase_ext/version.c +29 -26
- data/lib/action_dispatch/middleware/session/couchbase_store.rb +2 -2
- data/lib/active_support/cache/couchbase_store.rb +6 -6
- data/lib/couchbase.rb +1 -0
- data/lib/couchbase/bucket.rb +6 -11
- data/lib/couchbase/cluster.rb +105 -0
- data/lib/couchbase/utils.rb +8 -5
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase/view.rb +51 -5
- data/lib/couchbase/view_row.rb +1 -1
- data/lib/ext/multi_json_fix.rb +13 -9
- data/lib/rack/session/couchbase.rb +11 -7
- data/tasks/compile.rake +1 -1
- data/tasks/test.rake +40 -34
- data/tasks/util.rake +1 -1
- data/test/setup.rb +9 -2
- data/test/test_arithmetic.rb +37 -0
- data/test/test_async.rb +22 -18
- data/test/test_unlock.rb +0 -1
- data/test/test_utils.rb +32 -0
- metadata +13 -23
- data/HISTORY.markdown +0 -215
data/ext/couchbase_ext/delete.c
CHANGED
@@ -18,38 +18,39 @@
|
|
18
18
|
#include "couchbase_ext.h"
|
19
19
|
|
20
20
|
void
|
21
|
-
|
21
|
+
cb_delete_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_remove_resp_t *resp)
|
22
22
|
{
|
23
|
-
struct
|
24
|
-
struct
|
23
|
+
struct cb_context_st *ctx = (struct cb_context_st *)cookie;
|
24
|
+
struct cb_bucket_st *bucket = ctx->bucket;
|
25
25
|
VALUE key, *rv = ctx->rv, exc = Qnil, res;
|
26
26
|
|
27
27
|
ctx->nqueries--;
|
28
28
|
key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
|
29
|
-
|
29
|
+
cb_strip_key_prefix(bucket, key);
|
30
30
|
|
31
31
|
if (error != LCB_KEY_ENOENT || !ctx->quiet) {
|
32
32
|
exc = cb_check_error(error, "failed to remove value", key);
|
33
33
|
if (exc != Qnil) {
|
34
|
-
rb_ivar_set(exc,
|
35
|
-
|
36
|
-
ctx->exception = cb_gc_protect(bucket, exc);
|
37
|
-
}
|
34
|
+
rb_ivar_set(exc, cb_id_iv_operation, cb_sym_delete);
|
35
|
+
ctx->exception = cb_gc_protect(bucket, exc);
|
38
36
|
}
|
39
37
|
}
|
40
38
|
if (bucket->async) { /* asynchronous */
|
41
39
|
if (ctx->proc != Qnil) {
|
42
|
-
res = rb_class_new_instance(0, NULL,
|
43
|
-
rb_ivar_set(res,
|
44
|
-
rb_ivar_set(res,
|
45
|
-
rb_ivar_set(res,
|
46
|
-
cb_proc_call(ctx->proc, 1, res);
|
40
|
+
res = rb_class_new_instance(0, NULL, cb_cResult);
|
41
|
+
rb_ivar_set(res, cb_id_iv_error, exc);
|
42
|
+
rb_ivar_set(res, cb_id_iv_operation, cb_sym_delete);
|
43
|
+
rb_ivar_set(res, cb_id_iv_key, key);
|
44
|
+
cb_proc_call(bucket, ctx->proc, 1, res);
|
47
45
|
}
|
48
46
|
} else { /* synchronous */
|
49
47
|
rb_hash_aset(*rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
|
50
48
|
}
|
51
49
|
if (ctx->nqueries == 0) {
|
52
50
|
cb_gc_unprotect(bucket, ctx->proc);
|
51
|
+
if (bucket->async) {
|
52
|
+
free(ctx);
|
53
|
+
}
|
53
54
|
}
|
54
55
|
(void)handle;
|
55
56
|
}
|
@@ -99,29 +100,29 @@ delete_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_r
|
|
99
100
|
VALUE
|
100
101
|
cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
101
102
|
{
|
102
|
-
struct
|
103
|
-
struct
|
103
|
+
struct cb_bucket_st *bucket = DATA_PTR(self);
|
104
|
+
struct cb_context_st *ctx;
|
104
105
|
VALUE rv, exc;
|
105
106
|
VALUE args, proc;
|
106
107
|
lcb_error_t err;
|
107
|
-
struct
|
108
|
+
struct cb_params_st params;
|
108
109
|
|
109
110
|
if (bucket->handle == NULL) {
|
110
|
-
rb_raise(
|
111
|
+
rb_raise(cb_eConnectError, "closed connection");
|
111
112
|
}
|
112
113
|
rb_scan_args(argc, argv, "0*&", &args, &proc);
|
113
114
|
if (!bucket->async && proc != Qnil) {
|
114
115
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
115
116
|
}
|
116
|
-
rb_funcall(args,
|
117
|
-
memset(¶ms, 0, sizeof(struct
|
118
|
-
params.type =
|
117
|
+
rb_funcall(args, cb_id_flatten_bang, 0);
|
118
|
+
memset(¶ms, 0, sizeof(struct cb_params_st));
|
119
|
+
params.type = cb_cmd_remove;
|
119
120
|
params.bucket = bucket;
|
120
121
|
cb_params_build(¶ms, RARRAY_LEN(args), args);
|
121
122
|
|
122
|
-
ctx =
|
123
|
+
ctx = calloc(1, sizeof(struct cb_context_st));
|
123
124
|
if (ctx == NULL) {
|
124
|
-
rb_raise(
|
125
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
|
125
126
|
}
|
126
127
|
ctx->quiet = params.cmd.remove.quiet;
|
127
128
|
ctx->proc = cb_gc_protect(bucket, proc);
|
@@ -135,12 +136,12 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
135
136
|
cb_params_destroy(¶ms);
|
136
137
|
exc = cb_check_error(err, "failed to schedule delete request", Qnil);
|
137
138
|
if (exc != Qnil) {
|
138
|
-
|
139
|
+
free(ctx);
|
139
140
|
rb_exc_raise(exc);
|
140
141
|
}
|
141
142
|
bucket->nbytes += params.npayload;
|
142
143
|
if (bucket->async) {
|
143
|
-
|
144
|
+
cb_maybe_do_loop(bucket);
|
144
145
|
return Qnil;
|
145
146
|
} else {
|
146
147
|
if (ctx->nqueries > 0) {
|
@@ -148,12 +149,14 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
|
|
148
149
|
lcb_wait(bucket->handle);
|
149
150
|
}
|
150
151
|
exc = ctx->exception;
|
151
|
-
|
152
|
+
free(ctx);
|
152
153
|
if (exc != Qnil) {
|
153
154
|
rb_exc_raise(cb_gc_unprotect(bucket, exc));
|
154
155
|
}
|
155
|
-
|
156
|
-
|
156
|
+
exc = bucket->exception;
|
157
|
+
if (exc != Qnil) {
|
158
|
+
bucket->exception = Qnil;
|
159
|
+
rb_exc_raise(exc);
|
157
160
|
}
|
158
161
|
if (params.cmd.remove.num > 1) {
|
159
162
|
return rv; /* return as a hash {key => true, ...} */
|
@@ -20,7 +20,7 @@ require 'rbconfig'
|
|
20
20
|
# This hack is more robust, because in bundler environment bundler touches
|
21
21
|
# all constants from rbconfig.rb before loading any scripts. This is why
|
22
22
|
# RC_ARCHS doesn't work under bundler on MacOS.
|
23
|
-
if RUBY_PLATFORM =~ /darwin/
|
23
|
+
if RUBY_PLATFORM =~ /darwin/ && defined?(RbConfig::ARCHFLAGS)
|
24
24
|
[RbConfig::CONFIG, RbConfig::MAKEFILE_CONFIG].each do |cfg|
|
25
25
|
cfg["CFLAGS"].gsub!(RbConfig::ARCHFLAGS, '')
|
26
26
|
cfg["LDFLAGS"].gsub!(RbConfig::ARCHFLAGS, '')
|
@@ -119,14 +119,26 @@ if try_compile(<<-SRC)
|
|
119
119
|
define("HAVE_STDARG_PROTOTYPES")
|
120
120
|
end
|
121
121
|
|
122
|
+
def die(message)
|
123
|
+
STDERR.puts "\n#{"*" * 70}"
|
124
|
+
STDERR.puts "#{message}"
|
125
|
+
STDERR.puts "#{"*" * 70}\n\n"
|
126
|
+
abort
|
127
|
+
end
|
122
128
|
|
123
|
-
have_library("couchbase", "
|
129
|
+
have_library("couchbase", "lcb_verify_compiler_setup", "libcouchbase/couchbase.h") or die("You must install libcouchbase >= 2.0.0beta3. See http://www.couchbase.com/develop/ for more details")
|
124
130
|
have_header("mach/mach_time.h")
|
125
|
-
have_header("stdint.h") or
|
131
|
+
have_header("stdint.h") or die("Failed to locate stdint.h")
|
126
132
|
have_header("sys/time.h")
|
133
|
+
have_header("fcntl.h")
|
127
134
|
have_func("clock_gettime")
|
128
135
|
have_func("gettimeofday")
|
129
136
|
have_func("QueryPerformanceCounter")
|
137
|
+
have_func("rb_hash_lookup2")
|
138
|
+
have_func("rb_thread_fd_select")
|
139
|
+
have_func("rb_thread_blocking_region")
|
140
|
+
have_func("poll", "poll.h")
|
141
|
+
have_func("ppoll", "poll.h")
|
130
142
|
define("_GNU_SOURCE")
|
131
143
|
create_header("couchbase_config.h")
|
132
144
|
create_makefile("couchbase_ext")
|
data/ext/couchbase_ext/get.c
CHANGED
@@ -18,23 +18,21 @@
|
|
18
18
|
#include "couchbase_ext.h"
|
19
19
|
|
20
20
|
void
|
21
|
-
|
21
|
+
cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp)
|
22
22
|
{
|
23
|
-
struct
|
24
|
-
struct
|
23
|
+
struct cb_context_st *ctx = (struct cb_context_st *)cookie;
|
24
|
+
struct cb_bucket_st *bucket = ctx->bucket;
|
25
25
|
VALUE key, val, flags, cas, *rv = ctx->rv, exc = Qnil, res;
|
26
26
|
|
27
27
|
ctx->nqueries--;
|
28
28
|
key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
|
29
|
-
|
29
|
+
cb_strip_key_prefix(bucket, key);
|
30
30
|
|
31
31
|
if (error != LCB_KEY_ENOENT || !ctx->quiet) {
|
32
32
|
exc = cb_check_error(error, "failed to get value", key);
|
33
33
|
if (exc != Qnil) {
|
34
|
-
rb_ivar_set(exc,
|
35
|
-
|
36
|
-
ctx->exception = cb_gc_protect(bucket, exc);
|
37
|
-
}
|
34
|
+
rb_ivar_set(exc, cb_id_iv_operation, cb_sym_get);
|
35
|
+
ctx->exception = cb_gc_protect(bucket, exc);
|
38
36
|
}
|
39
37
|
}
|
40
38
|
|
@@ -42,30 +40,35 @@ get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_
|
|
42
40
|
cas = ULL2NUM(resp->v.v0.cas);
|
43
41
|
val = Qnil;
|
44
42
|
if (resp->v.v0.nbytes != 0) {
|
45
|
-
|
46
|
-
|
47
|
-
if (val
|
43
|
+
VALUE raw = STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes);
|
44
|
+
val = cb_decode_value(raw, resp->v.v0.flags, ctx->force_format);
|
45
|
+
if (rb_obj_is_kind_of(val, rb_eStandardError)) {
|
46
|
+
VALUE exc_str = rb_funcall(val, cb_id_to_s, 0);
|
47
|
+
VALUE msg = rb_funcall(rb_mKernel, cb_id_sprintf, 3,
|
48
|
+
rb_str_new2("unable to convert value for key '%s': %s"), key, exc_str);
|
48
49
|
if (ctx->exception != Qnil) {
|
49
50
|
cb_gc_unprotect(bucket, ctx->exception);
|
50
51
|
}
|
51
|
-
ctx->exception =
|
52
|
-
rb_ivar_set(ctx->exception,
|
53
|
-
rb_ivar_set(ctx->exception,
|
52
|
+
ctx->exception = rb_exc_new3(cb_eValueFormatError, msg);
|
53
|
+
rb_ivar_set(ctx->exception, cb_id_iv_operation, cb_sym_get);
|
54
|
+
rb_ivar_set(ctx->exception, cb_id_iv_key, key);
|
55
|
+
rb_ivar_set(ctx->exception, cb_id_iv_inner_exception, val);
|
54
56
|
cb_gc_protect(bucket, ctx->exception);
|
57
|
+
val = raw;
|
55
58
|
}
|
56
|
-
} else if (
|
57
|
-
val =
|
59
|
+
} else if (cb_flags_get_format(resp->v.v0.flags) == cb_sym_plain) {
|
60
|
+
val = cb_vStrEmpty;
|
58
61
|
}
|
59
62
|
if (bucket->async) { /* asynchronous */
|
60
63
|
if (ctx->proc != Qnil) {
|
61
|
-
res = rb_class_new_instance(0, NULL,
|
62
|
-
rb_ivar_set(res,
|
63
|
-
rb_ivar_set(res,
|
64
|
-
rb_ivar_set(res,
|
65
|
-
rb_ivar_set(res,
|
66
|
-
rb_ivar_set(res,
|
67
|
-
rb_ivar_set(res,
|
68
|
-
cb_proc_call(ctx->proc, 1, res);
|
64
|
+
res = rb_class_new_instance(0, NULL, cb_cResult);
|
65
|
+
rb_ivar_set(res, cb_id_iv_error, exc);
|
66
|
+
rb_ivar_set(res, cb_id_iv_operation, cb_sym_get);
|
67
|
+
rb_ivar_set(res, cb_id_iv_key, key);
|
68
|
+
rb_ivar_set(res, cb_id_iv_value, val);
|
69
|
+
rb_ivar_set(res, cb_id_iv_flags, flags);
|
70
|
+
rb_ivar_set(res, cb_id_iv_cas, cas);
|
71
|
+
cb_proc_call(bucket, ctx->proc, 1, res);
|
69
72
|
}
|
70
73
|
} else { /* synchronous */
|
71
74
|
if (NIL_P(exc) && error != LCB_KEY_ENOENT) {
|
@@ -79,6 +82,9 @@ get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_
|
|
79
82
|
|
80
83
|
if (ctx->nqueries == 0) {
|
81
84
|
cb_gc_unprotect(bucket, ctx->proc);
|
85
|
+
if (bucket->async) {
|
86
|
+
free(ctx);
|
87
|
+
}
|
82
88
|
}
|
83
89
|
(void)handle;
|
84
90
|
}
|
@@ -214,28 +220,28 @@ get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_
|
|
214
220
|
VALUE
|
215
221
|
cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
216
222
|
{
|
217
|
-
struct
|
218
|
-
struct
|
223
|
+
struct cb_bucket_st *bucket = DATA_PTR(self);
|
224
|
+
struct cb_context_st *ctx;
|
219
225
|
VALUE args, rv, proc, exc;
|
220
226
|
size_t ii;
|
221
227
|
lcb_error_t err = LCB_SUCCESS;
|
222
|
-
struct
|
228
|
+
struct cb_params_st params;
|
223
229
|
|
224
230
|
if (bucket->handle == NULL) {
|
225
|
-
rb_raise(
|
231
|
+
rb_raise(cb_eConnectError, "closed connection");
|
226
232
|
}
|
227
233
|
rb_scan_args(argc, argv, "0*&", &args, &proc);
|
228
234
|
if (!bucket->async && proc != Qnil) {
|
229
235
|
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
230
236
|
}
|
231
|
-
memset(¶ms, 0, sizeof(struct
|
232
|
-
params.type =
|
237
|
+
memset(¶ms, 0, sizeof(struct cb_params_st));
|
238
|
+
params.type = cb_cmd_get;
|
233
239
|
params.bucket = bucket;
|
234
240
|
params.cmd.get.keys_ary = cb_gc_protect(bucket, rb_ary_new());
|
235
241
|
cb_params_build(¶ms, RARRAY_LEN(args), args);
|
236
|
-
ctx =
|
242
|
+
ctx = calloc(1, sizeof(struct cb_context_st));
|
237
243
|
if (ctx == NULL) {
|
238
|
-
rb_raise(
|
244
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
|
239
245
|
}
|
240
246
|
ctx->extended = params.cmd.get.extended;
|
241
247
|
ctx->quiet = params.cmd.get.quiet;
|
@@ -257,12 +263,12 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
257
263
|
cb_gc_unprotect(bucket, params.cmd.get.keys_ary);
|
258
264
|
exc = cb_check_error(err, "failed to schedule get request", Qnil);
|
259
265
|
if (exc != Qnil) {
|
260
|
-
|
266
|
+
free(ctx);
|
261
267
|
rb_exc_raise(exc);
|
262
268
|
}
|
263
269
|
bucket->nbytes += params.npayload;
|
264
270
|
if (bucket->async) {
|
265
|
-
|
271
|
+
cb_maybe_do_loop(bucket);
|
266
272
|
return Qnil;
|
267
273
|
} else {
|
268
274
|
if (ctx->nqueries > 0) {
|
@@ -270,13 +276,15 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
|
|
270
276
|
lcb_wait(bucket->handle);
|
271
277
|
}
|
272
278
|
exc = ctx->exception;
|
273
|
-
|
279
|
+
free(ctx);
|
274
280
|
if (exc != Qnil) {
|
275
281
|
cb_gc_unprotect(bucket, exc);
|
276
282
|
rb_exc_raise(exc);
|
277
283
|
}
|
278
|
-
|
279
|
-
|
284
|
+
exc = bucket->exception;
|
285
|
+
if (exc != Qnil) {
|
286
|
+
bucket->exception = Qnil;
|
287
|
+
rb_exc_raise(exc);
|
280
288
|
}
|
281
289
|
if (params.cmd.get.gat || params.cmd.get.assemble_hash ||
|
282
290
|
(params.cmd.get.extended && (params.cmd.get.num > 1 || params.cmd.get.array))) {
|
data/ext/couchbase_ext/http.c
CHANGED
@@ -18,37 +18,44 @@
|
|
18
18
|
#include "couchbase_ext.h"
|
19
19
|
|
20
20
|
void
|
21
|
-
|
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
22
|
{
|
23
|
-
struct
|
24
|
-
struct
|
25
|
-
VALUE *rv = ctx->rv, key, val, res;
|
23
|
+
struct cb_context_st *ctx = (struct cb_context_st *)cookie;
|
24
|
+
struct cb_bucket_st *bucket = ctx->bucket;
|
25
|
+
VALUE *rv = ctx->rv, key, val, res, exc;
|
26
|
+
lcb_http_status_t status;
|
26
27
|
|
27
28
|
ctx->request->completed = 1;
|
28
29
|
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
30
|
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
31
|
+
exc = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status);
|
32
|
+
if (exc != Qnil) {
|
33
|
+
if (val != Qnil) {
|
34
|
+
rb_ivar_set(exc, cb_id_iv_body, val);
|
35
|
+
}
|
36
|
+
rb_funcall(exc, cb_id_parse_body_bang, 0);
|
37
|
+
ctx->exception = cb_gc_protect(bucket, exc);
|
38
|
+
}
|
39
|
+
status = resp->v.v0.status;
|
35
40
|
if (resp->v.v0.headers) {
|
36
41
|
cb_build_headers(ctx, resp->v.v0.headers);
|
37
42
|
cb_gc_unprotect(bucket, ctx->headers_val);
|
38
43
|
}
|
39
44
|
if (ctx->extended) {
|
40
|
-
res = rb_class_new_instance(0, NULL,
|
41
|
-
rb_ivar_set(res,
|
42
|
-
rb_ivar_set(res,
|
43
|
-
rb_ivar_set(res,
|
44
|
-
rb_ivar_set(res,
|
45
|
-
rb_ivar_set(res,
|
46
|
-
rb_ivar_set(res,
|
45
|
+
res = rb_class_new_instance(0, NULL, cb_cResult);
|
46
|
+
rb_ivar_set(res, cb_id_iv_error, ctx->exception);
|
47
|
+
rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
|
48
|
+
rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
|
49
|
+
rb_ivar_set(res, cb_id_iv_key, key);
|
50
|
+
rb_ivar_set(res, cb_id_iv_value, val);
|
51
|
+
rb_ivar_set(res, cb_id_iv_completed, Qtrue);
|
52
|
+
rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
|
47
53
|
} else {
|
48
54
|
res = val;
|
49
55
|
}
|
50
56
|
if (ctx->proc != Qnil) {
|
51
|
-
cb_proc_call(ctx->proc, 1, res);
|
57
|
+
cb_proc_call(bucket, ctx->proc, 1, res);
|
58
|
+
cb_gc_unprotect(bucket, ctx->proc);
|
52
59
|
}
|
53
60
|
if (!bucket->async && ctx->exception == Qnil) {
|
54
61
|
*rv = res;
|
@@ -58,36 +65,49 @@ http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *coo
|
|
58
65
|
}
|
59
66
|
|
60
67
|
void
|
61
|
-
|
68
|
+
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)
|
62
69
|
{
|
63
|
-
struct
|
64
|
-
struct
|
70
|
+
struct cb_context_st *ctx = (struct cb_context_st *)cookie;
|
71
|
+
struct cb_bucket_st *bucket = ctx->bucket;
|
65
72
|
VALUE key, val, res;
|
73
|
+
lcb_http_status_t status;
|
66
74
|
|
67
75
|
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
76
|
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
71
|
-
|
72
|
-
|
73
|
-
|
77
|
+
status = resp->v.v0.status;
|
78
|
+
if (NIL_P(ctx->exception)) {
|
79
|
+
ctx->exception = cb_check_error_with_status(error,
|
80
|
+
"failed to execute HTTP request", key, resp->v.v0.status);
|
81
|
+
if (ctx->exception != Qnil) {
|
82
|
+
VALUE body_str = rb_ivar_get(ctx->exception, cb_id_iv_body);
|
83
|
+
if (NIL_P(body_str)) {
|
84
|
+
cb_gc_protect(bucket, ctx->exception);
|
85
|
+
rb_ivar_set(ctx->exception, cb_id_iv_body, val);
|
86
|
+
} else {
|
87
|
+
rb_str_concat(body_str, val);
|
88
|
+
}
|
89
|
+
if (ctx->http_cancel_on_error) {
|
90
|
+
lcb_cancel_http_request(bucket->handle, request);
|
91
|
+
}
|
92
|
+
}
|
74
93
|
}
|
75
94
|
if (resp->v.v0.headers) {
|
76
95
|
cb_build_headers(ctx, resp->v.v0.headers);
|
77
96
|
}
|
78
97
|
if (ctx->proc != Qnil) {
|
79
98
|
if (ctx->extended) {
|
80
|
-
res = rb_class_new_instance(0, NULL,
|
81
|
-
rb_ivar_set(res,
|
82
|
-
rb_ivar_set(res,
|
83
|
-
rb_ivar_set(res,
|
84
|
-
rb_ivar_set(res,
|
85
|
-
rb_ivar_set(res,
|
86
|
-
rb_ivar_set(res,
|
99
|
+
res = rb_class_new_instance(0, NULL, cb_cResult);
|
100
|
+
rb_ivar_set(res, cb_id_iv_error, ctx->exception);
|
101
|
+
rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
|
102
|
+
rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
|
103
|
+
rb_ivar_set(res, cb_id_iv_key, key);
|
104
|
+
rb_ivar_set(res, cb_id_iv_value, val);
|
105
|
+
rb_ivar_set(res, cb_id_iv_completed, Qfalse);
|
106
|
+
rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
|
87
107
|
} else {
|
88
108
|
res = val;
|
89
109
|
}
|
90
|
-
cb_proc_call(ctx->proc, 1, res);
|
110
|
+
cb_proc_call(bucket, ctx->proc, 1, res);
|
91
111
|
}
|
92
112
|
(void)handle;
|
93
113
|
}
|
@@ -95,7 +115,7 @@ http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie,
|
|
95
115
|
void
|
96
116
|
cb_http_request_free(void *ptr)
|
97
117
|
{
|
98
|
-
struct
|
118
|
+
struct cb_http_request_st *request = ptr;
|
99
119
|
if (request) {
|
100
120
|
request->running = 0;
|
101
121
|
if (TYPE(request->bucket_obj) == T_DATA
|
@@ -103,17 +123,17 @@ cb_http_request_free(void *ptr)
|
|
103
123
|
&& !request->completed) {
|
104
124
|
lcb_cancel_http_request(request->bucket->handle, request->request);
|
105
125
|
}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
xfree(request);
|
126
|
+
free((char *)request->cmd.v.v0.content_type);
|
127
|
+
free((char *)request->cmd.v.v0.path);
|
128
|
+
free((char *)request->cmd.v.v0.body);
|
110
129
|
}
|
130
|
+
xfree(request);
|
111
131
|
}
|
112
132
|
|
113
133
|
void
|
114
134
|
cb_http_request_mark(void *ptr)
|
115
135
|
{
|
116
|
-
struct
|
136
|
+
struct cb_http_request_st *request = ptr;
|
117
137
|
if (request) {
|
118
138
|
rb_gc_mark(request->on_body_callback);
|
119
139
|
}
|
@@ -123,10 +143,10 @@ cb_http_request_mark(void *ptr)
|
|
123
143
|
cb_http_request_alloc(VALUE klass)
|
124
144
|
{
|
125
145
|
VALUE obj;
|
126
|
-
struct
|
146
|
+
struct cb_http_request_st *request;
|
127
147
|
|
128
148
|
/* allocate new bucket struct and set it to zero */
|
129
|
-
obj = Data_Make_Struct(klass, struct
|
149
|
+
obj = Data_Make_Struct(klass, struct cb_http_request_st, cb_http_request_mark,
|
130
150
|
cb_http_request_free, request);
|
131
151
|
return obj;
|
132
152
|
}
|
@@ -143,7 +163,7 @@ cb_http_request_alloc(VALUE klass)
|
|
143
163
|
cb_http_request_inspect(VALUE self)
|
144
164
|
{
|
145
165
|
VALUE str;
|
146
|
-
struct
|
166
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
147
167
|
char buf[200];
|
148
168
|
|
149
169
|
str = rb_str_buf_new2("#<");
|
@@ -167,14 +187,14 @@ cb_http_request_inspect(VALUE self)
|
|
167
187
|
VALUE
|
168
188
|
cb_http_request_init(int argc, VALUE *argv, VALUE self)
|
169
189
|
{
|
170
|
-
struct
|
190
|
+
struct cb_http_request_st *request = DATA_PTR(self);
|
171
191
|
VALUE bucket, path, opts, on_body, pp, arg;
|
172
192
|
rb_scan_args(argc, argv, "22", &bucket, &pp, &opts, &on_body);
|
173
193
|
|
174
194
|
if (NIL_P(on_body) && rb_block_given_p()) {
|
175
195
|
on_body = rb_block_proc();
|
176
196
|
}
|
177
|
-
if (CLASS_OF(bucket) !=
|
197
|
+
if (CLASS_OF(bucket) != cb_cBucket) {
|
178
198
|
rb_raise(rb_eTypeError, "wrong argument type (expected Couchbase::Bucket)");
|
179
199
|
}
|
180
200
|
memset(&request->cmd, 0, sizeof(lcb_http_cmd_t));
|
@@ -191,38 +211,38 @@ cb_http_request_init(int argc, VALUE *argv, VALUE self)
|
|
191
211
|
|
192
212
|
if (opts != Qnil) {
|
193
213
|
Check_Type(opts, T_HASH);
|
194
|
-
request->extended = RTEST(rb_hash_aref(opts,
|
195
|
-
request->cmd.v.v0.chunked = RTEST(rb_hash_aref(opts,
|
196
|
-
if ((arg = rb_hash_aref(opts,
|
197
|
-
if (arg ==
|
214
|
+
request->extended = RTEST(rb_hash_aref(opts, cb_sym_extended));
|
215
|
+
request->cmd.v.v0.chunked = RTEST(rb_hash_aref(opts, cb_sym_chunked));
|
216
|
+
if ((arg = rb_hash_aref(opts, cb_sym_type)) != Qnil) {
|
217
|
+
if (arg == cb_sym_view) {
|
198
218
|
request->type = LCB_HTTP_TYPE_VIEW;
|
199
|
-
} else if (arg ==
|
219
|
+
} else if (arg == cb_sym_management) {
|
200
220
|
request->type = LCB_HTTP_TYPE_MANAGEMENT;
|
201
221
|
} else {
|
202
222
|
rb_raise(rb_eArgError, "unsupported request type");
|
203
223
|
}
|
204
224
|
}
|
205
|
-
if ((arg = rb_hash_aref(opts,
|
206
|
-
if (arg ==
|
225
|
+
if ((arg = rb_hash_aref(opts, cb_sym_method)) != Qnil) {
|
226
|
+
if (arg == cb_sym_get) {
|
207
227
|
request->cmd.v.v0.method = LCB_HTTP_METHOD_GET;
|
208
|
-
} else if (arg ==
|
228
|
+
} else if (arg == cb_sym_post) {
|
209
229
|
request->cmd.v.v0.method = LCB_HTTP_METHOD_POST;
|
210
|
-
} else if (arg ==
|
230
|
+
} else if (arg == cb_sym_put) {
|
211
231
|
request->cmd.v.v0.method = LCB_HTTP_METHOD_PUT;
|
212
|
-
} else if (arg ==
|
232
|
+
} else if (arg == cb_sym_delete) {
|
213
233
|
request->cmd.v.v0.method = LCB_HTTP_METHOD_DELETE;
|
214
234
|
} else {
|
215
235
|
rb_raise(rb_eArgError, "unsupported HTTP method");
|
216
236
|
}
|
217
237
|
}
|
218
|
-
if ((arg = rb_hash_aref(opts,
|
238
|
+
if ((arg = rb_hash_aref(opts, cb_sym_body)) != Qnil) {
|
219
239
|
Check_Type(arg, T_STRING);
|
220
240
|
request->cmd.v.v0.body = strdup(RSTRING_PTR(arg));
|
221
241
|
request->cmd.v.v0.nbody = RSTRING_LEN(arg);
|
222
242
|
}
|
223
|
-
if ((arg = rb_hash_aref(opts,
|
243
|
+
if ((arg = rb_hash_aref(opts, cb_sym_content_type)) != Qnil) {
|
224
244
|
Check_Type(arg, T_STRING);
|
225
|
-
|
245
|
+
free((char *)request->cmd.v.v0.content_type);
|
226
246
|
request->cmd.v.v0.content_type = strdup(RSTRING_PTR(arg));
|
227
247
|
}
|
228
248
|
}
|
@@ -238,7 +258,7 @@ cb_http_request_init(int argc, VALUE *argv, VALUE self)
|
|
238
258
|
VALUE
|
239
259
|
cb_http_request_on_body(VALUE self)
|
240
260
|
{
|
241
|
-
struct
|
261
|
+
struct cb_http_request_st *request = DATA_PTR(self);
|
242
262
|
VALUE old = request->on_body_callback;
|
243
263
|
if (rb_block_given_p()) {
|
244
264
|
request->on_body_callback = rb_block_proc();
|
@@ -254,30 +274,31 @@ cb_http_request_on_body(VALUE self)
|
|
254
274
|
VALUE
|
255
275
|
cb_http_request_perform(VALUE self)
|
256
276
|
{
|
257
|
-
struct
|
258
|
-
struct
|
277
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
278
|
+
struct cb_context_st *ctx;
|
259
279
|
VALUE rv, exc;
|
260
280
|
lcb_error_t err;
|
261
|
-
struct
|
281
|
+
struct cb_bucket_st *bucket;
|
262
282
|
|
263
|
-
ctx =
|
283
|
+
ctx = calloc(1, sizeof(struct cb_context_st));
|
264
284
|
if (ctx == NULL) {
|
265
|
-
rb_raise(
|
285
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory");
|
266
286
|
}
|
267
287
|
rv = Qnil;
|
268
288
|
ctx->rv = &rv;
|
269
289
|
ctx->bucket = bucket = req->bucket;
|
270
|
-
ctx->proc = rb_block_given_p() ? rb_block_proc() : req->on_body_callback;
|
290
|
+
ctx->proc = rb_block_given_p() ? cb_gc_protect(bucket, rb_block_proc()) : req->on_body_callback;
|
271
291
|
ctx->extended = req->extended;
|
272
292
|
ctx->request = req;
|
273
293
|
ctx->headers_val = cb_gc_protect(bucket, rb_hash_new());
|
294
|
+
ctx->exception = Qnil;
|
274
295
|
|
275
296
|
err = lcb_make_http_request(bucket->handle, (const void *)ctx,
|
276
297
|
req->type, &req->cmd, &req->request);
|
277
298
|
exc = cb_check_error(err, "failed to schedule document request",
|
278
299
|
STR_NEW(req->cmd.v.v0.path, req->cmd.v.v0.npath));
|
279
300
|
if (exc != Qnil) {
|
280
|
-
|
301
|
+
free(ctx);
|
281
302
|
rb_exc_raise(exc);
|
282
303
|
}
|
283
304
|
req->running = 1;
|
@@ -288,7 +309,7 @@ cb_http_request_perform(VALUE self)
|
|
288
309
|
lcb_wait(bucket->handle);
|
289
310
|
if (req->completed) {
|
290
311
|
exc = ctx->exception;
|
291
|
-
|
312
|
+
free(ctx);
|
292
313
|
if (exc != Qnil) {
|
293
314
|
cb_gc_unprotect(bucket, exc);
|
294
315
|
rb_exc_raise(exc);
|
@@ -304,8 +325,8 @@ cb_http_request_perform(VALUE self)
|
|
304
325
|
VALUE
|
305
326
|
cb_http_request_pause(VALUE self)
|
306
327
|
{
|
307
|
-
struct
|
308
|
-
|
328
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
329
|
+
lcb_breakout(req->bucket->handle);
|
309
330
|
return Qnil;
|
310
331
|
}
|
311
332
|
|
@@ -313,14 +334,14 @@ cb_http_request_pause(VALUE self)
|
|
313
334
|
cb_http_request_continue(VALUE self)
|
314
335
|
{
|
315
336
|
VALUE exc, *rv;
|
316
|
-
struct
|
337
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
317
338
|
|
318
339
|
if (req->running) {
|
319
340
|
lcb_wait(req->bucket->handle);
|
320
341
|
if (req->completed) {
|
321
342
|
exc = req->ctx->exception;
|
322
343
|
rv = req->ctx->rv;
|
323
|
-
|
344
|
+
free(req->ctx);
|
324
345
|
if (exc != Qnil) {
|
325
346
|
cb_gc_unprotect(req->bucket, exc);
|
326
347
|
rb_exc_raise(exc);
|
@@ -342,7 +363,7 @@ cb_http_request_continue(VALUE self)
|
|
342
363
|
VALUE
|
343
364
|
cb_http_request_path_get(VALUE self)
|
344
365
|
{
|
345
|
-
struct
|
366
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
346
367
|
return STR_NEW_CSTR(req->cmd.v.v0.path);
|
347
368
|
}
|
348
369
|
|
@@ -356,7 +377,7 @@ cb_http_request_path_get(VALUE self)
|
|
356
377
|
VALUE
|
357
378
|
cb_http_request_chunked_get(VALUE self)
|
358
379
|
{
|
359
|
-
struct
|
380
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
360
381
|
return req->cmd.v.v0.chunked ? Qtrue : Qfalse;
|
361
382
|
}
|
362
383
|
|
@@ -370,7 +391,7 @@ cb_http_request_chunked_get(VALUE self)
|
|
370
391
|
VALUE
|
371
392
|
cb_http_request_extended_get(VALUE self)
|
372
393
|
{
|
373
|
-
struct
|
394
|
+
struct cb_http_request_st *req = DATA_PTR(self);
|
374
395
|
return req->extended ? Qtrue : Qfalse;
|
375
396
|
}
|
376
397
|
|
@@ -396,7 +417,7 @@ cb_bucket_make_http_request(int argc, VALUE *argv, VALUE self)
|
|
396
417
|
args[0] = self;
|
397
418
|
rb_scan_args(argc, argv, "11&", &args[1], &args[2], &args[3]);
|
398
419
|
|
399
|
-
return rb_class_new_instance(4, args,
|
420
|
+
return rb_class_new_instance(4, args, cb_cCouchRequest);
|
400
421
|
}
|
401
422
|
|
402
423
|
|