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
@@ -26,7 +26,7 @@ cb_timer_free(void *ptr)
26
26
  void
27
27
  cb_timer_mark(void *ptr)
28
28
  {
29
- struct timer_st *timer = ptr;
29
+ struct cb_timer_st *timer = ptr;
30
30
  if (timer) {
31
31
  rb_gc_mark(timer->callback);
32
32
  }
@@ -36,10 +36,10 @@ cb_timer_mark(void *ptr)
36
36
  cb_timer_alloc(VALUE klass)
37
37
  {
38
38
  VALUE obj;
39
- struct timer_st *timer;
39
+ struct cb_timer_st *timer;
40
40
 
41
41
  /* allocate new bucket struct and set it to zero */
42
- obj = Data_Make_Struct(klass, struct timer_st, cb_timer_mark,
42
+ obj = Data_Make_Struct(klass, struct cb_timer_st, cb_timer_mark,
43
43
  cb_timer_free, timer);
44
44
  return obj;
45
45
  }
@@ -56,7 +56,7 @@ cb_timer_alloc(VALUE klass)
56
56
  cb_timer_inspect(VALUE self)
57
57
  {
58
58
  VALUE str;
59
- struct timer_st *tm = DATA_PTR(self);
59
+ struct cb_timer_st *tm = DATA_PTR(self);
60
60
  char buf[200];
61
61
 
62
62
  str = rb_str_buf_new2("#<");
@@ -97,7 +97,7 @@ cb_timer_inspect(VALUE self)
97
97
  VALUE
98
98
  cb_timer_cancel(VALUE self)
99
99
  {
100
- struct timer_st *tm = DATA_PTR(self);
100
+ struct cb_timer_st *tm = DATA_PTR(self);
101
101
  lcb_timer_destroy(tm->bucket->handle, tm->timer);
102
102
  return self;
103
103
  }
@@ -105,15 +105,15 @@ cb_timer_cancel(VALUE self)
105
105
  static VALUE
106
106
  trigger_timer(VALUE timer)
107
107
  {
108
- struct timer_st *tm = DATA_PTR(timer);
109
- return cb_proc_call(tm->callback, 1, timer);
108
+ struct cb_timer_st *tm = DATA_PTR(timer);
109
+ return cb_proc_call(tm->bucket, tm->callback, 1, timer);
110
110
  }
111
111
 
112
112
  static void
113
113
  timer_callback(lcb_timer_t timer, lcb_t instance,
114
114
  const void *cookie)
115
115
  {
116
- struct timer_st *tm = (struct timer_st *)cookie;
116
+ struct cb_timer_st *tm = (struct cb_timer_st *)cookie;
117
117
  int error = 0;
118
118
 
119
119
  rb_protect(trigger_timer, tm->self, &error);
@@ -162,14 +162,14 @@ timer_callback(lcb_timer_t timer, lcb_t instance,
162
162
  VALUE
163
163
  cb_timer_init(int argc, VALUE *argv, VALUE self)
164
164
  {
165
- struct timer_st *tm = DATA_PTR(self);
165
+ struct cb_timer_st *tm = DATA_PTR(self);
166
166
  VALUE bucket, opts, timeout, exc, cb;
167
167
  lcb_error_t err;
168
168
 
169
169
  rb_need_block();
170
170
  rb_scan_args(argc, argv, "21&", &bucket, &timeout, &opts, &cb);
171
171
 
172
- if (CLASS_OF(bucket) != cBucket) {
172
+ if (CLASS_OF(bucket) != cb_cBucket) {
173
173
  rb_raise(rb_eTypeError, "wrong argument type (expected Couchbase::Bucket)");
174
174
  }
175
175
  tm->self = self;
@@ -178,7 +178,7 @@ cb_timer_init(int argc, VALUE *argv, VALUE self)
178
178
  tm->bucket = DATA_PTR(bucket);
179
179
  if (opts != Qnil) {
180
180
  Check_Type(opts, T_HASH);
181
- tm->periodic = RTEST(rb_hash_aref(opts, sym_periodic));
181
+ tm->periodic = RTEST(rb_hash_aref(opts, cb_sym_periodic));
182
182
  }
183
183
  tm->timer = lcb_timer_create(tm->bucket->handle, tm, tm->usec,
184
184
  tm->periodic, timer_callback, &err);
@@ -18,39 +18,40 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  void
21
- touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_touch_resp_t *resp)
21
+ cb_touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_touch_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 touch value", key);
33
33
  if (exc != Qnil) {
34
- rb_ivar_set(exc, id_iv_operation, sym_touch);
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_touch);
35
+ ctx->exception = cb_gc_protect(bucket, exc);
38
36
  }
39
37
  }
40
38
 
41
39
  if (bucket->async) { /* asynchronous */
42
40
  if (ctx->proc != Qnil) {
43
- res = rb_class_new_instance(0, NULL, cResult);
44
- rb_ivar_set(res, id_iv_error, exc);
45
- rb_ivar_set(res, id_iv_operation, sym_touch);
46
- rb_ivar_set(res, id_iv_key, key);
47
- cb_proc_call(ctx->proc, 1, res);
41
+ res = rb_class_new_instance(0, NULL, cb_cResult);
42
+ rb_ivar_set(res, cb_id_iv_error, exc);
43
+ rb_ivar_set(res, cb_id_iv_operation, cb_sym_touch);
44
+ rb_ivar_set(res, cb_id_iv_key, key);
45
+ cb_proc_call(bucket, ctx->proc, 1, res);
48
46
  }
49
47
  } else { /* synchronous */
50
48
  rb_hash_aset(*rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
51
49
  }
52
50
  if (ctx->nqueries == 0) {
53
51
  cb_gc_unprotect(bucket, ctx->proc);
52
+ if (bucket->async) {
53
+ free(ctx);
54
+ }
54
55
  }
55
56
  (void)handle;
56
57
  }
@@ -123,27 +124,27 @@ touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_to
123
124
  VALUE
124
125
  cb_bucket_touch(int argc, VALUE *argv, VALUE self)
125
126
  {
126
- struct bucket_st *bucket = DATA_PTR(self);
127
- struct context_st *ctx;
127
+ struct cb_bucket_st *bucket = DATA_PTR(self);
128
+ struct cb_context_st *ctx;
128
129
  VALUE args, rv, proc, exc;
129
130
  lcb_error_t err;
130
- struct params_st params;
131
+ struct cb_params_st params;
131
132
 
132
133
  if (bucket->handle == NULL) {
133
- rb_raise(eConnectError, "closed connection");
134
+ rb_raise(cb_eConnectError, "closed connection");
134
135
  }
135
136
  rb_scan_args(argc, argv, "0*&", &args, &proc);
136
137
  if (!bucket->async && proc != Qnil) {
137
138
  rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
138
139
  }
139
- rb_funcall(args, id_flatten_bang, 0);
140
- memset(&params, 0, sizeof(struct params_st));
141
- params.type = cmd_touch;
140
+ rb_funcall(args, cb_id_flatten_bang, 0);
141
+ memset(&params, 0, sizeof(struct cb_params_st));
142
+ params.type = cb_cmd_touch;
142
143
  params.bucket = bucket;
143
144
  cb_params_build(&params, RARRAY_LEN(args), args);
144
- ctx = xcalloc(1, sizeof(struct context_st));
145
+ ctx = calloc(1, sizeof(struct cb_context_st));
145
146
  if (ctx == NULL) {
146
- rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
147
+ rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
147
148
  }
148
149
  ctx->proc = cb_gc_protect(bucket, proc);
149
150
  ctx->bucket = bucket;
@@ -157,12 +158,12 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
157
158
  cb_params_destroy(&params);
158
159
  exc = cb_check_error(err, "failed to schedule touch request", Qnil);
159
160
  if (exc != Qnil) {
160
- xfree(ctx);
161
+ free(ctx);
161
162
  rb_exc_raise(exc);
162
163
  }
163
164
  bucket->nbytes += params.npayload;
164
165
  if (bucket->async) {
165
- maybe_do_loop(bucket);
166
+ cb_maybe_do_loop(bucket);
166
167
  return Qnil;
167
168
  } else {
168
169
  if (ctx->nqueries > 0) {
@@ -170,12 +171,14 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
170
171
  lcb_wait(bucket->handle);
171
172
  }
172
173
  exc = ctx->exception;
173
- xfree(ctx);
174
+ free(ctx);
174
175
  if (exc != Qnil) {
175
176
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
176
177
  }
177
- if (bucket->exception != Qnil) {
178
- rb_exc_raise(bucket->exception);
178
+ exc = bucket->exception;
179
+ if (exc != Qnil) {
180
+ bucket->exception = Qnil;
181
+ rb_exc_raise(exc);
179
182
  }
180
183
  if (params.cmd.touch.num > 1) {
181
184
  return rv; /* return as a hash {key => true, ...} */
@@ -18,39 +18,40 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  void
21
- unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_resp_t *resp)
21
+ cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_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 unlock value", key);
33
33
  if (exc != Qnil) {
34
- rb_ivar_set(exc, id_iv_operation, sym_unlock);
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_unlock);
35
+ ctx->exception = cb_gc_protect(bucket, exc);
38
36
  }
39
37
  }
40
38
 
41
39
  if (bucket->async) { /* asynchronous */
42
40
  if (ctx->proc != Qnil) {
43
- res = rb_class_new_instance(0, NULL, cResult);
44
- rb_ivar_set(res, id_iv_error, exc);
45
- rb_ivar_set(res, id_iv_operation, sym_unlock);
46
- rb_ivar_set(res, id_iv_key, key);
47
- cb_proc_call(ctx->proc, 1, res);
41
+ res = rb_class_new_instance(0, NULL, cb_cResult);
42
+ rb_ivar_set(res, cb_id_iv_error, exc);
43
+ rb_ivar_set(res, cb_id_iv_operation, cb_sym_unlock);
44
+ rb_ivar_set(res, cb_id_iv_key, key);
45
+ cb_proc_call(bucket, ctx->proc, 1, res);
48
46
  }
49
47
  } else { /* synchronous */
50
48
  rb_hash_aset(*rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
51
49
  }
52
50
  if (ctx->nqueries == 0) {
53
51
  cb_gc_unprotect(bucket, ctx->proc);
52
+ if (bucket->async) {
53
+ free(ctx);
54
+ }
54
55
  }
55
56
  (void)handle;
56
57
  }
@@ -113,27 +114,27 @@ unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_u
113
114
  VALUE
114
115
  cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
115
116
  {
116
- struct bucket_st *bucket = DATA_PTR(self);
117
- struct context_st *ctx;
117
+ struct cb_bucket_st *bucket = DATA_PTR(self);
118
+ struct cb_context_st *ctx;
118
119
  VALUE args, rv, proc, exc;
119
120
  lcb_error_t err;
120
- struct params_st params;
121
+ struct cb_params_st params;
121
122
 
122
123
  if (bucket->handle == NULL) {
123
- rb_raise(eConnectError, "closed connection");
124
+ rb_raise(cb_eConnectError, "closed connection");
124
125
  }
125
126
  rb_scan_args(argc, argv, "0*&", &args, &proc);
126
127
  if (!bucket->async && proc != Qnil) {
127
128
  rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
128
129
  }
129
- rb_funcall(args, id_flatten_bang, 0);
130
- memset(&params, 0, sizeof(struct params_st));
131
- params.type = cmd_unlock;
130
+ rb_funcall(args, cb_id_flatten_bang, 0);
131
+ memset(&params, 0, sizeof(struct cb_params_st));
132
+ params.type = cb_cmd_unlock;
132
133
  params.bucket = bucket;
133
134
  cb_params_build(&params, RARRAY_LEN(args), args);
134
- ctx = xcalloc(1, sizeof(struct context_st));
135
+ ctx = calloc(1, sizeof(struct cb_context_st));
135
136
  if (ctx == NULL) {
136
- rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
137
+ rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
137
138
  }
138
139
  ctx->proc = cb_gc_protect(bucket, proc);
139
140
  ctx->bucket = bucket;
@@ -147,12 +148,12 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
147
148
  cb_params_destroy(&params);
148
149
  exc = cb_check_error(err, "failed to schedule unlock request", Qnil);
149
150
  if (exc != Qnil) {
150
- xfree(ctx);
151
+ free(ctx);
151
152
  rb_exc_raise(exc);
152
153
  }
153
154
  bucket->nbytes += params.npayload;
154
155
  if (bucket->async) {
155
- maybe_do_loop(bucket);
156
+ cb_maybe_do_loop(bucket);
156
157
  return Qnil;
157
158
  } else {
158
159
  if (ctx->nqueries > 0) {
@@ -160,12 +161,14 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
160
161
  lcb_wait(bucket->handle);
161
162
  }
162
163
  exc = ctx->exception;
163
- xfree(ctx);
164
+ free(ctx);
164
165
  if (exc != Qnil) {
165
166
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
166
167
  }
167
- if (bucket->exception != Qnil) {
168
- rb_exc_raise(bucket->exception);
168
+ exc = bucket->exception;
169
+ if (exc != Qnil) {
170
+ bucket->exception = Qnil;
171
+ rb_exc_raise(exc);
169
172
  }
170
173
  if (params.cmd.unlock.num > 1) {
171
174
  return rv; /* return as a hash {key => true, ...} */
@@ -18,28 +18,80 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  VALUE
21
- cb_gc_protect(struct bucket_st *bucket, VALUE val)
21
+ cb_gc_protect(struct cb_bucket_st *bucket, VALUE val)
22
22
  {
23
23
  rb_hash_aset(bucket->object_space, val|1, val);
24
24
  return val;
25
25
  }
26
26
 
27
27
  VALUE
28
- cb_gc_unprotect(struct bucket_st *bucket, VALUE val)
28
+ cb_gc_unprotect(struct cb_bucket_st *bucket, VALUE val)
29
29
  {
30
- rb_funcall(bucket->object_space, id_delete, 1, val|1);
30
+ rb_funcall(bucket->object_space, cb_id_delete, 1, val|1);
31
31
  return val;
32
32
  }
33
33
 
34
+ struct proc_params_st
35
+ {
36
+ struct cb_bucket_st *bucket;
37
+ VALUE recv;
38
+ ID mid;
39
+ int argc;
40
+ VALUE *argv;
41
+ VALUE exc;
42
+ };
43
+
44
+ static VALUE
45
+ do_async_error_notify(VALUE ptr)
46
+ {
47
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
48
+ return rb_funcall(p->bucket->on_error_proc, cb_id_call, 1, p->exc);
49
+ }
50
+
51
+ void
52
+ cb_async_error_notify(struct cb_bucket_st *bucket, VALUE exc)
53
+ {
54
+ if (bucket->on_error_proc != Qnil) {
55
+ struct proc_params_st params;
56
+ int fail;
57
+ params.bucket = bucket;
58
+ params.exc = exc;
59
+ rb_protect(do_async_error_notify, (VALUE)&params, &fail);
60
+ if (fail) {
61
+ rb_warning("Couchbase::Bucket#on_error shouldn't raise exceptions");
62
+ }
63
+ } else {
64
+ if (NIL_P(bucket->exception)) {
65
+ bucket->exception = exc;
66
+ }
67
+ }
68
+ }
69
+
70
+ static VALUE
71
+ func_call_failed(VALUE ptr, VALUE exc)
72
+ {
73
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
74
+ cb_async_error_notify(p->bucket, exc);
75
+ return Qnil;
76
+ }
77
+
78
+ static VALUE
79
+ do_func_call(VALUE ptr)
80
+ {
81
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
82
+ return rb_funcall2(p->recv, p->mid, p->argc, p->argv);
83
+ }
84
+
34
85
  VALUE
35
- cb_proc_call(VALUE recv, int argc, ...)
86
+ cb_proc_call(struct cb_bucket_st *bucket, VALUE recv, int argc, ...)
36
87
  {
37
88
  VALUE *argv;
38
89
  va_list ar;
39
90
  int arity;
40
91
  int ii;
92
+ struct proc_params_st params;
41
93
 
42
- arity = FIX2INT(rb_funcall(recv, id_arity, 0));
94
+ arity = FIX2INT(rb_funcall(recv, cb_id_arity, 0));
43
95
  if (arity < 0) {
44
96
  arity = argc;
45
97
  }
@@ -57,13 +109,20 @@ cb_proc_call(VALUE recv, int argc, ...)
57
109
  } else {
58
110
  argv = NULL;
59
111
  }
60
- return rb_funcall2(recv, id_call, arity, argv);
112
+ params.bucket = bucket;
113
+ params.recv = recv;
114
+ params.mid = cb_id_call;
115
+ params.argc = arity;
116
+ params.argv = argv;
117
+ return rb_rescue2(do_func_call, (VALUE)&params,
118
+ func_call_failed, (VALUE)&params,
119
+ rb_eException, (VALUE)0);
61
120
  }
62
121
 
63
122
  VALUE
64
123
  cb_hash_delete(VALUE hash, VALUE key)
65
124
  {
66
- return rb_funcall(hash, id_delete, 1, key);
125
+ return rb_funcall(hash, cb_id_delete, 1, key);
67
126
  }
68
127
 
69
128
  /* Helper to convert return code from libcouchbase to meaningful exception.
@@ -77,83 +136,93 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
77
136
  VALUE klass, exc, str;
78
137
  char buf[300];
79
138
 
80
- if (rc == LCB_SUCCESS || rc == LCB_AUTH_CONTINUE) {
139
+ if ((rc == LCB_SUCCESS && (status == 0 || status / 100 == 2)) ||
140
+ rc == LCB_AUTH_CONTINUE) {
81
141
  return Qnil;
82
142
  }
83
143
  switch (rc) {
84
144
  case LCB_AUTH_ERROR:
85
- klass = eAuthError;
145
+ klass = cb_eAuthError;
86
146
  break;
87
147
  case LCB_DELTA_BADVAL:
88
- klass = eDeltaBadvalError;
148
+ klass = cb_eDeltaBadvalError;
89
149
  break;
90
150
  case LCB_E2BIG:
91
- klass = eTooBigError;
151
+ klass = cb_eTooBigError;
92
152
  break;
93
153
  case LCB_EBUSY:
94
- klass = eBusyError;
154
+ klass = cb_eBusyError;
95
155
  break;
96
156
  case LCB_EINTERNAL:
97
- klass = eInternalError;
157
+ klass = cb_eInternalError;
98
158
  break;
99
159
  case LCB_EINVAL:
100
- klass = eInvalidError;
160
+ klass = cb_eInvalidError;
101
161
  break;
102
162
  case LCB_ENOMEM:
103
- klass = eNoMemoryError;
163
+ klass = cb_eNoMemoryError;
104
164
  break;
105
165
  case LCB_ERANGE:
106
- klass = eRangeError;
166
+ klass = cb_eRangeError;
107
167
  break;
108
168
  case LCB_ETMPFAIL:
109
- klass = eTmpFailError;
169
+ klass = cb_eTmpFailError;
110
170
  break;
111
171
  case LCB_KEY_EEXISTS:
112
- klass = eKeyExistsError;
172
+ klass = cb_eKeyExistsError;
113
173
  break;
114
174
  case LCB_KEY_ENOENT:
115
- klass = eNotFoundError;
175
+ klass = cb_eNotFoundError;
116
176
  break;
117
- case LCB_LIBEVENT_ERROR:
118
- klass = eLibeventError;
177
+ case LCB_DLOPEN_FAILED:
178
+ klass = cb_eDlopenFailedError;
179
+ break;
180
+ case LCB_DLSYM_FAILED:
181
+ klass = cb_eDlsymFailedError;
119
182
  break;
120
183
  case LCB_NETWORK_ERROR:
121
- klass = eNetworkError;
184
+ klass = cb_eNetworkError;
122
185
  break;
123
186
  case LCB_NOT_MY_VBUCKET:
124
- klass = eNotMyVbucketError;
187
+ klass = cb_eNotMyVbucketError;
125
188
  break;
126
189
  case LCB_NOT_STORED:
127
- klass = eNotStoredError;
190
+ klass = cb_eNotStoredError;
128
191
  break;
129
192
  case LCB_NOT_SUPPORTED:
130
- klass = eNotSupportedError;
193
+ klass = cb_eNotSupportedError;
131
194
  break;
132
195
  case LCB_UNKNOWN_COMMAND:
133
- klass = eUnknownCommandError;
196
+ klass = cb_eUnknownCommandError;
134
197
  break;
135
198
  case LCB_UNKNOWN_HOST:
136
- klass = eUnknownHostError;
199
+ klass = cb_eUnknownHostError;
137
200
  break;
138
201
  case LCB_PROTOCOL_ERROR:
139
- klass = eProtocolError;
202
+ klass = cb_eProtocolError;
140
203
  break;
141
204
  case LCB_ETIMEDOUT:
142
- klass = eTimeoutError;
205
+ klass = cb_eTimeoutError;
143
206
  break;
144
207
  case LCB_CONNECT_ERROR:
145
- klass = eConnectError;
208
+ klass = cb_eConnectError;
146
209
  break;
147
210
  case LCB_BUCKET_ENOENT:
148
- klass = eBucketNotFoundError;
211
+ klass = cb_eBucketNotFoundError;
149
212
  break;
150
213
  case LCB_CLIENT_ENOMEM:
151
- klass = eClientNoMemoryError;
214
+ klass = cb_eClientNoMemoryError;
215
+ break;
216
+ case LCB_CLIENT_ETMPFAIL:
217
+ klass = cb_eClientTmpFailError;
218
+ break;
219
+ case LCB_EBADHANDLE:
220
+ klass = cb_eBadHandleError;
152
221
  break;
153
222
  case LCB_ERROR:
154
223
  /* fall through */
155
224
  default:
156
- klass = eLibcouchbaseError;
225
+ klass = cb_eLibcouchbaseError;
157
226
  }
158
227
 
159
228
  str = rb_str_buf_new2(msg ? msg : "");
@@ -164,6 +233,7 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
164
233
  }
165
234
  if (status > 0) {
166
235
  const char *reason = NULL;
236
+ klass = cb_eHTTPError;
167
237
  snprintf(buf, 300, "status=\"%d\"", status);
168
238
  rb_str_buf_cat2(str, buf);
169
239
  switch (status) {
@@ -261,11 +331,11 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
261
331
  snprintf(buf, 300, "error=0x%02x)", rc);
262
332
  rb_str_buf_cat2(str, buf);
263
333
  exc = rb_exc_new3(klass, str);
264
- rb_ivar_set(exc, id_iv_error, INT2FIX(rc));
265
- rb_ivar_set(exc, id_iv_key, key);
266
- rb_ivar_set(exc, id_iv_cas, Qnil);
267
- rb_ivar_set(exc, id_iv_operation, Qnil);
268
- rb_ivar_set(exc, id_iv_status, status ? INT2FIX(status) : Qnil);
334
+ rb_ivar_set(exc, cb_id_iv_error, INT2FIX(rc));
335
+ rb_ivar_set(exc, cb_id_iv_key, key);
336
+ rb_ivar_set(exc, cb_id_iv_cas, Qnil);
337
+ rb_ivar_set(exc, cb_id_iv_operation, Qnil);
338
+ rb_ivar_set(exc, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
269
339
  return exc;
270
340
  }
271
341
 
@@ -277,35 +347,35 @@ cb_check_error(lcb_error_t rc, const char *msg, VALUE key)
277
347
 
278
348
 
279
349
  uint32_t
280
- flags_set_format(uint32_t flags, ID format)
350
+ cb_flags_set_format(uint32_t flags, ID format)
281
351
  {
282
- flags &= ~((uint32_t)FMT_MASK); /* clear format bits */
283
-
284
- if (format == sym_document) {
285
- return flags | FMT_DOCUMENT;
286
- } else if (format == sym_marshal) {
287
- return flags | FMT_MARSHAL;
288
- } else if (format == sym_plain) {
289
- return flags | FMT_PLAIN;
352
+ flags &= ~((uint32_t)CB_FMT_MASK); /* clear format bits */
353
+
354
+ if (format == cb_sym_document) {
355
+ return flags | CB_FMT_DOCUMENT;
356
+ } else if (format == cb_sym_marshal) {
357
+ return flags | CB_FMT_MARSHAL;
358
+ } else if (format == cb_sym_plain) {
359
+ return flags | CB_FMT_PLAIN;
290
360
  }
291
361
  return flags; /* document is the default */
292
362
  }
293
363
 
294
364
  ID
295
- flags_get_format(uint32_t flags)
365
+ cb_flags_get_format(uint32_t flags)
296
366
  {
297
- flags &= FMT_MASK; /* select format bits */
367
+ flags &= CB_FMT_MASK; /* select format bits */
298
368
 
299
369
  switch (flags) {
300
- case FMT_DOCUMENT:
301
- return sym_document;
302
- case FMT_MARSHAL:
303
- return sym_marshal;
304
- case FMT_PLAIN:
370
+ case CB_FMT_DOCUMENT:
371
+ return cb_sym_document;
372
+ case CB_FMT_MARSHAL:
373
+ return cb_sym_marshal;
374
+ case CB_FMT_PLAIN:
305
375
  /* fall through */
306
376
  default:
307
377
  /* all other formats treated as plain */
308
- return sym_plain;
378
+ return cb_sym_plain;
309
379
  }
310
380
  }
311
381
 
@@ -314,14 +384,14 @@ flags_get_format(uint32_t flags)
314
384
  do_encode(VALUE *args)
315
385
  {
316
386
  VALUE val = args[0];
317
- uint32_t flags = ((uint32_t)args[1] & FMT_MASK);
387
+ uint32_t flags = ((uint32_t)args[1] & CB_FMT_MASK);
318
388
 
319
389
  switch (flags) {
320
- case FMT_DOCUMENT:
321
- return rb_funcall(mMultiJson, id_dump, 1, val);
322
- case FMT_MARSHAL:
323
- return rb_funcall(mMarshal, id_dump, 1, val);
324
- case FMT_PLAIN:
390
+ case CB_FMT_DOCUMENT:
391
+ return rb_funcall(cb_mMultiJson, cb_id_dump, 1, val);
392
+ case CB_FMT_MARSHAL:
393
+ return rb_funcall(cb_mMarshal, cb_id_dump, 1, val);
394
+ case CB_FMT_PLAIN:
325
395
  /* fall through */
326
396
  default:
327
397
  /* all other formats treated as plain */
@@ -336,22 +406,22 @@ do_decode(VALUE *args)
336
406
  VALUE force_format = args[2];
337
407
 
338
408
  if (TYPE(force_format) == T_SYMBOL) {
339
- if (force_format == sym_document) {
340
- return rb_funcall(mMultiJson, id_load, 1, blob);
341
- } else if (force_format == sym_marshal) {
342
- return rb_funcall(mMarshal, id_load, 1, blob);
343
- } else { /* sym_plain and any other symbol */
409
+ if (force_format == cb_sym_document) {
410
+ return rb_funcall(cb_mMultiJson, cb_id_load, 1, blob);
411
+ } else if (force_format == cb_sym_marshal) {
412
+ return rb_funcall(cb_mMarshal, cb_id_load, 1, blob);
413
+ } else { /* cb_sym_plain and any other cb_symbol */
344
414
  return blob;
345
415
  }
346
416
  } else {
347
- uint32_t flags = ((uint32_t)args[1] & FMT_MASK);
417
+ uint32_t flags = ((uint32_t)args[1] & CB_FMT_MASK);
348
418
 
349
419
  switch (flags) {
350
- case FMT_DOCUMENT:
351
- return rb_funcall(mMultiJson, id_load, 1, blob);
352
- case FMT_MARSHAL:
353
- return rb_funcall(mMarshal, id_load, 1, blob);
354
- case FMT_PLAIN:
420
+ case CB_FMT_DOCUMENT:
421
+ return rb_funcall(cb_mMultiJson, cb_id_load, 1, blob);
422
+ case CB_FMT_MARSHAL:
423
+ return rb_funcall(cb_mMarshal, cb_id_load, 1, blob);
424
+ case CB_FMT_PLAIN:
355
425
  /* fall through */
356
426
  default:
357
427
  /* all other formats treated as plain */
@@ -361,29 +431,25 @@ do_decode(VALUE *args)
361
431
  }
362
432
 
363
433
  static VALUE
364
- coding_failed(void)
434
+ coding_failed(VALUE unused, VALUE exc)
365
435
  {
366
- return Qundef;
436
+ (void)unused;
437
+ return exc;
367
438
  }
368
439
 
369
440
  VALUE
370
- encode_value(VALUE val, uint32_t flags)
441
+ cb_encode_value(VALUE val, uint32_t flags)
371
442
  {
372
443
  VALUE blob, args[2];
373
444
 
374
445
  args[0] = val;
375
446
  args[1] = (VALUE)flags;
376
- /* FIXME re-raise proper exception */
377
447
  blob = rb_rescue(do_encode, (VALUE)args, coding_failed, 0);
378
- /* it must be bytestring after all */
379
- if (TYPE(blob) != T_STRING) {
380
- return Qundef;
381
- }
382
- return blob;
448
+ return blob; /* bytestring or exception object */
383
449
  }
384
450
 
385
451
  VALUE
386
- decode_value(VALUE blob, uint32_t flags, VALUE force_format)
452
+ cb_decode_value(VALUE blob, uint32_t flags, VALUE force_format)
387
453
  {
388
454
  VALUE val, args[3];
389
455
 
@@ -395,23 +461,23 @@ decode_value(VALUE blob, uint32_t flags, VALUE force_format)
395
461
  args[1] = (VALUE)flags;
396
462
  args[2] = (VALUE)force_format;
397
463
  val = rb_rescue(do_decode, (VALUE)args, coding_failed, 0);
398
- return val;
464
+ return val; /* the value or exception object */
399
465
  }
400
466
 
401
467
  void
402
- strip_key_prefix(struct bucket_st *bucket, VALUE key)
468
+ cb_strip_key_prefix(struct cb_bucket_st *bucket, VALUE key)
403
469
  {
404
- if (bucket->key_prefix) {
405
- rb_str_update(key, 0, RSTRING_LEN(bucket->key_prefix_val), STR_NEW_CSTR(""));
470
+ if (RTEST(bucket->key_prefix_val)) {
471
+ rb_str_update(key, 0, RSTRING_LEN(bucket->key_prefix_val), cb_vStrEmpty);
406
472
  }
407
473
  }
408
474
 
409
475
  VALUE
410
- unify_key(struct bucket_st *bucket, VALUE key, int apply_prefix)
476
+ cb_unify_key(struct cb_bucket_st *bucket, VALUE key, int apply_prefix)
411
477
  {
412
478
  VALUE ret = Qnil, tmp;
413
479
 
414
- if (bucket->key_prefix && apply_prefix) {
480
+ if (RTEST(bucket->key_prefix_val) && apply_prefix) {
415
481
  ret = rb_str_dup(bucket->key_prefix_val);
416
482
  }
417
483
  switch (TYPE(key)) {
@@ -427,7 +493,7 @@ unify_key(struct bucket_st *bucket, VALUE key, int apply_prefix)
427
493
  }
428
494
 
429
495
  void
430
- cb_build_headers(struct context_st *ctx, const char * const *headers)
496
+ cb_build_headers(struct cb_context_st *ctx, const char * const *headers)
431
497
  {
432
498
  if (!ctx->headers_built) {
433
499
  VALUE key = Qnil, val;
@@ -469,3 +535,14 @@ cb_first_value_i(VALUE key, VALUE value, VALUE arg)
469
535
  (void)key;
470
536
  return ST_STOP;
471
537
  }
538
+
539
+ #ifndef HAVE_RB_HASH_LOOKUP2
540
+ VALUE
541
+ rb_hash_lookup2(VALUE hash, VALUE key, VALUE dflt)
542
+ {
543
+ if (RTEST(rb_funcall2(hash, cb_id_has_key_p, 1, &key))) {
544
+ dflt = rb_hash_aref(hash, key);
545
+ }
546
+ return dflt;
547
+ }
548
+ #endif