couchbase-jruby-client 0.2.2-java → 1.0.4-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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +103 -0
  3. data/.ruby-version +1 -1
  4. data/Rakefile +13 -2
  5. data/couchbase-jruby-client.gemspec +7 -6
  6. data/lib/couchbase/bucket.rb +11 -338
  7. data/lib/couchbase/cluster.rb +10 -88
  8. data/lib/couchbase/configuration.rb +39 -0
  9. data/lib/couchbase/design_doc.rb +18 -73
  10. data/lib/couchbase/document.rb +34 -0
  11. data/lib/couchbase/error.rb +0 -35
  12. data/lib/couchbase/operations.rb +60 -40
  13. data/lib/couchbase/version.rb +1 -1
  14. data/lib/couchbase/view.rb +55 -345
  15. data/lib/couchbase.rb +37 -141
  16. data/lib/jars/couchbase-core-io-1.1.4.jar +0 -0
  17. data/lib/jars/couchbase-java-client-2.1.4.jar +0 -0
  18. data/lib/jars/rxjava-1.0.8.jar +0 -0
  19. data/lib/jars/rxjruby-0.0.1.jar +0 -0
  20. data/test/{test_cas.rb → helper.rb} +15 -10
  21. data/test/test_bucket.rb +14 -228
  22. data/test/test_cluster.rb +1 -29
  23. data/test/test_configuration.rb +51 -0
  24. data/test/test_couchbase.rb +28 -28
  25. data/test/test_design_doc.rb +29 -0
  26. data/test/test_document.rb +51 -0
  27. data/test/test_operations.rb +49 -0
  28. data/test/test_view.rb +62 -116
  29. metadata +43 -125
  30. data/lib/couchbase/async/callback.rb +0 -38
  31. data/lib/couchbase/async/queue.rb +0 -26
  32. data/lib/couchbase/async.rb +0 -32
  33. data/lib/couchbase/constants.rb +0 -29
  34. data/lib/couchbase/operations/arithmetic.rb +0 -290
  35. data/lib/couchbase/operations/delete.rb +0 -115
  36. data/lib/couchbase/operations/design_docs.rb +0 -99
  37. data/lib/couchbase/operations/fetch.rb +0 -33
  38. data/lib/couchbase/operations/get.rb +0 -303
  39. data/lib/couchbase/operations/stats.rb +0 -42
  40. data/lib/couchbase/operations/store.rb +0 -463
  41. data/lib/couchbase/operations/touch.rb +0 -140
  42. data/lib/couchbase/operations/unlock.rb +0 -209
  43. data/lib/couchbase/operations/utils.rb +0 -68
  44. data/lib/couchbase/query.rb +0 -76
  45. data/lib/couchbase/result.rb +0 -60
  46. data/lib/couchbase/transcoder.rb +0 -81
  47. data/lib/couchbase/utils.rb +0 -62
  48. data/lib/couchbase/view_row.rb +0 -227
  49. data/lib/jars/commons-codec-1.5.jar +0 -0
  50. data/lib/jars/couchbase-client-1.3.2-javadoc.jar +0 -0
  51. data/lib/jars/couchbase-client-1.3.2-sources.jar +0 -0
  52. data/lib/jars/couchbase-client-1.3.2.jar +0 -0
  53. data/lib/jars/httpcore-4.3.1.jar +0 -0
  54. data/lib/jars/httpcore-nio-4.3.1.jar +0 -0
  55. data/lib/jars/jettison-1.1.jar +0 -0
  56. data/lib/jars/netty-3.5.5.Final.jar +0 -0
  57. data/lib/jars/spymemcached-2.10.5-javadoc.jar +0 -0
  58. data/lib/jars/spymemcached-2.10.5-sources.jar +0 -0
  59. data/lib/jars/spymemcached-2.10.5.jar +0 -0
  60. data/tasks/benchmark.rake +0 -6
  61. data/tasks/test.rake +0 -36
  62. data/tasks/util.rake +0 -21
  63. data/test/mock.rb +0 -85
  64. data/test/profile/.gitignore +0 -1
  65. data/test/profile/.jrubyrc +0 -722
  66. data/test/profile/Gemfile +0 -7
  67. data/test/profile/benchmark.rb +0 -177
  68. data/test/profile/profile.rb +0 -59
  69. data/test/setup.rb +0 -74
  70. data/test/test_arithmetic.rb +0 -155
  71. data/test/test_async.rb +0 -24
  72. data/test/test_couchbase_rails_cache_store.rb +0 -341
  73. data/test/test_delete.rb +0 -139
  74. data/test/test_design_docs.rb +0 -67
  75. data/test/test_errors.rb +0 -74
  76. data/test/test_fetch.rb +0 -71
  77. data/test/test_format.rb +0 -142
  78. data/test/test_get.rb +0 -363
  79. data/test/test_query.rb +0 -23
  80. data/test/test_result.rb +0 -15
  81. data/test/test_stats.rb +0 -44
  82. data/test/test_store.rb +0 -203
  83. data/test/test_touch.rb +0 -90
  84. data/test/test_unlock.rb +0 -89
  85. data/test/test_utils.rb +0 -67
  86. data/test/test_version.rb +0 -28
  87. data/test/test_view_row.rb +0 -74
