couchbase 3.0.0.alpha.3-universal-darwin-19 → 3.0.0.alpha.4-universal-darwin-19

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-6.0.3.yml +4 -1
  3. data/.github/workflows/tests-dev-preview.yml +4 -1
  4. data/.github/workflows/tests.yml +4 -1
  5. data/README.md +1 -1
  6. data/bin/check-cluster +31 -0
  7. data/bin/init-cluster +16 -4
  8. data/examples/analytics.rb +221 -0
  9. data/examples/managing_analytics_indexes.rb +72 -0
  10. data/examples/managing_view_indexes.rb +54 -0
  11. data/examples/search_with_consistency.rb +84 -0
  12. data/examples/view.rb +50 -0
  13. data/ext/.clang-tidy +1 -0
  14. data/ext/build_version.hxx.in +1 -1
  15. data/ext/couchbase/bucket.hxx +0 -1
  16. data/ext/couchbase/couchbase.cxx +1421 -55
  17. data/ext/couchbase/io/dns_client.hxx +215 -0
  18. data/ext/couchbase/io/dns_codec.hxx +207 -0
  19. data/ext/couchbase/io/dns_config.hxx +116 -0
  20. data/ext/couchbase/io/dns_message.hxx +558 -0
  21. data/ext/couchbase/io/http_session.hxx +16 -4
  22. data/ext/couchbase/io/mcbp_session.hxx +2 -1
  23. data/ext/couchbase/mutation_token.hxx +1 -1
  24. data/ext/couchbase/operations.hxx +19 -0
  25. data/ext/couchbase/operations/analytics_dataset_create.hxx +117 -0
  26. data/ext/couchbase/operations/analytics_dataset_drop.hxx +103 -0
  27. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +107 -0
  28. data/ext/couchbase/operations/analytics_dataverse_create.hxx +104 -0
  29. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +104 -0
  30. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +91 -0
  31. data/ext/couchbase/operations/analytics_index_create.hxx +128 -0
  32. data/ext/couchbase/operations/analytics_index_drop.hxx +110 -0
  33. data/ext/couchbase/operations/analytics_index_get_all.hxx +106 -0
  34. data/ext/couchbase/operations/analytics_link_connect.hxx +102 -0
  35. data/ext/couchbase/operations/analytics_link_disconnect.hxx +101 -0
  36. data/ext/couchbase/operations/design_document.hxx +59 -0
  37. data/ext/couchbase/operations/document_analytics.hxx +293 -0
  38. data/ext/couchbase/operations/document_query.hxx +2 -2
  39. data/ext/couchbase/operations/document_search.hxx +19 -1
  40. data/ext/couchbase/operations/document_view.hxx +227 -0
  41. data/ext/couchbase/operations/search_index.hxx +17 -0
  42. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -1
  43. data/ext/couchbase/operations/view_index_drop.hxx +67 -0
  44. data/ext/couchbase/operations/view_index_get.hxx +90 -0
  45. data/ext/couchbase/operations/view_index_get_all.hxx +125 -0
  46. data/ext/couchbase/operations/view_index_upsert.hxx +87 -0
  47. data/ext/couchbase/service_type.hxx +38 -1
  48. data/ext/couchbase/timeout_defaults.hxx +3 -1
  49. data/ext/couchbase/utils/connection_string.hxx +231 -0
  50. data/ext/couchbase/version.hxx +1 -1
  51. data/ext/test/main.cxx +3 -12
  52. data/lib/couchbase/analytics_options.rb +165 -0
  53. data/lib/couchbase/bucket.rb +49 -0
  54. data/lib/couchbase/cluster.rb +46 -207
  55. data/lib/couchbase/management/analytics_index_manager.rb +138 -24
  56. data/lib/couchbase/management/view_index_manager.rb +63 -10
  57. data/lib/couchbase/query_options.rb +219 -0
  58. data/lib/couchbase/search_options.rb +6 -6
  59. data/lib/couchbase/version.rb +1 -1
  60. data/lib/couchbase/view_options.rb +155 -0
  61. metadata +34 -2
@@ -18,7 +18,7 @@
18
18
  #pragma once
19
19
 
20
20
  #define BACKEND_VERSION_MAJOR 0
