couchbase-jruby-client 0.1.7-java → 0.1.8-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.
@@ -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)