couchbase 1.2.0.z.beta2-x86-mingw32 → 1.2.0.z.beta3-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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 [![Build Status](https://secure.travis-ci.org/couchbase/couchbase-ruby-client.png?branch=master)](http://travis-ci.org/couchbase/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
+
@@ -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
- 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
 
@@ -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.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;
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)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);
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
- bucket->io->stop_event_loop(bucket->io);
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
- * 0x18 :: LCB_CLIENT_ENOMEM (Out of memory on the client)
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")
@@ -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
- req->bucket->io->stop_event_loop(req->bucket->io);
314
+ lcb_breakout(req->bucket->handle);
309
315
  return Qnil;
310
316
  }
311
317
 
@@ -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, error;
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, id_iv_error);
52
+ attr = rb_ivar_get(self, id_iv_operation);
53
53
  if (RTEST(attr)) {
54
- error = rb_ivar_get(attr, id_iv_error);
55
- } else {
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, id_iv_operation);
58
+ attr = rb_ivar_get(self, id_iv_error);
62
59
  if (RTEST(attr)) {
63
- rb_str_buf_cat2(str, " operation=");
60
+ rb_str_buf_cat2(str, " error=");
64
61
  rb_str_append(str, rb_inspect(attr));
65
62
  }
66
63
 
@@ -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
@@ -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
@@ -19,11 +19,8 @@ module Couchbase
19
19
 
20
20
  class Utils
21
21
 
22
- def self.build_query(uri, params = nil)
23
- uri = uri.dup
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
@@ -17,5 +17,5 @@
17
17
 
18
18
  # Couchbase ruby client
19
19
  module Couchbase
20
- VERSION = "1.2.0.z.beta2"
20
+ VERSION = "1.2.0.z.beta3"
21
21
  end
data/lib/couchbase.rb CHANGED
@@ -26,6 +26,7 @@ require 'couchbase/bucket'
26
26
  require 'couchbase/view_row'
27
27
  require 'couchbase/view'
28
28
  require 'couchbase/result'
29
+ require 'couchbase/cluster'
29
30
 
30
31
  # Couchbase ruby client
31
32
  module Couchbase
@@ -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.0beta_5_g970a292"
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
- connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
158
- cas = connection.set(uniq_id, "foo")
159
- res = {}
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
- connection.run do |conn|
162
- conn.flush do |res1|
163
- assert res1.success?
164
- id = uniq_id(res1.node)
165
- res[id] = false
166
- conn.set(id, true) do |res2|
167
- res[id] = res2.cas
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
- assert_raises(Couchbase::Error::NotFound) do
173
- connection.get(uniq_id)
174
- end
175
- res.keys.each do |key|
176
- assert res[key].is_a?(Numeric)
177
- assert connection.get(key)
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.beta2
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-09-21 00:00:00.000000000 Z
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: -1839636572192674116
297
+ hash: -2344661928388476453
297
298
  required_rubygems_version: !ruby/object:Gem::Requirement
298
299
  none: false
299
300
  requirements: