couchbase-jruby-client 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.jrubyrc +722 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +203 -0
  7. data/README.md +349 -0
  8. data/Rakefile +10 -0
  9. data/couchbase-jruby-client.gemspec +31 -0
  10. data/lib/couchbase/async/callback.rb +19 -0
  11. data/lib/couchbase/async/queue.rb +26 -0
  12. data/lib/couchbase/async.rb +140 -0
  13. data/lib/couchbase/bucket.rb +556 -0
  14. data/lib/couchbase/cluster.rb +105 -0
  15. data/lib/couchbase/constants.rb +12 -0
  16. data/lib/couchbase/design_doc.rb +61 -0
  17. data/lib/couchbase/error.rb +43 -0
  18. data/lib/couchbase/jruby/couchbase_client.rb +22 -0
  19. data/lib/couchbase/jruby/future.rb +8 -0
  20. data/lib/couchbase/operations/arithmetic.rb +301 -0
  21. data/lib/couchbase/operations/delete.rb +104 -0
  22. data/lib/couchbase/operations/design_docs.rb +99 -0
  23. data/lib/couchbase/operations/get.rb +282 -0
  24. data/lib/couchbase/operations/stats.rb +26 -0
  25. data/lib/couchbase/operations/store.rb +461 -0
  26. data/lib/couchbase/operations/touch.rb +136 -0
  27. data/lib/couchbase/operations/unlock.rb +192 -0
  28. data/lib/couchbase/operations/utils.rb +44 -0
  29. data/lib/couchbase/operations.rb +27 -0
  30. data/lib/couchbase/query.rb +73 -0
  31. data/lib/couchbase/result.rb +43 -0
  32. data/lib/couchbase/transcoder.rb +77 -0
  33. data/lib/couchbase/utils.rb +62 -0
  34. data/lib/couchbase/version.rb +3 -0
  35. data/lib/couchbase/view.rb +367 -0
  36. data/lib/couchbase/view_row.rb +193 -0
  37. data/lib/couchbase.rb +157 -0
  38. data/lib/jars/commons-codec-1.5.jar +0 -0
  39. data/lib/jars/couchbase-client-1.2.0-javadoc.jar +0 -0
  40. data/lib/jars/couchbase-client-1.2.0-sources.jar +0 -0
  41. data/lib/jars/couchbase-client-1.2.0.jar +0 -0
  42. data/lib/jars/httpcore-4.1.1.jar +0 -0
  43. data/lib/jars/httpcore-nio-4.1.1.jar +0 -0
  44. data/lib/jars/jettison-1.1.jar +0 -0
  45. data/lib/jars/netty-3.5.5.Final.jar +0 -0
  46. data/lib/jars/spymemcached-2.10.0-javadoc.jar +0 -0
  47. data/lib/jars/spymemcached-2.10.0-sources.jar +0 -0
  48. data/lib/jars/spymemcached-2.10.0.jar +0 -0
  49. data/test/profile/.gitignore +1 -0
  50. data/test/profile/.jrubyrc +722 -0
  51. data/test/profile/Gemfile +6 -0
  52. data/test/profile/benchmark.rb +168 -0
  53. data/test/profile/profile.rb +59 -0
  54. data/test/setup.rb +203 -0
  55. data/test/test_arithmetic.rb +177 -0
  56. data/test/test_async.rb +324 -0
  57. data/test/test_bucket.rb +213 -0
  58. data/test/test_cas.rb +79 -0
  59. data/test/test_couchbase.rb +29 -0
  60. data/test/test_couchbase_rails_cache_store.rb +341 -0
  61. data/test/test_delete.rb +125 -0
  62. data/test/test_design_docs.rb +72 -0
  63. data/test/test_errors.rb +82 -0
  64. data/test/test_format.rb +161 -0
  65. data/test/test_get.rb +417 -0
  66. data/test/test_query.rb +23 -0
  67. data/test/test_stats.rb +57 -0
  68. data/test/test_store.rb +213 -0
  69. data/test/test_timer.rb +43 -0
  70. data/test/test_touch.rb +97 -0
  71. data/test/test_unlock.rb +121 -0
  72. data/test/test_utils.rb +58 -0
  73. data/test/test_version.rb +53 -0
  74. data/test/test_view.rb +94 -0
  75. metadata +255 -0
