couchbase 1.2.0.z.beta-x86-mingw32 → 1.2.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.travis.yml +1 -1
  2. data/Makefile +3 -0
  3. data/README.markdown +15 -4
  4. data/RELEASE_NOTES.markdown +526 -0
  5. data/couchbase.gemspec +0 -1
  6. data/ext/couchbase_ext/arguments.c +161 -244
  7. data/ext/couchbase_ext/arithmetic.c +29 -37
  8. data/ext/couchbase_ext/bucket.c +252 -219
  9. data/ext/couchbase_ext/couchbase_ext.c +540 -417
  10. data/ext/couchbase_ext/couchbase_ext.h +218 -191
  11. data/ext/couchbase_ext/delete.c +30 -27
  12. data/ext/couchbase_ext/extconf.rb +15 -3
  13. data/ext/couchbase_ext/get.c +45 -37
  14. data/ext/couchbase_ext/http.c +95 -74
  15. data/ext/couchbase_ext/multithread_plugin.c +1238 -0
  16. data/ext/couchbase_ext/observe.c +42 -37
  17. data/ext/couchbase_ext/result.c +17 -20
  18. data/ext/couchbase_ext/stats.c +30 -28
  19. data/ext/couchbase_ext/store.c +47 -39
  20. data/ext/couchbase_ext/timer.c +11 -11
  21. data/ext/couchbase_ext/touch.c +30 -27
  22. data/ext/couchbase_ext/unlock.c +30 -27
  23. data/ext/couchbase_ext/utils.c +166 -89
  24. data/ext/couchbase_ext/version.c +29 -26
  25. data/lib/action_dispatch/middleware/session/couchbase_store.rb +2 -2
  26. data/lib/active_support/cache/couchbase_store.rb +6 -6
  27. data/lib/couchbase.rb +1 -0
  28. data/lib/couchbase/bucket.rb +6 -11
  29. data/lib/couchbase/cluster.rb +105 -0
  30. data/lib/couchbase/utils.rb +8 -5
  31. data/lib/couchbase/version.rb +1 -1
  32. data/lib/couchbase/view.rb +51 -5
  33. data/lib/couchbase/view_row.rb +1 -1
  34. data/lib/ext/multi_json_fix.rb +13 -9
  35. data/lib/rack/session/couchbase.rb +11 -7
  36. data/tasks/compile.rake +1 -1
  37. data/tasks/test.rake +40 -34
  38. data/tasks/util.rake +1 -1
  39. data/test/setup.rb +9 -2
  40. data/test/test_arithmetic.rb +37 -0
  41. data/test/test_async.rb +22 -18
  42. data/test/test_unlock.rb +0 -1
  43. data/test/test_utils.rb +32 -0
  44. metadata +13 -23
  45. data/HISTORY.markdown +0 -219
@@ -18,38 +18,39 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  void
21
- delete_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_remove_resp_t *resp)
21
+ cb_delete_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_remove_resp_t *resp)
22
22
  {
23
- struct context_st *ctx = (struct context_st *)cookie;
24
- struct bucket_st *bucket = ctx->bucket;
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
- strip_key_prefix(bucket, key);
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, id_iv_operation, sym_delete);
35
- if (NIL_P(ctx->exception)) {
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, cResult);
43
- rb_ivar_set(res, id_iv_error, exc);
44
- rb_ivar_set(res, id_iv_operation, sym_delete);
45
- rb_ivar_set(res, id_iv_key, key);
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 bucket_st *bucket = DATA_PTR(self);
103
- struct context_st *ctx;
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 params_st params;
108
+ struct cb_params_st params;
108
109
 
109
110
  if (bucket->handle == NULL) {
110
- rb_raise(eConnectError, "closed connection");
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, id_flatten_bang, 0);
117
- memset(&params, 0, sizeof(struct params_st));
118
- params.type = cmd_remove;
117
+ rb_funcall(args, cb_id_flatten_bang, 0);
118
+ memset(&params, 0, sizeof(struct cb_params_st));
119
+ params.type = cb_cmd_remove;
119
120
  params.bucket = bucket;
120
121
  cb_params_build(&params, RARRAY_LEN(args), args);
121
122
 
