couchbase 1.2.0.z.beta3-x86-mingw32 → 1.2.0.z.beta4-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.
@@ -9,7 +9,7 @@ before_install:
9
9
  - wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -
10
10
  - echo deb http://packages.couchbase.com/snapshot/ubuntu oneiric oneiric/main | sudo tee /etc/apt/sources.list.d/couchbase.list
11
11
  - sudo apt-get update
12
- - sudo apt-get -y install libevent-dev libvbucket-dev libcouchbase-dev
12
+ - sudo apt-get -y install libcouchbase2-dev
13
13
 
14
14
  rvm:
15
15
  - 1.8.7
@@ -1,3 +1,24 @@
1
+ ## 1.2.0.z.beta4 / 2012-11-21
2
+
3
+ * Do not hide ValueFormat reason
4
+ * Adjust version check for MultiJson monkeypatch
5
+ * Update error codes
6
+ * Remove mentions of LCB_LIBEVENT_ERROR in utils.c
7
+ * Add Makefile for easier build with repo layout
8
+ * Check HTTP error code when building exception object
9
+ * Remove debug output in tests
10
+ * Make rack session store adapter quiet
11
+ * RCBC-90 Update documentation about session store
12
+ * Protect against non string values in :plain mode
13
+ * RCBC-89 Fetch documents using binary protocol by default
14
+ * Deserialize Base64 value from view
15
+ * Remove all_docs mentions
16
+ * RCBC-92 Use more portable version of rb_sprintf()
17
+ * Do not expose docs embedded in HTTP response
18
+ * RCBC-94 Reset global exception after usage
19
+ * Fix number of arguments to Kernel#sprintf
20
+ * Increase default connection timeout
21
+
1
22
  ## 1.2.0.z.beta3 / 2012-10-12
2
23
 
3
24
  * Update view API
@@ -0,0 +1,3 @@
1
+ all:
2
+ $(MAKE) -C../.. ruby-client
3
+
@@ -443,7 +443,6 @@ store a couple of posts using memcached API:
443
443
  c['hello-world'] = {:title => 'Hello World',
444
444
  :body => 'Well hello and welcome to my new blog...',
445
445
  :date => '2009/01/15 15:52:20'}
446
- c.all_docs.count #=> 3
447
446
 
448
447
  Now let's create design doc with sample view and save it in file
449
448
  'blog.json':
@@ -493,7 +492,7 @@ You can also use Enumerator to iterate view results
493
492
 
494
493
  require 'date'
495
494
  posts_by_date = Hash.new{|h,k| h[k] = []}
496
- enum = c.all_docs(:include_docs => true).each # request hasn't issued yet
495
+ enum = c.recent_posts(:include_docs => true).each # request hasn't issued yet
497
496
  enum.inject(posts_by_date) do |acc, doc|
498
497
  acc[date] = Date.strptime(doc['date'], '%Y/%m/%d')
499
498
  acc
