couchbase 1.2.0.beta-x86-mingw32 → 1.2.0-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 +513 -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 +1201 -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 +46 -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 -215
@@ -18,46 +18,35 @@
18
18
  #include "couchbase_ext.h"
19
19
 
20
20
  void
21
- arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_arithmetic_resp_t *resp)
21
+ cb_arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_arithmetic_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 cas, key, val, *rv = ctx->rv, exc, res;
26
26
  ID o;
27
27
 
28
28
  ctx->nqueries--;
29
29
  key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
30
- strip_key_prefix(bucket, key);
30
+ cb_strip_key_prefix(bucket, key);
31
31
 
32
32
  cas = resp->v.v0.cas > 0 ? ULL2NUM(resp->v.v0.cas) : Qnil;
33
- o = ctx->arith > 0 ? sym_increment : sym_decrement;
33
+ o = ctx->arith > 0 ? cb_sym_increment : cb_sym_decrement;
34
34
  exc = cb_check_error(error, "failed to perform arithmetic operation", key);
35
35
  if (exc != Qnil) {
36
- rb_ivar_set(exc, id_iv_cas, cas);
37
- rb_ivar_set(exc, id_iv_operation, o);
38
- if (bucket->async) {
39
- if (bucket->on_error_proc != Qnil) {
40
- cb_proc_call(bucket->on_error_proc, 3, o, key, exc);
41
- } else {
42
- if (NIL_P(bucket->exception)) {
43
- bucket->exception = exc;
44
- }
45
- }
46
- }
47
- if (NIL_P(ctx->exception)) {
48
- ctx->exception = cb_gc_protect(bucket, exc);
49
- }
36
+ rb_ivar_set(exc, cb_id_iv_cas, cas);
37
+ rb_ivar_set(exc, cb_id_iv_operation, o);
38
+ ctx->exception = cb_gc_protect(bucket, exc);
50
39
  }
51
40
  val = ULL2NUM(resp->v.v0.value);
52
41
  if (bucket->async) { /* asynchronous */
53
42
  if (ctx->proc != Qnil) {
54
- res = rb_class_new_instance(0, NULL, cResult);
55
- rb_ivar_set(res, id_iv_error, exc);
56
- rb_ivar_set(res, id_iv_operation, o);
57
- rb_ivar_set(res, id_iv_key, key);
58
- rb_ivar_set(res, id_iv_value, val);
59
- rb_ivar_set(res, id_iv_cas, cas);
60
- cb_proc_call(ctx->proc, 1, res);
43
+ res = rb_class_new_instance(0, NULL, cb_cResult);
44
+ rb_ivar_set(res, cb_id_iv_error, exc);
45
+ rb_ivar_set(res, cb_id_iv_operation, o);
46
+ rb_ivar_set(res, cb_id_iv_key, key);
47
+ rb_ivar_set(res, cb_id_iv_value, val);
48
+ rb_ivar_set(res, cb_id_iv_cas, cas);
49
+ cb_proc_call(bucket, ctx->proc, 1, res);
61
50
  }
62
51
  } else { /* synchronous */
63
52
  if (NIL_P(exc)) {
@@ -70,6 +59,9 @@ arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
70
59
  }
71
60
  if (ctx->nqueries == 0) {
72
61
  cb_gc_unprotect(bucket, ctx->proc);
62
+ if (bucket->async) {
63
+ free(ctx);
64
+ }
73
65
  }
74
66
  (void)handle;
75
67
  }
@@ -77,27 +69,27 @@ arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
77
69
  static inline VALUE
78
70
  cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
