couchbase-jruby-client 0.1.7-java → 0.1.8-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -59,45 +59,49 @@ module Couchbase::Operations
59
59
  # c.delete("foo", :cas => 123456) #=> will raise Couchbase::Error::KeyExists
60
60
  # c.delete("foo", :cas => ver) #=> true
61
61
  #
62
- def delete(*args, &block)
63
- sync_block_error if !async? && block_given?
64
- key, options = expand_get_args(args)
65
- key, cas = delete_args_parser(key)
62
+ def delete(*args)
63
+ key, cas, options = expand_delete_args(args)
66
64
 
67
65
  if key.respond_to?(:to_ary)
68
66
  delete_multi(key, options)
69
67
  else
70
- delete_single(key, cas, options, &block)
68
+ delete_single(key, cas, options)
71
69
  end
72
70
  end
73
71
 
72
+ def async_delete(*args, &block)
73
+ key, cas, options = expand_delete_args(args)
74
+
75
+ future = client.delete(key)
76
+ register_future(future, { op: :delete }, &block)
77
+ end
78
+
74
79
  private
75
80
 
76
- def delete_args_parser(args)
77
- if args.respond_to?(:to_str)
78
- [args, nil]
81
+ def expand_delete_args(args)
82
+ key, options = expand_get_args(args)
83
+
84
+ if key.respond_to?(:to_str)
85
+ [key, options[:cas], options]
79
86
  else
80
- cas = if args.size > 1 &&
81
- args.last.respond_to?(:to_int)
82
- args.pop
87
+ cas = if key.size > 1 &&
88
+ key.last.respond_to?(:to_int)
89
+ key.pop
83
90
  else
84
91
  nil
85
92
  end
86
93
 
87
- key = args.size == 1 ? args.first : args
94
+ key = key.size == 1 ? key.first : key
88
95
 
89
- [key, cas]
96
+ [key, cas, options]
90
97
  end
91
98
  end
92
99
 
93
- def delete_single(key, cas, options, &block)
94
- if async?
95
- java_async_delete(key, &block)
96
- else
97
- cas = java_delete(key)
98
- not_found_error(!cas, options)
99
- cas
100
- end
100
+ def delete_single(key, cas, options)
101
+ future = cas.nil? ? client.delete(key) : client.delete(key, cas)
102
+ cas = future_cas(future)
103
+ not_found_error(!cas, options)
104
+ cas
101
105
  end
102
106
 
103
107
  def delete_multi(keys, options = {})
@@ -107,15 +111,5 @@ module Couchbase::Operations
107
111
  end
108
112
  end
109
113
  end
110
-
111
- def java_delete(key)
112
- future = client.delete(key)
113
- future_cas(future)
114
- end
115
-
116
- def java_async_delete(key, &block)
117
- future = client.delete(key)
118
- register_future(future, { op: :delete }, &block)
119
- end
120
114
  end
121
115
  end
@@ -21,8 +21,9 @@ module Couchbase::Operations
21
21
  module Fetch
22
22
 
23
23
  def fetch(key, set_options = {}, &block)
24
- raise ArgumentError('Must pass a block to #fetch') unless block_given?
25
- get(key, :quiet => false)
24
+ fail ArgumentError 'Must pass a block to #fetch' unless block_given?
25
+
26
+ get(key, quiet: false)
26
27
  rescue Couchbase::Error::NotFound
27
28
  yield(block).tap {|value| set(key, value, set_options) }
28
29
  end
@@ -147,13 +147,7 @@ module Couchbase::Operations
147
147
  #
148
148
  def get(*args, &block)
149
149
  key, options = expand_get_args(args)
150
-
151
- if async?
152
- async_get(key, &block)
153
- else
154
- sync_block_error if block_given?
155
- get_key(key, options)
156
- end
150
+ get_key(key, options)
157
151
  end
158
152
 
159
153
  def [](key, options = {})
