couchbase-jruby-client 0.1.0-java → 0.1.5-java
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.
- checksums.yaml +4 -4
- data/.jrubyrc +722 -0
- data/.ruby-version +1 -1
- data/README.md +12 -90
- data/couchbase-jruby-client.gemspec +6 -6
- data/lib/couchbase/async.rb +18 -0
- data/lib/couchbase/bucket.rb +90 -180
- data/lib/couchbase/constants.rb +17 -0
- data/lib/couchbase/design_doc.rb +83 -0
- data/lib/couchbase/error.rb +31 -0
- data/lib/couchbase/operations/arithmetic.rb +17 -0
- data/lib/couchbase/operations/delete.rb +17 -0
- data/lib/couchbase/operations/design_docs.rb +99 -0
- data/lib/couchbase/operations/get.rb +73 -67
- data/lib/couchbase/operations/stats.rb +28 -1
- data/lib/couchbase/operations/store.rb +114 -97
- data/lib/couchbase/operations/touch.rb +49 -19
- data/lib/couchbase/operations/unlock.rb +209 -0
- data/lib/couchbase/operations/utils.rb +22 -10
- data/lib/couchbase/operations.rb +21 -0
- data/lib/couchbase/query.rb +92 -0
- data/lib/couchbase/result.rb +18 -1
- data/lib/couchbase/transcoder.rb +36 -42
- data/lib/couchbase/version.rb +18 -1
- data/lib/couchbase/view.rb +30 -172
- data/lib/couchbase/view_row.rb +38 -98
- data/lib/couchbase.rb +74 -72
- data/test/profile/.jrubyrc +722 -0
- data/test/profile/Gemfile +5 -5
- data/test/profile/benchmark.rb +106 -124
- data/test/profile/profile.rb +59 -0
- data/test/setup.rb +10 -145
- data/test/test_arithmetic.rb +54 -77
- data/test/test_async.rb +74 -102
- data/test/test_bucket.rb +74 -60
- data/test/test_cas.rb +10 -23
- data/test/test_couchbase.rb +11 -3
- data/test/test_delete.rb +41 -43
- data/test/test_design_docs.rb +62 -0
- data/test/test_errors.rb +9 -18
- data/test/test_format.rb +21 -31
- data/test/test_get.rb +107 -151
- data/test/test_query.rb +23 -0
- data/test/test_stats.rb +9 -24
- data/test/test_store.rb +52 -65
- data/test/test_timer.rb +4 -12
- data/test/test_touch.rb +26 -33
- data/test/test_unlock.rb +47 -78
- data/test/test_utils.rb +2 -11
- data/test/test_version.rb +5 -14
- data/test/test_view.rb +87 -0
- metadata +27 -14
- data/lib/couchbase/jruby/couchbase_client.rb +0 -22
- data/lib/couchbase/jruby/future.rb +0 -8
@@ -1,6 +1,31 @@
|
|
1
|
+
# Author:: Mike Evans <mike@urlgonomics.com>
|
2
|
+
# Copyright:: 2013 Urlgonomics LLC.
|
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
|
+
|
1
18
|
module Couchbase::Operations
|
2
19
|
module Store
|
3
20
|
|
21
|
+
STORE_OP_METHODS = {
|
22
|
+
set: -> client, key, value, ttl, transcoder { client.set(key, ttl, value, transcoder) },
|
23
|
+
add: -> client, key, value, ttl, transcoder { client.add(key, ttl, value, transcoder) },
|
24
|
+
replace: -> client, key, value, ttl, transcoder { client.replace(key, ttl, value, transcoder) },
|
25
|
+
append: -> client, key, value, ttl, transcoder { client.append(key, value) },
|
26
|
+
prepend: -> client, key, value, ttl, transcoder { client.prepend(key, value) }
|
27
|
+
}.freeze
|
28
|
+
|
4
29
|
# Unconditionally store the object in the Couchbase
|
5
30
|
#
|
6
31
|
# @since 1.0.0
|
@@ -94,17 +119,23 @@ module Couchbase::Operations
|
|
94
119
|
# @example Ensure that the key will be persisted at least on the one node
|
95
120
|
# c.set("foo", "bar", :observe => {:persisted => 1})
|
96
121
|
#
|
97
|
-
def set(key, value = nil, options = {}
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
122
|
+
def set(key, value = nil, options = {})
|
123
|
+
if async?
|
124
|
+
if block_given?
|
125
|
+
async_set(key, value, options, &Proc.new)
|
126
|
+
else
|
127
|
+
async_set(key, value, options)
|
128
|
+
end
|
103
129
|
else
|
104
|
-
|
130
|
+
sync_block_error if block_given?
|
131
|
+
store_op(:set, key, value, options)
|
105
132
|
end
|
106
133
|
end
|
107
134
|
|
135
|
+
def async_set(key, value, options, &block)
|
136
|
+
async_store_op(:set, key, value, options, &block)
|
137
|
+
end
|
138
|
+
|
108
139
|
def []=(key, *args)
|
109
140
|
options = args.size > 1 ? args.shift : {}
|
110
141
|
value = args.pop
|
@@ -161,17 +192,23 @@ module Couchbase::Operations
|
|
161
192
|
# @example Ensure that the key will be persisted at least on the one node
|
162
193
|
# c.add("foo", "bar", :observe => {:persisted => 1})
|
163
194
|
#
|
164
|
-
def add(key, value = nil, options = {}
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
195
|
+
def add(key, value = nil, options = {})
|
196
|
+
if async?
|
197
|
+
if block_given?
|
198
|
+
async_add(key, value, options, &Proc.new)
|
199
|
+
else
|
200
|
+
async_add(key, value, options)
|
201
|
+
end
|
170
202
|
else
|
171
|
-
|
203
|
+
sync_block_error if block_given?
|
204
|
+
store_op(:add, key, value, options)
|
172
205
|
end
|
173
206
|
end
|
174
207
|
|
208
|
+
def async_add(key, value, options, &block)
|
209
|
+
async_store_op(:add, key, value, options, &block)
|
210
|
+
end
|
211
|
+
|
175
212
|
# Replace the existing object in the database
|
176
213
|
#
|
177
214
|
# @since 1.0.0
|
@@ -214,14 +251,22 @@ module Couchbase::Operations
|
|
214
251
|
# c.replace("foo", "bar", :observe => {:persisted => 1})
|
215
252
|
#
|
216
253
|
def replace(key, value, options = {})
|
217
|
-
|
218
|
-
|
219
|
-
|
254
|
+
if async?
|
255
|
+
if block_given?
|
256
|
+
async_replace(key, value, options, &Proc.new)
|
257
|
+
else
|
258
|
+
async_replace(key, value, options)
|
259
|
+
end
|
220
260
|
else
|
221
|
-
|
261
|
+
sync_block_error if block_given?
|
262
|
+
store_op(:replace, key, value, options)
|
222
263
|
end
|
223
264
|
end
|
224
265
|
|
266
|
+
def async_replace(key, value, options, &block)
|
267
|
+
async_store_op(:replace, key, value, options, &block)
|
268
|
+
end
|
269
|
+
|
225
270
|
# Append this object to the existing object
|
226
271
|
#
|
227
272
|
# @since 1.0.0
|
@@ -296,12 +341,8 @@ module Couchbase::Operations
|
|
296
341
|
# c.append("foo", "bar", :observe => {:persisted => 1})
|
297
342
|
#
|
298
343
|
def append(key, value)
|
299
|
-
sync_block_error if
|
300
|
-
|
301
|
-
cas
|
302
|
-
else
|
303
|
-
raise Couchbase::Error::NotFound.new
|
304
|
-
end
|
344
|
+
sync_block_error if block_given?
|
345
|
+
store_op(:append, key, value)
|
305
346
|
end
|
306
347
|
|
307
348
|
# Prepend this object to the existing object
|
@@ -356,111 +397,87 @@ module Couchbase::Operations
|
|
356
397
|
# @example Ensure that the key will be persisted at least on the one node
|
357
398
|
# c.prepend("foo", "bar", :observe => {:persisted => 1})
|
358
399
|
#
|
359
|
-
def prepend(
|
360
|
-
sync_block_error if
|
400
|
+
def prepend(key, value)
|
401
|
+
sync_block_error if block_given?
|
402
|
+
store_op(:prepend, key, value)
|
361
403
|
end
|
362
404
|
|
363
405
|
private
|
364
406
|
|
365
407
|
def store_args_parser(key, value, options)
|
366
408
|
key = key.to_str if key.respond_to?(:to_str)
|
367
|
-
ttl = options
|
368
|
-
|
369
|
-
op = case key
|
370
|
-
when String, Symbol
|
371
|
-
:single
|
372
|
-
when Hash
|
373
|
-
raise TypeError.new if !value.nil?
|
374
|
-
:multi
|
375
|
-
else
|
376
|
-
raise TypeError.new
|
377
|
-
end
|
409
|
+
ttl = options.delete(:ttl) || default_ttl
|
410
|
+
transcoder = @transcoders[options.delete(:format)] || self.transcoder
|
378
411
|
|
379
|
-
[
|
412
|
+
[key, value, ttl, transcoder]
|
380
413
|
end
|
381
414
|
|
382
|
-
def
|
383
|
-
|
384
|
-
|
415
|
+
def store_op(op, key, value, options = {})
|
416
|
+
key, value, ttl, transcoder = store_args_parser(key, value, options)
|
417
|
+
|
418
|
+
if key.is_a?(String) || key.is_a?(Symbol)
|
419
|
+
store_by_string(op, key.to_s, value, ttl, transcoder, options)
|
420
|
+
elsif key.is_a?(Hash)
|
421
|
+
store_by_hash(op, key, value)
|
385
422
|
else
|
386
|
-
|
387
|
-
if java_set_cas(key, value, ttl, options[:cas])
|
388
|
-
get(key, extended: true)[2]
|
389
|
-
else
|
390
|
-
raise Couchbase::Error::KeyExists.new
|
391
|
-
end
|
392
|
-
else
|
393
|
-
if cas = java_set(key, value, ttl)
|
394
|
-
cas
|
395
|
-
else
|
396
|
-
raise Couchbase::Error::KeyExists.new
|
397
|
-
end
|
398
|
-
end
|
423
|
+
fail TypeError.new
|
399
424
|
end
|
400
425
|
end
|
401
426
|
|
402
|
-
def
|
403
|
-
if
|
404
|
-
|
427
|
+
def store_by_string(op, key, value, ttl, transcoder, options)
|
428
|
+
if options[:cas] && op == :set
|
429
|
+
client_cas(key, value, ttl, options[:cas], transcoder)
|
405
430
|
else
|
406
|
-
|
431
|
+
future = client_store_op(op, key, value, ttl, transcoder)
|
432
|
+
if cas = future_cas(future)
|
407
433
|
cas
|
408
434
|
else
|
409
|
-
|
435
|
+
fail_store_op(op)
|
410
436
|
end
|
411
437
|
end
|
412
438
|
end
|
413
439
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
440
|
+
def store_by_hash(op, key, value)
|
441
|
+
fail TypeError.new if !value.nil?
|
442
|
+
multi_op(op, key)
|
443
|
+
end
|
444
|
+
|
445
|
+
def async_store_op(op, key, value, options, &block)
|
446
|
+
key, value, ttl, transcoder = store_args_parser(key, value, options)
|
447
|
+
future = client_store_op(op, key, value, ttl, transcoder)
|
448
|
+
register_future(future, { op: op }, &block)
|
421
449
|
end
|
422
450
|
|
423
|
-
def
|
451
|
+
def multi_op(op, keys)
|
424
452
|
{}.tap do |results|
|
425
453
|
keys.each_pair do |key, value|
|
426
|
-
results[key] =
|
454
|
+
results[key] = client.send(op, key, default_ttl, value)
|
427
455
|
end
|
428
456
|
end
|
429
457
|
end
|
430
458
|
|
431
|
-
def
|
432
|
-
|
433
|
-
future_cas(future)
|
459
|
+
def client_store_op(op, key, value, ttl, transcoder)
|
460
|
+
STORE_OP_METHODS[op].call(self.client, key, value, ttl, transcoder)
|
434
461
|
end
|
435
462
|
|
436
|
-
def
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
client.replace(key.to_s, dump(value))
|
444
|
-
else
|
445
|
-
client.replace(key.to_s, ttl, dump(value))
|
446
|
-
end
|
447
|
-
|
448
|
-
future_cas(future)
|
449
|
-
end
|
450
|
-
|
451
|
-
def java_append(key, value)
|
452
|
-
future = client.append(key.to_s, dump(value))
|
453
|
-
future_cas(future)
|
454
|
-
end
|
455
|
-
|
456
|
-
def java_set_cas(key, value, ttl, cas)
|
457
|
-
cas_response = client.cas(key.to_s, cas, ttl, dump(value))
|
458
|
-
cas_response.to_s == 'OK'
|
463
|
+
def client_cas(key, value, ttl, cas, transcoder)
|
464
|
+
cas_response = client.cas(key, cas, ttl, value, transcoder)
|
465
|
+
if cas_response.to_s == 'OK'
|
466
|
+
get(key, extended: true)[2]
|
467
|
+
else
|
468
|
+
raise Couchbase::Error::KeyExists.new
|
469
|
+
end
|
459
470
|
end
|
460
471
|
|
461
|
-
def
|
462
|
-
|
463
|
-
|
472
|
+
def fail_store_op(op)
|
473
|
+
case op
|
474
|
+
when :replace
|
475
|
+
fail Couchbase::Error::NotFound
|
476
|
+
when :append, :prepend
|
477
|
+
fail Couchbase::Error::NotStored
|
478
|
+
else
|
479
|
+
fail Couchbase::Error::KeyExists
|
480
|
+
end
|
464
481
|
end
|
465
482
|
|
466
483
|
end
|
@@ -1,3 +1,20 @@
|
|
1
|
+
# Author:: Mike Evans <mike@urlgonomics.com>
|
2
|
+
# Copyright:: 2013 Urlgonomics LLC.
|
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
|
+
|
1
18
|
module Couchbase::Operations
|
2
19
|
module Touch
|
3
20
|
|
@@ -64,22 +81,35 @@ module Couchbase::Operations
|
|
64
81
|
# @example Touch single value
|
65
82
|
# c.touch("foo" => 10) #=> true
|
66
83
|
#
|
67
|
-
def touch(*args
|
84
|
+
def touch(*args)
|
68
85
|
sync_block_error if !async? && block_given?
|
69
|
-
key, options = expand_touch_args(args)
|
86
|
+
key, ttl, options = expand_touch_args(args)
|
70
87
|
|
71
|
-
|
72
|
-
|
73
|
-
elsif key.respond_to?(:to_ary)
|
74
|
-
multi_touch_array(key, options)
|
75
|
-
else
|
88
|
+
case key
|
89
|
+
when String, Symbol
|
76
90
|
if async?
|
77
|
-
|
91
|
+
if block_given?
|
92
|
+
async_touch(key, ttl, &Proc.new)
|
93
|
+
else
|
94
|
+
async_touch(key, ttl)
|
95
|
+
end
|
78
96
|
else
|
79
|
-
success =
|
97
|
+
success = client_touch(key, ttl)
|
80
98
|
not_found_error(!success, options)
|
81
99
|
success
|
82
100
|
end
|
101
|
+
when Hash
|
102
|
+
multi_touch_hash(key, options)
|
103
|
+
when Array
|
104
|
+
multi_touch_array(key, options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def async_touch(key, ttl)
|
109
|
+
if block_given?
|
110
|
+
register_future(client.touch(key, ttl), { op: :touch }, &Proc.new)
|
111
|
+
else
|
112
|
+
client.touch(key, ttl)
|
83
113
|
end
|
84
114
|
end
|
85
115
|
|
@@ -87,16 +117,20 @@ module Couchbase::Operations
|
|
87
117
|
|
88
118
|
def expand_touch_args(args)
|
89
119
|
options = extract_options_hash(args)
|
90
|
-
options[:ttl]
|
91
|
-
|
120
|
+
ttl = options[:ttl] || if args.size > 1 && args.last.respond_to?(:to_int?)
|
121
|
+
args.pop
|
122
|
+
else
|
123
|
+
default_ttl
|
124
|
+
end
|
125
|
+
key = args.size > 1 ? args : args.pop
|
92
126
|
|
93
|
-
[key, options]
|
127
|
+
[key, ttl, options]
|
94
128
|
end
|
95
129
|
|
96
130
|
def multi_touch_hash(keys, options = {})
|
97
131
|
{}.tap do |results|
|
98
132
|
keys.each_pair do |key, ttl|
|
99
|
-
results[key] =
|
133
|
+
results[key] = client_touch(key, ttl)
|
100
134
|
end
|
101
135
|
end
|
102
136
|
end
|
@@ -106,18 +140,14 @@ module Couchbase::Operations
|
|
106
140
|
|
107
141
|
{}.tap do |results|
|
108
142
|
keys.each do |key|
|
109
|
-
results[key] =
|
143
|
+
results[key] = client_touch(key, ttl)
|
110
144
|
end
|
111
145
|
end
|
112
146
|
end
|
113
147
|
|
114
|
-
def
|
148
|
+
def client_touch(key, ttl, options = {})
|
115
149
|
client.touch(key, ttl).get
|
116
150
|
end
|
117
151
|
|
118
|
-
def java_async_touch(key, ttl, &block)
|
119
|
-
register_future(client.touch(key, ttl), { op: :touch }, &block)
|
120
|
-
end
|
121
|
-
|
122
152
|
end
|
123
153
|
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# Author:: Mike Evans <mike@urlgonomics.com>
|
2
|
+
# Copyright:: 2013 Urlgonomics LLC.
|
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::Operations
|
19
|
+
module Unlock
|
20
|
+
|
21
|
+
# Unlock key
|
22
|
+
#
|
23
|
+
# @since 1.2.0
|
24
|
+
#
|
25
|
+
# The +unlock+ method allow you to unlock key once locked by {Bucket#get}
|
26
|
+
# with +:lock+ option.
|
27
|
+
#
|
28
|
+
# @overload unlock(key, options = {})
|
29
|
+
# @param key [String, Symbol] Key used to reference the value.
|
30
|
+
# @param options [Hash] Options for operation.
|
31
|
+
# @option options [Fixnum] :cas The CAS value must match the current one
|
32
|
+
# from the storage.
|
33
|
+
# @option options [true, false] :quiet (self.quiet) If set to +true+, the
|
34
|
+
# operation won't raise error for missing key, it will return +nil+.
|
35
|
+
#
|
36
|
+
# @return [true, false] +true+ if the operation was successful and +false+
|
37
|
+
# otherwise.
|
38
|
+
#
|
39
|
+
# @raise [Couchbase::Error::Connect] if connection closed (see {Bucket#reconnect})
|
40
|
+
#
|
41
|
+
# @raise [ArgumentError] when passing the block in synchronous mode
|
42
|
+
#
|
43
|
+
# @raise [Couchbase::Error::NotFound] if key(s) not found in the storage
|
44
|
+
#
|
45
|
+
# @raise [Couchbase::Error::TemporaryFail] if either the key wasn't
|
46
|
+
# locked or given CAS value doesn't match to actual in the storage
|
47
|
+
#
|
48
|
+
# @example Unlock the single key
|
49
|
+
# val, _, cas = c.get("foo", :lock => true, :extended => true)
|
50
|
+
# c.unlock("foo", :cas => cas)
|
51
|
+
#
|
52
|
+
# @overload unlock(keys)
|
53
|
+
# @param keys [Hash] The Hash where keys represent the keys in the
|
54
|
+
# database, values -- the CAS for corresponding key.
|
55
|
+
#
|
56
|
+
# @yieldparam ret [Result] the result of operation for each key in
|
57
|
+
# asynchronous mode (valid attributes: +error+, +operation+, +key+).
|
58
|
+
#
|
59
|
+
# @return [Hash] Mapping keys to result of unlock operation (+true+ if the
|
60
|
+
# operation was successful and +false+ otherwise)
|
61
|
+
#
|
62
|
+
# @example Unlock several keys
|
63
|
+
# c.unlock("foo" => cas1, :bar => cas2) #=> {"foo" => true, "bar" => true}
|
64
|
+
#
|
65
|
+
# @example Unlock several values in async mode
|
66
|
+
# c.run do
|
67
|
+
# c.unlock("foo" => 10, :bar => 20) do |ret|
|
68
|
+
# ret.operation #=> :unlock
|
69
|
+
# ret.success? #=> true
|
70
|
+
# ret.key #=> "foo" and "bar" in separate calls
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
|
75
|
+
def unlock(key, options = {})
|
76
|
+
cas = options.respond_to?(:to_hash) ? options[:cas] : options
|
77
|
+
if client.unlock(key.to_s, cas)
|
78
|
+
true
|
79
|
+
else
|
80
|
+
raise Couchbase::Error::TemporaryFail.new
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def async_unlock(key, options = {})
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
__END__
|
92
|
+
|
93
|
+
/*
|
94
|
+
* Unlock key
|
95
|
+
*
|
96
|
+
* @since 1.2.0
|
97
|
+
*
|
98
|
+
* The +unlock+ method allow you to unlock key once locked by {Bucket#get}
|
99
|
+
* with +:lock+ option.
|
100
|
+
*
|
101
|
+
* @overload unlock(key, options = {})
|
102
|
+
* @param key [String, Symbol] Key used to reference the value.
|
103
|
+
* @param options [Hash] Options for operation.
|
104
|
+
* @option options [Fixnum] :cas The CAS value must match the current one
|
105
|
+
* from the storage.
|
106
|
+
* @option options [true, false] :quiet (self.quiet) If set to +true+, the
|
107
|
+
* operation won't raise error for missing key, it will return +nil+.
|
108
|
+
*
|
109
|
+
* @return [true, false] +true+ if the operation was successful and +false+
|
110
|
+
* otherwise.
|
111
|
+
*
|
112
|
+
* @raise [Couchbase::Error::Connect] if connection closed (see {Bucket#reconnect})
|
113
|
+
*
|
114
|
+
* @raise [ArgumentError] when passing the block in synchronous mode
|
115
|
+
*
|
116
|
+
* @raise [Couchbase::Error::NotFound] if key(s) not found in the storage
|
117
|
+
*
|
118
|
+
* @raise [Couchbase::Error::TemporaryFail] if either the key wasn't
|
119
|
+
* locked or given CAS value doesn't match to actual in the storage
|
120
|
+
*
|
121
|
+
* @example Unlock the single key
|
122
|
+
* val, _, cas = c.get("foo", :lock => true, :extended => true)
|
123
|
+
* c.unlock("foo", :cas => cas)
|
124
|
+
*
|
125
|
+
* @overload unlock(keys)
|
126
|
+
* @param keys [Hash] The Hash where keys represent the keys in the
|
127
|
+
* database, values -- the CAS for corresponding key.
|
128
|
+
*
|
129
|
+
* @yieldparam ret [Result] the result of operation for each key in
|
130
|
+
* asynchronous mode (valid attributes: +error+, +operation+, +key+).
|
131
|
+
*
|
132
|
+
* @return [Hash] Mapping keys to result of unlock operation (+true+ if the
|
133
|
+
* operation was successful and +false+ otherwise)
|
134
|
+
*
|
135
|
+
* @example Unlock several keys
|
136
|
+
* c.unlock("foo" => cas1, :bar => cas2) #=> {"foo" => true, "bar" => true}
|
137
|
+
*
|
138
|
+
* @example Unlock several values in async mode
|
139
|
+
* c.run do
|
140
|
+
* c.unlock("foo" => 10, :bar => 20) do |ret|
|
141
|
+
* ret.operation #=> :unlock
|
142
|
+
* ret.success? #=> true
|
143
|
+
* ret.key #=> "foo" and "bar" in separate calls
|
144
|
+
* end
|
145
|
+
* end
|
146
|
+
*
|
147
|
+
*/
|
148
|
+
VALUE
|
149
|
+
cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
|
150
|
+
{
|
151
|
+
struct cb_bucket_st *bucket = DATA_PTR(self);
|
152
|
+
struct cb_context_st *ctx;
|
153
|
+
VALUE rv, proc, exc;
|
154
|
+
lcb_error_t err;
|
155
|
+
struct cb_params_st params;
|
156
|
+
|
157
|
+
if (!cb_bucket_connected_bang(bucket, cb_sym_unlock)) {
|
158
|
+
return Qnil;
|
159
|
+
}
|
160
|
+
|
161
|
+
memset(¶ms, 0, sizeof(struct cb_params_st));
|
162
|
+
rb_scan_args(argc, argv, "0*&", ¶ms.args, &proc);
|
163
|
+
if (!bucket->async && proc != Qnil) {
|
164
|
+
rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
|
165
|
+
}
|
166
|
+
rb_funcall(params.args, cb_id_flatten_bang, 0);
|
167
|
+
params.type = cb_cmd_unlock;
|
168
|
+
params.bucket = bucket;
|
169
|
+
cb_params_build(¶ms);
|
170
|
+
ctx = cb_context_alloc_common(bucket, proc, params.cmd.unlock.num);
|
171
|
+
ctx->quiet = params.cmd.unlock.quiet;
|
172
|
+
err = lcb_unlock(bucket->handle, (const void *)ctx,
|
173
|
+
params.cmd.unlock.num, params.cmd.unlock.ptr);
|
174
|
+
cb_params_destroy(¶ms);
|
175
|
+
exc = cb_check_error(err, "failed to schedule unlock request", Qnil);
|
176
|
+
if (exc != Qnil) {
|
177
|
+
cb_context_free(ctx);
|
178
|
+
rb_exc_raise(exc);
|
179
|
+
}
|
180
|
+
bucket->nbytes += params.npayload;
|
181
|
+
if (bucket->async) {
|
182
|
+
cb_maybe_do_loop(bucket);
|
183
|
+
return Qnil;
|
184
|
+
} else {
|
185
|
+
if (ctx->nqueries > 0) {
|
186
|
+
/* we have some operations pending */
|
187
|
+
lcb_wait(bucket->handle);
|
188
|
+
}
|
189
|
+
exc = ctx->exception;
|
190
|
+
rv = ctx->rv;
|
191
|
+
cb_context_free(ctx);
|
192
|
+
if (exc != Qnil) {
|
193
|
+
rb_exc_raise(exc);
|
194
|
+
}
|
195
|
+
exc = bucket->exception;
|
196
|
+
if (exc != Qnil) {
|
197
|
+
bucket->exception = Qnil;
|
198
|
+
rb_exc_raise(exc);
|
199
|
+
}
|
200
|
+
if (params.cmd.unlock.num > 1) {
|
201
|
+
return rv; /* return as a hash {key => true, ...} */
|
202
|
+
} else {
|
203
|
+
VALUE vv = Qnil;
|
204
|
+
rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
|
205
|
+
return vv;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
@@ -1,3 +1,20 @@
|
|
1
|
+
# Author:: Mike Evans <mike@urlgonomics.com>
|
2
|
+
# Copyright:: 2013 Urlgonomics LLC.
|
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
|
+
|
1
18
|
module Couchbase::Operations
|
2
19
|
module Utils
|
3
20
|
|
@@ -26,23 +43,18 @@ module Couchbase::Operations
|
|
26
43
|
def not_found_error(error, options = {})
|
27
44
|
if error
|
28
45
|
if options.key?(:quiet)
|
29
|
-
raise Error::NotFound.new if !options[:quiet]
|
46
|
+
raise Couchbase::Error::NotFound.new if !options[:quiet]
|
30
47
|
elsif !quiet?
|
31
|
-
raise Error::NotFound.new
|
48
|
+
raise Couchbase::Error::NotFound.new
|
32
49
|
end
|
33
50
|
end
|
34
51
|
end
|
35
52
|
|
36
53
|
def future_cas(future)
|
37
54
|
future.get && future.getCas
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
transcoder.dump(obj)
|
42
|
-
end
|
43
|
-
|
44
|
-
def load(blob)
|
45
|
-
transcoder.load(blob)
|
55
|
+
rescue Java::JavaLang::UnsupportedOperationException
|
56
|
+
# TODO: don't return fake cas
|
57
|
+
1
|
46
58
|
end
|
47
59
|
|
48
60
|
end
|