couchbase 3.4.0-arm64-darwin-20 → 3.4.2-arm64-darwin-20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a2277769a3018bb5da68ff42d71fd07a5c58bf5ddf909a44df354b1de15e3b8
4
- data.tar.gz: cdbd1ea416416a893e98d8f407e7758bbad151d7f74ba5ff63e7cf43ddc27fe0
3
+ metadata.gz: faa96b8ef64469a07b7665a4d70a8f25cc43003361ee727c403db2514890b96b
4
+ data.tar.gz: 43936d9b52ce4a258d24a83111d85b4d19704d54a3ab26d5169a32c1af5d79d8
5
5
  SHA512:
6
- metadata.gz: 3180001d391d32cbe4fd6a2ccb0c11c6f716e1a89ee52995d7deba670e1f7da7607a1b25199c499a7950fae2cb96cb9a278ae0884b182bf45f67310d92ce29ec
7
- data.tar.gz: 12411839477ef27153db8de7a97e1fb81cb88259e5e0a9964b2ea510b65c47110eaa20f44d07013c0353f74ec258f385114eefcc1a6d6b33a13c688d067caaab
6
+ metadata.gz: 6ca2f3e4cd54458cc4b4ee6399d79ba31e716640f1727aaee9f37d8916a3de13f5cdcb8e4a4849fa4c9d50b6bbe982ed8c728351b957fa4f5484ae96d96ba891
7
+ data.tar.gz: 712cf52caa8edfeb978c879575f204d44c69f42f9867d1b2232337d6ce103a4407669136ad27619e721c35f0b2802b6530966662b0d0806bc45aad59810ed1b1
data/README.md CHANGED
@@ -23,7 +23,7 @@ The library has been tested with MRI 3.0, 3.1 and 3.2. Supported platforms are L
23
23
  Add this line to your application's Gemfile:
24
24
 
25
25
  ```ruby
26
- gem "couchbase", "3.4.0"
26
+ gem "couchbase", "3.4.2"
27
27
  ```
28
28
 
29
29
  And then execute:
