couchbase-jruby-client 0.2.2-java → 1.0.4-java

Sign up to get free protection for your applications and to get access to all the features.
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