21
- #define BACKEND_VERSION_MINOR 3
21
+ #define BACKEND_VERSION_MINOR 4
22
22
  #define BACKEND_VERSION_PATCH 0
23
23
 
24
24
  #include <build_version.hxx>
data/ext/test/main.cxx CHANGED
@@ -44,23 +44,14 @@ main()
44
44
  rb_require("json");
45
45
  run_script(R"(
46
46
  p Couchbase::VERSION
47
- )");
48
-
49
- run_script(R"(
50
47
  B = Couchbase::Backend.new
51
48
  B.open("localhost", "Administrator", "password")
52
- )");
53
49
 
54
- run_script(R"(
55
- query = {
56
- query: "hello"
57
- }
58
- p B.document_search("beers", JSON.generate(query), {})
50
+ pp B.document_view("beer-sample", "test", "get_all", :development, {
51
+ keys: [JSON.generate("21st_amendment_brewery_cafe-563_stout")]
52
+ })
59
53
  )");
60
54
 
61
- run_script(R"(
62
- B.close
63
- )");
64
55
 
65
56
  ruby_finalize();
66
57
  return 0;
@@ -0,0 +1,165 @@
1
+ # Copyright 2020 Couchbase, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'couchbase/json_transcoder'
16
+
17
+ module Couchbase
18
+ class Cluster
19
+ class AnalyticsOptions
20
+ # @return [Integer] Timeout in milliseconds
21
+ attr_accessor :timeout
22
+
23
+ # @return [String] Provides a custom client context ID for this query
24
+ attr_accessor :client_context_id
25
+
26
+ # @return [:not_bounded, :request_plus] specifies level of consistency for the query
27
+ attr_accessor :scan_consistency
28
+
29
+ # @return [Integer] The maximum duration (in milliseconds) the query engine is willing to wait before failing.
30
+ attr_accessor :scan_wait
31
+
32
+ # @return [Boolean] Allows explicitly marking a query as being readonly and not mutating and documents on the server side.
33
+ attr_accessor :readonly
34
+
35
+ # @return [Boolean] Allows to give certain requests higher priority than others
36
+ attr_accessor :priority
37
+
38
+ # @return [JsonTranscoder] transcoder to use on rows
39
+ attr_accessor :transcoder
40
+
41
+ # @yieldparam [AnalyticsOptions] self
42
+ def initialize
43
+ @transcoder = JsonTranscoder.new
44
+ @raw_parameters = {}
45
+ @positional_parameters = nil
46
+ @named_parameters = nil
47
+ @scan_consistency = nil
48
+ yield self if block_given?
49
+ end
50
+
51
+ # Sets positional parameters for the query
52
+ #
53
+ # @param [Array] positional the list of parameters that have to be substituted in the statement
54
+ def positional_parameters(positional)
55
+ @positional_parameters = positional
56
+ @named_parameters = nil
57
+ end
58
+
59
+ # Sets named parameters for the query
60
+ #
61
+ # @param [Hash] named the key/value map of the parameters to substitute in the statement
62
+ def named_parameters(named)
63
+ @named_parameters = named
64
+ @positional_parameters = nil
65
+ end
66
+
67
+ # Allows providing custom JSON key/value pairs for advanced usage
68
+ #
69
+ # @param [String] key the parameter name (key of the JSON property)
70
+ # @param [Object] value the parameter value (value of the JSON property)
71
+ def raw(key, value)
72
+ @raw_parameters[key] = JSON.generate(value)
73
+ end
74
+ end
75
+
76
+ class AnalyticsWarning
77
+ # @return [Integer]
78
+ attr_accessor :code
79
+
80
+ # @return [String]
81
+ attr_accessor :message
82
+
83
+ # @param [Integer] code
84
+ # @param [String] message
85
+ def initialize(code, message)
86
+ @code = code
87
+ @message = message
88
+ end
89
+ end
90
+
91
+ class AnalyticsMetrics
92
+ # @return [Integer] duration in milliseconds
93
+ attr_accessor :elapsed_time
94
+
95
+ # @return [Integer] duration in milliseconds
96
+ attr_accessor :execution_time
97
+
98
+ # @return [Integer]
99
+ attr_accessor :result_count
100
+
101
+ # @return [Integer]
102
+ attr_accessor :result_size
103
+
104
+ # @return [Integer]
105
+ attr_accessor :error_count
106
+
107
+ # @return [Integer]
108
+ attr_accessor :processed_objects
109
+
110
+ # @return [Integer]
111
+ attr_accessor :warning_count
112
+
113
+ # @yieldparam [AnalyticsMetrics] self
114
+ def initialize
115
+ yield self if block_given?
116
+ end
117
+ end
118
+
119
+ class AnalyticsMetaData
120
+ # @return [String]
121
+ attr_accessor :request_id
122
+
123
+ # @return [String]
124
+ attr_accessor :client_context_id
125
+
126
+ # @return [:running, :success, :errors, :completed, :stopped, :timeout, :closed, :fatal, :aborted, :unknown]
127
+ attr_accessor :status
128
+
129
+ # @return [Hash] returns the signature as returned by the query engine which is then decoded as JSON object
130
+ attr_accessor :signature
131
+
132
+ # @return [Array<AnalyticsWarning>]
133
+ attr_accessor :warnings
134
+
135
+ # @return [AnalyticsMetrics]
136
+ attr_accessor :metrics
137
+
138
+ # @yieldparam [AnalyticsMetaData] self
139
+ def initialize
140
+ yield self if block_given?
141
+ end
142
+ end
143
+
144
+ class AnalyticsResult
145
+ # @return [AnalyticsMetaData]
146
+ attr_accessor :meta_data
147
+
148
+ attr_accessor :transcoder
149
+
150
+ # Returns all rows converted using a transcoder
151
+ #
152
+ # @return [Array]
153
+ def rows(transcoder = self.transcoder)
154
+ @rows.lazy.map { |row| transcoder.decode(row, 0) }
155
+ end
156
+
157
+ # @yieldparam [AnalyticsResult] self
158
+ def initialize
159
+ @transcoder = JsonTranscoder.new
160
+ yield self if block_given?
161
+ end
162
+ end
163
+ end
164
+ end
165
+
@@ -14,6 +14,8 @@
14
14
 