@@ -139,7 +139,7 @@ Now the API reference is accessible using a web browser (where `VERSION` is the
139
139
 
140
140
  The gem is available as open source under the terms of the [Apache2 License](https://opensource.org/licenses/Apache-2.0).
141
141
 
142
- Copyright 2011-2021 Couchbase, Inc.
142
+ Copyright 2011-Present Couchbase, Inc.
143
143
 
144
144
  Licensed under the Apache License, Version 2.0 (the "License");
145
145
  you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ module Couchbase
38
38
  # collection.get("mydoc", Options::Get(transcoder: nil)).content #=> "foobar"
39
39
  #
40
40
  # @return [Collection::MutationResult]
41
- def append(id, content, options = Options::Append.new)
41
+ def append(id, content, options = Options::Append::DEFAULT)
42
42
  resp = @backend.document_append(@collection.bucket_name, @collection.scope_name, @collection.name,
43
43
  id, content, options.to_backend)
44
44
  Collection::MutationResult.new do |res|
@@ -59,7 +59,7 @@ module Couchbase
59
59
  # collection.get("mydoc", Options::Get(transcoder: nil)).content #=> "barfoo"
60
60
  #
61
61
  # @return [Collection::MutationResult]
62
- def prepend(id, content, options = Options::Prepend.new)
62
+ def prepend(id, content, options = Options::Prepend::DEFAULT)
63
63
  resp = @backend.document_prepend(@collection.bucket_name, @collection.scope_name, @collection.name,
64
64
  id, content, options.to_backend)
65
65
  Collection::MutationResult.new do |res|
@@ -80,7 +80,7 @@ module Couchbase
80
80
  # res.content #=> 10
81
81
  #
82
82
  # @return [CounterResult]
83
- def increment(id, options = Options::Increment.new)
83
+ def increment(id, options = Options::Increment::DEFAULT)
84
84
  resp = @backend.document_increment(@collection.bucket_name, @collection.scope_name, @collection.name, id,
85
85
  options.to_backend)
86
86
  CounterResult.new do |res|
@@ -102,7 +102,7 @@ module Couchbase
102
102
  # res.value #=> 98
103
103
  #
104
104
  # @return [CounterResult]
105
- def decrement(id, options = Options::Decrement.new)
105
+ def decrement(id, options = Options::Decrement::DEFAULT)
106
106
  resp = @backend.document_decrement(@collection.bucket_name, @collection.scope_name, @collection.name, id,
107
107
  options.to_backend)
108
108
  CounterResult.new do |res|
@@ -32,13 +32,13 @@ module Couchbase
32
32
 
33
33
  # Connect to the Couchbase cluster
34
34
  #
35
- # @overload connect(connection_string, options)
36
- # @param [String] connection_string connection string used to locate the Couchbase Cluster
35
+ # @overload connect(connection_string_or_config, options)
36
+ # @param [String, Configuration] connection_string_or_config connection string used to locate the Couchbase Cluster
37
37
  # @param [Options::Cluster] options custom options when creating the cluster connection
38
38
  #
39
- # @overload connect(connection_string, username, password, options)
39
+ # @overload connect(connection_string_or_config, username, password, options)
40
40
  # Shortcut for {PasswordAuthenticator}
41
- # @param [String] connection_string connection string used to locate the Couchbase Cluster
41
+ # @param [String] connection_string_or_config connection string used to locate the Couchbase Cluster
42
42
  # @param [String] username name of the user
43
43
  # @param [String] password password of the user
44
44
  # @param [Options::Cluster, nil] options custom options when creating the cluster connection
@@ -62,12 +62,16 @@ module Couchbase
62
62
  # @see https://docs.couchbase.com/server/current/manage/manage-security/configure-client-certificates.html
63
63
  #
64
64
  # @return [Cluster]
65
- def self.connect(connection_string, *options)
66
- regexp = /^((couchbases?|http):\/\/.*)$/i
67
- if regexp.match?(connection_string) || !connection_string.include?("://")
68
- Cluster.new(connection_string, *options)
65
+ def self.connect(connection_string_or_config, *options)
66
+ connection_string = if connection_string_or_config.is_a?(Configuration)
67
+ connection_string_or_config.connection_string
68
+ else
69
+ connection_string_or_config
70
+ end
71
+ if connection_string =~ /\Acouchbases?:\/\/.*\z/i || !connection_string.include?("://")
72
+ Cluster.new(connection_string_or_config, *options)
69
73
  else
70
- ClusterRegistry.instance.connect(connection_string, *options)
74
+ ClusterRegistry.instance.connect(connection_string_or_config, *options)
71
75
  end
72
76
  end
73
77
 
@@ -26,9 +26,14 @@ module Couchbase
26
26
  @handlers = {}
27
27
  end
28
28
 
29
- def connect(connection_string, *options)
29
+ def connect(connection_string_or_config, *options)
30
+ connection_string = if connection_string_or_config.is_a?(Configuration)
31
+ connection_string_or_config.connection_string
32
+ else
33
+ connection_string_or_config
34
+ end
30
35
  @handlers.each do |regexp, cluster_class|
31
- return cluster_class.connect(connection_string, *options) if regexp.match?(connection_string)
36
+ return cluster_class.connect(connection_string_or_config, *options) if regexp.match?(connection_string)
32
37
  end
33
38
  raise(Error::FeatureNotAvailable, "Connection string '#{connection_string}' not supported.")
34
39
  end
@@ -43,6 +43,11 @@ module Couchbase
43
43
  BinaryCollection.new(self)
44
44
  end
45
45
 
46
+ # @return [Management::CollectionQueryIndexManager]
47
+ def query_indexes
48
+ Management::CollectionQueryIndexManager.new(@backend, @bucket_name, @scope_name, @name)
49
+ end
50
+
46
51
  # Fetches the full document from the collection
47
52
  #
48
53
  # @param [String] id the document id which is used to uniquely identify it
@@ -33,10 +33,9 @@ module Couchbase
33
33
  private
34
34
 
35
35
  def load_configuration(settings)
36
- configuration = settings.with_indifferent_access
37
- @connection_string = configuration[:connection_string]
38
- @username = configuration[:username]
39
- @password = configuration[:password]
36
+ @connection_string = settings[:connection_string] || settings["connection_string"]
37
+ @username = settings[:username] || settings["username"]
38
+ @password = settings[:password] || settings["password"]
40
39
  end
41
40
 
42
41
  def load_yaml(path, environment)
@@ -21,6 +21,11 @@ module Couchbase
21
21
  # @return [Hash] attributes associated with the error
22
22
  attr_reader :context
23
23
 
24
+ def initialize(msg = nil, context = nil)
25
+ @context = context unless context.nil?
26
+ super(msg)
27
+ end
28
+
24
29
  def to_s
25
30
  defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super
26
31
  end
@@ -30,6 +35,11 @@ module Couchbase
30
35
  # @return [Hash] attributes associated with the error
31
36
  attr_reader :context
32
37
 
38
+ def initialize(msg = nil, context = nil)
39
+ @context = context unless context.nil?
40
+ super(msg)
41
+ end
42
+
33
43
  def to_s
34
44
  defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super
35
45
  end
Binary file
@@ -0,0 +1,183 @@
1
+ # Copyright 2023 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/management/query_index_manager"
16
+ require "couchbase/utils/time"
17
+
18
+ module Couchbase
19
+ module Management
20
+ class CollectionQueryIndexManager
21
+ alias inspect to_s
22
+
23
+ # @param [Couchbase::Backend] backend
24
+ # @param [String] bucket_name name of the bucket
25
+ # @param [String] scope_name name of the scope
26
+ # @param [String] collection_name name of the collection
27
+ def initialize(backend, bucket_name, scope_name, collection_name)
28
+ @backend = backend
29
+ @bucket_name = bucket_name
30
+ @scope_name = scope_name
31
+ @collection_name = collection_name
32
+ end
33
+
34
+ # Fetches all indexes from the server
35
+ #
36
+ # @param [Options::Query::GetAllIndexes] options
37
+ #
38
+ # @return [Array<QueryIndex>]
39
+ #
40
+ # @raise [ArgumentError]
41
+ def get_all_indexes(options = Options::Query::GetAllIndexes.new)
42
+ res = @backend.collection_query_index_get_all(@bucket_name, @scope_name, @collection_name, options.to_backend)
43
+ res[:indexes].map do |idx|
44
+ QueryIndex.new do |index|
45
+ index.name = idx[:name]
46
+ index.is_primary = idx[:is_primary]
47
+ index.type = idx[:type]
48
+ index.state = idx[:state]
49
+ index.bucket = idx[:bucket_name]
50
+ index.scope = idx[:scope_name]
51
+ index.collection = idx[:collection_name]
52
+ index.index_key = idx[:index_key]
53
+ index.condition = idx[:condition]
54
+ index.partition = idx[:partition]
55
+ end
56
+ end
57
+ end
58
+
59
+ # Creates a new index
60
+ #
61
+ # @param [String] index_name name of the index
62
+ # @param [Array<String>] fields the lists of fields to create th index over
63
+ # @param [Options::Query::CreateIndex] options
64
+ #
65
+ # @return void
66
+ #
67
+ # @raise [ArgumentError]
68
+ # @raise [Error::IndexExists]
69
+ def create_index(index_name, fields, options = Options::Query::CreateIndex.new)
70
+ unless options.scope_name.nil?
71
+ raise ArgumentError, "Scope name cannot be set in the options when using the Query Index manager at the collection level"
72
+ end
73
+
74
+ unless options.collection_name.nil?
75
+ raise ArgumentError, "Collection name cannot be set in the options when using the Query Index manager at the collection level"
76
+ end
77
+
78
+ @backend.collection_query_index_create(@bucket_name, @scope_name, @collection_name, index_name, fields, options.to_backend)
79
+ end
80
+
81
+ # Creates new primary index
82
+ #
83
+ # @param [Options::Query::CreatePrimaryIndex] options
84
+ #
85
+ # @return void
86
+ #
87
+ # @raise [ArgumentError]
88
+ # @raise [Error::IndexExists]
89
+ def create_primary_index(options = Options::Query::CreatePrimaryIndex.new)
90
+ unless options.scope_name.nil?
91
+ raise ArgumentError, "Scope name cannot be set in the options when using the Query Index manager at the collection level"
92
+ end
93
+
94
+ unless options.collection_name.nil?
95
+ raise ArgumentError, "Collection name cannot be set in the options when using the Query Index manager at the collection level"
96
+ end
97
+
98
+ @backend.collection_query_index_create_primary(@bucket_name, @scope_name, @collection_name, options.to_backend)
99
+ end
100
+
101
+ # Drops the index
102
+ #
103
+ # @param [String] index_name name of the index
104
+ # @param [Options::Query::DropIndex] options
105
+ #
106
+ # @return void
107
+ #
108
+ # @raise [ArgumentError]
109
+ # @raise [Error::IndexNotFound]
110
+ def drop_index(index_name, options = Options::Query::DropIndex.new)
111
+ unless options.scope_name.nil?
112
+ raise ArgumentError, "Scope name cannot be set in the options when using the Query Index manager at the collection level"
113
+ end
114
+
115
+ unless options.collection_name.nil?
116
+ raise ArgumentError, "Collection name cannot be set in the options when using the Query Index manager at the collection level"
117
+ end
118
+
119
+ @backend.collection_query_index_drop(@bucket_name, @scope_name, @collection_name, index_name, options.to_backend)
120
+ end
121
+
122
+ # Drops the primary index
123
+ #
124
+ # @param [Options::Query::DropPrimaryIndex] options
125
+ #
126
+ # @return void
127
+ #
128
+ # @raise [ArgumentError]
129
+ # @raise [Error::IndexNotFound]
130
+ def drop_primary_index(options = Options::Query::DropPrimaryIndex.new)
131
+ unless options.scope_name.nil?
132
+ raise ArgumentError, "Scope name cannot be set in the options when using the Query Index manager at the collection level"
133
+ end
134
+
135
+ unless options.collection_name.nil?
136
+ raise ArgumentError, "Collection name cannot be set in the options when using the Query Index manager at the collection level"
137
+ end
138
+
139
+ @backend.collection_query_index_drop_primary(@bucket_name, @scope_name, @collection_name, options.to_backend)
140
+ end
141
+
142
+ # Build all indexes which are currently in deferred state
143
+ #
144
+ # @param [Options::Query::BuildDeferredIndexes] options
145
+ #
146
+ # @return void
147
+ #
148
+ # @raise [ArgumentError]
149
+ def build_deferred_indexes(options = Options::Query::BuildDeferredIndexes.new)
150
+ @backend.collection_query_index_build_deferred(@bucket_name, @scope_name, @collection_name, options.to_backend)
151
+ end
152
+
153
+ # Polls indexes until they are online
154
+ #
155
+ # @param [Array<String>] index_names names of the indexes to watch
156
+ # @param [Integer, #in_milliseconds] timeout the time in milliseconds allowed for the operation to complete
157
+ # @param [Options::Query::WatchIndexes] options
158
+ #
159
+ # @raise [ArgumentError]
160
+ # @raise [Error::IndexNotFound]
161
+ def watch_indexes(index_names, timeout, options = Options::Query::WatchIndexes.new)
162
+ index_names.append("#primary") if options.watch_primary
163
+
164
+ interval_millis = 50
165
+ deadline = Time.now + (Utils::Time.extract_duration(timeout) * 0.001)
166
+ while Time.now <= deadline
167
+ get_all_opts = Options::Query::GetAllIndexes.new(timeout: ((deadline - Time.now) * 1000).round)
168
+ indexes = get_all_indexes(get_all_opts).select { |idx| index_names.include? idx.name }
169
+ indexes_not_found = index_names - indexes.map(&:name)
170
+ raise Error::IndexNotFound, "Failed to find the indexes: #{indexes_not_found.join(', ')}" unless indexes_not_found.empty?
171
+
172
+ all_online = indexes.all? { |idx| idx.state == :online }
173
+ return if all_online
174
+
175
+ sleep(interval_millis / 1000)
176
+ interval_millis += 500
177
+ interval_millis = 1000 if interval_millis > 1000
178
+ end
179
+ raise Error::UnambiguousTimeout, "Failed to find all indexes online within the allotted time"
180
+ end
181
+ end
182
+ end
183
+ end
@@ -14,6 +14,7 @@
14
14
 
15
15
  require "couchbase/errors"
16
16
  require "couchbase/options"
17
+ require "couchbase/utils/time"
17
18
 
18
19
  module Couchbase
19
20
  module Management
@@ -371,6 +372,10 @@ module Couchbase
371
372
  # @raise [ArgumentError]
372
373
  # @raise [Error::IndexExists]
373
374
  def create_index(bucket_name, index_name, fields, options = Options::Query::CreateIndex.new)
375
+ unless options.scope_name.nil? && options.collection_name.nil?
376
+ warn "The attributes 'scope_name' and 'collection_name' have been deprecated. Use 'collection.query_indexes' instead"
377
+ end
378
+
374
379
  @backend.query_index_create(bucket_name, index_name, fields, options.to_backend)
375
380
  end
376
381
 
@@ -384,6 +389,10 @@ module Couchbase
384
389
  # @raise [ArgumentError]
385
390
  # @raise [Error::IndexExists]
386
391
  def create_primary_index(bucket_name, options = Options::Query::CreatePrimaryIndex.new)
392
+ unless options.scope_name.nil? && options.collection_name.nil?
393
+ warn "The attributes 'scope_name' and 'collection_name' have been deprecated. Use 'collection.query_indexes' instead"
394
+ end
395
+
387
396
  @backend.query_index_create_primary(bucket_name, options.to_backend)
388
397
  end
389
398
 
@@ -398,8 +407,11 @@ module Couchbase
398
407
  # @raise [ArgumentError]
399
408
  # @raise [Error::IndexNotFound]
400
409
  def drop_index(bucket_name, index_name, options = Options::Query::DropIndex.new)
410
+ unless options.scope_name.nil? && options.collection_name.nil?
411
+ warn "The attributes 'scope_name' and 'collection_name' have been deprecated. Use 'collection.query_indexes' instead"
412
+ end
413
+
401
414
  @backend.query_index_drop(bucket_name, index_name, options.to_backend)
402
- true
403
415
  end
404
416
 
405
417
  # Drops the primary index
@@ -412,8 +424,11 @@ module Couchbase
412
424
  # @raise [ArgumentError]
413
425
  # @raise [Error::IndexNotFound]
414
426
  def drop_primary_index(bucket_name, options = Options::Query::DropPrimaryIndex.new)
427
+ unless options.scope_name.nil? && options.collection_name.nil?
428
+ warn "The attributes 'scope_name' and 'collection_name' have been deprecated. Use 'collection.query_indexes' instead"
429
+ end
430
+
415
431
  @backend.query_index_drop_primary(bucket_name, options.to_backend)
416
- true
417
432
  end
418
433
 
419
434
  # Build all indexes which are currently in deferred state
@@ -438,7 +453,24 @@ module Couchbase
438
453
  # @raise [ArgumentError]
439
454
  # @raise [Error::IndexNotFound]
440
455
  def watch_indexes(bucket_name, index_names, timeout, options = Options::Query::WatchIndexes.new)
441
- @backend.query_index_watch(bucket_name, index_names, Utils::Time.extract_duration(timeout), options.to_backend)
456
+ index_names.append("#primary") if options.watch_primary
457
+
458
+ interval_millis = 50
459
+ deadline = Time.now + (Utils::Time.extract_duration(timeout) * 0.001)
460
+ while Time.now <= deadline
461
+ get_all_opts = Options::Query::GetAllIndexes.new(timeout: ((deadline - Time.now) * 1000).round)
462
+ indexes = get_all_indexes(bucket_name, get_all_opts).select { |idx| index_names.include? idx.name }
463
+ indexes_not_found = index_names - indexes.map(&:name)
464
+ raise Error::IndexNotFound, "Failed to find the indexes: #{indexes_not_found.join(', ')}" unless indexes_not_found.empty?
465
+
466
+ all_online = indexes.all? { |idx| idx.state == :online }
467
+ return if all_online
468
+
469
+ sleep(interval_millis / 1000)
470
+ interval_millis += 500
471
+ interval_millis = 1000 if interval_millis > 1000
472
+ end
473
+ raise Error::UnambiguousTimeout, "Failed to find all indexes online within the allotted time"
442
474
  end
443
475
 
444
476
  # @api private
@@ -22,6 +22,7 @@ require "couchbase/management/analytics_index_manager"
22
22
  require "couchbase/management/bucket_manager"
23
23
  require "couchbase/management/collection_manager"
24
24
  require "couchbase/management/query_index_manager"
25
+ require "couchbase/management/collection_query_index_manager"
25
26
  require "couchbase/management/search_index_manager"
26
27
  require "couchbase/management/user_manager"
27
28
  require "couchbase/management/view_index_manager"
@@ -1029,10 +1029,38 @@ module Couchbase
1029
1029
  # Options for {BinaryCollection#append}
1030
1030
  class Append < Base
1031
1031
  attr_accessor :cas # @return [Integer]
1032
+ attr_accessor :durability_level # @return [Symbol]
1033
+ attr_accessor :replicate_to # @return [Symbol]
1034
+ attr_accessor :persist_to # @return [Symbol]
1032
1035
 
1033
1036
  # Creates an instance of options for {BinaryCollection#append}
1034
1037
  #
1035
1038
  # @param [Integer] cas The default CAS used (0 means no CAS in this context)
1039
+ # @param [Symbol] durability_level level of durability
1040
+ # +:none+::
1041
+ # no enhanced durability required for the mutation
1042
+ # +:majority+::
1043
+ # the mutation must be replicated to a majority of the Data Service nodes
1044
+ # (that is, held in the memory allocated to the bucket)
1045
+ # +:majority_and_persist_to_active+::
1046
+ # The mutation must be replicated to a majority of the Data Service nodes.
1047
+ # Additionally, it must be persisted (that is, written and synchronised to disk) on the
1048
+ # node hosting the active partition (vBucket) for the data.
1049
+ # +:persist_to_majority+::
1050
+ # The mutation must be persisted to a majority of the Data Service nodes.
1051
+ # Accordingly, it will be written to disk on those nodes.
1052
+ # @param [Symbol] replicate_to number of nodes to replicate
1053
+ # +:none+:: do not apply any replication requirements.
1054
+ # +:one+:: wait for replication to at least one node.
1055
+ # +:two+:: wait for replication to at least two nodes.
1056
+ # +:three+:: wait for replication to at least three nodes.
1057
+ # @param [Symbol] persist_to number of nodes to persist
1058
+ # +:none+:: do not apply any persistence requirements.
1059
+ # +:active+:: wait for persistence to active node
1060
+ # +:one+:: wait for persistence to at least one node.
1061
+ # +:two+:: wait for persistence to at least two nodes.
1062
+ # +:three+:: wait for persistence to at least three nodes.
1063
+ # +:four+:: wait for persistence to four nodes (active and replicas).
1036
1064
  #
1037
1065
  # @param [Integer, #in_milliseconds, nil] timeout
1038
1066
  # @param [Proc, nil] retry_strategy the custom retry strategy, if set
@@ -1041,12 +1069,23 @@ module Couchbase
1041
1069
  #
1042
1070
  # @yieldparam [Append] self
1043
1071
  def initialize(cas: nil,
1072
+ durability_level: :none,
1073
+ replicate_to: :none,
1074
+ persist_to: :none,
1044
1075
  timeout: nil,
1045
1076
  retry_strategy: nil,
1046
1077
  client_context: nil,
1047
1078
  parent_span: nil)
1048
1079
  super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
1049
1080
  @cas = cas
1081
+
1082
+ if durability_level != :none && (replicate_to != :none || persist_to != :none)
1083
+ raise ArgumentError, "durability_level conflicts with replicate_to and persist_to options"
1084
+ end
1085
+
1086
+ @durability_level = durability_level
1087
+ @replicate_to = replicate_to
1088
+ @persist_to = persist_to
1050
1089
  yield self if block_given?
1051
1090
  end
1052
1091
 
@@ -1055,6 +1094,9 @@ module Couchbase
1055
1094
  {
1056
1095
  timeout: Utils::Time.extract_duration(@timeout),
1057
1096
  cas: @cas,
1097
+ durability_level: @durability_level,
1098
+ persist_to: @persist_to,
1099
+ replicate_to: @replicate_to,
1058
1100
  }
1059
1101
  end
1060
1102
 
@@ -1064,12 +1106,39 @@ module Couchbase
1064
1106
 
1065
1107
  # Options for {BinaryCollection#prepend}
1066
1108
  class Prepend < Base
1067
- # @return [Integer] The default CAS used (0 means no CAS in this context)
1068
- attr_accessor :cas
1109
+ attr_accessor :cas # @return [Integer]
1110
+ attr_accessor :durability_level # @return [Symbol]
1111
+ attr_accessor :replicate_to # @return [Symbol]
1112
+ attr_accessor :persist_to # @return [Symbol]
1069
1113
 
1070
1114
  # Creates an instance of options for {BinaryCollection#prepend}
1071
1115
  #
1072
1116
  # @param [Integer] cas The default CAS used (0 means no CAS in this context)
1117
+ # @param [Symbol] durability_level level of durability
1118
+ # +:none+::
1119
+ # no enhanced durability required for the mutation
1120
+ # +:majority+::
1121
+ # the mutation must be replicated to a majority of the Data Service nodes
1122
+ # (that is, held in the memory allocated to the bucket)
1123
+ # +:majority_and_persist_to_active+::
1124
+ # The mutation must be replicated to a majority of the Data Service nodes.
1125
+ # Additionally, it must be persisted (that is, written and synchronised to disk) on the
1126
+ # node hosting the active partition (vBucket) for the data.
1127
+ # +:persist_to_majority+::
1128
+ # The mutation must be persisted to a majority of the Data Service nodes.
1129
+ # Accordingly, it will be written to disk on those nodes.
1130
+ # @param [Symbol] replicate_to number of nodes to replicate
1131
+ # +:none+:: do not apply any replication requirements.
1132
+ # +:one+:: wait for replication to at least one node.
1133
+ # +:two+:: wait for replication to at least two nodes.
1134
+ # +:three+:: wait for replication to at least three nodes.
1135
+ # @param [Symbol] persist_to number of nodes to persist
1136
+ # +:none+:: do not apply any persistence requirements.
1137
+ # +:active+:: wait for persistence to active node
1138
+ # +:one+:: wait for persistence to at least one node.
1139
+ # +:two+:: wait for persistence to at least two nodes.
1140
+ # +:three+:: wait for persistence to at least three nodes.
1141
+ # +:four+:: wait for persistence to four nodes (active and replicas).
1073
1142
  #
1074
1143
  # @param [Integer, #in_milliseconds, nil] timeout
1075
1144
  # @param [Proc, nil] retry_strategy the custom retry strategy, if set
@@ -1078,12 +1147,23 @@ module Couchbase
1078
1147
  #
1079
1148
  # @yieldparam [Prepend] self
1080
1149
  def initialize(cas: nil,
1150
+ durability_level: :none,
1151
+ replicate_to: :none,
1152
+ persist_to: :none,
1081
1153
  timeout: nil,
1082
1154
  retry_strategy: nil,
1083
1155
  client_context: nil,
1084
1156
  parent_span: nil)
1085
1157
  super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
1086
1158
  @cas = cas
1159
+
1160
+ if durability_level != :none && (replicate_to != :none || persist_to != :none)
1161
+ raise ArgumentError, "durability_level conflicts with replicate_to and persist_to options"
1162
+ end
1163
+
1164
+ @durability_level = durability_level
1165
+ @replicate_to = replicate_to
1166
+ @persist_to = persist_to
1087
1167
  yield self if block_given?
1088
1168
  end
1089
1169
 
@@ -1092,6 +1172,9 @@ module Couchbase
1092
1172
  {
1093
1173
  timeout: Utils::Time.extract_duration(@timeout),
1094
1174
  cas: @cas,
1175
+ durability_level: @durability_level,
1176
+ persist_to: @persist_to,
1177
+ replicate_to: @replicate_to,
1095
1178
  }
1096
1179
  end
1097
1180
 
@@ -2091,7 +2174,7 @@ module Couchbase
2091
2174
  attr_reader :scan_consistency
2092
2175
 
2093
2176
  # @api private
2094
- def to_backend(scope_name: nil)
2177
+ def to_backend(*)
2095
2178
  {
2096
2179
  timeout: Utils::Time.extract_duration(@timeout),
2097
2180
  limit: @limit,
@@ -2099,8 +2182,7 @@ module Couchbase
2099
2182
  explain: @explain,
2100
2183
  disable_scoring: @disable_scoring,
2101
2184
  include_locations: @include_locations,
2102
- scope: scope_name,
2103
- collections: scope_name ? @collections : nil,
2185
+ collections: @collections,
2104
2186
  highlight_style: @highlight_style,
2105
2187
  highlight_fields: @highlight_fields,
2106
2188
  fields: @fields,