@@ -176,7 +170,9 @@ module Couchbase::Operations
176
170
  end
177
171
  end
178
172
 
179
- def async_get(key)
173
+ def async_get(key, &block)
174
+ fail ArgumentError, 'Must pass a block to #async_get' unless block_given?
175
+
180
176
  case key
181
177
  when String, Symbol
182
178
  meta = { op: :get, key: key }
@@ -187,7 +183,7 @@ module Couchbase::Operations
187
183
  when Hash
188
184
  # async_get_and_touch(key, options, &block)
189
185
  end
190
- register_future(future, meta, &Proc.new) if block_given?
186
+ register_future(future, meta, &block)
191
187
  end
192
188
 
193
189
  private
@@ -19,7 +19,6 @@ module Couchbase::Operations
19
19
  module Stats
20
20
 
21
21
  def stats(statname = nil)
22
- sync_block_error if !async? && block_given?
23
22
  stats = if statname.nil?
24
23
  client.getStats
25
24
  else
@@ -126,19 +126,10 @@ module Couchbase::Operations
126
126
  # c.set("foo", "bar", :observe => {:persisted => 1})
127
127
  #
128
128
  def set(key, value = nil, options = {})
129
- if async?
130
- if block_given?
131
- async_set(key, value, options, &Proc.new)
132
- else
133
- async_set(key, value, options)
134
- end
135
- else
136
- sync_block_error if block_given?
137
- store_op(:set, key, value, options)
138
- end
129
+ store_op(:set, key, value, options)
139
130
  end
140
131
 
141
- def async_set(key, value, options, &block)
132
+ def async_set(key, value, options = {}, &block)
142
133
  async_store_op(:set, key, value, options, &block)
143
134
  end
144
135
 
@@ -199,16 +190,7 @@ module Couchbase::Operations
199
190
  # c.add("foo", "bar", :observe => {:persisted => 1})
200
191
  #
201
192
  def add(key, value = nil, options = {})
202
- if async?
203
- if block_given?
204
- async_add(key, value, options, &Proc.new)
205
- else
206
- async_add(key, value, options)
207
- end
208
- else
209
- sync_block_error if block_given?
210
- store_op(:add, key, value, options)
211
- end
193
+ store_op(:add, key, value, options)
212
194
  end
213
195
 
214
196
  def async_add(key, value, options, &block)
@@ -257,16 +239,7 @@ module Couchbase::Operations
257
239
  # c.replace("foo", "bar", :observe => {:persisted => 1})
258
240
  #
259
241
  def replace(key, value, options = {})
260
- if async?
261
- if block_given?
262
- async_replace(key, value, options, &Proc.new)
263
- else
264
- async_replace(key, value, options)
265
- end
266
- else
267
- sync_block_error if block_given?
268
- store_op(:replace, key, value, options)
269
- end
242
+ store_op(:replace, key, value, options)
270
243
  end
271
244
 
272
245
  def async_replace(key, value, options, &block)
@@ -347,7 +320,6 @@ module Couchbase::Operations
347
320
  # c.append("foo", "bar", :observe => {:persisted => 1})
348
321
  #
349
322
  def append(key, value)
350
- sync_block_error if block_given?
351
323
  store_op(:append, key, value)
352
324
  end
353
325
 
@@ -404,7 +376,6 @@ module Couchbase::Operations
404
376
  # c.prepend("foo", "bar", :observe => {:persisted => 1})
405
377
  #
406
378
  def prepend(key, value)
407
- sync_block_error if block_given?
408
379
  store_op(:prepend, key, value)
409
380
  end
410
381
 
@@ -82,22 +82,13 @@ module Couchbase::Operations
82
82
  # c.touch("foo" => 10) #=> true
83
83
  #
84
84
  def touch(*args)
85
- sync_block_error if !async? && block_given?
86
85
  key, ttl, options = expand_touch_args(args)
87
86
 
88
87
  case key
89
88
  when String, Symbol