@@ -1,378 +1,88 @@
1
- # Author:: Couchbase <info@couchbase.com>
2
- # Copyright:: 2011 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 'base64'
19
-
20
1
  module Couchbase
21
-
22
- module Error
23
- class View < Base
24
- attr_reader :from, :reason
25
-
26
- def initialize(from, reason, prefix = "SERVER: ")
27
- @from = from
28
- @reason = reason
29
- super("#{prefix}#{from}: #{reason}")
30
- end
31
- end
32
-
33
- class HTTP < Base
34
- attr_reader :type, :reason
35
-
36
- def parse_body!
37
- if @body
38
- hash = MultiJson.load(@body)
39
- if hash["errors"]
40
- @type = :invalid_arguments
41
- @reason = hash["errors"].values.join(" ")
42
- else
43
- @type = hash["error"]
44
- @reason = hash["reason"]
45
- end
46
- end
47
- rescue MultiJson::DecodeError
48
- @type = @reason = nil
49
- end
50
-
51
- def to_s
52
- str = super
53
- if @type || @reason
54
- str.sub(/ \(/, ": #{[@type, @reason].compact.join(": ")} (")
55
- else
56
- str
57
- end
58
- end
59
- end
60
- end
61
-
62
- # This class implements Couchbase View execution
63
- #
64
- # @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views.html
65
2
  class View
3
+ java_import com.couchbase.client.java.view.ViewQuery
4
+ java_import com.couchbase.client.java.document.json.JsonArray
5
+ java_import com.couchbase.client.java.document.RawJsonDocument
66
6
 
67
- include Enumerable
68
- include Constants
69
-
70
- class ArrayWithTotalRows < Array # :nodoc:
71
- attr_accessor :total_rows
72
- alias total_entries total_rows
7
+ def initialize(design_doc, view, bucket)
8
+ @format = :json
9
+ @bucket = bucket.bucket
10
+ @view_query = ViewQuery.from(design_doc, view.to_s)
73
11
  end
74
12
 
75
- attr_reader :params, :design_doc, :name
76
-
77
- # Set up view endpoint and optional params
78
- #
79
- # @param [Couchbase::Bucket] bucket Connection object which
80
- # stores all info about how to make requests to Couchbase views.
81
- #
82
- # @param [String] endpoint Full Couchbase View URI.
83
- #
84
- # @param [Hash] params Optional parameter which will be passed to
85
- # {View#fetch}
86
- #
87
- def initialize(bucket, endpoint, params = {})
88
- @bucket = bucket
89
- @endpoint = endpoint
90
- @design_doc, @name = parse_endpoint(endpoint)
91
- @wrapper_class = params.delete(:wrapper_class) || ViewRow
92
- @params = { connection_timeout: 75_000 }.merge(params)
93
- unless @wrapper_class.respond_to?(:wrap)
94
- raise ArgumentError, "wrapper class should respond to :wrap, check the options"
95
- end
13
+ def key(key)
14
+ @view_query.key(convert_key(key))
15
+ self
96
16
  end
97
17
 
98
- # Yields each document that was fetched by view. It doesn't instantiate
99
- # all the results because of streaming JSON parser. Returns Enumerator
100
- # unless block given.
101
- #
102
- # @param [Hash] params Params for Couchdb query. Some useful are:
103
- # :start_key, :start_key_doc_id, :descending. See {View#fetch}.
104
- #
105
- # @example Use each method with block
106
- #
107
- # view.each do |doc|
108
- # # do something with doc
109
- # end
110
- #
111
- # @example Use Enumerator version
112
- #
113
- # enum = view.each # request hasn't issued yet
114
- # enum.map{|doc| doc.title.upcase}
115
- #
116
- # @example Pass options during view initialization
117
- #
118
- # endpoint = "http://localhost:5984/default/_design/blog/_view/recent"
119
- # view = View.new(conn, endpoint, :descending => true)
120
- # view.each do |document|
121
- # # do something with document
122
- # end
123
- #
124
- def each(params = {})
125
- return enum_for(:each, params) unless block_given?
126
- fetch(params) { |doc| yield(doc) }
18
+ def keys(keys)
19
+ @view_query.keys(JsonArray.from(keys.to_java))
20
+ self
127
21
  end
128
22
 
129
- def first(params = {})
130
- params = params.merge(:limit => 1)
131
- fetch(params).first
23
+ def start_key(key)
24
+ @view_query.start_key(convert_key(key))
25
+ self
132
26
  end
133
27
 
134
- def take(n, params = {})
135
- params = params.merge(:limit => n)
136
- fetch(params)
28
+ def end_key(key)
29
+ @view_query.end_key(convert_key(key))
30
+ self
137
31
  end
138
32
 
139
- # Registers callback function for handling error objects in view
140
- # results stream.
141
- #
142
- # @yieldparam [String] from Location of the node where error occured
143
- # @yieldparam [String] reason The reason message describing what
144
- # happened.
145
- #
146
- # @example Using +#on_error+ to log all errors in view result
147
- #
148
- # # JSON-encoded view result
149
- # #
150
- # # {
151
- # # "total_rows": 0,
152
- # # "rows": [ ],
153
- # # "errors": [
154
- # # {
155
- # # "from": "127.0.0.1:5984",
156
- # # "reason": "Design document `_design/testfoobar` missing in database `test_db_b`."
157
- # # },
158
- # # {
159
- # # "from": "http:// localhost:5984/_view_merge/",
160
- # # "reason": "Design document `_design/testfoobar` missing in database `test_db_c`."
161
- # # }
162
- # # ]
163
- # # }
164
- #
165
- # view.on_error do |from, reason|
166
- # logger.warn("#{view.inspect} received the error '#{reason}' from #{from}")
167
- # end
168
- # docs = view.fetch
169
- #
170
- # @example More concise example to just count errors
171
- #
172
- # errcount = 0
173
- # view.on_error{|f,r| errcount += 1}.fetch
174
- #
175
- def on_error(&callback)
176
- @on_error = callback
177
- self # enable call chains
33
+ def limit(num)
34
+ @view_query.limit(num)
35
+ self
178
36
  end
179
37
 
180
- # Performs query to Couchbase view. This method will stream results if block
181
- # given or return complete result set otherwise. In latter case it defines
182
- # method +total_rows+ returning corresponding entry from
183
- # Couchbase result object.
184
- #
185
- # @note Avoid using +$+ symbol as prefix for properties in your
186
- # documents, because server marks with it meta fields like flags and
187
- # expiration, therefore dollar prefix is some kind of reserved. It
188
- # won't hurt your application. Currently the {ViewRow}
189
- # class extracts +$flags+, +$cas+ and +$expiration+ properties from
190
- # the document and store them in {ViewRow#meta} hash.
191
- #
192
- # @param [Hash] params parameters for Couchbase query.
193
- # @option params [true, false] :include_docs (false) Include the
194
- # full content of the documents in the return. Note that the document
195
- # is fetched from the in memory cache where it may have been changed
196
- # or even deleted. See also +:quiet+ parameter below to control error
197
- # reporting during fetch.
198
- # @option params [true, false] :quiet (true) Do not raise error if
199
- # associated document not found in the memory. If the parameter +true+
200
- # will use +nil+ value instead.
201
- # @option params [true, false] :descending (false) Return the documents
202
- # in descending by key order
203
- # @option params [String, Fixnum, Hash, Array] :key Return only
204
- # documents that match the specified key. Will be JSON encoded.
205
- # @option params [Array] :keys The same as +:key+, but will work for
206
- # set of keys. Will be JSON encoded.
207
- # @option params [String, Fixnum, Hash, Array] :startkey Return
208
- # records starting with the specified key. +:start_key+ option should
209
- # also work here. Will be JSON encoded.
210
- # @option params [String] :startkey_docid Document id to start with
211
- # (to allow pagination for duplicate startkeys). +:start_key_doc_id+
212
- # also should work.
213
- # @option params [String, Fixnum, Hash, Array] :endkey Stop returning
214
- # records when the specified key is reached. +:end_key+ option should
215
- # also work here. Will be JSON encoded.
216
- # @option params [String] :endkey_docid Last document id to include
217
- # in the output (to allow pagination for duplicate startkeys).
218
- # +:end_key_doc_id+ also should work.
219
- # @option params [true, false] :inclusive_end (true) Specifies whether
220
- # the specified end key should be included in the result
221
- # @option params [Fixnum] :limit Limit the number of documents in the
222
- # output.
223
- # @option params [Fixnum] :skip Skip this number of records before
224
- # starting to return the results.
225
- # @option params [String, Symbol] :on_error (:continue) Sets the
226
- # response in the event of an error. Supported values:
227
- # :continue:: Continue to generate view information in the event of an
228
- # error, including the error information in the view
229
- # response stream.
230
- # :stop:: Stop immediately when an error condition occurs. No
231
- # further view information will be returned.
232
- # @option params [Fixnum] :connection_timeout (75000) Timeout before the
233
- # view request is dropped (milliseconds)
234
- # @option params [true, false] :reduce (true) Use the reduction function
235
- # @option params [true, false] :group (false) Group the results using
236
- # the reduce function to a group or single row.
237
- # @option params [Fixnum] :group_level Specify the group level to be
238
- # used.
239
- # @option params [String, Symbol, false] :stale (:update_after) Allow
240
- # the results from a stale view to be used. Supported values:
241
- # false:: Force a view update before returning data
242
- # :ok:: Allow stale views
243
- # :update_after:: Allow stale view, update view after it has been
244
- # accessed
245
- # @option params [Hash] :body Accepts the same parameters, except
246
- # +:body+ of course, but sends them in POST body instead of query
247
- # string. It could be useful for really large and complex parameters.
248
- #
249
- # @yieldparam [Couchbase::ViewRow] document
250
- #
251
- # @return [Array] with documents. There will be +total_entries+
252
- # method defined on this array if it's possible.
253
- #
254
- # @raise [Couchbase::Error::View] when +on_error+ callback is nil and
255
- # error object found in the result stream.
256
- #
257
- # @example Query +recent_posts+ view with key filter
258
- # doc.recent_posts(:body => {:keys => ["key1", "key2"]})
259
- #
260
- # @example Fetch second page of result set (splitted in 10 items per page)
261
- # page = 2
262
- # per_page = 10
263
- # doc.recent_posts(:skip => (page - 1) * per_page, :limit => per_page)
264
- #
265
- # @example Simple join using Map/Reduce
266
- # # Given the bucket with Posts(:id, :type, :title, :body) and
267
- # # Comments(:id, :type, :post_id, :author, :body). The map function
268
- # # below (in javascript) will build the View index called
269
- # # "recent_posts_with_comments" which will behave like left inner join.
270
- # #
271
- # # function(doc) {
272
- # # switch (doc.type) {
273
- # # case "Post":
274
- # # emit([doc.id, 0], null);
275
- # # break;
276
- # # case "Comment":
277
- # # emit([doc.post_id, 1], null);
278
- # # break;
279
- # # }
280
- # # }
281
- # #
282
- # post_id = 42
283
- # doc.recent_posts_with_comments(:start_key => [post_id, 0],
284
- # :end_key => [post_id, 1],
285
- # :include_docs => true)
286
- def fetch(params = {})
287
- params = @params.merge(params)
288
- # quiet = params.fetch(:quiet, true)
289
-
290
- view = @bucket.client.getView(@design_doc, @name)
291
-
292
- query = Query.new(params)
293
-
294
- request = @bucket.client.query(view, query.generate)
295
-
296
- if block_given?
297
- fetch_block(request, Proc.new)
298
- else
299
- fetch_array(request)
300
- end
38
+ def skip(num)
39
+ @view_query.skip(num)
40
+ self
301
41
  end
302
42
 
303
- # Method for fetching asynchronously all rows and passing array to callback
304
- #
305
- # Parameters are same as for {View#fetch} method, but callback is called for whole set for
306
- # rows instead of one by each.
307
- #
308
- # @example
309
- # con.run do
310
- # doc.recent_posts.fetch_all do |posts|
311
- # do_something_with_all_posts(posts)
312
- # end
313
- # end
314
- def fetch_all(params = {}, &block)
315
- return fetch(params) unless @bucket.async?
316
- raise ArgumentError, "Block needed for fetch_all in async mode" unless block
317
-
318
- all = []
319
- fetch(params) do |row|
320
- all << row
321
- if row.last?
322
- @bucket.create_timer(0) { block.call(all) }
323
- end
324
- end
43
+ def group(group = true)
44
+ @view_query.group(group)
45
+ self
325
46
  end
326
47
 
327
-
328
- # Returns a string containing a human-readable representation of the {View}
329
- #
330
- # @return [String]
331
- def inspect
332
- %(#<#{self.class.name}:#{self.object_id} @endpoint=#{@endpoint.inspect} @params=#{@params.inspect}>)
48
+ def group_level(level)
49
+ @view_query.group_level(level)
50
+ self
333
51
  end
334
52
 
335
- private
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
53
+ def reduce(reduce = true)
54
+ @view_query.reduce(reduce)
55
+ self
344
56
  end
345
57
 
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
58
+ def fresh
59
+ @view_query.stale(com.couchbase.client.java.view.Stale::FALSE)
60
+ self
352
61
  end
353
62
 
354
- def wrap_or_parse_data(data)
355
- if data.is_a? ViewRowReduced
356
- data.value
357
- else
358
- @wrapper_class.wrap(@bucket, data)
63
+ def fetch
64
+ results = @bucket.query(@view_query)
65
+ {}.tap do |response|
66
+ results.each do |view_row|
67
+ if view_row.id.nil?
68
+ # Reduced view
69
+ return view_row.value
70
+ else
71
+ doc = view_row.document(RawJsonDocument.java_class)
72
+ response[view_row.id] = doc.nil? ? nil : Document.new(doc)
73
+ end
74
+ end
359
75
  end
360
76
  end
361
77
 
362
- def send_error(*args)
363
- if @on_error
364
- @on_error.call(*args.take(2))
365
- else
366
- raise Error::View.new(*args)
367
- end
368
- end
78
+ private
369
79
 
370
- def parse_endpoint(endpoint)
371
- parts = endpoint.split('/')
372
- if endpoint =~ /^_design/
373
- [parts[1], parts[3]]
80
+ def convert_key(key)
81
+ case key
82
+ when Array
83
+ JsonArray.from(key.to_java)
374
84
  else
375
- [parts[0], parts[2]]
85
+ key
376
86
  end
377
87
  end
378
88
  end
data/lib/couchbase.rb CHANGED
@@ -15,38 +15,23 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- unless RUBY_PLATFORM =~ /java/
19
- fail "This gem is only compatible with a java-based ruby environment like JRuby."
20
- exit 255
21
- end
18
+ fail 'This gem is only compatible with JRuby.' unless RUBY_PLATFORM =~ /java/
22
19
 
23
- require 'java'
24
- require 'jars/commons-codec-1.5.jar'
25
- require 'jars/couchbase-client-1.3.2.jar'
26
- require 'jars/jettison-1.1.jar'
27
- require 'jars/httpcore-4.3.1.jar'
28
- require 'jars/httpcore-nio-4.3.1.jar'
29
- require 'jars/netty-3.5.5.Final.jar'
30
- require 'jars/spymemcached-2.10.5.jar'
20
+ require 'jars/rxjava-1.0.8'
21
+ require 'jars/rxjruby-0.0.1'
22
+ require 'jars/couchbase-core-io-1.1.4'
23
+ require 'jars/couchbase-java-client-2.1.4'
24
+ require 'rx/lang/jruby/interop'
31
25
  require 'couchbase/version'
32
- require 'uri'
33
- require 'thread_safe'
34
- require 'couchbase/transcoder'
35
- require 'couchbase/async'
36
- require 'couchbase/operations'
37
26
  require 'couchbase/error'
38
- require 'couchbase/constants'
39
- require 'couchbase/utils'
27
+ require 'couchbase/document'
28
+ require 'couchbase/operations'
29
+ require 'couchbase/cluster'
40
30
  require 'couchbase/bucket'
41
- require 'couchbase/view_row'
42
31
  require 'couchbase/view'
43
- require 'couchbase/result'
44
- require 'couchbase/cluster'
45
32
  require 'couchbase/design_doc'
33
+ require 'couchbase/configuration'
46
34
  require 'couchbase/view'
47
- require 'couchbase/query'
48
-
49
- include Java
50
35
 
51
36
  at_exit do
52
37
  Couchbase.disconnect
@@ -55,131 +40,42 @@ end
55
40
  # Couchbase jruby client
56
41
  module Couchbase
57
42
 
58
- @@buckets = ThreadSafe::Cache.new
59
- @@connections = ThreadSafe::Array.new
43
+ class ConfigurationError < Error::Base; end
60
44
 
61
- class << self
45
+ module_function
62
46
 
63
- # The method +connect+ initializes new Bucket instance with all arguments passed.
64
- #
65
- # @since 1.0.0
66
- #
67
- # @see Bucket#initialize
68
- #
69
- # @example Use default values for all options
70
- # Couchbase.connect
71
- #
72
- # @example Establish connection with couchbase default pool and default bucket
73
- # Couchbase.connect("http://localhost:8091/pools/default")
74
- #
75
- # @example Select custom bucket
76
- # Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog')
77
- #
78
- # @example Specify bucket credentials
79
- # Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog', :username => 'bucket', :password => 'secret')
80
- #
81
- # @example Use URL notation
82
- # Couchbase.connect("http://bucket:secret@localhost:8091/pools/default/buckets/blog")
83
- #
84
- # @return [Bucket] connection instance
85
- def connect(*options)
86
- bucket = Bucket.new(*(options.flatten))
87
- @@connections << bucket
88
- bucket
89
- end
90
- alias :new :connect
91
-
92
- # Default connection options
93
- #
94
- # @since 1.1.0
95
- #
96
- # @example Using {Couchbase#connection_options} to change the bucket
97
- # Couchbase.connection_options = {:bucket => 'blog'}
98
- # Couchbase.bucket.name #=> "blog"
99
- #
100
- # @return [Hash, String]
101
- attr_reader :connection_options
47
+ @conn = Configuration.new
102
48
 
103
- def connection_options=(options)
104
- @connection_options = normalize_connection_options(options)
105
- end
106
-
107
- def normalize_connection_options(options)
108
- Hash[ options.map { |k, v| [k.to_sym, v] } ]
109
- end
49
+ def connection_options=(options)
50
+ fail ConfigurationError, 'Cannot reconfigure an already connected cluster.' if connected?
51
+ @conn = Configuration.new(options)
52
+ end
110
53
 
111
- # The connection instance for current thread
112
- #
113
- # @since 1.1.0
114
- #
115
- # @see Couchbase.connection_options
116
- #
117
- # @example
118
- # Couchbase.bucket.set("foo", "bar")
119
- #
120
- # @example Set connection options using Hash
121
- # Couchbase.connection_options = {:node_list => ["example.com:8091"]}
122
- # Couchbase.bucket("slot1").set("foo", "bar")
123
- # Couchbase.bucket("slot1").bucket #=> "default"
124
- # Couchbase.connection_options[:bucket] = "test"
125
- # Couchbase.bucket("slot2").bucket #=> "test"
126
- #
127
- # @example Set connection options using URI
128
- # Couchbase.connection_options = "http://example.com:8091/pools"
129
- # Couchbase.bucket("slot1").set("foo", "bar")
130
- # Couchbase.bucket("slot1").bucket #=> "default"
131
- # Couchbase.connection_options = "http://example.com:8091/pools/buckets/test"
132
- # Couchbase.bucket("slot2").bucket #=> "test"
133
- #
134
- # @example Use named slots to keep a connection
135
- # Couchbase.connection_options = {
136
- # :node_list => ["example.com", "example.org"],
137
- # :bucket => "users"
138
- # }
139
- # Couchbase.bucket("users").set("john", {"balance" => 0})
140
- # Couchbase.connection_options[:bucket] = "orders"
141
- # Couchbase.bucket("other").set("john:1", {"products" => [42, 66]})
142
- #
143
- # @return [Bucket]
144
- def bucket(name = nil)
145
- name ||= case @connection_options
146
- when Hash
147
- @connection_options[:bucket]
148
- when String
149
- path = URI.parse(@connection_options).path
150
- path[%r(^(/pools/([A-Za-z0-9_.-]+)(/buckets/([A-Za-z0-9_.-]+))?)?), 3] || 'default'
151
- else
152
- 'default'
153
- end
54
+ def connected?
55
+ @cluster
56
+ end
154
57
 
155
- @@buckets[name] ||= connect(connection_options)
156
- end
58
+ def disconnect
59
+ @cluster.disconnect if @cluster
60
+ @buckets = nil
61
+ end
157
62
 
158
- # Set a connection instance for current thread
159
- #
160
- # @since 1.1.0
161
- #
162
- # @return [Bucket]
163
- def bucket=(connection)
164
- name = @connection_options && @connection_options[:bucket] || "default"
165
- @@buckets[name] = connection
166
- end
167
- alias set_bucket bucket=
63
+ def cluster
64
+ @cluster ||= Cluster.new(@conn.hosts)
65
+ end
168
66
 
169
- def connected?
170
- !!@@buckets.empty?
171
- end
67
+ def bucket(name = nil)
68
+ name ||= :default
69
+ buckets[name.to_sym]
70
+ end
172
71
 
173
- def disconnect
174
- @@buckets.each_pair do |bucket, connection|
175
- connection.disconnect if connection.connected?
72
+ def buckets
73
+ @buckets ||= begin
74
+ {}.tap do |buckets|
75
+ @conn.buckets.each do |bucket|
76
+ buckets[bucket.name.to_sym] = cluster.open_bucket(bucket.name, bucket.password)
77
+ end
176
78
  end
177
- @@connections.each do |connection|
178
- connection.disconnect if connection.connected?
179
- end
180
- @@buckets = ThreadSafe::Cache.new
181
- @@connections = ThreadSafe::Array.new
182
79
  end
183
80
  end
184
81
  end
185
-
Binary file
Binary file
@@ -15,18 +15,23 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require File.join(File.dirname(__FILE__), 'setup')
18
+ gem 'minitest'
19
+ require 'coveralls'
20
+ Coveralls.wear!
21
+ require 'minitest'
22
+ require 'minitest/autorun'
23
+ require 'pry'
24
+ require 'couchbase'
25
+ require 'ostruct'
19
26
 
20
- class TestCas < Minitest::Test
27
+ module Minitest
28
+ class Test
21
29
 
22
- def test_compare_and_swap
23
- cb.set(uniq_id, {"bar" => 1})
24
- cb.cas(uniq_id) do |val|
25
- val["baz"] = 2
26
- val
30
+ def uniq_id(*suffixes)
31
+ test_id = [caller.first[/.*[` ](.*)'/, 1], suffixes].compact.join('_')
32
+ @ids ||= {}
33
+ @ids[test_id] ||= Time.now.to_f
34
+ [test_id, @ids[test_id]].join('_')
27
35
  end
28
- val = cb.get(uniq_id)
29
- expected = {"bar" => 1, "baz" => 2}
30
- assert_equal expected, val
31
36
  end
32
37
  end