@@ -237,8 +237,18 @@ cb_params_store_init_item(struct params_st *params, lcb_size_t idx,
237
237
  {
238
238
  key_obj = unify_key(params->bucket, key_obj, 1);
239
239
  value_obj = encode_value(value_obj, params->cmd.store.flags);
240
- if (value_obj == Qundef) {
241
- rb_raise(eValueFormatError, "unable to convert value for key '%s'", RSTRING_PTR(key_obj));
240
+ if (rb_obj_is_kind_of(value_obj, rb_eStandardError)) {
241
+ VALUE exc_str = rb_funcall(value_obj, id_to_s, 0);
242
+ VALUE msg = rb_funcall(rb_mKernel, id_sprintf, 3,
243
+ rb_str_new2("unable to convert value for key '%s': %s"), key_obj, exc_str);
244
+ VALUE exc = rb_exc_new3(eValueFormatError, msg);
245
+ rb_ivar_set(exc, id_iv_inner_exception, value_obj);
246
+ rb_exc_raise(exc);
247
+ }
248
+ /* the value must be string after conversion */
249
+ if (TYPE(value_obj) != T_STRING) {
250
+ VALUE val = rb_any_to_s(value_obj);
251
+ rb_raise(eValueFormatError, "unable to convert value for key '%s' to string: %s", RSTRING_PTR(key_obj), RSTRING_PTR(val));
242
252
  }
243
253
  params->cmd.store.items[idx].v.v0.datatype = params->cmd.store.datatype;
244
254
  params->cmd.store.items[idx].v.v0.operation = params->cmd.store.operation;
@@ -108,6 +108,7 @@ ID id_iv_error;
108
108
  ID id_iv_flags;
109
109
  ID id_iv_from_master;
110
110
  ID id_iv_headers;
111
+ ID id_iv_inner_exception;
111
112
  ID id_iv_key;
112
113
  ID id_iv_node;
113
114
  ID id_iv_operation;
@@ -123,6 +124,7 @@ ID id_password;
123
124
  ID id_path;
124
125
  ID id_port;
125
126
  ID id_scheme;
127
+ ID id_sprintf;
126
128
  ID id_to_s;
127
129
  ID id_user;
128
130
  ID id_verify_observe_options;
@@ -130,6 +132,8 @@ ID id_verify_observe_options;
130
132
  /* Errors */
131
133
  VALUE eBaseError;
132
134
  VALUE eValueFormatError;
135
+ VALUE eHTTPError;
136
+
133
137
  /* LCB_SUCCESS = 0x00 */
134
138
  /* LCB_AUTH_CONTINUE = 0x01 */
135
139
  VALUE eAuthError; /* LCB_AUTH_ERROR = 0x02 */
@@ -144,20 +148,21 @@ VALUE eLibcouchbaseError; /* LCB_ERROR = 0x0a */
144
148
  VALUE eTmpFailError; /* LCB_ETMPFAIL = 0x0b */
145
149
  VALUE eKeyExistsError; /* LCB_KEY_EEXISTS = 0x0c */
146
150
  VALUE eNotFoundError; /* LCB_KEY_ENOENT = 0x0d */
147
- VALUE eLibeventError; /* LCB_LIBEVENT_ERROR = 0x0e */
148
- VALUE eNetworkError; /* LCB_NETWORK_ERROR = 0x0f */
149
- VALUE eNotMyVbucketError; /* LCB_NOT_MY_VBUCKET = 0x10 */
150
- VALUE eNotStoredError; /* LCB_NOT_STORED = 0x11 */
151
- VALUE eNotSupportedError; /* LCB_NOT_SUPPORTED = 0x12 */
152
- VALUE eUnknownCommandError; /* LCB_UNKNOWN_COMMAND = 0x13 */
153
- VALUE eUnknownHostError; /* LCB_UNKNOWN_HOST = 0x14 */
154
- VALUE eProtocolError; /* LCB_PROTOCOL_ERROR = 0x15 */
155
- VALUE eTimeoutError; /* LCB_ETIMEDOUT = 0x16 */
156
- VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x17 */
157
- VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x18 */
158
- VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x19 */
159
- VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x20 */
160
- VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x21 */
151
+ VALUE eDlopenFailedError; /* LCB_DLOPEN_FAILED = 0x0e */
152
+ VALUE eDlsymFailedError; /* LCB_DLSYM_FAILED = 0x0f */
153
+ VALUE eNetworkError; /* LCB_NETWORK_ERROR = 0x10 */
154
+ VALUE eNotMyVbucketError; /* LCB_NOT_MY_VBUCKET = 0x11 */
155
+ VALUE eNotStoredError; /* LCB_NOT_STORED = 0x12 */
156
+ VALUE eNotSupportedError; /* LCB_NOT_SUPPORTED = 0x13 */
157
+ VALUE eUnknownCommandError; /* LCB_UNKNOWN_COMMAND = 0x14 */
158
+ VALUE eUnknownHostError; /* LCB_UNKNOWN_HOST = 0x15 */
159
+ VALUE eProtocolError; /* LCB_PROTOCOL_ERROR = 0x16 */
160
+ VALUE eTimeoutError; /* LCB_ETIMEDOUT = 0x17 */
161
+ VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x18 */
162
+ VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x19 */
163
+ VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x1a */
164
+ VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x1b */
165
+ VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
161
166
 
162
167
 
163
168
  /* Ruby Extension initializer */
@@ -179,17 +184,24 @@ Init_couchbase_ext(void)
179
184
  /* Document-class: Couchbase::Error::Auth
180
185
  * Authentication error
181
186
  *
187
+ * You provided an invalid username/password combination.
188
+ *
182
189
  * @since 1.0.0
183
190
  */
184
191
  eAuthError = rb_define_class_under(mError, "Auth", eBaseError);
185
192
  /* Document-class: Couchbase::Error::BucketNotFound
186
- * The given bucket not found in the cluster
193
+ * Bucket not found
194
+ *
195
+ * The requested bucket not found in the cluster
187
196
  *
188
197
  * @since 1.0.0
189
198
  */
190
199
  eBucketNotFoundError = rb_define_class_under(mError, "BucketNotFound", eBaseError);
191
200
  /* Document-class: Couchbase::Error::Busy
192
- * The cluster is too busy now. Try again later
201
+ * The cluster is too busy
202
+ *
203
+ * The server is too busy to handle your request right now.
204
+ * please back off and try again at a later time.
193
205
  *
194
206
  * @since 1.0.0
195
207
  */
@@ -203,6 +215,9 @@ Init_couchbase_ext(void)
203
215
  /* Document-class: Couchbase::Error::Internal
204
216
  * Internal error
205
217
  *
218
+ * Internal error inside the library. You would have
219
+ * to destroy the instance and create a new one to recover.
220
+ *
206
221
  * @since 1.0.0
207
222
  */
208
223
  eInternalError = rb_define_class_under(mError, "Internal", eBaseError);
@@ -215,6 +230,8 @@ Init_couchbase_ext(void)
215
230
  /* Document-class: Couchbase::Error::KeyExists
216
231
  * Key already exists
217
232
  *
233
+ * The key already exists (with another CAS value)
234
+ *
218
235
  * @since 1.0.0
219
236
  */
220
237
  eKeyExistsError = rb_define_class_under(mError, "KeyExists", eBaseError);
@@ -224,21 +241,20 @@ Init_couchbase_ext(void)
224
241
  * @since 1.0.0
225
242
  */
226
243
  eLibcouchbaseError = rb_define_class_under(mError, "Libcouchbase", eBaseError);
227
- /* Document-class: Couchbase::Error::Libevent
228
- * Problem using libevent
229
- *
230
- * @since 1.0.0
231
- */
232
- eLibeventError = rb_define_class_under(mError, "Libevent", eBaseError);
233
244
  /* Document-class: Couchbase::Error::Network
234
245
  * Network error
235
246
  *
247
+ * A network related problem occured (name lookup, read/write/connect
248
+ * etc)
249
+ *
236
250
  * @since 1.0.0
237
251
  */
238
252
  eNetworkError = rb_define_class_under(mError, "Network", eBaseError);
239
253
  /* Document-class: Couchbase::Error::NoMemory
240
254
  * Out of memory error (on Server)
241
255
  *
256
+ * The client ran out of memory
257
+ *
242
258
  * @since 1.0.0
243
259
  */
244
260
  eNoMemoryError = rb_define_class_under(mError, "NoMemory", eBaseError);
@@ -257,29 +273,44 @@ Init_couchbase_ext(void)
257
273
  /* Document-class: Couchbase::Error::NotMyVbucket
258
274
  * The vbucket is not located on this server
259
275
  *
276
+ * The server who received the request is not responsible for the
277
+ * object anymore. (This happens during changes in the cluster
278
+ * topology)
279
+ *
260
280
  * @since 1.0.0
261
281
  */
262
282
  eNotMyVbucketError = rb_define_class_under(mError, "NotMyVbucket", eBaseError);
263
283
  /* Document-class: Couchbase::Error::NotStored
264
284
  * Not stored
265
285
  *
286
+ * The object was not stored on the server
287
+ *
266
288
  * @since 1.0.0
267
289
  */
268
290
  eNotStoredError = rb_define_class_under(mError, "NotStored", eBaseError);
269
291
  /* Document-class: Couchbase::Error::NotSupported
270
292
  * Not supported
271
293
  *
294
+ * The server doesn't support the requested command. This error differs
295
+ * from {Couchbase::Error::UnknownCommand} by that the server knows
296
+ * about the command, but for some reason decided to not support it.
297
+ *
272
298
  * @since 1.0.0
273
299
  */
274
300
  eNotSupportedError = rb_define_class_under(mError, "NotSupported", eBaseError);
275
301
  /* Document-class: Couchbase::Error::Range
276
302
  * Invalid range
277
303
  *
304
+ * An invalid range specified
305
+ *
278
306
  * @since 1.0.0
279
307
  */
280
308
  eRangeError = rb_define_class_under(mError, "Range", eBaseError);
281
309
  /* Document-class: Couchbase::Error::TemporaryFail
282
- * Temporary failure. Try again later
310
+ * Temporary failure
311
+ *
312
+ * The server tried to perform the requested operation, but failed
313
+ * due to a temporary constraint. Retrying the operation may work.
283
314
  *
284
315
  * @since 1.0.0
285
316
  */
@@ -287,24 +318,33 @@ Init_couchbase_ext(void)
287
318
  /* Document-class: Couchbase::Error::ClientTemporaryFail
288
319
  * Temporary failure (on Client)
289
320
  *
321
+ * The client encountered a temporary error (retry might resolve
322
+ * the problem)
323
+ *
290
324
  * @since 1.2.0
291
325
  */
292
326
  eClientTmpFailError = rb_define_class_under(mError, "ClientTemporaryFail", eBaseError);
293
327
  /* Document-class: Couchbase::Error::TooBig
294
328
  * Object too big
295
329
  *
330
+ * The sever reported that this object is too big
331
+ *
296
332
  * @since 1.0.0
297
333
  */
298
334
  eTooBigError = rb_define_class_under(mError, "TooBig", eBaseError);
299
335
  /* Document-class: Couchbase::Error::UnknownCommand
300
336
  * Unknown command
301
337
  *
338
+ * The server doesn't know what that command is.
339
+ *
302
340
  * @since 1.0.0
303
341
  */
304
342
  eUnknownCommandError = rb_define_class_under(mError, "UnknownCommand", eBaseError);
305
343
  /* Document-class: Couchbase::Error::UnknownHost
306
344
  * Unknown host
307
345
  *
346
+ * The server failed to resolve the requested hostname
347
+ *
308
348
  * @since 1.0.0
309
349
  */
310
350
  eUnknownHostError = rb_define_class_under(mError, "UnknownHost", eBaseError);
@@ -317,12 +357,17 @@ Init_couchbase_ext(void)
317
357
  /* Document-class: Couchbase::Error::Protocol
318
358
  * Protocol error
319
359
  *
360
+ * There is something wrong with the datastream received from
361
+ * the server
362
+ *
320
363
  * @since 1.0.0
321
364
  */
322
365
  eProtocolError = rb_define_class_under(mError, "Protocol", eBaseError);
323
366
  /* Document-class: Couchbase::Error::Timeout
324
367
  * Timeout error
325
368
  *
369
+ * The operation timed out
370
+ *
326
371
  * @since 1.1.0
327
372
  */
328
373
  eTimeoutError = rb_define_class_under(mError, "Timeout", eBaseError);
@@ -341,6 +386,30 @@ Init_couchbase_ext(void)
341
386
  */
342
387
  eBadHandleError = rb_define_class_under(mError, "BadHandle", eBaseError);
343
388
 
389
+ /* Document-class: Couchbase::Error::DlopenFailed
390
+ * dlopen() failed
391
+ *
392
+ * Failed to open shared object
393
+ *
394
+ * @since 1.2.0
395
+ */
396
+ eDlopenFailedError = rb_define_class_under(mError, "DlopenFailed", eBaseError);
397
+
398
+ /* Document-class: Couchbase::Error::DlsymFailed
399
+ * dlsym() failed
400
+ *
401
+ * Failed to locate the requested symbol in the shared object
402
+ *
403
+ * @since 1.2.0
404
+ */
405
+ eDlsymFailedError = rb_define_class_under(mError, "DlsymFailed", eBaseError);
406
+
407
+ /* Document-class: Couchbase::Error::HTTP
408
+ * HTTP error with status code
409
+ *
410
+ * @since 1.2.0
411
+ */
412
+ eHTTPError = rb_define_class_under(mError, "HTTP", eBaseError);
344
413
  /* Document-method: error
345
414
  *
346
415
  * The underlying libcouchbase library could return one of the following
@@ -352,29 +421,31 @@ Init_couchbase_ext(void)
352
421
  * 0x02 :: LCB_AUTH_ERROR (Authentication error)
353
422
  * 0x03 :: LCB_DELTA_BADVAL (Not a number)
354
423
  * 0x04 :: LCB_E2BIG (Object too big)
355
- * 0x05 :: LCB_EBUSY (Too busy. Try again later)
424
+ * 0x05 :: LCB_EBUSY (Too busy)
356
425
  * 0x06 :: LCB_EINTERNAL (Internal error)
357
426
  * 0x07 :: LCB_EINVAL (Invalid arguments)
358
427
  * 0x08 :: LCB_ENOMEM (Out of memory)
359
428
  * 0x09 :: LCB_ERANGE (Invalid range)
360
429
  * 0x0a :: LCB_ERROR (Generic error)
361
- * 0x0b :: LCB_ETMPFAIL (Temporary failure. Try again later)
430
+ * 0x0b :: LCB_ETMPFAIL (Temporary failure)
362
431
  * 0x0c :: LCB_KEY_EEXISTS (Key exists (with a different CAS value))
363
432
  * 0x0d :: LCB_KEY_ENOENT (No such key)
364
- * 0x0e :: LCB_LIBEVENT_ERROR (Problem using libevent)
365
- * 0x0f :: LCB_NETWORK_ERROR (Network error)
366
- * 0x10 :: LCB_NOT_MY_VBUCKET (The vbucket is not located on this server)
367
- * 0x11 :: LCB_NOT_STORED (Not stored)
368
- * 0x12 :: LCB_NOT_SUPPORTED (Not supported)
369
- * 0x13 :: LCB_UNKNOWN_COMMAND (Unknown command)
370
- * 0x14 :: LCB_UNKNOWN_HOST (Unknown host)
371
- * 0x15 :: LCB_PROTOCOL_ERROR (Protocol error)
372
- * 0x16 :: LCB_ETIMEDOUT (Operation timed out)
373
- * 0x17 :: LCB_CONNECT_ERROR (Connection failure)
374
- * 0x18 :: LCB_BUCKET_ENOENT (No such bucket)
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)
433
+ * 0x0e :: LCB_DLOPEN_FAILED (Failed to open shared object)
434
+ * 0x0f :: LCB_DLSYM_FAILED (Failed to locate the requested symbol in shared object)
435
+ * 0x10 :: LCB_NETWORK_ERROR (Network error)
436
+ * 0x11 :: LCB_NOT_MY_VBUCKET (The vbucket is not located on this server)
437
+ * 0x12 :: LCB_NOT_STORED (Not stored)
438
+ * 0x13 :: LCB_NOT_SUPPORTED (Not supported)
439
+ * 0x14 :: LCB_UNKNOWN_COMMAND (Unknown command)
440
+ * 0x15 :: LCB_UNKNOWN_HOST (Unknown host)
441
+ * 0x16 :: LCB_PROTOCOL_ERROR (Protocol error)
442
+ * 0x17 :: LCB_ETIMEDOUT (Operation timed out)
443
+ * 0x18 :: LCB_CONNECT_ERROR (Connection failure)
444
+ * 0x19 :: LCB_BUCKET_ENOENT (No such bucket)
445
+ * 0x1a :: LCB_CLIENT_ENOMEM (Out of memory on the client)
446
+ * 0x1b :: LCB_CLIENT_ETMPFAIL (Temporary failure on the client)
447
+ * 0x1c :: LCB_EBADHANDLE (Invalid handle type)
448
+ *
378
449
  *
379
450
  * @since 1.0.0
380
451
  *
@@ -410,6 +481,14 @@ Init_couchbase_ext(void)
410
481
  * @return [Symbol] the operation (+nil+ unless accessible) */
411
482
  rb_define_attr(eBaseError, "operation", 1, 0);
412
483
  id_iv_operation = rb_intern("@operation");
484
+ /* Document-method: inner_exception
485
+ *
486
+ * @since 1.2.0.beta4
487
+ *
488
+ * @return [Exception] the inner exception or +nil+. Some exceptions like
489
+ * {Error::ValueFormat} wrap the original exception */
490
+ rb_define_attr(eBaseError, "inner_exception", 1, 0);
491
+ id_iv_inner_exception = rb_intern("@inner_exception");
413
492
 
414
493
  /* Document-class: Couchbase::Result
415
494
  *
@@ -910,6 +989,7 @@ Init_couchbase_ext(void)
910
989
  id_path = rb_intern("path");
911
990
  id_port = rb_intern("port");
912
991
  id_scheme = rb_intern("scheme");
992
+ id_sprintf = rb_intern("sprintf");
913
993
  id_to_s = rb_intern("to_s");
914
994
  id_user = rb_intern("user");
915
995
  id_verify_observe_options = rb_intern("verify_observe_options");
@@ -228,6 +228,7 @@ extern ID id_iv_error;
228
228
  extern ID id_iv_flags;
229
229
  extern ID id_iv_from_master;
230
230
  extern ID id_iv_headers;
231
+ extern ID id_iv_inner_exception;
231
232
  extern ID id_iv_key;
232
233
  extern ID id_iv_node;
233
234
  extern ID id_iv_operation;
@@ -243,6 +244,7 @@ extern ID id_password;
243
244
  extern ID id_path;
244
245
  extern ID id_port;
245
246
  extern ID id_scheme;
247
+ extern ID id_sprintf;
246
248
  extern ID id_to_s;
247
249
  extern ID id_user;
248
250
  extern ID id_verify_observe_options;
@@ -250,6 +252,7 @@ extern ID id_verify_observe_options;
250
252
  /* Errors */
251
253
  extern VALUE eBaseError;
252
254
  extern VALUE eValueFormatError;
255
+ extern VALUE eHTTPError;
253
256
  /* LCB_SUCCESS = 0x00 */
254
257
  /* LCB_AUTH_CONTINUE = 0x01 */
255
258
  extern VALUE eAuthError; /* LCB_AUTH_ERROR = 0x02 */
@@ -264,20 +267,21 @@ extern VALUE eLibcouchbaseError; /* LCB_ERROR = 0x0a */
264
267
  extern VALUE eTmpFailError; /* LCB_ETMPFAIL = 0x0b */
265
268
  extern VALUE eKeyExistsError; /* LCB_KEY_EEXISTS = 0x0c */
266
269
  extern VALUE eNotFoundError; /* LCB_KEY_ENOENT = 0x0d */
267
- extern VALUE eLibeventError; /* LCB_LIBEVENT_ERROR = 0x0e */
268
- extern VALUE eNetworkError; /* LCB_NETWORK_ERROR = 0x0f */
269
- extern VALUE eNotMyVbucketError; /* LCB_NOT_MY_VBUCKET = 0x10 */
270
- extern VALUE eNotStoredError; /* LCB_NOT_STORED = 0x11 */
271
- extern VALUE eNotSupportedError; /* LCB_NOT_SUPPORTED = 0x12 */
272
- extern VALUE eUnknownCommandError; /* LCB_UNKNOWN_COMMAND = 0x13 */
273
- extern VALUE eUnknownHostError; /* LCB_UNKNOWN_HOST = 0x14 */
274
- extern VALUE eProtocolError; /* LCB_PROTOCOL_ERROR = 0x15 */
275
- extern VALUE eTimeoutError; /* LCB_ETIMEDOUT = 0x16 */
276
- extern VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x17 */
277
- extern VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x18 */
278
- extern VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x19 */
279
- extern VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x20 */
280
- extern VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x21 */
270
+ extern VALUE eDlopenFailedError; /* LCB_DLOPEN_FAILED = 0x0e */
271
+ extern VALUE eDlsymFailedError; /* LCB_DLSYM_FAILED = 0x0f */
272
+ extern VALUE eNetworkError; /* LCB_NETWORK_ERROR = 0x10 */
273
+ extern VALUE eNotMyVbucketError; /* LCB_NOT_MY_VBUCKET = 0x11 */
274
+ extern VALUE eNotStoredError; /* LCB_NOT_STORED = 0x12 */
275
+ extern VALUE eNotSupportedError; /* LCB_NOT_SUPPORTED = 0x13 */
276
+ extern VALUE eUnknownCommandError; /* LCB_UNKNOWN_COMMAND = 0x14 */
277
+ extern VALUE eUnknownHostError; /* LCB_UNKNOWN_HOST = 0x15 */
278
+ extern VALUE eProtocolError; /* LCB_PROTOCOL_ERROR = 0x16 */
279
+ extern VALUE eTimeoutError; /* LCB_ETIMEDOUT = 0x17 */
280
+ extern VALUE eConnectError; /* LCB_CONNECT_ERROR = 0x18 */
281
+ extern VALUE eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x19 */
282
+ extern VALUE eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x1a */
283
+ extern VALUE eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x1b */
284
+ extern VALUE eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
281
285
 
282
286
  void strip_key_prefix(struct bucket_st *bucket, VALUE key);
283
287
  VALUE cb_check_error(lcb_error_t rc, const char *msg, VALUE key);
@@ -152,8 +152,10 @@ cb_bucket_delete(int argc, VALUE *argv, VALUE self)
152
152
  if (exc != Qnil) {
153
153
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
154
154
  }
155
- if (bucket->exception != Qnil) {
156
- rb_exc_raise(bucket->exception);
155
+ exc = bucket->exception;
156
+ if (exc != Qnil) {
157
+ bucket->exception = Qnil;
158
+ rb_exc_raise(exc);
157
159
  }
158
160
  if (params.cmd.remove.num > 1) {
159
161
  return rv; /* return as a hash {key => true, ...} */
@@ -119,7 +119,7 @@ if try_compile(<<-SRC)
119
119
  define("HAVE_STDARG_PROTOTYPES")
120
120
  end
121
121
 
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"
122
+ have_library("couchbase", "lcb_verify_compiler_setup", "libcouchbase/couchbase.h") or abort "You should install libcouchbase >= 2.0.0beta3. See http://www.couchbase.com/develop/ for more details"
123
123
  have_header("mach/mach_time.h")
124
124
  have_header("stdint.h") or abort "Failed to locate stdint.h"
125
125
  have_header("sys/time.h")
@@ -42,16 +42,21 @@ get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_
42
42
  cas = ULL2NUM(resp->v.v0.cas);
43
43
  val = Qnil;
44
44
  if (resp->v.v0.nbytes != 0) {
45
- val = decode_value(STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes),
46
- resp->v.v0.flags, ctx->force_format);
47
- if (val == Qundef) {
45
+ VALUE raw = STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes);
46
+ val = decode_value(raw, resp->v.v0.flags, ctx->force_format);
47
+ if (rb_obj_is_kind_of(val, rb_eStandardError)) {
48
+ VALUE exc_str = rb_funcall(val, id_to_s, 0);
49
+ VALUE msg = rb_funcall(rb_mKernel, id_sprintf, 3,
50
+ rb_str_new2("unable to convert value for key '%s': %s"), key, exc_str);
48
51
  if (ctx->exception != Qnil) {
49
52
  cb_gc_unprotect(bucket, ctx->exception);
50
53
  }
51
- ctx->exception = rb_exc_new2(eValueFormatError, "unable to convert value");
54
+ ctx->exception = rb_exc_new3(eValueFormatError, msg);
52
55
  rb_ivar_set(ctx->exception, id_iv_operation, sym_get);
53
56
  rb_ivar_set(ctx->exception, id_iv_key, key);
57
+ rb_ivar_set(ctx->exception, id_iv_inner_exception, val);
54
58
  cb_gc_protect(bucket, ctx->exception);
59
+ val = raw;
55
60
  }
56
61
  } else if (flags_get_format(resp->v.v0.flags) == sym_plain) {
57
62
  val = STR_NEW_CSTR("");
@@ -275,8 +280,10 @@ cb_bucket_get(int argc, VALUE *argv, VALUE self)
275
280
  cb_gc_unprotect(bucket, exc);
276
281
  rb_exc_raise(exc);
277
282
  }
278
- if (bucket->exception != Qnil) {
279
- rb_exc_raise(bucket->exception);
283
+ exc = bucket->exception;
284
+ if (exc != Qnil) {
285
+ bucket->exception = Qnil;
286
+ rb_exc_raise(exc);
280
287
  }
281
288
  if (params.cmd.get.gat || params.cmd.get.assemble_hash ||
282
289
  (params.cmd.get.extended && (params.cmd.get.num > 1 || params.cmd.get.array))) {
@@ -160,8 +160,10 @@ cb_bucket_observe(int argc, VALUE *argv, VALUE self)
160
160
  cb_gc_unprotect(bucket, exc);
161
161
  rb_exc_raise(exc);
162
162
  }
163
- if (bucket->exception != Qnil) {
164
- rb_exc_raise(bucket->exception);
163
+ exc = bucket->exception;
164
+ if (exc != Qnil) {
165
+ bucket->exception = Qnil;
166
+ rb_exc_raise(exc);
165
167
  }
166
168
  if (params.cmd.observe.num > 1 || params.cmd.observe.array) {
167
169
  return rv; /* return as a hash {key => {}, ...} */
@@ -157,8 +157,10 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
157
157
  cb_gc_unprotect(bucket, exc);
158
158
  rb_exc_raise(exc);
159
159
  }
160
- if (bucket->exception != Qnil) {
161
- rb_exc_raise(bucket->exception);
160
+ exc = bucket->exception;
161
+ if (exc != Qnil) {
162
+ bucket->exception = Qnil;
163
+ rb_exc_raise(exc);
162
164
  }
163
165
  return rv;
164
166
  }
@@ -161,8 +161,10 @@ cb_bucket_store(lcb_storage_t cmd, int argc, VALUE *argv, VALUE self)
161
161
  cb_gc_unprotect(bucket, exc);
162
162
  rb_exc_raise(exc);
163
163
  }
164
- if (bucket->exception != Qnil) {
165
- rb_exc_raise(bucket->exception);
164
+ exc = bucket->exception;
165
+ if (exc != Qnil) {
166
+ bucket->exception = Qnil;
167
+ rb_exc_raise(exc);
166
168
  }
167
169
  if (RTEST(obs)) {
168
170
  cb_gc_unprotect(bucket, obs);
@@ -174,8 +174,10 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
174
174
  if (exc != Qnil) {
175
175
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
176
176
  }
177
- if (bucket->exception != Qnil) {
178
- rb_exc_raise(bucket->exception);
177
+ exc = bucket->exception;
178
+ if (exc != Qnil) {
179
+ bucket->exception = Qnil;
180
+ rb_exc_raise(exc);
179
181
  }
180
182
  if (params.cmd.touch.num > 1) {
181
183
  return rv; /* return as a hash {key => true, ...} */
@@ -164,8 +164,10 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
164
164
  if (exc != Qnil) {
165
165
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
166
166
  }
167
- if (bucket->exception != Qnil) {
168
- rb_exc_raise(bucket->exception);
167
+ exc = bucket->exception;
168
+ if (exc != Qnil) {
169
+ bucket->exception = Qnil;
170
+ rb_exc_raise(exc);
169
171
  }
170
172
  if (params.cmd.unlock.num > 1) {
171
173
  return rv; /* return as a hash {key => true, ...} */
@@ -77,7 +77,8 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
77
77
  VALUE klass, exc, str;
78
78
  char buf[300];
79
79
 
80
- if (rc == LCB_SUCCESS || rc == LCB_AUTH_CONTINUE) {
80
+ if ((rc == LCB_SUCCESS && (status == 0 || status / 100 == 2)) ||
81
+ rc == LCB_AUTH_CONTINUE) {
81
82
  return Qnil;
82
83
  }
83
84
  switch (rc) {
@@ -114,8 +115,11 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
114
115
  case LCB_KEY_ENOENT:
115
116
  klass = eNotFoundError;
116
117
  break;
117
- case LCB_LIBEVENT_ERROR:
118
- klass = eLibeventError;
118
+ case LCB_DLOPEN_FAILED:
119
+ klass = eDlopenFailedError;
120
+ break;
121
+ case LCB_DLSYM_FAILED:
122
+ klass = eDlsymFailedError;
119
123
  break;
120
124
  case LCB_NETWORK_ERROR:
121
125
  klass = eNetworkError;
@@ -170,6 +174,7 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
170
174
  }
171
175
  if (status > 0) {
172
176
  const char *reason = NULL;
177
+ klass = eHTTPError;
173
178
  snprintf(buf, 300, "status=\"%d\"", status);
174
179
  rb_str_buf_cat2(str, buf);
175
180
  switch (status) {
@@ -367,9 +372,10 @@ do_decode(VALUE *args)
367
372
  }
368
373
 
369
374
  static VALUE
370
- coding_failed(void)
375
+ coding_failed(VALUE unused, VALUE exc)
371
376
  {
372
- return Qundef;
377
+ (void)unused;
378
+ return exc;
373
379
  }
374
380
 
375
381
  VALUE
@@ -379,13 +385,8 @@ encode_value(VALUE val, uint32_t flags)
379
385
 
380
386
  args[0] = val;
381
387
  args[1] = (VALUE)flags;
382
- /* FIXME re-raise proper exception */
383
388
  blob = rb_rescue(do_encode, (VALUE)args, coding_failed, 0);
384
- /* it must be bytestring after all */
385
- if (TYPE(blob) != T_STRING) {
386
- return Qundef;
387
- }
388
- return blob;
389
+ return blob; /* bytestring or exception object */
389
390
  }
390
391
 
391
392
  VALUE
@@ -401,7 +402,7 @@ decode_value(VALUE blob, uint32_t flags, VALUE force_format)
401
402
  args[1] = (VALUE)flags;
402
403
  args[2] = (VALUE)force_format;
403
404
  val = rb_rescue(do_decode, (VALUE)args, coding_failed, 0);
404
- return val;
405
+ return val; /* the value or exception object */
405
406
  }
406
407
 
407
408
  void
@@ -137,8 +137,10 @@ cb_bucket_version(int argc, VALUE *argv, VALUE self)
137
137
  cb_gc_unprotect(bucket, exc);
138
138
  rb_exc_raise(exc);
139
139
  }
140
- if (bucket->exception != Qnil) {
141
- rb_exc_raise(bucket->exception);
140
+ exc = bucket->exception;
141
+ if (exc != Qnil) {
142
+ bucket->exception = Qnil;
143
+ rb_exc_raise(exc);
142
144
  }
143
145
  return rv;
144
146
  }
@@ -16,7 +16,7 @@ module ActionDispatch
16
16
  # Or remove this file and add following line to your `config/application.rb`:
17
17
  #
18
18
  # require 'action_dispatch/middleware/session/couchbase_store'
19
- # config.session_storage = :couchbase_store
19
+ # config.session_store :couchbase_store
20
20
  #
21
21
  # You can also pass additional options:
22
22
  #
@@ -25,7 +25,7 @@ module ActionDispatch
25
25
  # :expire_after => 5.minutes,
26
26
  # :couchbase => {:bucket => "sessions", :default_format => :marshal}
27
27
  # }
28
- # config.session_storage = :couchbase_store, session_options
28
+ # config.session_store :couchbase_store, session_options
29
29
  #
30
30
  # By default sessions will be serialized to JSON, to allow analyse them
31
31
  # using Map/Reduce.
@@ -106,6 +106,9 @@ module Couchbase
106
106
  req.on_body do |body|
107
107
  res = MultiJson.load(body.value)
108
108
  res["rows"].each do |obj|
109
+ if obj['doc']
110
+ obj['doc']['value'] = obj['doc'].delete('json')
111
+ end
109
112
  doc = ViewRow.wrap(self, obj)
110
113
  key = doc.id.sub(/^_design\//, '')
111
114
  next if self.environment == :production && key =~ /dev_/
@@ -117,17 +120,6 @@ module Couchbase
117
120
  async? ? nil : docmap
118
121
  end
119
122
 
120
- # Fetch all documents from the bucket.
121
- #
122
- # @since 1.2.0
123
- #
124
- # @param [Hash] params Params for Couchbase +/_all_docs+ query
125
- #
126
- # @return [Couchbase::View] View object
127
- def all_docs(params = {})
128
- View.new(self, "_all_docs", params)
129
- end
130
-
131
123
  # Update or create design doc with supplied views
132
124
  #
133
125
  # @since 1.2.0
@@ -17,5 +17,5 @@
17
17
 
18
18
  # Couchbase ruby client
19
19
  module Couchbase
20
- VERSION = "1.2.0.z.beta3"
20
+ VERSION = "1.2.0.z.beta4"
21
21
  end
@@ -15,6 +15,8 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
+ require 'base64'
19
+
18
20
  module Couchbase
19
21
 
20
22
  module Error
@@ -50,7 +52,7 @@ module Couchbase
50
52
  def initialize(bucket, endpoint, params = {})
51
53
  @bucket = bucket
52
54
  @endpoint = endpoint
53
- @params = params
55
+ @params = {:connection_timeout => 75_000}.merge(params)
54
56
  @wrapper_class = params.delete(:wrapper_class) || ViewRow
55
57
  unless @wrapper_class.respond_to?(:wrap)
56
58
  raise ArgumentError, "wrapper class should reposond to :wrap, check the options"
@@ -142,8 +144,14 @@ module Couchbase
142
144
  # the document and store them in {ViewRow#meta} hash.
143
145
  #
144
146
  # @param [Hash] params parameters for Couchbase query.
145
- # @option params [true, false] :include_docs (false) Include the full
146
- # content of the documents in the return.
147
+ # @option params [true, false] :include_docs (false) Include the
148
+ # full content of the documents in the return. Note that the document
149
+ # is fetched from the in memory cache where it may have been changed
150
+ # or even deleted. See also +:quiet+ parameter below to control error
151
+ # reporting during fetch.
152
+ # @option params [true, false] :quiet (true) Do not raise error if
153
+ # associated document not found in the memory. If the parameter +true+
154
+ # will use +nil+ value instead.
147
155
  # @option params [true, false] :descending (false) Return the documents
148
156
  # in descending by key order
149
157
  # @option params [String, Fixnum, Hash, Array] :key Return only
@@ -175,7 +183,7 @@ module Couchbase
175
183
  # response stream.
176
184
  # :stop:: Stop immediately when an error condition occurs. No
177
185
  # further view information will be returned.
178
- # @option params [Fixnum] :connection_timeout (60000) Timeout before the
186
+ # @option params [Fixnum] :connection_timeout (75000) Timeout before the
179
187
  # view request is dropped (milliseconds)
180
188
  # @option params [true, false] :reduce (true) Use the reduction function
181
189
  # @option params [true, false] :group (false) Group the results using
@@ -236,6 +244,11 @@ module Couchbase
236
244
  body = MultiJson.dump(body) unless body.is_a?(String)
237
245
  options.update(:body => body, :method => params.delete(:method) || :post)
238
246
  end
247
+ include_docs = params.delete(:include_docs)
248
+ quiet = true
249
+ if params.has_key?(:quiet)
250
+ quiet = params.delete(:quiet)
251
+ end
239
252
  path = Utils.build_query(@endpoint, params)
240
253
  request = @bucket.make_http_request(path, options)
241
254
  res = []
@@ -260,6 +273,17 @@ module Couchbase
260
273
  raise Error::View.new(from, reason)
261
274
  end
262
275
  else
276
+ if include_docs
277
+ val, flags, cas = @bucket.get(obj['id'], :extended => true, :quiet => quiet)
278
+ obj['doc'] = {
279
+ 'value' => val,
280
+ 'meta' => {
281
+ 'id' => obj['id'],
282
+ 'flags' => flags,
283
+ 'cas' => cas
284
+ }
285
+ }
286
+ end
263
287
  if block_given?
264
288
  yield @wrapper_class.wrap(@bucket, obj)
265
289
  else
@@ -115,7 +115,7 @@ module Couchbase
115
115
  @value = data['value']
116
116
  if data['doc']
117
117
  @meta = data['doc']['meta']
118
- @doc = data['doc']['json']
118
+ @doc = data['doc']['value']
119
119
  end
120
120
  @id = data['id'] || @meta && @meta['id']
121
121
  @views = []
@@ -24,6 +24,16 @@ if MultiJson.respond_to?(:engine)
24
24
  else
25
25
  multi_json_engine = MultiJson.send(:adapter)
26
26
  end
27
+
28
+ # Patch for MultiJson versions < 1.3.3
29
+ require 'multi_json/version'
30
+ if Gem::Version.new(MultiJson::VERSION) < Gem::Version.new('1.3.3')
31
+ class << MultiJson
32
+ alias :dump :encode
33
+ alias :load :decode
34
+ end
35
+ end
36
+
27
37
  if multi_json_engine.name =~ /JsonGem$/
28
38
  class << multi_json_engine
29
39
  alias _load_object load
@@ -36,12 +46,3 @@ if multi_json_engine.name =~ /JsonGem$/
36
46
  end
37
47
  end
38
48
  end
39
-
40
- # Patch for MultiJson versions < 1.3.3
41
- if MultiJson.respond_to?(:decode) && MultiJson.respond_to?(:encode) &&
42
- !MultiJson.respond_to?(:load) && !MultiJson.respond_to?(:dump)
43
- class << MultiJson
44
- alias :dump :encode
45
- alias :load :decode
46
- end
47
- end
@@ -42,7 +42,8 @@ module Rack
42
42
  attr_reader :mutex, :pool
43
43
 
44
44
  DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge(
45
- :couchbase => {:default_format => :document, :key_prefix => 'rack:session:'})
45
+ :couchbase => {:quiet => true, :default_format => :document,
46
+ :key_prefix => 'rack:session:'})
46
47
 
47
48
  def initialize(app, options = {})
48
49
  # Support old :expires option
@@ -75,7 +76,7 @@ module Rack
75
76
 
76
77
  def set_session(env, session_id, new_session, options)
77
78
  with_lock(env, false) do
78
- @pool.set session_id, new_session, options
79
+ @pool.set(session_id, new_session, options)
79
80
  session_id
80
81
  end
81
82
  end
@@ -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.0beta2_1_gf60b9fe"
87
+ recipe = MiniPortile.new "libcouchbase", "2.0.0beta3"
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",
@@ -71,7 +71,6 @@ class TestTouch < MiniTest::Unit::TestCase
71
71
  end
72
72
  ret = connection.unlock(uniq_id(1) => info[uniq_id(1)][2],
73
73
  uniq_id(2) => info[uniq_id(2)][2])
74
- puts ret.inspect
75
74
  assert ret[uniq_id(1)]
76
75
  assert ret[uniq_id(2)]
77
76
  connection.set(uniq_id(1), "bar")
@@ -19,8 +19,40 @@ require File.join(File.dirname(__FILE__), 'setup')
19
19
 
20
20
  class TestUtils < MiniTest::Unit::TestCase
21
21
 
22
+ def setup
23
+ @mock = start_mock
24
+ end
25
+
26
+ def teardown
27
+ stop_mock(@mock)
28
+ end
29
+
22
30
  def test_complex_startkey
23
31
  assert_equal "all_docs?startkey=%5B%22Deadmau5%22%2C%22%22%5D", Couchbase::Utils.build_query("all_docs", :startkey => ["Deadmau5", ""])
24
32
  end
25
33
 
34
+ def test_it_provides_enough_info_with_value_error
35
+ class << MultiJson
36
+ alias dump_good dump
37
+ def dump(obj)
38
+ raise ArgumentError, "cannot accept your object"
39
+ end
40
+ end
41
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
42
+ assert_raises(Couchbase::Error::ValueFormat) do
43
+ connection.set(uniq_id, "foo")
44
+ end
45
+ begin
46
+ connection.set(uniq_id, "foo")
47
+ rescue Couchbase::Error::ValueFormat => ex
48
+ assert_match /cannot accept your object/, ex.to_s
49
+ assert_instance_of ArgumentError, ex.inner_exception
50
+ end
51
+ ensure
52
+ class << MultiJson
53
+ undef dump
54
+ alias dump dump_good
55
+ end
56
+ end
57
+
26
58
  end
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.beta3
4
+ version: 1.2.0.z.beta4
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-10-16 00:00:00.000000000 Z
12
+ date: 2012-11-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yaji
@@ -215,6 +215,7 @@ files:
215
215
  - Gemfile
216
216
  - HISTORY.markdown
217
217
  - LICENSE
218
+ - Makefile
218
219
  - README.markdown
219
220
  - Rakefile
220
221
  - couchbase.gemspec
@@ -294,7 +295,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
294
295
  version: '0'
295
296
  segments:
296
297
  - 0
297
- hash: -2344661928388476453
298
+ hash: 1903080247241788551
298
299
  required_rubygems_version: !ruby/object:Gem::Requirement
299
300
  none: false
300
301
  requirements:
@@ -307,4 +308,25 @@ rubygems_version: 1.8.23
307
308
  signing_key:
308
309
  specification_version: 3
309
310
  summary: Couchbase ruby driver
310
- test_files: []
311
+ test_files:
312
+ - test/profile/.gitignore
313
+ - test/profile/Gemfile
314
+ - test/profile/benchmark.rb
315
+ - test/setup.rb
316
+ - test/test_arithmetic.rb
317
+ - test/test_async.rb
318
+ - test/test_bucket.rb
319
+ - test/test_cas.rb
320
+ - test/test_couchbase.rb
321
+ - test/test_couchbase_rails_cache_store.rb
322
+ - test/test_delete.rb
323
+ - test/test_errors.rb
324
+ - test/test_format.rb
325
+ - test/test_get.rb
326
+ - test/test_stats.rb
327
+ - test/test_store.rb
328
+ - test/test_timer.rb
329
+ - test/test_touch.rb
330
+ - test/test_unlock.rb
331
+ - test/test_utils.rb
332
+ - test/test_version.rb