90
- if async?
91
- if block_given?
92
- async_touch(key, ttl, &Proc.new)
93
- else
94
- async_touch(key, ttl)
95
- end
96
- else
97
- success = client_touch(key, ttl)
98
- not_found_error(!success, options)
99
- success
100
- end
89
+ success = client_touch(key, ttl)
90
+ not_found_error(!success, options)
91
+ success
101
92
  when Hash
102
93
  multi_touch_hash(key, options)
103
94
  when Array
@@ -105,12 +96,8 @@ module Couchbase::Operations
105
96
  end
106
97
  end
107
98
 
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)
113
- end
99
+ def async_touch(key, ttl, &block)
100
+ register_future(client.touch(key, ttl), { op: :touch }, &block)
114
101
  end
115
102
 
116
103
  private
@@ -36,10 +36,6 @@ module Couchbase::Operations
36
36
  end
37
37
  end
38
38
 
39
- def sync_block_error
40
- raise ArgumentError, "synchronous mode doesn't support callbacks"
41
- end
42
-
43
39
  def not_found_error(error, options = {})
44
40
  if error
45
41
  if options.key?(:quiet)
@@ -36,9 +36,11 @@ module Couchbase
36
36
 
37
37
  MultiJson.load(data)
38
38
  rescue MultiJson::LoadError
39
- ::Marshal.load(data)
40
- rescue TypeError
41
- data
39
+ begin
40
+ ::Marshal.load(data)
41
+ rescue TypeError
42
+ data
43
+ end
42
44
  end
43
45
 
44
46
  def encode(o)
@@ -16,5 +16,5 @@
16
16
  #
17
17
 
18
18
  module Couchbase
19
- VERSION = '0.1.7'
19
+ VERSION = '0.1.8'
20
20
  end
@@ -294,19 +294,9 @@ module Couchbase
294
294
  request = @bucket.client.query(view, query.generate)
295
295
 
296
296
  if block_given?
297
- block = Proc.new
298
- request.each do |data|
299
- doc = @wrapper_class.wrap(@bucket, data)
300
- block.call(doc)
301
- end
302
- nil
297
+ fetch_block(request, Proc.new)
303
298
  else
304
- docs = request.to_a.map { |data|
305
- @wrapper_class.wrap(@bucket, data)
306
- }
307
- docs = ArrayWithTotalRows.new(docs)
308
- docs.total_rows = request.size
309
- docs
299
+ fetch_array(request)
310
300
  end
311
301
  end
312
302
 
@@ -344,6 +334,27 @@ module Couchbase
344
334
 
345
335
  private
346
336
 
337
+ def fetch_array(request)
338
+ docs = request.to_a.map { |data|
339
+ wrap_or_parse_data(data)
340
+ }
341
+ docs = ArrayWithTotalRows.new(docs)
342
+ docs.total_rows = request.size
343
+ docs
344
+ end
345
+
346
+ def fetch_block(request, block)
347
+ request.each do |data|
348
+ doc = wrap_or_parse_data(data)
349
+ block.call(doc)
350
+ end
351
+ nil
352
+ end
353
+
354
+ def wrap_or_parse_data(data)
355
+ @wrapper_class.wrap(@bucket, data)
356
+ end
357
+
347
358
  def send_error(*args)
348
359
  if @on_error
349
360
  @on_error.call(*args.take(2))
@@ -123,13 +123,14 @@ module Couchbase
123
123
  @bucket = bucket
124
124
  @data = data
125
125
  @key = data.key
126
- @value = data.value
127
- @id = data.id
128
126
  @last = false
129
127
 
130
128
  case data
131
129
  when ViewRowWithDocs, SpatialViewRowWithDocs
132
- @doc = data.document
130
+ @id = data.id
131
+ @doc = data.document
132
+ when ViewRowReduced
133
+ @value = MultiJson.load(data.value)
133
134
  when SpatialViewRowNoDocs, SpatialViewRowWithDocs