122
- ctx = xcalloc(1, sizeof(struct context_st));
123
+ ctx = calloc(1, sizeof(struct cb_context_st));
123
124
  if (ctx == NULL) {
124
- rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
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(&params);
136
137
  exc = cb_check_error(err, "failed to schedule delete request", Qnil);
137
138
  if (exc != Qnil) {
138
- xfree(ctx);
139
+ free(ctx);
139
140
  rb_exc_raise(exc);
140
141
  }
141
142
  bucket->nbytes += params.npayload;
142
143
  if (bucket->async) {
143
- maybe_do_loop(bucket);
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
- xfree(ctx);
152
+ free(ctx);
152
153
  if (exc != Qnil) {
153
154
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
154
155
  }
155
- if (bucket->exception != Qnil) {
156
- rb_exc_raise(bucket->exception);
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", "lcb_get", "libcouchbase/couchbase.h") or abort "You should install libcouchbase >= 2.0.0. See http://www.couchbase.com/develop/ for more details"
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 abort "Failed to locate stdint.h"
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")
@@ -18,23 +18,21 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  void
21
- get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp)
21
+ cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp)
22
22
  {
23
- struct context_st *ctx = (struct context_st *)cookie;
24
- struct bucket_st *bucket = ctx->bucket;
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
- strip_key_prefix(bucket, key);
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, id_iv_operation, sym_get);
35
- if (NIL_P(ctx->exception)) {
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
- val = decode_value(STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes),
46
- resp->v.v0.flags, ctx->force_format);
47
- if (val == Qundef) {
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 = rb_exc_new2(eValueFormatError, "unable to convert value");
52
- rb_ivar_set(ctx->exception, id_iv_operation, sym_get);
53
- rb_ivar_set(ctx->exception, id_iv_key, key);
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 (flags_get_format(resp->v.v0.flags) == sym_plain) {
57
- val = STR_NEW_CSTR("");
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, cResult);
62
- rb_ivar_set(res, id_iv_error, exc);
63
- rb_ivar_set(res, id_iv_operation, sym_get);
64
- rb_ivar_set(res, id_iv_key, key);
65
- rb_ivar_set(res, id_iv_value, val);
66
- rb_ivar_set(res, id_iv_flags, flags);
67
- rb_ivar_set(res, id_iv_cas, cas);
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 bucket_st *bucket = DATA_PTR(self);
218
- struct context_st *ctx;
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 params_st params;
228
+ struct cb_params_st params;
223
229
 
224
230
  if (bucket->handle == NULL) {
225
- rb_raise(eConnectError, "closed connection");
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(&params, 0, sizeof(struct params_st));
232
- params.type = cmd_get;
237
+ memset(&params, 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(&params, RARRAY_LEN(args), args);
236
- ctx = xcalloc(1, sizeof(struct context_st));
242
+ ctx = calloc(1, sizeof(struct cb_context_st));
237
243
  if (ctx == NULL) {
238
- rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
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
- xfree(ctx);
266
+ free(ctx);
261
267
  rb_exc_raise(exc);
262
268
  }
263
269
  bucket->nbytes += params.npayload;
264
270
  if (bucket->async) {
265
- maybe_do_loop(bucket);
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
- xfree(ctx);
279
+ free(ctx);
274
280
  if (exc != Qnil) {
275
281
  cb_gc_unprotect(bucket, exc);
276
282
  rb_exc_raise(exc);
277
283
  }
278
- if (bucket->exception != Qnil) {
279
- rb_exc_raise(bucket->exception);
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))) {
@@ -18,37 +18,44 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
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)
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 context_st *ctx = (struct context_st *)cookie;
24
- struct bucket_st *bucket = ctx->bucket;
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, 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);
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
- http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
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 context_st *ctx = (struct context_st *)cookie;
64
- struct bucket_st *bucket = ctx->bucket;
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
- if (ctx->exception != Qnil) {
72
- cb_gc_protect(bucket, ctx->exception);
73
- lcb_cancel_http_request(bucket->handle, request);
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, 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);
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 http_request_st *request = ptr;
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
- 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);
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 http_request_st *request = ptr;
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 http_request_st *request;
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 http_request_st, cb_http_request_mark,
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 http_request_st *req = DATA_PTR(self);
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 http_request_st *request = DATA_PTR(self);
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) != cBucket) {
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, 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) {
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 == sym_management) {
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, sym_method)) != Qnil) {
206
- if (arg == sym_get) {
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 == sym_post) {
228
+ } else if (arg == cb_sym_post) {
209
229
  request->cmd.v.v0.method = LCB_HTTP_METHOD_POST;
210
- } else if (arg == sym_put) {
230
+ } else if (arg == cb_sym_put) {
211
231
  request->cmd.v.v0.method = LCB_HTTP_METHOD_PUT;
212
- } else if (arg == sym_delete) {
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, sym_body)) != Qnil) {
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, sym_content_type)) != Qnil) {
243
+ if ((arg = rb_hash_aref(opts, cb_sym_content_type)) != Qnil) {
224
244
  Check_Type(arg, T_STRING);
225
- xfree((char *)request->cmd.v.v0.content_type);
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 http_request_st *request = DATA_PTR(self);
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 http_request_st *req = DATA_PTR(self);
258
- struct context_st *ctx;
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 bucket_st *bucket;
281
+ struct cb_bucket_st *bucket;
262
282
 
263
- ctx = xcalloc(1, sizeof(struct context_st));
283
+ ctx = calloc(1, sizeof(struct cb_context_st));
264
284
  if (ctx == NULL) {
265
- rb_raise(eClientNoMemoryError, "failed to allocate memory");
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
- xfree(ctx);
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
- xfree(ctx);
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 http_request_st *req = DATA_PTR(self);
308
- req->bucket->io->stop_event_loop(req->bucket->io);
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 http_request_st *req = DATA_PTR(self);
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
- xfree(req->ctx);
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 http_request_st *req = DATA_PTR(self);
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 http_request_st *req = DATA_PTR(self);
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 http_request_st *req = DATA_PTR(self);
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, cCouchRequest);
420
+ return rb_class_new_instance(4, args, cb_cCouchRequest);
400
421
  }
401
422
 
402
423