15
15
  require "couchbase/scope"
16
16
  require "couchbase/management/collection_manager"
17
+ require "couchbase/management/view_index_manager"
18
+ require "couchbase/view_options"
17
19
 
18
20
  module Couchbase
19
21
  class Bucket
@@ -58,11 +60,58 @@ module Couchbase
58
60
  default_scope.default_collection
59
61
  end
60
62
 
63
+ # Performs query to view index.
64
+ #
65
+ # @param [String] design_document_name name of the design document
66
+ # @param [String] view_name name of the view to query
67
+ # @param [ViewOptions] options
68
+ #
69
+ # @return [ViewQueryResult]
70
+ def view_query(design_document_name, view_name, options = ViewOptions.new)
71
+ resp = @backend.document_view(@name, design_document_name, view_name, options.namespace, {
72
+ timeout: options.timeout,
73
+ scan_consistency: options.scan_consistency,
74
+ skip: options.skip,
75
+ limit: options.limit,
76
+ start_key: (JSON.generate(options.start_key) unless options.start_key.nil?),
77
+ end_key: (JSON.generate(options.end_key) unless options.end_key.nil?),
78
+ start_key_doc_id: options.start_key_doc_id,
79
+ end_key_doc_id: options.end_key_doc_id,
80
+ inclusive_end: options.inclusive_end,
81
+ group: options.group,
82
+ group_level: options.group_level,
83
+ key: (JSON.generate(options.key) unless options.key.nil?),
84
+ keys: options.keys&.map { |key| JSON.generate(key) },
85
+ order: options.order,
86
+ reduce: options.reduce,
87
+ on_error: options.on_error,
88
+ debug: options.debug,
89
+ })
90
+ ViewResult.new do |res|
91
+ res.meta_data = ViewMetaData.new do |meta|
92
+ meta.total_rows = resp[:meta][:total_rows]
93
+ meta.debug_info = resp[:meta][:debug_info]
94
+ end
95
+ res.rows = resp[:rows].map do |entry|
96
+ ViewRow.new do |row|
97
+ row.id = entry[:id] if entry.key?(:id)
98
+ row.key = JSON.parse(entry[:key])
99
+ row.value = JSON.parse(entry[:value])
100
+ end
101
+ end
102
+ end
103
+ end
104
+
61
105
  # @return [Management::CollectionManager]