79
71
  {
80
- struct bucket_st *bucket = DATA_PTR(self);
81
- struct context_st *ctx;
72
+ struct cb_bucket_st *bucket = DATA_PTR(self);
73
+ struct cb_context_st *ctx;
82
74
  VALUE args, rv, proc, exc;
83
75
  lcb_error_t err;
84
- struct params_st params;
76
+ struct cb_params_st params;
85
77
 
86
78
  if (bucket->handle == NULL) {
87
- rb_raise(eConnectError, "closed connection");
79
+ rb_raise(cb_eConnectError, "closed connection");
88
80
  }
89
81
  rb_scan_args(argc, argv, "0*&", &args, &proc);
90
82
  if (!bucket->async && proc != Qnil) {
91
83
  rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
92
84
  }
93
- memset(&params, 0, sizeof(struct params_st));
94
- params.type = cmd_arith;
85
+ memset(&params, 0, sizeof(struct cb_params_st));
86
+ params.type = cb_cmd_arith;
95
87
  params.bucket = bucket;
96
88
  params.cmd.arith.sign = sign;
97
89
  cb_params_build(&params, RARRAY_LEN(args), args);
98
- ctx = xcalloc(1, sizeof(struct context_st));
90
+ ctx = calloc(1, sizeof(struct cb_context_st));
99
91
  if (ctx == NULL) {
100
- rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
92
+ rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
101
93
  }
102
94
  rv = rb_hash_new();
103
95
  ctx->rv = &rv;
@@ -110,12 +102,12 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
110
102
  cb_params_destroy(&params);
111
103
  exc = cb_check_error(err, "failed to schedule arithmetic request", Qnil);
112
104
  if (exc != Qnil) {
113
- xfree(ctx);
105
+ free(ctx);
114
106
  rb_exc_raise(exc);
115
107
  }
116
108
  bucket->nbytes += params.npayload;
117
109
  if (bucket->async) {
118
- maybe_do_loop(bucket);
110
+ cb_maybe_do_loop(bucket);
119
111
  return Qnil;
120
112
  } else {
121
113
  if (ctx->nqueries > 0) {
@@ -123,7 +115,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
123
115
  lcb_wait(bucket->handle);
124
116
  }
125
117
  exc = ctx->exception;
126
- xfree(ctx);
118
+ free(ctx);
127
119
  if (exc != Qnil) {
128
120
  cb_gc_unprotect(bucket, exc);
129
121
  rb_exc_raise(exc);
@@ -20,38 +20,38 @@
20
20
  static void
21
21
  error_callback(lcb_t handle, lcb_error_t error, const char *errinfo)
22
22
  {
23
- struct bucket_st *bucket = (struct bucket_st *)lcb_get_cookie(handle);
23
+ struct cb_bucket_st *bucket = (struct cb_bucket_st *)lcb_get_cookie(handle);
24
24
 
25
- bucket->io->stop_event_loop(bucket->io);
25
+ lcb_breakout(handle);
26
26
  bucket->exception = cb_check_error(error, errinfo, Qnil);
27
27
  }
28
28
 
29
29
  void
30
30
  cb_bucket_free(void *ptr)
31
31
  {
32
- struct bucket_st *bucket = ptr;
32
+ struct cb_bucket_st *bucket = ptr;
33
33
 
34
34
  if (bucket) {
35
35
  if (bucket->handle) {
36
36
  lcb_destroy(bucket->handle);
37
+ lcb_destroy_io_ops(bucket->io);
37
38
  }
38
- xfree(bucket->authority);
39
- xfree(bucket->hostname);
40
- xfree(bucket->pool);
41
- xfree(bucket->bucket);
42
- xfree(bucket->username);
43
- xfree(bucket->password);
44
- xfree(bucket->key_prefix);
45
- xfree(bucket);
46
39
  }
40
+ xfree(bucket);
47
41
  }
48
42
 
49
43
  void
50
44
  cb_bucket_mark(void *ptr)
51
45
  {
52
- struct bucket_st *bucket = ptr;
46
+ struct cb_bucket_st *bucket = ptr;
53
47
 
54
48
  if (bucket) {
49
+ rb_gc_mark(bucket->authority);
50
+ rb_gc_mark(bucket->hostname);
51
+ rb_gc_mark(bucket->pool);
52
+ rb_gc_mark(bucket->bucket);
53
+ rb_gc_mark(bucket->username);
54
+ rb_gc_mark(bucket->password);
55
55
  rb_gc_mark(bucket->exception);
56
56
  rb_gc_mark(bucket->on_error_proc);
57
57
  rb_gc_mark(bucket->key_prefix_val);
@@ -60,10 +60,10 @@ cb_bucket_mark(void *ptr)
60
60
  }
61
61
 
62
62
  static void
63
- do_scan_connection_options(struct bucket_st *bucket, int argc, VALUE *argv)
63
+ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
64
64
  {
65
65
  VALUE uri, opts, arg;
66
- size_t len;
66
+ char port_s[8];
67
67
 
68
68
  if (rb_scan_args(argc, argv, "02", &uri, &opts) > 0) {
69
69
  if (TYPE(uri) == T_HASH && argc == 1) {
@@ -75,203 +75,210 @@ do_scan_connection_options(struct bucket_st *bucket, int argc, VALUE *argv)
75
75
  VALUE match, uri_obj, re;
76
76
 
77
77
  Check_Type(uri, T_STRING);
78
- uri_obj = rb_funcall(mURI, id_parse, 1, uri);
78
+ uri_obj = rb_funcall(cb_mURI, cb_id_parse, 1, uri);
79
79
 
80
- arg = rb_funcall(uri_obj, id_scheme, 0);
80
+ arg = rb_funcall(uri_obj, cb_id_scheme, 0);
81
81
  if (arg == Qnil || rb_str_cmp(arg, STR_NEW_CSTR("http"))) {
82
82
  rb_raise(rb_eArgError, "invalid URI: invalid scheme");
83
83
  }
84
84
 
85
- arg = rb_funcall(uri_obj, id_user, 0);
85
+ arg = rb_funcall(uri_obj, cb_id_user, 0);
86
86
  if (arg != Qnil) {
87
- xfree(bucket->username);
88
- bucket->username = strdup(RSTRING_PTR(arg));
89
- if (bucket->username == NULL) {
90
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
91
- }
87
+ bucket->username = rb_str_dup_frozen(StringValue(arg));
92
88
  }
93
89
 
94
- arg = rb_funcall(uri_obj, id_password, 0);
90
+ arg = rb_funcall(uri_obj, cb_id_password, 0);
95
91
  if (arg != Qnil) {
96
- xfree(bucket->password);
97
- bucket->password = strdup(RSTRING_PTR(arg));
98
- if (bucket->password == NULL) {
99
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
100
- }
92
+ bucket->password = rb_str_dup_frozen(StringValue(arg));
101
93
  }
102
- arg = rb_funcall(uri_obj, id_host, 0);
94
+ arg = rb_funcall(uri_obj, cb_id_host, 0);
103
95
  if (arg != Qnil) {
104
- xfree(bucket->hostname);
105
- bucket->hostname = strdup(RSTRING_PTR(arg));
106
- if (bucket->hostname == NULL) {
107
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
108
- }
96
+ bucket->hostname = rb_str_dup_frozen(StringValue(arg));
109
97
  } else {
110
98
  rb_raise(rb_eArgError, "invalid URI: missing hostname");
111
99
  }
112
100
 
113
- arg = rb_funcall(uri_obj, id_port, 0);
101
+ arg = rb_funcall(uri_obj, cb_id_port, 0);
114
102
  bucket->port = NIL_P(arg) ? 8091 : (uint16_t)NUM2UINT(arg);
115
103
 
116
- arg = rb_funcall(uri_obj, id_path, 0);
104
+ arg = rb_funcall(uri_obj, cb_id_path, 0);
117
105
  re = rb_reg_new(path_re, sizeof(path_re) - 1, 0);
118
- match = rb_funcall(re, id_match, 1, arg);
106
+ match = rb_funcall(re, cb_id_match, 1, arg);
119
107
  arg = rb_reg_nth_match(2, match);
120
- xfree(bucket->pool);
121
- bucket->pool = strdup(NIL_P(arg) ? "default" : RSTRING_PTR(arg));
108
+ bucket->pool = NIL_P(arg) ? cb_vStrDefault : rb_str_dup_frozen(StringValue(arg));
109
+ rb_str_freeze(bucket->pool);
122
110
  arg = rb_reg_nth_match(4, match);
123
- xfree(bucket->bucket);
124
- bucket->bucket = strdup(NIL_P(arg) ? "default" : RSTRING_PTR(arg));
111
+ bucket->bucket = NIL_P(arg) ? cb_vStrDefault : rb_str_dup_frozen(StringValue(arg));
112
+ rb_str_freeze(bucket->bucket);
125
113
  }
126
114
  if (TYPE(opts) == T_HASH) {
127
- arg = rb_hash_aref(opts, sym_node_list);
115
+ arg = rb_hash_aref(opts, cb_sym_type);
116
+ if (arg != Qnil) {
117
+ if (arg == cb_sym_cluster) {
118
+ bucket->type = LCB_TYPE_CLUSTER;
119
+ } else {
120
+ bucket->type = LCB_TYPE_BUCKET;
121
+ }
122
+ }
123
+ arg = rb_hash_aref(opts, cb_sym_node_list);
128
124
  if (arg != Qnil) {
129
- VALUE tt;
130
- xfree(bucket->node_list);
131
125
  Check_Type(arg, T_ARRAY);
132
- tt = rb_ary_join(arg, STR_NEW_CSTR(";"));
133
- bucket->node_list = strdup(StringValueCStr(tt));
126
+ bucket->node_list = rb_ary_join(arg, STR_NEW_CSTR(";"));
127
+ rb_str_freeze(bucket->node_list);
134
128
  }
135
- arg = rb_hash_aref(opts, sym_hostname);
129
+ arg = rb_hash_aref(opts, cb_sym_hostname);
136
130
  if (arg != Qnil) {
137
- xfree(bucket->hostname);
138
- bucket->hostname = strdup(StringValueCStr(arg));
131
+ bucket->hostname = rb_str_dup_frozen(StringValue(arg));
139
132
  }
140
- arg = rb_hash_aref(opts, sym_pool);
133
+ arg = rb_hash_aref(opts, cb_sym_pool);
141
134
  if (arg != Qnil) {
142
- xfree(bucket->pool);
143
- bucket->pool = strdup(StringValueCStr(arg));
135
+ bucket->pool = rb_str_dup_frozen(StringValue(arg));
144
136
  }
145
- arg = rb_hash_aref(opts, sym_bucket);
137
+ arg = rb_hash_aref(opts, cb_sym_bucket);
146
138
  if (arg != Qnil) {
147
- xfree(bucket->bucket);
148
- bucket->bucket = strdup(StringValueCStr(arg));
139
+ bucket->bucket = rb_str_dup_frozen(StringValue(arg));
149
140
  }
150
- arg = rb_hash_aref(opts, sym_username);
141
+ arg = rb_hash_aref(opts, cb_sym_username);
151
142
  if (arg != Qnil) {
152
- xfree(bucket->username);
153
- bucket->username = strdup(StringValueCStr(arg));
143
+ bucket->username = rb_str_dup_frozen(StringValue(arg));
154
144
  }
155
- arg = rb_hash_aref(opts, sym_password);
145
+ arg = rb_hash_aref(opts, cb_sym_password);
156
146
  if (arg != Qnil) {
157
- xfree(bucket->password);
158
- bucket->password = strdup(StringValueCStr(arg));
147
+ bucket->password = rb_str_dup_frozen(StringValue(arg));
159
148
  }
160
- arg = rb_hash_aref(opts, sym_port);
149
+ arg = rb_hash_aref(opts, cb_sym_port);
161
150
  if (arg != Qnil) {
162
151
  bucket->port = (uint16_t)NUM2UINT(arg);
163
152
  }
164
- if (RTEST(rb_funcall(opts, id_has_key_p, 1, sym_quiet))) {
165
- bucket->quiet = RTEST(rb_hash_aref(opts, sym_quiet));
153
+ arg = rb_hash_lookup2(opts, cb_sym_quiet, Qundef);
154
+ if (arg != Qundef) {
155
+ bucket->quiet = RTEST(arg);
166
156
  }
167
- arg = rb_hash_aref(opts, sym_timeout);
157
+ arg = rb_hash_aref(opts, cb_sym_timeout);
168
158
  if (arg != Qnil) {
169
159
  bucket->timeout = (uint32_t)NUM2ULONG(arg);
170
160
  }
171
- arg = rb_hash_aref(opts, sym_default_ttl);
161
+ arg = rb_hash_aref(opts, cb_sym_default_ttl);
172
162
  if (arg != Qnil) {
173
163
  bucket->default_ttl = (uint32_t)NUM2ULONG(arg);
174
164
  }
175
- arg = rb_hash_aref(opts, sym_default_observe_timeout);
165
+ arg = rb_hash_aref(opts, cb_sym_default_observe_timeout);
176
166
  if (arg != Qnil) {
177
167
  bucket->default_observe_timeout = (uint32_t)NUM2ULONG(arg);
178
168
  }
179
- arg = rb_hash_aref(opts, sym_default_flags);
169
+ arg = rb_hash_aref(opts, cb_sym_default_flags);
180
170
  if (arg != Qnil) {
181
171
  bucket->default_flags = (uint32_t)NUM2ULONG(arg);
182
172
  }
183
- arg = rb_hash_aref(opts, sym_default_format);
173
+ arg = rb_hash_aref(opts, cb_sym_default_format);
184
174
  if (arg != Qnil) {
185
175
  if (TYPE(arg) == T_FIXNUM) {
186
176
  switch (FIX2INT(arg)) {
187
- case FMT_DOCUMENT:
188
- arg = sym_document;
177
+ case CB_FMT_DOCUMENT:
178
+ arg = cb_sym_document;
189
179
  break;
190
- case FMT_MARSHAL:
191
- arg = sym_marshal;
180
+ case CB_FMT_MARSHAL:
181
+ arg = cb_sym_marshal;
192
182
  break;
193
- case FMT_PLAIN:
194
- arg = sym_plain;
183
+ case CB_FMT_PLAIN:
184
+ arg = cb_sym_plain;
195
185
  break;
196
186
  }
197
187
  }
198
- if (arg == sym_document || arg == sym_marshal || arg == sym_plain) {
188
+ if (arg == cb_sym_document || arg == cb_sym_marshal || arg == cb_sym_plain) {
199
189
  bucket->default_format = arg;
200
- bucket->default_flags = flags_set_format(bucket->default_flags, arg);
190
+ bucket->default_flags = cb_flags_set_format(bucket->default_flags, arg);
201
191
  }
202
192
  }
203
- arg = rb_hash_aref(opts, sym_environment);
193
+ arg = rb_hash_aref(opts, cb_sym_environment);
204
194
  if (arg != Qnil) {
205
- if (arg == sym_production || arg == sym_development) {
195
+ if (arg == cb_sym_production || arg == cb_sym_development) {
206
196
  bucket->environment = arg;
207
197
  }
208
198
  }
209
- arg = rb_hash_aref(opts, sym_key_prefix);
199
+ arg = rb_hash_aref(opts, cb_sym_key_prefix);
210
200
  if (arg != Qnil) {
211
- xfree(bucket->key_prefix);
212
- bucket->key_prefix = strdup(StringValueCStr(arg));
213
- bucket->key_prefix_val = STR_NEW_CSTR(bucket->key_prefix);
201
+ bucket->key_prefix_val = rb_str_dup_frozen(StringValue(arg));
202
+ }
203
+ arg = rb_hash_aref(opts, cb_sym_default_arithmetic_init);
204
+ if (arg != Qnil) {
205
+ bucket->default_arith_create = RTEST(arg);
206
+ if (TYPE(arg) == T_FIXNUM) {
207
+ bucket->default_arith_init = NUM2ULL(arg);
208
+ }
214
209
  }
215
210
  } else {
216
211
  opts = Qnil;
217
212
  }
218
213
  }
219
- if (bucket->password && bucket->username == NULL) {
220
- bucket->username = strdup(bucket->bucket);
214
+ if (RTEST(bucket->password) && !RTEST(bucket->username)) {
215
+ bucket->username = bucket->bucket;
221
216
  }
222
- len = strlen(bucket->hostname) + 10;
223
217
  if (bucket->default_observe_timeout < 2) {
224
218
  rb_raise(rb_eArgError, "default_observe_timeout is too low");
225
219
  }
226
- xfree(bucket->authority);
227
- bucket->authority = xcalloc(len, sizeof(char));
228
- if (bucket->authority == NULL) {
229
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
230
- }
231
- snprintf(bucket->authority, len, "%s:%u", bucket->hostname, bucket->port);
220
+ snprintf(port_s, sizeof(port_s), ":%u", bucket->port);
221
+ bucket->authority = rb_str_dup(bucket->hostname);
222
+ rb_str_cat2(bucket->authority, port_s);
223
+ rb_str_freeze(bucket->authority);
232
224
  }
233
225
 
234
226
  static void
235
- do_connect(struct bucket_st *bucket)
227
+ do_connect(struct cb_bucket_st *bucket)
236
228
  {
237
229
  lcb_error_t err;
238
230
  struct lcb_create_st create_opts;
239
231
 
240
232
  if (bucket->handle) {
241
233
  lcb_destroy(bucket->handle);
234
+ lcb_destroy_io_ops(bucket->io);
242
235
  bucket->handle = NULL;
243
236
  bucket->io = NULL;
244
237
  }
238
+
239
+ #ifndef _WIN32
240
+ {
241
+ struct lcb_create_io_ops_st ciops;
242
+ memset(&ciops, 0, sizeof(ciops));
243
+ ciops.version = 1;
244
+ ciops.v.v1.sofile = NULL;
245
+ ciops.v.v1.symbol = "cb_create_ruby_mt_io_opts";
246
+ ciops.v.v1.cookie = NULL;
247
+
248
+ err = lcb_create_io_ops(&bucket->io, &ciops);
249
+ }
250
+ #else
245
251
  err = lcb_create_io_ops(&bucket->io, NULL);
252
+ #endif
246
253
  if (err != LCB_SUCCESS) {
247
254
  rb_exc_raise(cb_check_error(err, "failed to create IO instance", Qnil));
248
255
  }
249
256
 
250
257
  memset(&create_opts, 0, sizeof(struct lcb_create_st));
251
- create_opts.v.v0.host = bucket->node_list ? bucket-> node_list : bucket->authority;
252
- create_opts.v.v0.user = bucket->username;
253
- create_opts.v.v0.passwd = bucket->password;
254
- create_opts.v.v0.bucket = bucket->bucket;
255
- create_opts.v.v0.io = bucket->io;
258
+ create_opts.version = 1;
259
+ create_opts.v.v1.type = bucket->type;
260
+ create_opts.v.v1.host = RTEST(bucket->node_list) ? RSTRING_PTR(bucket-> node_list) : RSTRING_PTR(bucket->authority);
261
+ create_opts.v.v1.user = RTEST(bucket->username) ? RSTRING_PTR(bucket->username) : NULL;
262
+ create_opts.v.v1.passwd = RTEST(bucket->username) ? RSTRING_PTR(bucket->password) : NULL;
263
+ create_opts.v.v1.bucket = RSTRING_PTR(bucket->bucket);
264
+ create_opts.v.v1.io = bucket->io;
256
265
  err = lcb_create(&bucket->handle, &create_opts);
257
266
  if (err != LCB_SUCCESS) {
258
267
  rb_exc_raise(cb_check_error(err, "failed to create libcouchbase instance", Qnil));
259
268
  }
260
269
  lcb_set_cookie(bucket->handle, bucket);
261
270
  (void)lcb_set_error_callback(bucket->handle, error_callback);
262
- (void)lcb_set_store_callback(bucket->handle, storage_callback);
263
- (void)lcb_set_get_callback(bucket->handle, get_callback);
264
- (void)lcb_set_touch_callback(bucket->handle, touch_callback);
265
- (void)lcb_set_remove_callback(bucket->handle, delete_callback);
266
- (void)lcb_set_stat_callback(bucket->handle, stat_callback);
267
- (void)lcb_set_arithmetic_callback(bucket->handle, arithmetic_callback);
268
- (void)lcb_set_version_callback(bucket->handle, version_callback);
269
- (void)lcb_set_view_complete_callback(bucket->handle, http_complete_callback);
270
- (void)lcb_set_view_data_callback(bucket->handle, http_data_callback);
271
- (void)lcb_set_management_complete_callback(bucket->handle, http_complete_callback);
272
- (void)lcb_set_management_data_callback(bucket->handle, http_data_callback);
273
- (void)lcb_set_observe_callback(bucket->handle, observe_callback);
274
- (void)lcb_set_unlock_callback(bucket->handle, unlock_callback);
271
+ (void)lcb_set_store_callback(bucket->handle, cb_storage_callback);
272
+ (void)lcb_set_get_callback(bucket->handle, cb_get_callback);
273
+ (void)lcb_set_touch_callback(bucket->handle, cb_touch_callback);
274
+ (void)lcb_set_remove_callback(bucket->handle, cb_delete_callback);
275
+ (void)lcb_set_stat_callback(bucket->handle, cb_stat_callback);
276
+ (void)lcb_set_arithmetic_callback(bucket->handle, cb_arithmetic_callback);
277
+ (void)lcb_set_version_callback(bucket->handle, cb_version_callback);
278
+ (void)lcb_set_http_complete_callback(bucket->handle, cb_http_complete_callback);
279
+ (void)lcb_set_http_data_callback(bucket->handle, cb_http_data_callback);
280
+ (void)lcb_set_observe_callback(bucket->handle, cb_observe_callback);
281
+ (void)lcb_set_unlock_callback(bucket->handle, cb_unlock_callback);
275
282
 
276
283
  if (bucket->timeout > 0) {
277
284
  lcb_set_timeout(bucket->handle, bucket->timeout);
@@ -281,6 +288,7 @@ do_connect(struct bucket_st *bucket)
281
288
  err = lcb_connect(bucket->handle);
282
289
  if (err != LCB_SUCCESS) {
283
290
  lcb_destroy(bucket->handle);
291
+ lcb_destroy_io_ops(bucket->io);
284
292
  bucket->handle = NULL;
285
293
  bucket->io = NULL;
286
294
  rb_exc_raise(cb_check_error(err, "failed to connect libcouchbase instance to server", Qnil));
@@ -289,6 +297,7 @@ do_connect(struct bucket_st *bucket)
289
297
  lcb_wait(bucket->handle);
290
298
  if (bucket->exception != Qnil) {
291
299
  lcb_destroy(bucket->handle);
300
+ lcb_destroy_io_ops(bucket->io);
292
301
  bucket->handle = NULL;
293
302
  bucket->io = NULL;
294
303
  rb_exc_raise(bucket->exception);
@@ -299,10 +308,10 @@ do_connect(struct bucket_st *bucket)
299
308
  cb_bucket_alloc(VALUE klass)
300
309
  {
301
310
  VALUE obj;
302
- struct bucket_st *bucket;
311
+ struct cb_bucket_st *bucket;
303
312
 
304
313
  /* allocate new bucket struct and set it to zero */
305
- obj = Data_Make_Struct(klass, struct bucket_st, cb_bucket_mark, cb_bucket_free,
314
+ obj = Data_Make_Struct(klass, struct cb_bucket_st, cb_bucket_mark, cb_bucket_free,
306
315
  bucket);
307
316
  return obj;
308
317
  }
@@ -360,6 +369,11 @@ cb_bucket_alloc(VALUE klass)
360
369
  * returning back to the application.
361
370
  * @option options [Fixnum] :timeout (2500000) the timeout for IO
362
371
  * operations (in microseconds)
372
+ * @option options [Fixnum, true] :default_arithmetic_init (0) the default
373
+ * initial value for arithmetic operations. Setting this option to any
374
+ * non positive number forces creation missing keys with given default
375
+ * value. Setting it to +true+ will use zero as initial value. (see
376
+ * {Bucket#incr} and {Bucket#decr}).
363
377
  *
364
378
  * @example Initialize connection using default options
365
379
  * Couchbase.new
@@ -387,28 +401,31 @@ cb_bucket_alloc(VALUE klass)
387
401
  VALUE
388
402
  cb_bucket_init(int argc, VALUE *argv, VALUE self)
389
403
  {
390
- struct bucket_st *bucket = DATA_PTR(self);
404
+ struct cb_bucket_st *bucket = DATA_PTR(self);
391
405
 
392
406
  bucket->self = self;
393
407
  bucket->exception = Qnil;
394
- bucket->hostname = strdup("localhost");
408
+ bucket->type = LCB_TYPE_BUCKET;
409
+ bucket->hostname = rb_str_new2("localhost");
395
410
  bucket->port = 8091;
396
- bucket->pool = strdup("default");
397
- bucket->bucket = strdup("default");
411
+ bucket->pool = cb_vStrDefault;
412
+ rb_str_freeze(bucket->pool);
413
+ bucket->bucket = cb_vStrDefault;
414
+ rb_str_freeze(bucket->bucket);
415
+ bucket->username = Qnil;
416
+ bucket->password = Qnil;
398
417
  bucket->async = 0;
399
418
  bucket->quiet = 0;
400
419
  bucket->default_ttl = 0;
401
420
  bucket->default_flags = 0;
402
- bucket->default_format = sym_document;
421
+ bucket->default_format = cb_sym_document;
403
422
  bucket->default_observe_timeout = 2500000;
404
423
  bucket->on_error_proc = Qnil;
405
424
  bucket->timeout = 0;
406
- bucket->environment = sym_production;
407
- bucket->key_prefix = NULL;
425
+ bucket->environment = cb_sym_production;
408
426
  bucket->key_prefix_val = Qnil;
409
- bucket->node_list = NULL;
427
+ bucket->node_list = Qnil;
410
428
  bucket->object_space = rb_hash_new();
411
- bucket->node_list = NULL;
412
429
 
413
430
  do_scan_connection_options(bucket, argc, argv);
414
431
  do_connect(bucket);
@@ -428,8 +445,8 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
428
445
  VALUE
429
446
  cb_bucket_init_copy(VALUE copy, VALUE orig)
430
447
  {
431
- struct bucket_st *copy_b;
432
- struct bucket_st *orig_b;
448
+ struct cb_bucket_st *copy_b;
449
+ struct cb_bucket_st *orig_b;
433
450
 
434
451
  if (copy == orig)
435
452
  return copy;
@@ -444,19 +461,12 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
444
461
 
445
462
  copy_b->self = copy_b->self;
446
463
  copy_b->port = orig_b->port;
447
- copy_b->authority = strdup(orig_b->authority);
448
- copy_b->hostname = strdup(orig_b->hostname);
449
- copy_b->pool = strdup(orig_b->pool);
450
- copy_b->bucket = strdup(orig_b->bucket);
451
- if (orig_b->username) {
452
- copy_b->username = strdup(orig_b->username);
453
- }
454
- if (orig_b->password) {
455
- copy_b->password = strdup(orig_b->password);
456
- }
457
- if (orig_b->key_prefix) {
458
- copy_b->key_prefix = strdup(orig_b->key_prefix);
459
- }
464
+ copy_b->authority = orig_b->authority;
465
+ copy_b->hostname = orig_b->hostname;
466
+ copy_b->pool = orig_b->pool;
467
+ copy_b->bucket = orig_b->bucket;
468
+ copy_b->username = orig_b->username;
469
+ copy_b->password = orig_b->password;
460
470
  copy_b->async = orig_b->async;
461
471
  copy_b->quiet = orig_b->quiet;
462
472
  copy_b->default_format = orig_b->default_format;
@@ -466,11 +476,9 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
466
476
  copy_b->timeout = orig_b->timeout;
467
477
  copy_b->exception = Qnil;
468
478
  if (orig_b->on_error_proc != Qnil) {
469
- copy_b->on_error_proc = rb_funcall(orig_b->on_error_proc, id_dup, 0);
470
- }
471
- if (orig_b->key_prefix_val != Qnil) {
472
- copy_b->key_prefix_val = rb_funcall(orig_b->key_prefix_val, id_dup, 0);
479
+ copy_b->on_error_proc = rb_funcall(orig_b->on_error_proc, cb_id_dup, 0);
473
480
  }
481
+ copy_b->key_prefix_val = orig_b->key_prefix_val;
474
482
 
475
483
  do_connect(copy_b);
476
484
 
@@ -502,7 +510,7 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
502
510
  VALUE
503
511
  cb_bucket_reconnect(int argc, VALUE *argv, VALUE self)
504
512
  {
505
- struct bucket_st *bucket = DATA_PTR(self);
513
+ struct cb_bucket_st *bucket = DATA_PTR(self);
506
514
 
507
515
  do_scan_connection_options(bucket, argc, argv);
508
516
  do_connect(bucket);
@@ -520,7 +528,7 @@ cb_bucket_reconnect(int argc, VALUE *argv, VALUE self)
520
528
  VALUE
521
529
  cb_bucket_connected_p(VALUE self)
522
530
  {
523
- struct bucket_st *bucket = DATA_PTR(self);
531
+ struct cb_bucket_st *bucket = DATA_PTR(self);
524
532
  return bucket->handle ? Qtrue : Qfalse;
525
533
  }
526
534
 
@@ -548,21 +556,21 @@ cb_bucket_connected_p(VALUE self)
548
556
  VALUE
549
557
  cb_bucket_async_p(VALUE self)
550
558
  {
551
- struct bucket_st *bucket = DATA_PTR(self);
559
+ struct cb_bucket_st *bucket = DATA_PTR(self);
552
560
  return bucket->async ? Qtrue : Qfalse;
553
561
  }
554
562
 
555
563
  VALUE
556
564
  cb_bucket_quiet_get(VALUE self)
557
565
  {
558
- struct bucket_st *bucket = DATA_PTR(self);
566
+ struct cb_bucket_st *bucket = DATA_PTR(self);
559
567
  return bucket->quiet ? Qtrue : Qfalse;
560
568
  }
561
569
 
562
570
  VALUE
563
571
  cb_bucket_quiet_set(VALUE self, VALUE val)
564
572
  {
565
- struct bucket_st *bucket = DATA_PTR(self);
573
+ struct cb_bucket_st *bucket = DATA_PTR(self);
566
574
  VALUE new;
567
575
 
568
576
  bucket->quiet = RTEST(val);
@@ -573,48 +581,48 @@ cb_bucket_quiet_set(VALUE self, VALUE val)
573
581
  VALUE
574
582
  cb_bucket_default_flags_get(VALUE self)
575
583
  {
576
- struct bucket_st *bucket = DATA_PTR(self);
584
+ struct cb_bucket_st *bucket = DATA_PTR(self);
577
585
  return ULONG2NUM(bucket->default_flags);
578
586
  }
579
587
 
580
588
  VALUE
581
589
  cb_bucket_default_flags_set(VALUE self, VALUE val)
582
590
  {
583
- struct bucket_st *bucket = DATA_PTR(self);
591
+ struct cb_bucket_st *bucket = DATA_PTR(self);
584
592
 
585
593
  bucket->default_flags = (uint32_t)NUM2ULONG(val);
586
- bucket->default_format = flags_get_format(bucket->default_flags);
594
+ bucket->default_format = cb_flags_get_format(bucket->default_flags);
587
595
  return val;
588
596
  }
589
597
 
590
598
  VALUE
591
599
  cb_bucket_default_format_get(VALUE self)
592
600
  {
593
- struct bucket_st *bucket = DATA_PTR(self);
601
+ struct cb_bucket_st *bucket = DATA_PTR(self);
594
602
  return bucket->default_format;
595
603
  }
596
604
 
597
605
  VALUE
598
606
  cb_bucket_default_format_set(VALUE self, VALUE val)
599
607
  {
600
- struct bucket_st *bucket = DATA_PTR(self);
608
+ struct cb_bucket_st *bucket = DATA_PTR(self);
601
609
 
602
610
  if (TYPE(val) == T_FIXNUM) {
603
611
  switch (FIX2INT(val)) {
604
- case FMT_DOCUMENT:
605
- val = sym_document;
612
+ case CB_FMT_DOCUMENT:
613
+ val = cb_sym_document;
606
614
  break;
607
- case FMT_MARSHAL:
608
- val = sym_marshal;
615
+ case CB_FMT_MARSHAL:
616
+ val = cb_sym_marshal;
609
617
  break;
610
- case FMT_PLAIN:
611
- val = sym_plain;
618
+ case CB_FMT_PLAIN:
619
+ val = cb_sym_plain;
612
620
  break;
613
621
  }
614
622
  }
615
- if (val == sym_document || val == sym_marshal || val == sym_plain) {
623
+ if (val == cb_sym_document || val == cb_sym_marshal || val == cb_sym_plain) {
616
624
  bucket->default_format = val;
617
- bucket->default_flags = flags_set_format(bucket->default_flags, val);
625
+ bucket->default_flags = cb_flags_set_format(bucket->default_flags, val);
618
626
  }
619
627
 
620
628
  return val;
@@ -623,9 +631,9 @@ cb_bucket_default_format_set(VALUE self, VALUE val)
623
631
  VALUE
624
632
  cb_bucket_on_error_set(VALUE self, VALUE val)
625
633
  {
626
- struct bucket_st *bucket = DATA_PTR(self);
634
+ struct cb_bucket_st *bucket = DATA_PTR(self);
627
635
 
628
- if (rb_respond_to(val, id_call)) {
636
+ if (rb_respond_to(val, cb_id_call)) {
629
637
  bucket->on_error_proc = val;
630
638
  } else {
631
639
  bucket->on_error_proc = Qnil;
@@ -637,7 +645,7 @@ cb_bucket_on_error_set(VALUE self, VALUE val)
637
645
  VALUE
638
646
  cb_bucket_on_error_get(VALUE self)
639
647
  {
640
- struct bucket_st *bucket = DATA_PTR(self);
648
+ struct cb_bucket_st *bucket = DATA_PTR(self);
641
649
 
642
650
  if (rb_block_given_p()) {
643
651
  return cb_bucket_on_error_set(self, rb_block_proc());
@@ -649,14 +657,14 @@ cb_bucket_on_error_get(VALUE self)
649
657
  VALUE
650
658
  cb_bucket_timeout_get(VALUE self)
651
659
  {
652
- struct bucket_st *bucket = DATA_PTR(self);
660
+ struct cb_bucket_st *bucket = DATA_PTR(self);
653
661
  return ULONG2NUM(bucket->timeout);
654
662
  }
655
663
 
656
664
  VALUE
657
665
  cb_bucket_timeout_set(VALUE self, VALUE val)
658
666
  {
659
- struct bucket_st *bucket = DATA_PTR(self);
667
+ struct cb_bucket_st *bucket = DATA_PTR(self);
660
668
  VALUE tmval;
661
669
 
662
670
  bucket->timeout = (uint32_t)NUM2ULONG(val);
@@ -666,20 +674,40 @@ cb_bucket_timeout_set(VALUE self, VALUE val)
666
674
  return tmval;
667
675
  }
668
676
 
677
+ VALUE
678
+ cb_bucket_default_arithmetic_init_get(VALUE self)
679
+ {
680
+ struct cb_bucket_st *bucket = DATA_PTR(self);
681
+ return ULL2NUM(bucket->default_arith_init);
682
+ }
683
+
684
+ VALUE
685
+ cb_bucket_default_arithmetic_init_set(VALUE self, VALUE val)
686
+ {
687
+ struct cb_bucket_st *bucket = DATA_PTR(self);
688
+
689
+ bucket->default_arith_create = RTEST(val);
690
+ if (bucket->default_arith_create) {
691
+ bucket->default_arith_init = NUM2ULL(val);
692
+ } else {
693
+ bucket->default_arith_init = 0;
694
+ }
695
+ return ULL2NUM(bucket->default_arith_init);
696
+ }
697
+
669
698
  VALUE
670
699
  cb_bucket_key_prefix_get(VALUE self)
671
700
  {
672
- struct bucket_st *bucket = DATA_PTR(self);
701
+ struct cb_bucket_st *bucket = DATA_PTR(self);
673
702
  return bucket->key_prefix_val;
674
703
  }
675
704
 
676
705
  VALUE
677
706
  cb_bucket_key_prefix_set(VALUE self, VALUE val)
678
707
  {
679
- struct bucket_st *bucket = DATA_PTR(self);
708
+ struct cb_bucket_st *bucket = DATA_PTR(self);
680
709
 
681
- bucket->key_prefix = strdup(StringValueCStr(val));
682
- bucket->key_prefix_val = STR_NEW_CSTR(bucket->key_prefix);
710
+ bucket->key_prefix_val = rb_str_dup_frozen(StringValue(val));
683
711
 
684
712
  return bucket->key_prefix_val;
685
713
  }
@@ -693,15 +721,17 @@ cb_bucket_key_prefix_set(VALUE self, VALUE val)
693
721
  VALUE
694
722
  cb_bucket_hostname_get(VALUE self)
695
723
  {
696
- struct bucket_st *bucket = DATA_PTR(self);
724
+ struct cb_bucket_st *bucket = DATA_PTR(self);
725
+
697
726
  if (bucket->handle) {
698
- xfree(bucket->hostname);
699
- bucket->hostname = strdup(lcb_get_host(bucket->handle));
700
- if (bucket->hostname == NULL) {
701
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
727
+ const char * host = lcb_get_host(bucket->handle);
728
+ unsigned long len = RSTRING_LEN(bucket->hostname);
729
+ if (len != strlen(host) || strncmp(RSTRING_PTR(bucket->hostname), host, len) != 0) {
730
+ bucket->hostname = STR_NEW_CSTR(host);
731
+ rb_str_freeze(bucket->hostname);
702
732
  }
703
733
  }
704
- return STR_NEW_CSTR(bucket->hostname);
734
+ return bucket->hostname;
705
735
  }
706
736
 
707
737
  /* Document-method: port
@@ -713,7 +743,7 @@ cb_bucket_hostname_get(VALUE self)
713
743
  VALUE
714
744
  cb_bucket_port_get(VALUE self)
715
745
  {
716
- struct bucket_st *bucket = DATA_PTR(self);
746
+ struct cb_bucket_st *bucket = DATA_PTR(self);
717
747
  if (bucket->handle) {
718
748
  bucket->port = atoi(lcb_get_port(bucket->handle));
719
749
  }
@@ -729,18 +759,20 @@ cb_bucket_port_get(VALUE self)
729
759
  VALUE
730
760
  cb_bucket_authority_get(VALUE self)
731
761
  {
732
- struct bucket_st *bucket = DATA_PTR(self);
733
- size_t len;
734
-
735
- (void)cb_bucket_hostname_get(self);
736
- (void)cb_bucket_port_get(self);
737
- len = strlen(bucket->hostname) + 10;
738
- bucket->authority = xcalloc(len, sizeof(char));
739
- if (bucket->authority == NULL) {
740
- rb_raise(eClientNoMemoryError, "failed to allocate memory for Bucket");
762
+ struct cb_bucket_st *bucket = DATA_PTR(self);
763
+ VALUE old_hostname = bucket->hostname;
764
+ uint16_t old_port = bucket->port;
765
+ VALUE hostname = cb_bucket_hostname_get(self);
766
+ cb_bucket_port_get(self);
767
+
768
+ if (hostname != old_hostname || bucket->port != old_port) {
769
+ char port_s[8];
770
+ snprintf(port_s, sizeof(port_s), ":%u", bucket->port);
771
+ bucket->authority = rb_str_dup(hostname);
772
+ rb_str_cat2(bucket->authority, port_s);
773
+ rb_str_freeze(bucket->authority);
741
774
  }
742
- snprintf(bucket->authority, len, "%s:%u", bucket->hostname, bucket->port);
743
- return STR_NEW_CSTR(bucket->authority);
775
+ return bucket->authority;
744
776
  }
745
777
 
746
778
  /* Document-method: bucket
@@ -752,8 +784,8 @@ cb_bucket_authority_get(VALUE self)
752
784
  VALUE
753
785
  cb_bucket_bucket_get(VALUE self)
754
786
  {
755
- struct bucket_st *bucket = DATA_PTR(self);
756
- return STR_NEW_CSTR(bucket->bucket);
787
+ struct cb_bucket_st *bucket = DATA_PTR(self);
788
+ return bucket->bucket;
757
789
  }
758
790
 
759
791
  /* Document-method: pool
@@ -765,8 +797,8 @@ cb_bucket_bucket_get(VALUE self)
765
797
  VALUE
766
798
  cb_bucket_pool_get(VALUE self)
767
799
  {
768
- struct bucket_st *bucket = DATA_PTR(self);
769
- return STR_NEW_CSTR(bucket->pool);
800
+ struct cb_bucket_st *bucket = DATA_PTR(self);
801
+ return bucket->pool;
770
802
  }
771
803
 
772
804
  /* Document-method: username
@@ -779,8 +811,8 @@ cb_bucket_pool_get(VALUE self)
779
811
  VALUE
780
812
  cb_bucket_username_get(VALUE self)
781
813
  {
782
- struct bucket_st *bucket = DATA_PTR(self);
783
- return STR_NEW_CSTR(bucket->username);
814
+ struct cb_bucket_st *bucket = DATA_PTR(self);
815
+ return bucket->username;
784
816
  }
785
817
 
786
818
  /* Document-method: password
@@ -792,8 +824,8 @@ cb_bucket_username_get(VALUE self)
792
824
  VALUE
793
825
  cb_bucket_password_get(VALUE self)
794
826
  {
795
- struct bucket_st *bucket = DATA_PTR(self);
796
- return STR_NEW_CSTR(bucket->password);
827
+ struct cb_bucket_st *bucket = DATA_PTR(self);
828
+ return bucket->password;
797
829
  }
798
830
 
799
831
  /* Document-method: environment
@@ -807,7 +839,7 @@ cb_bucket_password_get(VALUE self)
807
839
  VALUE
808
840
  cb_bucket_environment_get(VALUE self)
809
841
  {
810
- struct bucket_st *bucket = DATA_PTR(self);
842
+ struct cb_bucket_st *bucket = DATA_PTR(self);
811
843
  return bucket->environment;
812
844
  }
813
845
  /* Document-method: num_replicas
@@ -821,7 +853,7 @@ cb_bucket_environment_get(VALUE self)
821
853
  VALUE
822
854
  cb_bucket_num_replicas_get(VALUE self)
823
855
  {
824
- struct bucket_st *bucket = DATA_PTR(self);
856
+ struct cb_bucket_st *bucket = DATA_PTR(self);
825
857
  int32_t nr = lcb_get_num_replicas(bucket->handle);
826
858
  if (nr < 0) {
827
859
  return Qnil;
@@ -841,7 +873,7 @@ cb_bucket_num_replicas_get(VALUE self)
841
873
  VALUE
842
874
  cb_bucket_default_observe_timeout_get(VALUE self)
843
875
  {
844
- struct bucket_st *bucket = DATA_PTR(self);
876
+ struct cb_bucket_st *bucket = DATA_PTR(self);
845
877
  return INT2FIX(bucket->default_observe_timeout);
846
878
  }
847
879
 
@@ -857,7 +889,7 @@ cb_bucket_default_observe_timeout_get(VALUE self)
857
889
  VALUE
858
890
  cb_bucket_default_observe_timeout_set(VALUE self, VALUE val)
859
891
  {
860
- struct bucket_st *bucket = DATA_PTR(self);
892
+ struct cb_bucket_st *bucket = DATA_PTR(self);
861
893
  bucket->default_observe_timeout = FIX2INT(val);
862
894
  return val;
863
895
  }
@@ -870,16 +902,16 @@ cb_bucket_default_observe_timeout_set(VALUE self, VALUE val)
870
902
  VALUE
871
903
  cb_bucket_url_get(VALUE self)
872
904
  {
873
- struct bucket_st *bucket = DATA_PTR(self);
905
+ struct cb_bucket_st *bucket = DATA_PTR(self);
874
906
  VALUE str;
875
907
 
876
908
  (void)cb_bucket_authority_get(self);
877
909
  str = rb_str_buf_new2("http://");
878
- rb_str_buf_cat2(str, bucket->authority);
910
+ rb_str_append(str, bucket->authority);
879
911
  rb_str_buf_cat2(str, "/pools/");
880
- rb_str_buf_cat2(str, bucket->pool);
912
+ rb_str_append(str, bucket->pool);
881
913
  rb_str_buf_cat2(str, "/buckets/");
882
- rb_str_buf_cat2(str, bucket->bucket);
914
+ rb_str_append(str, bucket->bucket);
883
915
  rb_str_buf_cat2(str, "/");
884
916
  return str;
885
917
  }
@@ -896,7 +928,7 @@ cb_bucket_url_get(VALUE self)
896
928
  cb_bucket_inspect(VALUE self)
897
929
  {
898
930
  VALUE str;
899
- struct bucket_st *bucket = DATA_PTR(self);
931
+ struct cb_bucket_st *bucket = DATA_PTR(self);
900
932
  char buf[200];
901
933
 
902
934
  str = rb_str_buf_new2("#<");
@@ -905,11 +937,11 @@ cb_bucket_inspect(VALUE self)
905
937
  (void)cb_bucket_authority_get(self);
906
938
  rb_str_buf_cat2(str, buf);
907
939
  rb_str_buf_cat2(str, "http://");
908
- rb_str_buf_cat2(str, bucket->authority);
940
+ rb_str_append(str, bucket->authority);
909
941
  rb_str_buf_cat2(str, "/pools/");
910
- rb_str_buf_cat2(str, bucket->pool);
942
+ rb_str_append(str, bucket->pool);
911
943
  rb_str_buf_cat2(str, "/buckets/");
912
- rb_str_buf_cat2(str, bucket->bucket);
944
+ rb_str_append(str, bucket->bucket);
913
945
  rb_str_buf_cat2(str, "/");
914
946
  snprintf(buf, 150, "\" default_format=:%s, default_flags=0x%x, quiet=%s, connected=%s, timeout=%u",
915
947
  rb_id2name(SYM2ID(bucket->default_format)),
@@ -918,7 +950,7 @@ cb_bucket_inspect(VALUE self)
918
950
  bucket->handle ? "true" : "false",
919
951
  bucket->timeout);
920
952
  rb_str_buf_cat2(str, buf);
921
- if (bucket->key_prefix) {
953
+ if (RTEST(bucket->key_prefix_val)) {
922
954
  rb_str_buf_cat2(str, ", key_prefix=");
923
955
  rb_str_append(str, rb_inspect(bucket->key_prefix_val));
924
956
  }
@@ -928,14 +960,14 @@ cb_bucket_inspect(VALUE self)
928
960
  }
929
961
 
930
962
  static void
931
- do_loop(struct bucket_st *bucket)
963
+ do_loop(struct cb_bucket_st *bucket)
932
964
  {
933
965
  lcb_wait(bucket->handle);
934
966
  bucket->nbytes = 0;
935
967
  }
936
968
 
937
969
  void
938
- maybe_do_loop(struct bucket_st *bucket)
970
+ cb_maybe_do_loop(struct cb_bucket_st *bucket)
939
971
  {
940
972
  if (bucket->threshold != 0 && bucket->nbytes > bucket->threshold) {
941
973
  do_loop(bucket);
@@ -946,25 +978,25 @@ maybe_do_loop(struct bucket_st *bucket)
946
978
  do_run(VALUE *args)
947
979
  {
948
980
  VALUE self = args[0], opts = args[1], proc = args[2], exc;
949
- struct bucket_st *bucket = DATA_PTR(self);
981
+ struct cb_bucket_st *bucket = DATA_PTR(self);
950
982
 
951
983
  if (bucket->handle == NULL) {
952
- rb_raise(eConnectError, "closed connection");
984
+ rb_raise(cb_eConnectError, "closed connection");
953
985
  }
954
986
  if (bucket->async) {
955
- rb_raise(eInvalidError, "nested #run");
987
+ rb_raise(cb_eInvalidError, "nested #run");
956
988
  }
957
989
  bucket->threshold = 0;
958
990
  if (opts != Qnil) {
959
991
  VALUE arg;
960
992
  Check_Type(opts, T_HASH);
961
- arg = rb_hash_aref(opts, sym_send_threshold);
993
+ arg = rb_hash_aref(opts, cb_sym_send_threshold);
962
994
  if (arg != Qnil) {
963
995
  bucket->threshold = (uint32_t)NUM2ULONG(arg);
964
996
  }
965
997
  }
966
998
  bucket->async = 1;
967
- cb_proc_call(proc, 1, self);
999
+ cb_proc_call(bucket, proc, 1, self);
968
1000
  do_loop(bucket);
969
1001
  if (bucket->exception != Qnil) {
970
1002
  exc = bucket->exception;
@@ -978,7 +1010,7 @@ do_run(VALUE *args)
978
1010
  ensure_run(VALUE *args)
979
1011
  {
980
1012
  VALUE self = args[0];
981
- struct bucket_st *bucket = DATA_PTR(self);
1013
+ struct cb_bucket_st *bucket = DATA_PTR(self);
982
1014
 
983
1015
  bucket->async = 0;
984
1016
  return Qnil;
@@ -1059,8 +1091,8 @@ cb_bucket_run(int argc, VALUE *argv, VALUE self)
1059
1091
  VALUE
1060
1092
  cb_bucket_stop(VALUE self)
1061
1093
  {
1062
- struct bucket_st *bucket = DATA_PTR(self);
1063
- bucket->io->stop_event_loop(bucket->io);
1094
+ struct cb_bucket_st *bucket = DATA_PTR(self);
1095
+ lcb_breakout(bucket->handle);
1064
1096
  return Qnil;
1065
1097
  }
1066
1098
 
@@ -1076,15 +1108,16 @@ cb_bucket_stop(VALUE self)
1076
1108
  VALUE
1077
1109
  cb_bucket_disconnect(VALUE self)
1078
1110
  {
1079
- struct bucket_st *bucket = DATA_PTR(self);
1111
+ struct cb_bucket_st *bucket = DATA_PTR(self);
1080
1112
 
1081
1113
  if (bucket->handle) {
1082
1114
  lcb_destroy(bucket->handle);
1115
+ lcb_destroy_io_ops(bucket->io);
1083
1116
  bucket->handle = NULL;
1084
1117
  bucket->io = NULL;
1085
1118
  return Qtrue;
1086
1119
  } else {
1087
- rb_raise(eConnectError, "closed connection");
1120
+ rb_raise(cb_eConnectError, "closed connection");
1088
1121
  return Qfalse;
1089
1122
  }
1090
1123
  }