@@ -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
@@ -0,0 +1,12 @@
1
+ module Couchbase
2
+ module Constants # :nodoc:
3
+ S_ID = 'id'.freeze
4
+ S_DOC = 'doc'.freeze
5
+ S_VALUE = 'value'.freeze
6
+ S_META = 'meta'.freeze
7
+ S_FLAGS = 'flags'.freeze
8
+ S_CAS = 'cas'.freeze
9
+ S_KEY = 'key'.freeze
10
+ S_IS_LAST = Object.new.freeze
11
+ end
12
+ end
@@ -0,0 +1,61 @@
1
+ module Couchbase
2
+ class DesignDoc
3
+
4
+ def initialize(bucket, doc)
5
+ @all_views = {}
6
+ @bucket = bucket
7
+ @name = doc.name
8
+ @views = doc.views
9
+ @spatial = doc.spatial_views
10
+ @views.each { |view| @all_views[view.name] = "#{@name}/_view/#{view.name}" }
11
+ @spatial.each { |view| @all_views[view.name] = "#{@name}/_spatial/#{view.name}" }
12
+ end
13
+
14
+ def method_missing(meth, *args)
15
+ if path = @all_views[meth.to_s]
16
+ View.new(@bucket, path, *args)
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def respond_to_missing?(meth, *args)
23
+ @all_views[meth.to_s] || super
24
+ end
25
+
26
+ # The list of views defined or empty array
27
+ #
28
+ # @since 1.2.1
29
+ #
30
+ # @return [Array<View>]
31
+ attr_accessor :views
32
+
33
+ # The list of spatial views defined or empty array
34
+ #
35
+ # @since 1.2.1
36
+ #
37
+ # @return [Array<View>]
38
+ attr_accessor :spatial
39
+
40
+ # Check if the document has views defines
41
+ #
42
+ # @since 1.2.1
43
+ #
44
+ # @see DesignDoc#views
45
+ #
46
+ # @return [true, false] +true+ if the document have views
47
+ def has_views?
48
+ !@views.empty?
49
+ end
50
+
51
+ def inspect
52
+ desc = "#<#{self.class.name}:#{self.object_id}"
53
+ [:@id, :@views, :@spatial].each do |iv|
54
+ desc << " #{iv}=#{instance_variable_get(iv).inspect}"
55
+ end
56
+ desc << ">"
57
+ desc
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+
2
+ module Couchbase
3
+ module Error
4
+ class Base < Exception
5
+ attr_accessor :cas, :error, :inner_exception, :key, :operation, :status
6
+
7
+ def to_s
8
+ if inner_exception
9
+ inner_exception.to_s
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+
16
+ class Connect < Base
17
+ end
18
+
19
+ class Auth < Base
20
+ end
21
+
22
+ class Connect < Base
23
+ end
24
+
25
+ class NotFound < Base
26
+ end
27
+
28
+ class Invalid < Base
29
+ end
30
+
31
+ class KeyExists < Base
32
+ end
33
+
34
+ class ValueFormat < Base
35
+ end
36
+
37
+ class TemporaryFail < Base
38
+ end
39
+
40
+ class NotStored < Base
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ module Couchbase
2
+ module Jruby
3
+ class CouchbaseClient < Java::ComCouchbaseClient::CouchbaseClient
4
+
5
+ # Futures
6
+ %w(add set append asyncCAS asyncDecr asyncGet asyncGetAndTouch asyncGetBulk
7
+ asyncGets asyncIncr delete flush prepend replace set touch).each do |op|
8
+ define_method(op) do |*|
9
+ super
10
+ end
11
+ end
12
+
13
+ def get(*)
14
+ super
15
+ end
16
+
17
+ VALUE_OPS = %w(
18
+
19
+ ).freeze
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module Couchbase
2
+ module Jruby
3
+ module Future
4
+
5
+
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,301 @@
1
+ module Couchbase::Operations
2
+ module Arithmetic
3
+
4
+ # Increment the value of an existing numeric key
5
+ #
6
+ # @since 1.0.0
7
+ #
8
+ # The increment methods allow you to increase a given stored integer
9
+ # value. These are the incremental equivalent of the decrement operations
10
+ # and work on the same basis; updating the value of a key if it can be
11
+ # parsed to an integer. The update operation occurs on the server and is
12
+ # provided at the protocol level. This simplifies what would otherwise be a
13
+ # two-stage get and set operation.
14
+ #
15
+ # @note that server values stored and transmitted as unsigned numbers,
16
+ # therefore if you try to store negative number and then increment or
17
+ # decrement it will cause overflow. (see "Integer overflow" example
18
+ # below)
19
+ #
20
+ # @overload incr(key, delta = 1, options = {})
21
+ # @param key [String, Symbol] Key used to reference the value.
22
+ # @param delta [Fixnum] Integer (up to 64 bits) value to increment
23
+ # @param options [Hash] Options for operation.
24
+ # @option options [true, false] :create (false) If set to +true+, it will
25
+ # initialize the key with zero value and zero flags (use +:initial+
26
+ # option to set another initial value). Note: it won't increment the
27
+ # missing value.
28
+ # @option options [Fixnum] :initial (0) Integer (up to 64 bits) value for
29
+ # missing key initialization. This option imply +:create+ option is
30
+ # +true+.
31
+ # @option options [Fixnum] :ttl (self.default_ttl) Expiry time for key.
32
+ # Values larger than 30*24*60*60 seconds (30 days) are interpreted as
33
+ # absolute times (from the epoch). This option ignored for existent
34
+ # keys.
35
+ # @option options [true, false] :extended (false) If set to +true+, the
36
+ # operation will return tuple +[value, cas]+, otherwise (by default) it
37
+ # returns just value.
38
+ #
39
+ # @yieldparam ret [Result] the result of operation in asynchronous mode
40
+ # (valid attributes: +error+, +operation+, +key+, +value+, +cas+).
41
+ #
42
+ # @return [Fixnum] the actual value of the key.
43
+ #
44
+ # @raise [Couchbase::Error::NotFound] if key is missing and +:create+
45
+ # option isn't +true+.
46
+ #
47
+ # @raise [Couchbase::Error::DeltaBadval] if the key contains non-numeric
48
+ # value
49
+ #
50
+ # @raise [Couchbase::Error::Connect] if connection closed (see {Bucket#reconnect})
51
+ #
52
+ # @raise [ArgumentError] when passing the block in synchronous mode
53
+ #
54
+ # @example Increment key by one
55
+ # c.incr("foo")
56
+ #
57
+ # @example Increment key by 50
58
+ # c.incr("foo", 50)
59
+ #
60
+ # @example Increment key by one <b>OR</b> initialize with zero
61
+ # c.incr("foo", :create => true) #=> will return old+1 or 0
62
+ #
63
+ # @example Increment key by one <b>OR</b> initialize with three
64
+ # c.incr("foo", 50, :initial => 3) #=> will return old+50 or 3
65
+ #
66
+ # @example Increment key and get its CAS value
67
+ # val, cas = c.incr("foo", :extended => true)
68
+ #
69
+ # @example Integer overflow
70
+ # c.set("foo", -100)
71
+ # c.get("foo") #=> -100
72
+ # c.incr("foo") #=> 18446744073709551517
73
+ #
74
+ # @example Asynchronous invocation
75
+ # c.run do
76
+ # c.incr("foo") do |ret|
77
+ # ret.operation #=> :increment
78
+ # ret.success? #=> true
79
+ # ret.key #=> "foo"
80
+ # ret.value
81
+ # ret.cas
82
+ # end
83
+ # end
84
+ #
85
+ def incr(*args)
86
+ sync_block_error if !async? && block_given?
87
+ do_arithmetic(:incr, *args)
88
+ end
89
+ alias_method :increment, :incr
90
+
91
+ # Decrement the value of an existing numeric key
92
+ #
93
+ # @since 1.0.0
94
+ #
95
+ # The decrement methods reduce the value of a given key if the
96
+ # corresponding value can be parsed to an integer value. These operations
97
+ # are provided at a protocol level to eliminate the need to get, update,
98
+ # and reset a simple integer value in the database. It supports the use of
99
+ # an explicit offset value that will be used to reduce the stored value in
100
+ # the database.
101
+ #
102
+ # @note that server values stored and transmitted as unsigned numbers,
103
+ # therefore if you try to decrement negative or zero key, you will always
104
+ # get zero.
105
+ #
106
+ # @overload decr(key, delta = 1, options = {})
107
+ # @param key [String, Symbol] Key used to reference the value.
108
+ # @param delta [Fixnum] Integer (up to 64 bits) value to decrement
109
+ # @param options [Hash] Options for operation.
110
+ # @option options [true, false] :create (false) If set to +true+, it will
111
+ # initialize the key with zero value and zero flags (use +:initial+
112
+ # option to set another initial value). Note: it won't decrement the
113
+ # missing value.
114
+ # @option options [Fixnum] :initial (0) Integer (up to 64 bits) value for
115
+ # missing key initialization. This option imply +:create+ option is
116
+ # +true+.
117
+ # @option options [Fixnum] :ttl (self.default_ttl) Expiry time for key.
118
+ # Values larger than 30*24*60*60 seconds (30 days) are interpreted as
119
+ # absolute times (from the epoch). This option ignored for existent
120
+ # keys.
121
+ # @option options [true, false] :extended (false) If set to +true+, the
122
+ # operation will return tuple +[value, cas]+, otherwise (by default) it
123
+ # returns just value.
124
+ #
125
+ # @yieldparam ret [Result] the result of operation in asynchronous mode
126
+ # (valid attributes: +error+, +operation+, +key+, +value+, +cas+).
127
+ #
128
+ # @return [Fixnum] the actual value of the key.
129
+ #
130
+ # @raise [Couchbase::Error::NotFound] if key is missing and +:create+
131
+ # option isn't +true+.
132
+ #
133
+ # @raise [Couchbase::Error::DeltaBadval] if the key contains non-numeric
134
+ # value
135
+ #
136
+ # @raise [Couchbase::Error::Connect] if connection closed (see {Bucket#reconnect})
137
+ #
138
+ # @raise [ArgumentError] when passing the block in synchronous mode
139
+ #
140
+ # @example Decrement key by one
141
+ # c.decr("foo")
142
+ #
143
+ # @example Decrement key by 50
144
+ # c.decr("foo", 50)
145
+ #
146
+ # @example Decrement key by one <b>OR</b> initialize with zero
147
+ # c.decr("foo", :create => true) #=> will return old-1 or 0
148
+ #
149
+ # @example Decrement key by one <b>OR</b> initialize with three
150
+ # c.decr("foo", 50, :initial => 3) #=> will return old-50 or 3
151
+ #
152
+ # @example Decrement key and get its CAS value
153
+ # val, cas = c.decr("foo", :extended => true)
154
+ #
155
+ # @example Decrementing zero
156
+ # c.set("foo", 0)
157
+ # c.decrement("foo", 100500) #=> 0
158
+ #
159
+ # @example Decrementing negative value
160
+ # c.set("foo", -100)
161
+ # c.decrement("foo", 100500) #=> 0
162
+ #
163
+ # @example Asynchronous invocation
164
+ # c.run do
165
+ # c.decr("foo") do |ret|
166
+ # ret.operation #=> :decrement
167
+ # ret.success? #=> true
168
+ # ret.key #=> "foo"
169
+ # ret.value
170
+ # ret.cas
171
+ # end
172
+ # end
173
+ #
174
+ def decr(*args)
175
+ sync_block_error if !async? && block_given?
176
+ do_arithmetic(:decr, *args)
177
+ end
178
+ alias_method :decrement, :decr
179
+
180
+ private
181
+
182
+ def do_arithmetic(op, *args)
183
+ key, delta, options = expand_arithmetic_args(args)
184
+
185
+ case key
186
+ when String, Symbol
187
+ single_arithmetic(op, key, delta, options)
188
+ when Array, Hash
189
+ multi_arithmetic(op, key, delta)
190
+ else
191
+ raise # something
192
+ end
193
+ end
194
+
195
+ def expand_arithmetic_args(args)
196
+ options = if args.size > 1 && args.last.respond_to?(:to_h)
197
+ args.pop
198
+ else
199
+ {}
200
+ end
201
+
202
+ delta = if args.size > 1 && args.last.respond_to?(:to_int)
203
+ args.pop
204
+ else
205
+ options[:delta] || 1
206
+ end
207
+
208
+ key = args.size == 1 ? args.first : args
209
+
210
+ [key, delta, options]
211
+ end
212
+
213
+ def single_arithmetic(op, key, delta, options = {})
214
+ if async?
215
+ java_async_arithmetic(op, key, delta)
216
+ else
217
+ result = java_arithmetic(op, key, delta)
218
+ set_default_arithmetic_or_raise(key, result, options)
219
+ end
220
+ end
221
+
222
+ def set_default_arithmetic_or_raise(key, result, options)
223
+ if result < 0
224
+ if options[:initial] || options[:create] || set_default_arithmetic_init?
225
+ value = if options[:initial]
226
+ options[:initial]
227
+ elsif options[:create]
228
+ 0
229
+ else
230
+ default_arithmetic_init_int
231
+ end
232
+
233
+ set(key, value, options) && value
234
+ else
235
+ not_found_error(true)
236
+ end
237
+ else
238
+ result
239
+ end
240
+ end
241
+
242
+ def set_default_arithmetic_init?
243
+ default_arithmetic_init == true ||
244
+ default_arithmetic_init.respond_to?(:to_int) &&
245
+ default_arithmetic_init > 0
246
+ end
247
+
248
+ def default_arithmetic_init_int
249
+ default_arithmetic_init == true ? 0 : default_arithmetic_init
250
+ end
251
+
252
+ def multi_arithmetic(op, keys, delta)
253
+ {}.tap do |results|
254
+ if keys.respond_to?(:each_pair)
255
+ keys.each_pair do |k, v|
256
+ results[k] = single_arithmetic(op, k, v)
257
+ end
258
+ else
259
+ keys.each do |k|
260
+ results[k] = single_arithmetic(op, k, delta)
261
+ end
262
+ end
263
+ end
264
+ end
265
+
266
+ def java_arithmetic(op, key, delta)
267
+ case op
268
+ when :incr
269
+ java_incr(key, delta)
270
+ when :decr
271
+ java_decr(key, delta)
272
+ end
273
+ end
274
+
275
+ def java_async_arithmetic(op, key, delta)
276
+ case op
277
+ when :incr
278
+ java_async_incr(key, delta)
279
+ when :decr
280
+ java_async_decr(key, delta)
281
+ end
282
+ end
283
+
284
+ def java_incr(key, delta)
285
+ client.incr(key, delta)
286
+ end
287
+
288
+ def java_async_incr(key, delta)
289
+ client.asyncIncr(key, delta)
290
+ end
291
+
292
+ def java_decr(key, delta)
293
+ client.decr(key, delta)
294
+ end
295
+
296
+ def java_async_decr(key, delta)
297
+ client.asyncDecr(key, delta)
298
+ end
299
+
300
+ end
301
+ end
@@ -0,0 +1,104 @@
1
+ module Couchbase::Operations
2
+ module Delete
3
+
4
+ # Delete the specified key
5
+ #
6
+ # @since 1.0.0
7
+ #
8
+ # @overload delete(key, options = {})
9
+ # @param key [String, Symbol] Key used to reference the value.
10
+ # @param options [Hash] Options for operation.
11
+ # @option options [true, false] :quiet (self.quiet) If set to +true+, the
12
+ # operation won't raise error for missing key, it will return +nil+.
13
+ # Otherwise it will raise error in synchronous mode. In asynchronous
14
+ # mode this option ignored.
15
+ # @option options [Fixnum] :cas The CAS value for an object. This value
16
+ # created on the server and is guaranteed to be unique for each value of
17
+ # a given key. This value is used to provide simple optimistic
18
+ # concurrency control when multiple clients or threads try to
19
+ # update/delete an item simultaneously.
20
+ #
21
+ # @raise [Couchbase::Error::Connect] if connection closed (see {Bucket#reconnect})
22
+ # @raise [ArgumentError] when passing the block in synchronous mode
23
+ # @raise [Couchbase::Error::KeyExists] on CAS mismatch
24
+ # @raise [Couchbase::Error::NotFound] if key is missing in verbose mode
25
+ #
26
+ # @return [true, false, Hash<String, Boolean>] the result of the
27
+ # operation
28
+ #
29
+ # @example Delete the key in quiet mode (default)
30
+ # c.set("foo", "bar")
31
+ # c.delete("foo") #=> true
32
+ # c.delete("foo") #=> false
33
+ #
34
+ # @example Delete the key verbosely
35
+ # c.set("foo", "bar")
36
+ # c.delete("foo", :quiet => false) #=> true
37
+ # c.delete("foo", :quiet => true) #=> nil (default behaviour)
38
+ # c.delete("foo", :quiet => false) #=> will raise Couchbase::Error::NotFound
39
+ #
40
+ # @example Delete the key with version check
41
+ # ver = c.set("foo", "bar") #=> 5992859822302167040
42
+ # c.delete("foo", :cas => 123456) #=> will raise Couchbase::Error::KeyExists
43
+ # c.delete("foo", :cas => ver) #=> true
44
+ #
45
+ def delete(*args, &block)
46
+ sync_block_error if !async? && block_given?
47
+ key, options = expand_get_args(args)
48
+ key, cas = delete_args_parser(key)
49
+
50
+ if key.respond_to?(:to_ary)
51
+ delete_multi(key, options)
52
+ else
53
+ delete_single(key, cas, options, &block)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def delete_args_parser(args)
60
+ if args.respond_to?(:to_str)
61
+ [args, nil]
62
+ else
63
+ cas = if args.size > 1 &&
64
+ args.last.respond_to?(:to_int)
65
+ args.pop
66
+ else
67
+ nil
68
+ end
69
+
70
+ key = args.size == 1 ? args.first : args
71
+
72
+ [key, cas]
73
+ end
74
+ end
75
+
76
+ def delete_single(key, cas, options, &block)
77
+ if async?
78
+ java_async_delete(key, &block)
79
+ else
80
+ cas = java_delete(key)
81
+ not_found_error(!cas, options)
82
+ cas
83
+ end
84
+ end
85
+
86
+ def delete_multi(keys, options = {})
87
+ {}.tap do |results|
88
+ keys.each do |key|
89
+ results[key] = delete_single(key, nil, options)
90
+ end
91
+ end
92
+ end
93
+
94
+ def java_delete(key)
95
+ future = client.delete(key)
96
+ future_cas(future)
97
+ end
98
+
99
+ def java_async_delete(key, &block)
100
+ future = client.delete(key)
101
+ register_future(future, { op: :delete }, &block)
102
+ end
103
+ end
104
+ end