couchbase 3.4.0-arm64-darwin-20

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +202 -0
  3. data/README.md +154 -0
  4. data/ext/extconf.rb +0 -0
  5. data/lib/active_support/cache/couchbase_store.rb +339 -0
  6. data/lib/couchbase/analytics_options.rb +107 -0
  7. data/lib/couchbase/authenticator.rb +65 -0
  8. data/lib/couchbase/binary_collection.rb +128 -0
  9. data/lib/couchbase/binary_collection_options.rb +24 -0
  10. data/lib/couchbase/bucket.rb +144 -0
  11. data/lib/couchbase/cluster.rb +439 -0
  12. data/lib/couchbase/cluster_registry.rb +44 -0
  13. data/lib/couchbase/collection.rb +589 -0
  14. data/lib/couchbase/collection_options.rb +300 -0
  15. data/lib/couchbase/config_profiles.rb +55 -0
  16. data/lib/couchbase/configuration.rb +57 -0
  17. data/lib/couchbase/datastructures/couchbase_list.rb +160 -0
  18. data/lib/couchbase/datastructures/couchbase_map.rb +194 -0
  19. data/lib/couchbase/datastructures/couchbase_queue.rb +134 -0
  20. data/lib/couchbase/datastructures/couchbase_set.rb +128 -0
  21. data/lib/couchbase/datastructures.rb +24 -0
  22. data/lib/couchbase/diagnostics.rb +181 -0
  23. data/lib/couchbase/errors.rb +351 -0
  24. data/lib/couchbase/json_transcoder.rb +32 -0
  25. data/lib/couchbase/libcouchbase.bundle +0 -0
  26. data/lib/couchbase/logger.rb +85 -0
  27. data/lib/couchbase/management/analytics_index_manager.rb +1127 -0
  28. data/lib/couchbase/management/bucket_manager.rb +436 -0
  29. data/lib/couchbase/management/collection_manager.rb +321 -0
  30. data/lib/couchbase/management/query_index_manager.rb +520 -0
  31. data/lib/couchbase/management/search_index_manager.rb +408 -0
  32. data/lib/couchbase/management/user_manager.rb +468 -0
  33. data/lib/couchbase/management/view_index_manager.rb +237 -0
  34. data/lib/couchbase/management.rb +27 -0
  35. data/lib/couchbase/mutation_state.rb +63 -0
  36. data/lib/couchbase/options.rb +2580 -0
  37. data/lib/couchbase/query_options.rb +120 -0
  38. data/lib/couchbase/railtie.rb +45 -0
  39. data/lib/couchbase/scope.rb +232 -0
  40. data/lib/couchbase/search_options.rb +1570 -0
  41. data/lib/couchbase/subdoc.rb +290 -0
  42. data/lib/couchbase/utils/generic_logger_adapter.rb +38 -0
  43. data/lib/couchbase/utils/stdlib_logger_adapter.rb +65 -0
  44. data/lib/couchbase/utils/time.rb +56 -0
  45. data/lib/couchbase/utils.rb +21 -0
  46. data/lib/couchbase/version.rb +23 -0
  47. data/lib/couchbase/view_options.rb +65 -0
  48. data/lib/couchbase.rb +20 -0
  49. data/lib/rails/generators/couchbase/config/config_generator.rb +27 -0
  50. metadata +101 -0