62
106
  def collections
63
107
  Management::CollectionManager.new(@backend, @name)
64
108
  end
65
109
 
110
+ # @return [Management::ViewIndexManager]
111
+ def view_indexes
112
+ Management::ViewIndexManager.new(@backend, @name)
113
+ end
114
+
66
115
  # Performs application-level ping requests against services in the couchbase cluster
67
116
  #
68
117
  # @return [PingResult]
@@ -22,6 +22,8 @@ require "couchbase/management/analytics_index_manager"
22
22
  require "couchbase/management/search_index_manager"
23
23
 
24
24
  require "couchbase/search_options"
25
+ require "couchbase/query_options"
26
+ require "couchbase/analytics_options"
25
27
 
26
28
  module Couchbase
27
29
  class Cluster
@@ -87,6 +89,7 @@ module Couchbase
87
89
  metrics.execution_time = resp[:meta][:metrics][:execution_time]
88
90
  metrics.sort_count = resp[:meta][:metrics][:sort_count]
89
91
  metrics.result_count = resp[:meta][:metrics][:result_count]
92
+ metrics.result_size = resp[:meta][:metrics][:result_size]
90
93
  metrics.mutation_count = resp[:meta][:metrics][:mutation_count]
91
94
  metrics.error_count = resp[:meta][:metrics][:error_count]
92
95
  metrics.warning_count = resp[:meta][:metrics][:warning_count]
@@ -104,7 +107,42 @@ module Couchbase
104
107
  # @param [AnalyticsOptions] options the custom options for this query
105
108
  #
106
109
  # @return [AnalyticsResult]
107
- def analytics_query(statement, options = AnalyticsOptions.new) end
110
+ def analytics_query(statement, options = AnalyticsOptions.new)
111
+ resp = @backend.document_analytics(statement, {
112
+ timeout: options.timeout,
113
+ client_context_id: options.client_context_id,
114
+ scan_consistency: options.scan_consistency,
115
+ readonly: options.readonly,
116
+ priority: options.priority,
117
+ positional_parameters: options.instance_variable_get("@positional_parameters")&.map { |p| JSON.dump(p) },
118
+ named_parameters: options.instance_variable_get("@named_parameters")&.each_with_object({}) { |(n, v), o| o[n.to_s] = JSON.dump(v) },
119
+ raw_parameters: options.instance_variable_get("@raw_parameters"),
120
+ })
121
+
122
+ AnalyticsResult.new do |res|
123
+ res.transcoder = options.transcoder
124
+ res.meta_data = AnalyticsMetaData.new do |meta|
125
+ meta.status = resp[:meta][:status]
126
+ meta.request_id = resp[:meta][:request_id]
127
+ meta.client_context_id = resp[:meta][:client_context_id]
128
+ meta.signature = JSON.parse(resp[:meta][:signature]) if resp[:meta][:signature]
129
+ meta.profile = JSON.parse(resp[:meta][:profile]) if resp[:meta][:profile]
130
+ meta.metrics = AnalyticsMetrics.new do |metrics|
131
+ if resp[:meta][:metrics]
132
+ metrics.elapsed_time = resp[:meta][:metrics][:elapsed_time]
133
+ metrics.execution_time = resp[:meta][:metrics][:execution_time]
134
+ metrics.result_count = resp[:meta][:metrics][:result_count]
135
+ metrics.result_size = resp[:meta][:metrics][:result_size]
136
+ metrics.error_count = resp[:meta][:metrics][:error_count]
137
+ metrics.warning_count = resp[:meta][:metrics][:warning_count]
138
+ metrics.processed_objects = resp[:meta][:metrics][:processed_objects]
139
+ end
140
+ end
141
+ res[:warnings] = resp[:warnings].map { |warn| QueryWarning.new(warn[:code], warn[:message]) } if resp[:warnings]
142
+ end
143
+ res.instance_variable_set("@rows", resp[:rows])
144
+ end
145
+ end
108
146
 
109
147
  # Performs a Full Text Search (FTS) query
110
148
  #