134
135
  @geometry = data.geometry
135
136
  @bbox = data.bbox
data/lib/couchbase.rb CHANGED
@@ -144,7 +144,7 @@ module Couchbase
144
144
  @connection_options[:bucket]
145
145
  when String
146
146
  path = URI.parse(@connection_options).path
147
- path[%r(^(/pools/([A-Za-z0-9_.-]+)(/buckets/([A-Za-z0-9_.-]+))?)?), 3] || "default"
147
+ path[%r(^(/pools/([A-Za-z0-9_.-]+)(/buckets/([A-Za-z0-9_.-]+))?)?), 3] || 'default'
148
148
  else
149
149
  'default'
150
150
  end
@@ -161,6 +161,7 @@ module Couchbase
161
161
  name = @connection_options && @connection_options[:bucket] || "default"
162
162
  @@buckets[name] = connection
163
163
  end
164
+ alias set_bucket bucket=
164
165
 
165
166
  def connected?
166
167
  !!@@buckets.empty?
@@ -169,8 +170,9 @@ module Couchbase
169
170
  def disconnect
170
171
  @@buckets.each_key do |name|
171
172
  bucket = @@buckets.delete(name)
172
- bucket.disconnect if connected?
173
+ bucket.disconnect
173
174
  end
175
+ @@buckets = ThreadSafe::Cache.new
174
176
  end
175
177
  end
176
178
  end