@@ -0,0 +1,300 @@
1
+ # Copyright 2020-2021 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 "rubygems/deprecate"
16
+
17
+ require "couchbase/json_transcoder"
18
+ require "couchbase/subdoc"
19
+ require "couchbase/mutation_state"
20
+
21
+ module Couchbase
22
+ class Collection
23
+ class GetResult
24
+ extend Gem::Deprecate
25
+
26
+ # @return [Integer] holds the CAS value of the fetched document
27
+ attr_accessor :cas
28
+
29
+ # @return [Integer] the expiration if fetched and present
30
+ attr_writer :expiry
31
+
32
+ # @return [Error::CouchbaseError, nil] error associated with the result, or nil (used in {Collection#get_multi})
33
+ attr_accessor :error
34
+
35
+ # @return [String, nil] identifier of the document (used for {Collection#get_multi})
36
+ attr_accessor :id
37
+
38
+ # @return [Boolean] true if error was not associated with the result (useful for multi-operations)
39
+ def success?
40
+ !error
41
+ end
42
+
43
+ # @return [String] The encoded content when loading the document
44
+ # @api private
45
+ attr_accessor :encoded
46
+
47
+ # Decodes the content of the document using given (or default transcoder)
48
+ #
49
+ # @param [JsonTranscoder] transcoder custom transcoder
50
+ #
51
+ # @return [Object]
52
+ def content(transcoder = self.transcoder)
53
+ transcoder ? transcoder.decode(@encoded, @flags) : @encoded
54
+ end
55
+
56
+ # @return [Time] time when the document will expire
57
+ def expiry_time
58
+ Time.at(@expiry) if @expiry
59
+ end
60
+
61
+ # @yieldparam [GetResult] self
62
+ def initialize
63
+ @expiry = nil
64
+ @error = nil
65
+ @id = nil
66
+ yield self if block_given?
67
+ end
68
+
69
+ # @return [Integer] The flags from the operation
70
+ # @api private
71
+ attr_accessor :flags
72
+
73
+ # @return [JsonTranscoder] The default transcoder which should be used
74
+ attr_accessor :transcoder
75
+
76
+ # @deprecated Use {#expiry_time}
77
+ # @return [Integer] the expiration if fetched and present
78
+ def expiry # rubocop:disable Style/TrivialAccessors will be removed in next major release
79
+ @expiry
80
+ end
81
+
82
+ deprecate :expiry, :expiry_time, 2021, 1
83
+ end
84
+
85
+ class GetReplicaResult < GetResult
86
+ # @return [Boolean] true if this result came from a replica
87
+ attr_accessor :is_replica
88
+ alias replica? is_replica
89
+ end
90
+
91
+ class ExistsResult
92
+ # @return [Integer] holds the CAS value of the fetched document
93
+ attr_accessor :cas
94
+
95
+ # @return [Boolean] true if the document was deleted
96
+ attr_accessor :deleted
97
+
98
+ # @return [Boolean] true if the document exists
99
+ attr_accessor :exists
100
+ alias exists? exists
101
+
102
+ # @yieldparam [ExistsResult]
103
+ def initialize
104
+ yield self if block_given?
105
+ end
106
+
107
+ # @return [Integer] the expiration if fetched and present
108
+ attr_writer :expiry
109
+
110
+ # @return [Time] time when the document will expire
111
+ def expiry_time
112
+ Time.at(@expiry) if @expiry
113
+ end
114
+
115
+ # @api private
116
+ # @return [Integer] flags
117
+ attr_accessor :flags
118
+
119
+ # @api private
120
+ # @return [Integer] sequence_number
121
+ attr_accessor :sequence_number
122
+
123
+ # @api private
124
+ # @return [Integer] datatype
125
+ attr_accessor :datatype
126
+ end
127
+
128
+ class MutationResult
129
+ # @return [Integer] holds the CAS value of the document after the mutation
130
+ attr_accessor :cas
131
+
132
+ # @return [MutationToken] if returned, holds the mutation token of the document after the mutation
133
+ attr_accessor :mutation_token
134
+
135
+ # @return [Error::CouchbaseError, nil] error or nil (used in multi-operations like {Collection#upsert_multi},
136
+ # {Collection#remove_multi})
137
+ attr_accessor :error
138
+
139
+ # @return [String, nil] identifier of the document (used in multi-operations like {Collection#upsert_multi},
140
+ # {Collection#remove_multi})
141
+ attr_accessor :id
142
+
143
+ # @return [Boolean] true if error was not associated with the result (useful for multi-operations)
144
+ def success?
145
+ !error
146
+ end
147
+
148
+ # @yieldparam [MutationResult] self
149
+ def initialize
150
+ @error = nil
151
+ @id = nil
152
+ yield self if block_given?
153
+ end
154
+ end
155
+
156
+ class LookupInResult
157
+ # @return [Integer] holds the CAS value of the fetched document
158
+ attr_accessor :cas
159
+
160
+ # Decodes the content at the given index (or path)
161
+ #
162
+ # @param [Integer, String] path_or_index the index (or path) of the subdocument value to decode
163
+ #
164
+ # @return [Object] the decoded
165
+ def content(path_or_index, transcoder = self.transcoder)
166
+ field = get_field_at_index(path_or_index)
167
+ raise Error::PathNotFound, "Path is not found: #{path_or_index}" unless field.exists
168
+
169
+ transcoder.decode(field.value, :json)
170
+ end
171
+
172
+ # Allows to check if a value at the given index exists
173
+ #
174
+ # @param [Integer, String] path_or_index the index (or path) of the subdocument value to check
175
+ #
176
+ # @return [Boolean] true if a value is present at the index, false otherwise
177
+ def exists?(path_or_index)
178
+ field =
179
+ case path_or_index
180
+ when String
181
+ encoded.find { |f| f.path == path_or_index }
182
+ else
183
+ return false unless path_or_index >= 0 && path_or_index < encoded.size
184
+
185
+ encoded[path_or_index]
186
+ end
187
+ return false unless field
188
+
189
+ field.exists
190
+ end
191
+
192
+ # @return [Array<SubDocumentField>] holds the encoded subdocument responses
193
+ attr_accessor :encoded
194
+
195
+ # @yieldparam [LookupInResult] self
196
+ def initialize
197
+ @deleted = false
198
+ yield self if block_given?
199
+ end
200
+
201
+ # @return [JsonTranscoder] The default transcoder which should be used
202
+ attr_accessor :transcoder
203
+
204
+ # @api private
205
+ #
206
+ # @see MutateInOptions#create_as_deleted
207
+ #
208
+ # @return [Boolean] true if the document is a tombstone (created in deleted state)
209
+ def deleted?
210
+ @deleted
211
+ end
212
+
213
+ # @api private
214
+ attr_accessor :deleted
215
+
216
+ private
217
+
218
+ def get_field_at_index(path_or_index)
219
+ case path_or_index
220
+ when String
221
+ encoded.find { |field| field.path == path_or_index } or raise Error::PathInvalid, "Path is not found: #{path_or_index}"
222
+ else
223
+ raise Error::PathInvalid, "Index is out of bounds: #{path_or_index}" unless path_or_index >= 0 && path_or_index < encoded.size
224
+
225
+ encoded[path_or_index]
226
+ end
227
+ end
228
+ end
229
+
230
+ class MutateInResult < MutationResult
231
+ # Decodes the content at the given index
232
+ #
233
+ # @param [Integer, String] path_or_index the index (or path) of the subdocument value to decode
234
+ #
235
+ # @return [Object] the decoded
236
+ def content(path_or_index, transcoder = self.transcoder)
237
+ field = get_field_at_index(path_or_index)
238
+ transcoder.decode(field.value, :json)
239
+ end
240
+
241
+ # @yieldparam [MutateInResult] self
242
+ def initialize
243
+ super
244
+ yield self if block_given?
245
+ end
246
+
247
+ # @return [Array<SubDocumentField>] holds the encoded subdocument responses
248
+ # @api private
249
+ attr_accessor :encoded
250
+
251
+ # @return [JsonTranscoder] The default transcoder which should be used
252
+ attr_accessor :transcoder
253
+
254
+ # @api private
255
+ #
256
+ # @see MutateInOptions#create_as_deleted
257
+ #
258
+ # @return [Boolean] true if the document is a tombstone (created in deleted state)
259
+ def deleted?
260
+ @deleted
261
+ end
262
+
263
+ # @api private
264
+ attr_accessor :deleted
265
+
266
+ private
267
+
268
+ def get_field_at_index(path_or_index)
269
+ case path_or_index
270
+ when String
271
+ encoded.find { |field| field.path == path_or_index } or raise Error::PathInvalid, "Path is not found: #{path_or_index}"
272
+ else
273
+ raise Error::PathInvalid, "Index is out of bounds: #{path_or_index}" unless path_or_index >= 0 && path_or_index < encoded.size
274
+
275
+ encoded[path_or_index]
276
+ end
277
+ end
278
+ end
279
+
280
+ # @api private
281
+ class SubDocumentField
282
+ # @return [Boolean] true if the path exists in the document
283
+ attr_accessor :exists
284
+
285
+ # @return [String] value
286
+ attr_accessor :value
287
+
288
+ # @return [Integer] index
289
+ attr_accessor :index
290
+
291
+ # @return [String] path
292
+ attr_accessor :path
293
+
294
+ # @yieldparam [SubDocumentField] self
295
+ def initialize
296
+ yield self if block_given?
297
+ end
298
+ end
299
+ end
300
+ end
@@ -0,0 +1,55 @@
1
+ # Copyright 2020-2022 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
+ module Couchbase
16
+ module ConfigProfiles
17
+ class Profiles
18
+ attr :profiles
19
+
20
+ def initialize
21
+ @profiles = {}
22
+ register_profile("wan_development", DevelopmentProfile.new)
23
+ end
24
+
25
+ def register_profile(name, profile)
26
+ @profiles[name] = profile
27
+ end
28
+
29
+ def apply(profile_name, options)
30
+ raise ArgumentError, "#{profile_name} is not a registered profile" unless @profiles.key?(profile_name)
31
+
32
+ @profiles[profile_name].apply(options)
33
+ end
34
+ end
35
+
36
+ class Profile
37
+ def apply(options); end
38
+ end
39
+
40
+ class DevelopmentProfile < Profile
41
+ def apply(options)
42
+ options.key_value_timeout = 20_000
43
+ # TODO: Add `options.key_value_durable_timeout = 20_000` when key_value_durable_timeout is added to Options::Cluster
44
+ options.connect_timeout = 20_000
45
+ options.view_timeout = 120_000
46
+ options.query_timeout = 120_000
47
+ options.analytics_timeout = 120_000
48
+ options.search_timeout = 120_000
49
+ options.management_timeout = 120_000
50
+ end
51
+ end
52
+
53
+ KNOWN_PROFILES = Profiles.new
54
+ end
55
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright 2020-2021 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 "yaml"
16
+ require "erb"
17
+
18
+ module Couchbase
19
+ class Configuration
20
+ attr_accessor :connection_string
21
+ attr_accessor :username
22
+ attr_accessor :password
23
+
24
+ def initialize
25
+ @connection_string = "couchbase://localhost"
26
+ end
27
+
28
+ def load!(path, environment = default_environment_name)
29
+ settings = load_yaml(path, environment)
30
+ load_configuration(settings)
31
+ end
32
+
33
+ private
34
+
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]
40
+ end
41
+
42
+ def load_yaml(path, environment)
43
+ file_content = ERB.new(File.read(path)).result
44
+ YAML.safe_load(file_content, aliases: :default)[environment]
45
+ end
46
+
47
+ def default_environment_name
48
+ if defined?(::Rails)
49
+ ::Rails.env
50
+ elsif defined?(::Sinatra)
51
+ ::Sinatra::Base.environment.to_s
52
+ else
53
+ ENV.fetch("RACK_ENV", nil) || ENV.fetch("COUCHBASE_ENV", nil) or raise ::Couchbase::Error::NoEnvironment
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,160 @@
1
+ # Copyright 2020-2021 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/collection"
16
+ require "couchbase/errors"
17
+ require "couchbase/options"
18
+
19
+ module Couchbase
20
+ module Datastructures
21
+ # A {CouchbaseList} is implements +Enumerable+ interface and backed by {Collection} document (more specifically
22
+ # a JSON array).
23
+ #
24
+ # Note that as such, a {CouchbaseList} is restricted to the types that JSON array can contain.
25
+ class CouchbaseList
26
+ include Enumerable
27
+
28
+ # Create a new List, backed by the document identified by +id+ in +collection+.
29
+ #
30
+ # @param [String] id the id of the document to back the list.
31
+ # @param [Collection] collection the Couchbase collection through which to interact with the document.
32
+ # @param [Options::CouchbaseList] options customization of the datastructure
33
+ def initialize(id, collection, options = Options::CouchbaseList.new)
34
+ @id = id
35
+ @collection = collection
36
+ @options = options
37
+ @cas = 0
38
+ end
39
+
40
+ # Calls the given block once for each element in the list, passing that element as a parameter.
41
+ #
42
+ # @yieldparam [Object] item
43
+ #
44
+ # @return [CouchbaseList, Enumerable]
45
+ def each
46
+ if block_given?
47
+ begin
48
+ result = @collection.get(@id, @options.get_options)
49
+ current = result.content
50
+ @cas = result.cas
51
+ rescue Error::DocumentNotFound
52
+ current = []
53
+ @cas = 0
54
+ end
55
+ current.each do |entry|
56
+ yield entry
57
+ end
58
+ self
59
+ else
60
+ enum_for(:each)
61
+ end
62
+ end
63
+
64
+ # @return [Integer] returns the number of elements in the list.
65
+ def length
66
+ result = @collection.lookup_in(@id, [
67
+ LookupInSpec.count(""),
68
+ ], @options.lookup_in_options)
69
+ result.content(0)
70
+ rescue Error::DocumentNotFound
71
+ 0
72
+ end
73
+
74
+ alias size length
75
+
76
+ # @return [Boolean] returns true if list is empty
77
+ def empty?
78
+ size.zero?
79
+ end
80
+
81
+ # Appends the given object(s) on to the end of this error. This expression returns the array itself, so several
82
+ # appends may be chained together.
83
+ #
84
+ # @param [Object...] obj object(s) to append
85
+ # @return [CouchbaseList]
86
+ def push(*obj)
87
+ @collection.mutate_in(@id, [
88
+ MutateInSpec.array_append("", obj),
89
+ ], @options.mutate_in_options)
90
+ self
91
+ end
92
+
93
+ alias append push
94
+
95
+ # Prepends objects to the front of the list, moving other elements upwards
96
+ #
97
+ # @param [Object...] obj object(s) to prepend
98
+ # @return [CouchbaseList]
99
+ def unshift(*obj)
100
+ @collection.mutate_in(@id, [
101
+ MutateInSpec.array_prepend("", obj),
102
+ ], @options.mutate_in_options)
103
+ self
104
+ end
105
+
106
+ alias prepend unshift
107
+
108
+ # Inserts the given values before the element with the given +index+.
109
+ #
110
+ # @param [Integer] index
111
+ # @param [Object...] obj object(s) to insert
112
+ # @return [CouchbaseList]
113
+ def insert(index, *obj)
114
+ @collection.mutate_in(@id, [
115
+ MutateInSpec.array_insert("[#{index.to_i}]", obj),
116
+ ])
117
+ self
118
+ end
119
+
120
+ # Returns the element at +index+. A negative index counts from the end. Returns +nil+ if the index is out of range.
121
+ #
122
+ # @param [Integer] index
123
+ # @return [Object, nil]
124
+ def at(index)
125
+ result = @collection.lookup_in(@id, [
126
+ LookupInSpec.get("[#{index.to_i}]"),
127
+ ], @options.lookup_in_options)
128
+ result.exists?(0) ? result.content(0) : nil
129
+ rescue Error::DocumentNotFound
130
+ nil
131
+ end
132
+
133
+ alias [] at
134
+
135
+ # Deletes the element at the specified +index+, returning that element, or nil
136
+ #
137
+ # @param [Integer] index
138
+ # @return [CouchbaseList]
139
+ def delete_at(index)
140
+ @collection.mutate_in(@id, [
141
+ MutateInSpec.remove("[#{index.to_i}]"),
142
+ ])
143
+ self
144
+ rescue Error::DocumentNotFound
145
+ self
146
+ end
147
+
148
+ # Removes all elements from the list
149
+ def clear
150
+ @collection.remove(@id, @options.remove_options)
151
+ nil
152
+ rescue Error::DocumentNotFound
153
+ nil
154
+ end
155
+ end
156
+
157
+ # @api private
158
+ CouchbaseListOptions = ::Couchbase::Options::CouchbaseList
159
+ end
160
+ end