@@ -243,210 +281,6 @@ module Couchbase
243
281
  end
244
282
  end
245
283
 
246
- class QueryOptions
247
- # @return [Integer] Timeout in milliseconds
248
- attr_accessor :timeout
249
-
250
- # @return [Boolean] Allows turning this request into a prepared statement query
251
- attr_accessor :adhoc
252
-
253
- # @return [String] Provides a custom client context ID for this query
254
- attr_accessor :client_context_id
255
-
256
- # @return [Integer] Allows overriding the default maximum parallelism for the query execution on the server side.
257
- attr_accessor :max_parallelism
258
-
259
- # @return [Boolean] Allows explicitly marking a query as being readonly and not mutating and documents on the server side.
260
- attr_accessor :readonly
261
-
262
- # Allows customizing how long (in milliseconds) the query engine is willing to wait until the index catches up to whatever scan consistency is asked for in this query.
263
- #
264
- # @note that if +:not_bounded+ consistency level is used, this method doesn't do anything
265
- # at all. If no value is provided to this method, the server default is used.
266
- #
267
- # @return [Integer] The maximum duration (in milliseconds) the query engine is willing to wait before failing.
268
- attr_accessor :scan_wait
269
-
270
- # @return [Integer] Supports customizing the maximum buffered channel size between the indexer and the query service
271
- attr_accessor :scan_cap
272
-
273
- # @return [Integer] Supports customizing the number of items execution operators can batch for fetch from the KV layer on the server.
274
- attr_accessor :pipeline_batch
275
-
276
- # @return [Integer] Allows customizing the maximum number of items each execution operator can buffer between various operators on the server.
277
- attr_accessor :pipeline_cap
278
-
279
- # @return [Boolean] Enables per-request metrics in the trailing section of the query
280
- attr_accessor :metrics
281
-
282
- # @return [:off, :phases, :timings] Customize server profile level for this query
283
- attr_accessor :profile
284
-
285
- def initialize
286
- @timeout = 75_000 # ms
287
- @adhoc = true
288
- @raw_parameters = {}
289
- @positional_parameters = nil
290
- @named_parameters = nil
291
- @scan_consistency = nil
292
- @mutation_state = nil
293
- yield self if block_given?
294
- end
295
-
296
- # Allows providing custom JSON key/value pairs for advanced usage
297
- #
298
- # @param [String] key the parameter name (key of the JSON property)
299
- # @param [Object] value the parameter value (value of the JSON property)
300
- def raw(key, value)
301
- @raw_parameters[key] = JSON.generate(value)
302
- end
303
-
304
- # Customizes the consistency guarantees for this query
305
- #
306
- # @note overrides consistency level set by {#consistent_with}
307
- #
308
- # [+:not_bounded+] The indexer will return whatever state it has to the query engine at the time of query. This is the default (for single-statement requests).
309
- #
310
- # [+:request_plus+] The indexer will wait until all mutations have been processed at the time of request before returning to the query engine.
311
- #
312
- # @param [:not_bounded, :request_plus] level the index scan consistency to be used for this query
313
- def scan_consistency=(level)
314
- @mutation_state = nil if @mutation_state
315
- @scan_consistency = level
316
- end
317
-
318
- # Sets the mutation tokens this query should be consistent with
319
- #
320
- # @note overrides consistency level set by {#scan_consistency=}
321
- #
322
- # @param [MutationState] mutation_state the mutation state containing the mutation tokens
323
- def consistent_with(mutation_state)
324
- @scan_consistency = nil if @scan_consistency
325
- @mutation_state = mutation_state
326
- end
327
-
328
- # Sets positional parameters for the query
329
- #
330
- # @param [Array] positional the list of parameters that have to be substituted in the statement
331
- def positional_parameters(positional)
332
- @positional_parameters = positional
333
- @named_parameters = nil
334
- end
335
-
336
- # Sets named parameters for the query
337
- #
338
- # @param [Hash] named the key/value map of the parameters to substitute in the statement
339
- def named_parameters(named)
340
- @named_parameters = named
341
- @positional_parameters = nil
342
- end
343
- end
344
-
345
- class QueryResult
346
- # @return [QueryMetaData] returns object representing additional metadata associated with this query
347
- attr_accessor :meta_data
348
-
349
- attr_accessor :transcoder
350
-
351
- # Returns all rows converted using a transcoder
352
- #
353
- # @return [Array]
354
- def rows(transcoder = self.transcoder)
355
- @rows.lazy.map do |row|
356
- if transcoder == :json
357
- JSON.parse(row)
358
- else
359
- transcoder.call(row)
360
- end
361
- end
362
- end
363
-
364
- # @yieldparam [QueryResult] self
365
- def initialize
366
- yield self if block_given?
367
- @transcoder = :json
368
- end
369
- end
370
-
371
- class QueryMetaData
372
- # @return [String] returns the request identifier string of the query request
373
- attr_accessor :request_id
374
-
375
- # @return [String] returns the client context identifier string set of the query request
376
- attr_accessor :client_context_id
377
-
378
- # @return [Symbol] returns raw query execution status as returned by the query engine
379
- attr_accessor :status
380
-
381
- # @return [Hash] returns the signature as returned by the query engine which is then decoded as JSON object
382
- attr_accessor :signature
383
-
384
- # @return [Hash] returns the profiling information returned by the query engine which is then decoded as JSON object
385
- attr_accessor :profile
386
-
387
- # @return [QueryMetrics] metrics as returned by the query engine, if enabled
388
- attr_accessor :metrics
389
-
390
- # @return [List<QueryWarning>] list of warnings returned by the query engine
391
- attr_accessor :warnings
392
-
393
- # @yieldparam [QueryMetaData] self
394
- def initialize
395
- yield self if block_given?
396
- end
397
- end
398
-
399
- class QueryMetrics
400
- # @return [Integer] The total time taken for the request, that is the time from when the request was received until the results were returned
401
- attr_accessor :elapsed_time
402
-
403
- # @return [Integer] The time taken for the execution of the request, that is the time from when query execution started until the results were returned
404
- attr_accessor :execution_time
405
-
406
- # @return [Integer] the total number of results selected by the engine before restriction through LIMIT clause.
407
- attr_accessor :sort_count
408
-
409
- # @return [Integer] The total number of objects in the results.
410
- attr_accessor :result_count
411
-
412
- # @return [Integer] The total number of bytes in the results.
413
- attr_accessor :result_size
414
-
415
- # @return [Integer] The number of mutations that were made during the request.
416
- attr_accessor :mutation_count
417
-
418
- # @return [Integer] The number of errors that occurred during the request.
419
- attr_accessor :error_count
420
-
421
- # @return [Integer] The number of warnings that occurred during the request.
422
- attr_accessor :warning_count
423
-
424
- # @yieldparam [QueryMetrics] self
425
- def initialize
426
- yield self if block_given?
427
- end
428
- end
429
-
430
- # Represents a single warning returned from the query engine.
431
- class QueryWarning
432
- # @return [Integer]
433
- attr_accessor :code
434
-
435
- # @return [String]
436
- attr_accessor :message
437
-
438
- def initialize(code, message)
439
- @code = code
440
- @message = message
441
- end
442
- end
443
-
444
- class AnalyticsOptions
445
- def initialize
446
- yield self if block_given?
447
- end
448
- end
449
-
450
284
  class DiagnosticsOptions
451
285
  # @return [String] Holds custom report id.
452
286
  attr_accessor :report_id
@@ -458,9 +292,14 @@ module Couchbase
458
292
 
459
293
  private
460
294
 
295
+ # Initialize {Cluster} object
296
+ #
297
+ # @param [String] connection_string connection string used to locate the Couchbase Cluster
298
+ # @param [ClusterOptions] options custom options when creating the cluster connection
461
299
  def initialize(connection_string, options)
462
- hostname = connection_string[%r{^couchbase://(.*)}, 1]
463
- raise ArgumentError, "missing hostname" unless hostname
300
+ conn_info = Backend.parse_connection_string(connection_string)
301
+ raise ArgumentError, "missing hostname" if conn_info[:nodes].empty?
302
+ hostname = conn_info[:nodes].first[:address]
464
303
  raise ArgumentError, "options must have authenticator configured" unless options.authenticator
465
304
  username = options.authenticator.username
466
305
  raise ArgumentError, "missing username" unless username