@@ -0,0 +1,6 @@
1
+ desc 'Run benchmarks and compare them to memcached and dalli gems'
2
+ task :benchmark => [:clean, :compile] do
3
+ cd File.expand_path(File.join(__FILE__, '..', '..', 'test', 'profile')) do
4
+ sh "bundle install && bundle exec ruby benchmark.rb | tee benchmark-#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}.log"
5
+ end
6
+ end
data/tasks/test.rake ADDED
@@ -0,0 +1,34 @@
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
+ require 'rake/testtask'
19
+ require 'rake/clean'
20
+
21
+ rule 'test/CouchbaseMock.jar' do |task|
22
+ jar_path = "0.6-SNAPSHOT/CouchbaseMock-0.6-20130903.160518-3.jar"
23
+ sh %{wget -q -O test/CouchbaseMock.jar http://files.couchbase.com/maven2/org/couchbase/mock/CouchbaseMock/#{jar_path}}
24
+ end
25
+
26
+ CLOBBER << 'test/CouchbaseMock.jar'
27
+
28
+ Rake::TestTask.new(:test) do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/test_*.rb'
31
+ test.verbose = true
32
+ end
33
+
34
+ Rake::Task['test'].prerequisites.unshift('test/CouchbaseMock.jar')
data/tasks/util.rake ADDED
@@ -0,0 +1,21 @@
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
+ desc 'Start an irb session and load the library.'
19
+ task :console do
20
+ exec "irb -I lib -rcouchbase"
21
+ end
data/test/mock.rb ADDED
@@ -0,0 +1,85 @@
1
+ class CouchbaseServer
2
+ attr_accessor :host, :port, :num_nodes, :buckets_spec
3
+
4
+ def real?
5
+ true
6
+ end
7
+
8
+ def initialize(params = {})
9
+ @host, @port = ENV['COUCHBASE_SERVER'].split(':')
10
+ @port = @port.to_i
11
+
12
+ if @host.nil? || @host.empty? || @port == 0
13
+ raise ArgumentError, 'Check COUCHBASE_SERVER variable. It should be hostname:port'
14
+ end
15
+
16
+ @config = MultiJson.load(open("http://#{@host}:#{@port}/pools/default"))
17
+ @num_nodes = @config['nodes'].size
18
+ @buckets_spec = params[:buckets_spec] || 'default:' # "default:,protected:secret,cache::memcache"
19
+ end
20
+
21
+ def start
22
+ # flush all buckets
23
+ @buckets_spec.split(',') do |bucket|
24
+ name, password, _ = bucket.split(':')
25
+ connection = Couchbase.new(:hostname => @host,
26
+ :port => @port,
27
+ :username => name,
28
+ :bucket => name,
29
+ :password => password)
30
+ connection.flush
31
+ end
32
+ end
33
+ def stop; end
34
+ end
35
+
36
+ require "#{File.dirname(__FILE__)}/CouchbaseMock.jar"
37
+
38
+ class CouchbaseMock
39
+ attr_accessor :host, :port, :num_nodes, :buckets_spec, :num_vbuckets
40
+
41
+ def real?
42
+ false
43
+ end
44
+
45
+ def initialize(params = {})
46
+ @host = 'localhost'
47
+ @port = 8091
48
+ @num_nodes = 1
49
+ @num_vbuckets = 4096
50
+ @buckets_spec = 'default:' # "default:,protected:secret,cache::memcache"
51
+ params.each do |key, value|
52
+ send("#{key}=", value)
53
+ end
54
+ yield self if block_given?
55
+ if @num_vbuckets < 1 || (@num_vbuckets & (@num_vbuckets - 1) != 0)
56
+ raise ArgumentError, 'Number of vbuckets should be a power of two and greater than zero'
57
+ end
58
+ @mock = Java::OrgCouchbaseMock::CouchbaseMock.new(@host, @port, @num_nodes, @num_vbuckets, @buckets_spec)
59
+ end
60
+
61
+ def start
62
+ @mock.start
63
+ @mock.waitForStartup
64
+ end
65
+
66
+ def stop
67
+ @mock.stop
68
+ end
69
+ end
70
+
71
+ def start_mock(params = {})
72
+ mock = nil
73
+ if ENV['COUCHBASE_SERVER']
74
+ mock = CouchbaseServer.new(params)
75
+ if (params[:port] && mock.port != params[:port]) ||
76
+ (params[:host] && mock.host != params[:host]) ||
77
+ mock.buckets_spec != 'default:'
78
+ skip("Unable to configure real cluster. Requested config is: #{params.inspect}")
79
+ end
80
+ else
81
+ mock = CouchbaseMock.new(params)
82
+ end
83
+ mock.start
84
+ mock
85
+ end
data/test/setup.rb CHANGED
@@ -18,13 +18,11 @@
18
18
  gem 'minitest'
19
19
  require 'coveralls'
20
20
  Coveralls.wear!
21
- require 'minitest/autorun'
21
+ require 'minitest'
22
22
  require 'couchbase'
23
-
24
- require 'socket'
25
23
  require 'open-uri'
26
24
  require 'ostruct'
27
-
25
+ require_relative 'mock'
28
26
  require 'pry'
29
27
 
30
28
  # Surpress connection logging
@@ -42,9 +40,7 @@ require 'pry'
42
40
 
43
41
  # $stderr = StringIO.new
44
42
 
45
- Minitest.after_run { Couchbase.disconnect }
46
-
47
- class MiniTest::Test
43
+ class Minitest::Test
48
44
 
49
45
  def cb
50
46
  Couchbase.bucket
@@ -66,3 +62,12 @@ class MiniTest::Test
66
62
  end
67
63
 
68
64
  end
65
+
66
+ $mock = start_mock
67
+
68
+ Dir.glob('test/test_store.rb').each { |test| require test }
69
+ exit_code = Minitest.run(ARGV)
70
+ Couchbase.disconnect
71
+ $mock.stop
72
+ java.lang.System.exit(exit_code ? 0 : 1)
73
+
@@ -112,6 +112,7 @@ class TestArithmetic < MiniTest::Test
112
112
  end
113
113
 
114
114
  def test_decrement_with_absolute_ttl
115
+ skip unless $mock.real?
115
116
  # absolute TTL: one second from now
116
117
  exp = Time.now.to_i + 1
117
118
  val = cb.decr(uniq_id, 12, :initial => 0, :ttl => exp)