couchbase 1.2.0.z.beta2-x86-mingw32 → 1.2.0.z.beta3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.markdown +15 -0
- data/README.markdown +14 -2
- data/ext/couchbase_ext/bucket.c +25 -11
- data/ext/couchbase_ext/couchbase_ext.c +14 -1
- data/ext/couchbase_ext/couchbase_ext.h +6 -0
- data/ext/couchbase_ext/extconf.rb +1 -2
- data/ext/couchbase_ext/http.c +7 -1
- data/ext/couchbase_ext/result.c +6 -9
- data/ext/couchbase_ext/utils.c +6 -0
- data/lib/active_support/cache/couchbase_store.rb +6 -6
- data/lib/couchbase/1.8/couchbase_ext.so +0 -0
- data/lib/couchbase/1.9/couchbase_ext.so +0 -0
- data/lib/couchbase/bucket.rb +3 -0
- data/lib/couchbase/cluster.rb +105 -0
- data/lib/couchbase/utils.rb +8 -5
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase.rb +1 -0
- data/lib/rack/session/couchbase.rb +1 -1
- data/tasks/compile.rake +1 -1
- data/test/test_async.rb +21 -17
- metadata +4 -3
data/HISTORY.markdown
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 1.2.0.z.beta3 / 2012-10-12
|
2
|
+
|
3
|
+
* Update view API
|
4
|
+
* Mention couchbase-model and em-couchbase in README
|
5
|
+
* Use global scope to find Error classes (thanks to @wr0ngway)
|
6
|
+
* RCBC-87 Fix build error on macos
|
7
|
+
* Use lcb_breakout()
|
8
|
+
* Propogate status code for HTTP responses
|
9
|
+
* Extract params encoding for easier reusage
|
10
|
+
* Destory IO operations struct (fix memleak)
|
11
|
+
* Don't try to convert error to number, it is exception object
|
12
|
+
* Update error codes
|
13
|
+
* Implement bucket create/delete operations
|
14
|
+
* Fixup FLUSH tests
|
15
|
+
|
1
16
|
## 1.2.0.z.beta2 / 2012-09-19
|
2
17
|
|
3
18
|
* RCBC-82 Fix extconf.rb for RVM/MacOS. (Not all rubies are fat on MacOS)
|
data/README.markdown
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
# Couchbase Ruby Client
|
1
|
+
# Couchbase Ruby Client
|
2
2
|
|
3
|
-
This is the official client library for use with Couchbase Server.
|
3
|
+
This is the official client library for use with Couchbase Server. There
|
4
|
+
are related libraries available:
|
5
|
+
|
6
|
+
* [couchbase-model][6] the ActiveModel implementation, git repository:
|
7
|
+
[https://github.com/couchbase/couchbase-ruby-model][7]
|
8
|
+
|
9
|
+
* [em-couchbase][8] EventMachine friendly implementation of couchbase
|
10
|
+
client, git repository: [https://github.com/couchbase/couchbase-ruby-client-em][9]
|
4
11
|
|
5
12
|
## SUPPORT
|
6
13
|
|
@@ -519,3 +526,8 @@ the error is detected.
|
|
519
526
|
[3]: http://www.couchbase.com/develop/c/current
|
520
527
|
[4]: https://github.com/mxcl/homebrew/pulls/avsej
|
521
528
|
[5]: http://code.google.com/p/memcached/wiki/BinaryProtocolRevamped
|
529
|
+
[6]: https://rubygems.org/gems/couchbase-model
|
530
|
+
[7]: https://github.com/couchbase/couchbase-ruby-model
|
531
|
+
[8]: https://rubygems.org/gems/em-couchbase
|
532
|
+
[9]: https://github.com/couchbase/couchbase-ruby-client-em
|
533
|
+
|
data/ext/couchbase_ext/bucket.c
CHANGED
@@ -22,7 +22,7 @@ error_callback(lcb_t handle, lcb_error_t error, const char *errinfo)
|
|
22
22
|
{
|
23
23
|
struct bucket_st *bucket = (struct bucket_st *)lcb_get_cookie(handle);
|
24
24
|
|
25
|
-
|
25
|
+
lcb_breakout(handle);
|
26
26
|
bucket->exception = cb_check_error(error, errinfo, Qnil);
|
27
27
|
}
|
28
28
|
|
@@ -34,6 +34,7 @@ cb_bucket_free(void *ptr)
|
|
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
39
|
xfree(bucket->authority);
|
39
40
|
xfree(bucket->hostname);
|
@@ -124,6 +125,14 @@ do_scan_connection_options(struct bucket_st *bucket, int argc, VALUE *argv)
|
|
124
125
|
bucket->bucket = strdup(NIL_P(arg) ? "default" : RSTRING_PTR(arg));
|
125
126
|
}
|
126
127
|
if (TYPE(opts) == T_HASH) {
|
128
|
+
arg = rb_hash_aref(opts, sym_type);
|
129
|
+
if (arg != Qnil) {
|
130
|
+
if (arg == sym_cluster) {
|
131
|
+
bucket->type = LCB_TYPE_CLUSTER;
|
132
|
+
} else {
|
133
|
+
bucket->type = LCB_TYPE_BUCKET;
|
134
|
+
}
|
135
|
+
}
|
127
136
|
arg = rb_hash_aref(opts, sym_node_list);
|
128
137
|
if (arg != Qnil) {
|
129
138
|
VALUE tt;
|
@@ -239,6 +248,7 @@ do_connect(struct bucket_st *bucket)
|
|
239
248
|
|
240
249
|
if (bucket->handle) {
|
241
250
|
lcb_destroy(bucket->handle);
|
251
|
+
lcb_destroy_io_ops(bucket->io);
|
242
252
|
bucket->handle = NULL;
|
243
253
|
bucket->io = NULL;
|
244
254
|
}
|
@@ -248,11 +258,13 @@ do_connect(struct bucket_st *bucket)
|
|
248
258
|
}
|
249
259
|
|
250
260
|
memset(&create_opts, 0, sizeof(struct lcb_create_st));
|
251
|
-
create_opts.
|
252
|
-
create_opts.v.
|
253
|
-
create_opts.v.
|
254
|
-
create_opts.v.
|
255
|
-
create_opts.v.
|
261
|
+
create_opts.version = 1;
|
262
|
+
create_opts.v.v1.type = bucket->type;
|
263
|
+
create_opts.v.v1.host = bucket->node_list ? bucket-> node_list : bucket->authority;
|
264
|
+
create_opts.v.v1.user = bucket->username;
|
265
|
+
create_opts.v.v1.passwd = bucket->password;
|
266
|
+
create_opts.v.v1.bucket = bucket->bucket;
|
267
|
+
create_opts.v.v1.io = bucket->io;
|
256
268
|
err = lcb_create(&bucket->handle, &create_opts);
|
257
269
|
if (err != LCB_SUCCESS) {
|
258
270
|
rb_exc_raise(cb_check_error(err, "failed to create libcouchbase instance", Qnil));
|
@@ -266,10 +278,8 @@ do_connect(struct bucket_st *bucket)
|
|
266
278
|
(void)lcb_set_stat_callback(bucket->handle, stat_callback);
|
267
279
|
(void)lcb_set_arithmetic_callback(bucket->handle, arithmetic_callback);
|
268
280
|
(void)lcb_set_version_callback(bucket->handle, version_callback);
|
269
|
-
(void)
|
270
|
-
(void)
|
271
|
-
(void)lcb_set_management_complete_callback(bucket->handle, http_complete_callback);
|
272
|
-
(void)lcb_set_management_data_callback(bucket->handle, http_data_callback);
|
281
|
+
(void)lcb_set_http_complete_callback(bucket->handle, http_complete_callback);
|
282
|
+
(void)lcb_set_http_data_callback(bucket->handle, http_data_callback);
|
273
283
|
(void)lcb_set_observe_callback(bucket->handle, observe_callback);
|
274
284
|
(void)lcb_set_unlock_callback(bucket->handle, unlock_callback);
|
275
285
|
|
@@ -281,6 +291,7 @@ do_connect(struct bucket_st *bucket)
|
|
281
291
|
err = lcb_connect(bucket->handle);
|
282
292
|
if (err != LCB_SUCCESS) {
|
283
293
|
lcb_destroy(bucket->handle);
|
294
|
+
lcb_destroy_io_ops(bucket->io);
|
284
295
|
bucket->handle = NULL;
|
285
296
|
bucket->io = NULL;
|
286
297
|
rb_exc_raise(cb_check_error(err, "failed to connect libcouchbase instance to server", Qnil));
|
@@ -289,6 +300,7 @@ do_connect(struct bucket_st *bucket)
|
|
289
300
|
lcb_wait(bucket->handle);
|
290
301
|
if (bucket->exception != Qnil) {
|
291
302
|
lcb_destroy(bucket->handle);
|
303
|
+
lcb_destroy_io_ops(bucket->io);
|
292
304
|
bucket->handle = NULL;
|
293
305
|
bucket->io = NULL;
|
294
306
|
rb_exc_raise(bucket->exception);
|
@@ -391,6 +403,7 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
391
403
|
|
392
404
|
bucket->self = self;
|
393
405
|
bucket->exception = Qnil;
|
406
|
+
bucket->type = LCB_TYPE_BUCKET;
|
394
407
|
bucket->hostname = strdup("localhost");
|
395
408
|
bucket->port = 8091;
|
396
409
|
bucket->pool = strdup("default");
|
@@ -1060,7 +1073,7 @@ cb_bucket_run(int argc, VALUE *argv, VALUE self)
|
|
1060
1073
|
cb_bucket_stop(VALUE self)
|
1061
1074
|
{
|
1062
1075
|
struct bucket_st *bucket = DATA_PTR(self);
|
1063
|
-
|
1076
|
+
lcb_breakout(bucket->handle);
|
1064
1077
|
return Qnil;
|
1065
1078
|
}
|
1066
1079
|
|
@@ -1080,6 +1093,7 @@ cb_bucket_disconnect(VALUE self)
|
|
1080
1093
|
|
1081
1094
|
if (bucket->handle) {
|
1082
1095
|
lcb_destroy(bucket->handle);
|
1096
|
+
lcb_destroy_io_ops(bucket->io);
|
1083
1097
|
bucket->handle = NULL;
|
1084
1098
|
bucket->io = NULL;
|
1085
1099
|
return Qtrue;
|
@@ -41,6 +41,7 @@ ID sym_cas;
|
|
41
41
|
ID sym_chunked;
|
42
42
|
ID sym_content_type;
|
43
43
|
ID sym_create;
|
44
|
+
ID sym_cluster;
|
44
45
|
ID sym_decrement;
|
45
46
|
ID sym_default_flags;
|
46
47
|
ID sym_default_format;
|
@@ -156,6 +157,7 @@ VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x17 */
|
|
156
157
|
VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x18 */
|
157
158
|
VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x19 */
|
158
159
|
VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x20 */
|
160
|
+
VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x21 */
|
159
161
|
|
160
162
|
|
161
163
|
/* Ruby Extension initializer */
|
@@ -330,6 +332,14 @@ Init_couchbase_ext(void)
|
|
330
332
|
* @since 1.1.0
|
331
333
|
*/
|
332
334
|
eConnectError = rb_define_class_under(mError, "Connect", eBaseError);
|
335
|
+
/* Document-class: Couchbase::Error::BadHandle
|
336
|
+
* Invalid handle type.
|
337
|
+
*
|
338
|
+
* The requested operation isn't allowed for given type.
|
339
|
+
*
|
340
|
+
* @since 1.2.0
|
341
|
+
*/
|
342
|
+
eBadHandleError = rb_define_class_under(mError, "BadHandle", eBaseError);
|
333
343
|
|
334
344
|
/* Document-method: error
|
335
345
|
*
|
@@ -362,7 +372,9 @@ Init_couchbase_ext(void)
|
|
362
372
|
* 0x16 :: LCB_ETIMEDOUT (Operation timed out)
|
363
373
|
* 0x17 :: LCB_CONNECT_ERROR (Connection failure)
|
364
374
|
* 0x18 :: LCB_BUCKET_ENOENT (No such bucket)
|
365
|
-
*
|
375
|
+
* 0x19 :: LCB_CLIENT_ENOMEM (Out of memory on the client)
|
376
|
+
* 0x20 :: LCB_CLIENT_ETMPFAIL (Temporary failure on the client)
|
377
|
+
* 0x21 :: LCB_EBADHANDLE (Invalid handle type)
|
366
378
|
*
|
367
379
|
* @since 1.0.0
|
368
380
|
*
|
@@ -911,6 +923,7 @@ Init_couchbase_ext(void)
|
|
911
923
|
sym_chunked = ID2SYM(rb_intern("chunked"));
|
912
924
|
sym_content_type = ID2SYM(rb_intern("content_type"));
|
913
925
|
sym_create = ID2SYM(rb_intern("create"));
|
926
|
+
sym_cluster = ID2SYM(rb_intern("cluster"));
|
914
927
|
sym_decrement = ID2SYM(rb_intern("decrement"));
|
915
928
|
sym_default_flags = ID2SYM(rb_intern("default_flags"));
|
916
929
|
sym_default_format = ID2SYM(rb_intern("default_format"));
|
@@ -23,6 +23,9 @@
|
|
23
23
|
#endif
|
24
24
|
|
25
25
|
#include "couchbase_config.h"
|
26
|
+
#ifdef HAVE_STDINT_H
|
27
|
+
#include <stdint.h>
|
28
|
+
#endif
|
26
29
|
#ifndef HAVE_GETHRTIME
|
27
30
|
typedef uint64_t hrtime_t;
|
28
31
|
extern hrtime_t gethrtime(void);
|
@@ -65,6 +68,7 @@ extern hrtime_t gethrtime(void);
|
|
65
68
|
struct bucket_st
|
66
69
|
{
|
67
70
|
lcb_t handle;
|
71
|
+
lcb_type_t type;
|
68
72
|
struct lcb_io_opt_st *io;
|
69
73
|
uint16_t port;
|
70
74
|
char *authority;
|
@@ -155,6 +159,7 @@ extern ID sym_body;
|
|
155
159
|
extern ID sym_bucket;
|
156
160
|
extern ID sym_cas;
|
157
161
|
extern ID sym_chunked;
|
162
|
+
extern ID sym_cluster;
|
158
163
|
extern ID sym_content_type;
|
159
164
|
extern ID sym_create;
|
160
165
|
extern ID sym_decrement;
|
@@ -272,6 +277,7 @@ extern VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x17 */
|
|
272
277
|
extern VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x18 */
|
273
278
|
extern VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x19 */
|
274
279
|
extern VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x20 */
|
280
|
+
extern VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x21 */
|
275
281
|
|
276
282
|
void strip_key_prefix(struct bucket_st *bucket, VALUE key);
|
277
283
|
VALUE cb_check_error(lcb_error_t rc, const char *msg, VALUE key);
|
@@ -119,8 +119,7 @@ if try_compile(<<-SRC)
|
|
119
119
|
define("HAVE_STDARG_PROTOTYPES")
|
120
120
|
end
|
121
121
|
|
122
|
-
|
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"
|
122
|
+
have_library("couchbase", "lcb_set_http_data_callback", "libcouchbase/couchbase.h") or abort "You should install libcouchbase >= 2.0.0beta2. See http://www.couchbase.com/develop/ for more details"
|
124
123
|
have_header("mach/mach_time.h")
|
125
124
|
have_header("stdint.h") or abort "Failed to locate stdint.h"
|
126
125
|
have_header("sys/time.h")
|
data/ext/couchbase_ext/http.c
CHANGED
@@ -23,6 +23,7 @@ http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *coo
|
|
23
23
|
struct context_st *ctx = (struct context_st *)cookie;
|
24
24
|
struct bucket_st *bucket = ctx->bucket;
|
25
25
|
VALUE *rv = ctx->rv, key, val, res;
|
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);
|
@@ -32,6 +33,7 @@ http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *coo
|
|
32
33
|
cb_gc_protect(bucket, ctx->exception);
|
33
34
|
}
|
34
35
|
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
36
|
+
status = resp->v.v0.status;
|
35
37
|
if (resp->v.v0.headers) {
|
36
38
|
cb_build_headers(ctx, resp->v.v0.headers);
|
37
39
|
cb_gc_unprotect(bucket, ctx->headers_val);
|
@@ -39,6 +41,7 @@ http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *coo
|
|
39
41
|
if (ctx->extended) {
|
40
42
|
res = rb_class_new_instance(0, NULL, cResult);
|
41
43
|
rb_ivar_set(res, id_iv_error, ctx->exception);
|
44
|
+
rb_ivar_set(res, id_iv_status, status ? INT2FIX(status) : Qnil);
|
42
45
|
rb_ivar_set(res, id_iv_operation, sym_http_request);
|
43
46
|
rb_ivar_set(res, id_iv_key, key);
|
44
47
|
rb_ivar_set(res, id_iv_value, val);
|
@@ -63,11 +66,13 @@ http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie,
|
|
63
66
|
struct context_st *ctx = (struct context_st *)cookie;
|
64
67
|
struct bucket_st *bucket = ctx->bucket;
|
65
68
|
VALUE key, val, res;
|
69
|
+
lcb_http_status_t status;
|
66
70
|
|
67
71
|
key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
|
68
72
|
ctx->exception = cb_check_error_with_status(error,
|
69
73
|
"failed to execute HTTP request", key, resp->v.v0.status);
|
70
74
|
val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
|
75
|
+
status = resp->v.v0.status;
|
71
76
|
if (ctx->exception != Qnil) {
|
72
77
|
cb_gc_protect(bucket, ctx->exception);
|
73
78
|
lcb_cancel_http_request(bucket->handle, request);
|
@@ -79,6 +84,7 @@ http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie,
|
|
79
84
|
if (ctx->extended) {
|
80
85
|
res = rb_class_new_instance(0, NULL, cResult);
|
81
86
|
rb_ivar_set(res, id_iv_error, ctx->exception);
|
87
|
+
rb_ivar_set(res, id_iv_status, status ? INT2FIX(status) : Qnil);
|
82
88
|
rb_ivar_set(res, id_iv_operation, sym_http_request);
|
83
89
|
rb_ivar_set(res, id_iv_key, key);
|
84
90
|
rb_ivar_set(res, id_iv_value, val);
|
@@ -305,7 +311,7 @@ cb_http_request_perform(VALUE self)
|
|
305
311
|
cb_http_request_pause(VALUE self)
|
306
312
|
{
|
307
313
|
struct http_request_st *req = DATA_PTR(self);
|
308
|
-
|
314
|
+
lcb_breakout(req->bucket->handle);
|
309
315
|
return Qnil;
|
310
316
|
}
|
311
317
|
|
data/ext/couchbase_ext/result.c
CHANGED
@@ -41,7 +41,7 @@ cb_result_success_p(VALUE self)
|
|
41
41
|
VALUE
|
42
42
|
cb_result_inspect(VALUE self)
|
43
43
|
{
|
44
|
-
VALUE str, attr
|
44
|
+
VALUE str, attr;
|
45
45
|
char buf[100];
|
46
46
|
|
47
47
|
str = rb_str_buf_new2("#<");
|
@@ -49,18 +49,15 @@ cb_result_inspect(VALUE self)
|
|
49
49
|
snprintf(buf, 100, ":%p", (void *)self);
|
50
50
|
rb_str_buf_cat2(str, buf);
|
51
51
|
|
52
|
-
attr = rb_ivar_get(self,
|
52
|
+
attr = rb_ivar_get(self, id_iv_operation);
|
53
53
|
if (RTEST(attr)) {
|
54
|
-
|
55
|
-
|
56
|
-
error = INT2FIX(0);
|
54
|
+
rb_str_buf_cat2(str, " operation=");
|
55
|
+
rb_str_append(str, rb_inspect(attr));
|
57
56
|
}
|
58
|
-
rb_str_buf_cat2(str, " error=0x");
|
59
|
-
rb_str_append(str, rb_funcall(error, id_to_s, 1, INT2FIX(16)));
|
60
57
|
|
61
|
-
attr = rb_ivar_get(self,
|
58
|
+
attr = rb_ivar_get(self, id_iv_error);
|
62
59
|
if (RTEST(attr)) {
|
63
|
-
rb_str_buf_cat2(str, "
|
60
|
+
rb_str_buf_cat2(str, " error=");
|
64
61
|
rb_str_append(str, rb_inspect(attr));
|
65
62
|
}
|
66
63
|
|
data/ext/couchbase_ext/utils.c
CHANGED
@@ -150,6 +150,12 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
|
|
150
150
|
case LCB_CLIENT_ENOMEM:
|
151
151
|
klass = eClientNoMemoryError;
|
152
152
|
break;
|
153
|
+
case LCB_CLIENT_ETMPFAIL:
|
154
|
+
klass = eClientTmpFailError;
|
155
|
+
break;
|
156
|
+
case LCB_EBADHANDLE:
|
157
|
+
klass = eBadHandleError;
|
158
|
+
break;
|
153
159
|
case LCB_ERROR:
|
154
160
|
/* fall through */
|
155
161
|
default:
|
@@ -184,7 +184,7 @@ module ActiveSupport
|
|
184
184
|
instrument(:read_multi, names, options) do
|
185
185
|
@data.get(names, options)
|
186
186
|
end
|
187
|
-
rescue Couchbase::Error::Base => e
|
187
|
+
rescue ::Couchbase::Error::Base => e
|
188
188
|
logger.error("#{e.class}: #{e.message}") if logger
|
189
189
|
raise if @raise_errors
|
190
190
|
false
|
@@ -245,7 +245,7 @@ module ActiveSupport
|
|
245
245
|
payload[:amount] = amount if payload
|
246
246
|
@data.incr(name, amount, options)
|
247
247
|
end
|
248
|
-
rescue Couchbase::Error::Base => e
|
248
|
+
rescue ::Couchbase::Error::Base => e
|
249
249
|
logger.error("#{e.class}: #{e.message}") if logger
|
250
250
|
raise if @raise_errors
|
251
251
|
false
|
@@ -277,7 +277,7 @@ module ActiveSupport
|
|
277
277
|
payload[:amount] = amount if payload
|
278
278
|
@data.decr(name, amount, options)
|
279
279
|
end
|
280
|
-
rescue Couchbase::Error::Base => e
|
280
|
+
rescue ::Couchbase::Error::Base => e
|
281
281
|
logger.error("#{e.class}: #{e.message}") if logger
|
282
282
|
raise if @raise_errors
|
283
283
|
false
|
@@ -297,7 +297,7 @@ module ActiveSupport
|
|
297
297
|
# Read an entry from the cache.
|
298
298
|
def read_entry(key, options) # :nodoc:
|
299
299
|
@data.get(key, options)
|
300
|
-
rescue Couchbase::Error::Base => e
|
300
|
+
rescue ::Couchbase::Error::Base => e
|
301
301
|
logger.error("#{e.class}: #{e.message}") if logger
|
302
302
|
raise if @raise_errors
|
303
303
|
nil
|
@@ -314,7 +314,7 @@ module ActiveSupport
|
|
314
314
|
options[:ttl] ||= ttl
|
315
315
|
end
|
316
316
|
@data.send(method, key, value, options)
|
317
|
-
rescue Couchbase::Error::Base => e
|
317
|
+
rescue ::Couchbase::Error::Base => e
|
318
318
|
logger.error("#{e.class}: #{e.message}") if logger
|
319
319
|
raise if @raise_errors
|
320
320
|
false
|
@@ -323,7 +323,7 @@ module ActiveSupport
|
|
323
323
|
# Delete an entry from the cache.
|
324
324
|
def delete_entry(key, options) # :nodoc:
|
325
325
|
@data.delete(key, options)
|
326
|
-
rescue Couchbase::Error::Base => e
|
326
|
+
rescue ::Couchbase::Error::Base => e
|
327
327
|
logger.error("#{e.class}: #{e.message}") if logger
|
328
328
|
raise if @raise_errors
|
329
329
|
false
|
Binary file
|
Binary file
|
data/lib/couchbase/bucket.rb
CHANGED
@@ -238,6 +238,9 @@ module Couchbase
|
|
238
238
|
# end
|
239
239
|
# end
|
240
240
|
def flush
|
241
|
+
if !async? && block_given?
|
242
|
+
raise ArgumentError, "synchronous mode doesn't support callbacks"
|
243
|
+
end
|
241
244
|
req = make_http_request("/pools/default/buckets/#{bucket}/controller/doFlush",
|
242
245
|
:type => :management, :method => :post, :extended => true)
|
243
246
|
res = nil
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2011, 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module Couchbase
|
19
|
+
|
20
|
+
class Cluster
|
21
|
+
|
22
|
+
# Establish connection to the cluster for administration
|
23
|
+
#
|
24
|
+
# @param [Hash] options The connection parameter
|
25
|
+
# @option options [String] :username The username
|
26
|
+
# @option options [String] :password The password
|
27
|
+
# @option options [String] :pool ("default") The pool name
|
28
|
+
# @option options [String] :hostname ("localhost") The hostname
|
29
|
+
# @option options [String] :port (8091) The port
|
30
|
+
def initialize(options = {})
|
31
|
+
if options[:username].nil? || options[:password].nil?
|
32
|
+
raise ArgumentError, "username and password mandatory to connect to the cluster"
|
33
|
+
end
|
34
|
+
@connection = Bucket.new(options.merge(:type => :cluster))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create data bucket
|
38
|
+
#
|
39
|
+
# @param [String] name The name of the bucket
|
40
|
+
# @param [Hash] options The bucket parameters
|
41
|
+
# @option options [String] :bucket_type ("couchbase") The type of the
|
42
|
+
# bucket. Possible values are "memcached" and "couchbase".
|
43
|
+
# @option options [Fixnum] :ram_quota (100) The RAM quota in megabytes.
|
44
|
+
# @option options [Fixnum] :replica_number (1) The number of replicas of
|
45
|
+
# each document
|
46
|
+
# @option options [String] :auth_type ("sasl") The authentication type.
|
47
|
+
# Possible values are "sasl" and "none". Note you should specify free
|
48
|
+
# port for "none"
|
49
|
+
# @option options [Fixnum] :proxy_port The port for moxi
|
50
|
+
def create_bucket(name, options = {})
|
51
|
+
defaults = {
|
52
|
+
:type => "couchbase",
|
53
|
+
:ram_quota => 100,
|
54
|
+
:replica_number => 1,
|
55
|
+
:auth_type => "sasl",
|
56
|
+
:sasl_password => "",
|
57
|
+
:proxy_port => nil
|
58
|
+
}
|
59
|
+
options = defaults.merge(options)
|
60
|
+
params = {"name" => name}
|
61
|
+
params["bucketType"] = options[:type]
|
62
|
+
params["ramQuotaMB"] = options[:ram_quota]
|
63
|
+
params["replicaNumber"] = options[:replica_number]
|
64
|
+
params["authType"] = options[:auth_type]
|
65
|
+
params["saslPassword"] = options[:sasl_password]
|
66
|
+
params["proxyPort"] = options[:proxy_port]
|
67
|
+
payload = Utils.encode_params(params.reject!{|k, v| v.nil?})
|
68
|
+
request = @connection.make_http_request("/pools/default/buckets",
|
69
|
+
:content_type => "application/x-www-form-urlencoded",
|
70
|
+
:type => :management,
|
71
|
+
:method => :post,
|
72
|
+
:extended => true,
|
73
|
+
:body => payload)
|
74
|
+
response = nil
|
75
|
+
request.on_body do |r|
|
76
|
+
response = r
|
77
|
+
response.instance_variable_set("@operation", :create_bucket)
|
78
|
+
yield(response) if block_given?
|
79
|
+
end
|
80
|
+
request.continue
|
81
|
+
response
|
82
|
+
end
|
83
|
+
|
84
|
+
# Delete the data bucket
|
85
|
+
#
|
86
|
+
# @param [String] name The name of the bucket
|
87
|
+
# @param [Hash] options
|
88
|
+
def delete_bucket(name, options = {})
|
89
|
+
request = @connection.make_http_request("/pools/default/buckets/#{name}",
|
90
|
+
:type => :management,
|
91
|
+
:method => :delete,
|
92
|
+
:extended => true)
|
93
|
+
response = nil
|
94
|
+
request.on_body do |r|
|
95
|
+
response = r
|
96
|
+
response.instance_variable_set("@operation", :delete_bucket)
|
97
|
+
yield(response) if block_given?
|
98
|
+
end
|
99
|
+
request.continue
|
100
|
+
response
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
data/lib/couchbase/utils.rb
CHANGED
@@ -19,11 +19,8 @@ module Couchbase
|
|
19
19
|
|
20
20
|
class Utils
|
21
21
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
return uri if params.nil? || params.empty?
|
25
|
-
uri << "?"
|
26
|
-
uri << params.map do |k, v|
|
22
|
+
def self.encode_params(params)
|
23
|
+
params.map do |k, v|
|
27
24
|
next if !v && k.to_s == "group"
|
28
25
|
if %w{key keys startkey endkey start_key end_key}.include?(k.to_s)
|
29
26
|
v = MultiJson.dump(v)
|
@@ -36,6 +33,12 @@ module Couchbase
|
|
36
33
|
end.compact.join("&")
|
37
34
|
end
|
38
35
|
|
36
|
+
def self.build_query(uri, params = nil)
|
37
|
+
uri = uri.dup
|
38
|
+
return uri if params.nil? || params.empty?
|
39
|
+
uri << "?" << encode_params(params)
|
40
|
+
end
|
41
|
+
|
39
42
|
def self.escape(s)
|
40
43
|
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/nu) {
|
41
44
|
'%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
data/lib/couchbase/version.rb
CHANGED
data/lib/couchbase.rb
CHANGED
@@ -90,7 +90,7 @@ module Rack
|
|
90
90
|
def with_lock(env, default = nil)
|
91
91
|
@mutex.lock if env['rack.multithread']
|
92
92
|
yield
|
93
|
-
rescue Couchbase::Error::Connect, Couchbase::Error::Timeout
|
93
|
+
rescue ::Couchbase::Error::Connect, ::Couchbase::Error::Timeout
|
94
94
|
if $VERBOSE
|
95
95
|
warn "#{self} is unable to find Couchbase server."
|
96
96
|
warn $!.inspect
|
data/tasks/compile.rake
CHANGED
@@ -84,7 +84,7 @@ namespace :ports do
|
|
84
84
|
directory "ports"
|
85
85
|
|
86
86
|
task :libcouchbase => ["ports"] do
|
87
|
-
recipe = MiniPortile.new "libcouchbase", "2.0.
|
87
|
+
recipe = MiniPortile.new "libcouchbase", "2.0.0beta2_1_gf60b9fe"
|
88
88
|
recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
|
89
89
|
recipe.configure_options.push("--disable-debug",
|
90
90
|
"--disable-dependency-tracking",
|
data/test/test_async.rb
CHANGED
@@ -154,27 +154,31 @@ class TestAsync < MiniTest::Unit::TestCase
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def test_nested_async_flush_set
|
157
|
-
|
158
|
-
|
159
|
-
|
157
|
+
if @mock.real?
|
158
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
159
|
+
cas = connection.set(uniq_id, "foo")
|
160
|
+
res = {}
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
162
|
+
connection.run do |conn|
|
163
|
+
conn.flush do |res1|
|
164
|
+
assert res1.success?
|
165
|
+
id = uniq_id(res1.node)
|
166
|
+
res[id] = false
|
167
|
+
conn.set(id, true) do |res2|
|
168
|
+
res[id] = res2.cas
|
169
|
+
end
|
168
170
|
end
|
169
171
|
end
|
170
|
-
end
|
171
172
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
173
|
+
assert_raises(Couchbase::Error::NotFound) do
|
174
|
+
connection.get(uniq_id)
|
175
|
+
end
|
176
|
+
res.keys.each do |key|
|
177
|
+
assert res[key].is_a?(Numeric)
|
178
|
+
assert connection.get(key)
|
179
|
+
end
|
180
|
+
else
|
181
|
+
skip("REST FLUSH isn't implemented in CouchbaseMock.jar yet")
|
178
182
|
end
|
179
183
|
end
|
180
184
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.0.z.
|
4
|
+
version: 1.2.0.z.beta3
|
5
5
|
prerelease: 6
|
6
6
|
platform: x86-mingw32
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yaji
|
@@ -242,6 +242,7 @@ files:
|
|
242
242
|
- lib/active_support/cache/couchbase_store.rb
|
243
243
|
- lib/couchbase.rb
|
244
244
|
- lib/couchbase/bucket.rb
|
245
|
+
- lib/couchbase/cluster.rb
|
245
246
|
- lib/couchbase/result.rb
|
246
247
|
- lib/couchbase/utils.rb
|
247
248
|
- lib/couchbase/version.rb
|
@@ -293,7 +294,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
293
294
|
version: '0'
|
294
295
|
segments:
|
295
296
|
- 0
|
296
|
-
hash: -
|
297
|
+
hash: -2344661928388476453
|
297
298
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
298
299
|
none: false
|
299
300
|
requirements:
|