couchbase 3.0.0.alpha.5-universal-darwin-19 → 3.0.0.beta.1-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.
- checksums.yaml +4 -4
- data/Gemfile +12 -3
- data/README.md +4 -2
- data/Rakefile +1 -1
- data/couchbase.gemspec +17 -12
- data/ext/.idea/misc.xml +12 -0
- data/ext/CMakeLists.txt +10 -1
- data/ext/build_config.hxx.in +20 -0
- data/ext/build_version.hxx.in +1 -1
- data/ext/couchbase/bucket.hxx +90 -24
- data/ext/couchbase/cluster.hxx +125 -84
- data/ext/couchbase/cluster_options.hxx +53 -0
- data/ext/couchbase/configuration.hxx +220 -2
- data/ext/couchbase/couchbase.cxx +134 -127
- data/ext/couchbase/io/dns_client.hxx +3 -1
- data/ext/couchbase/io/http_command.hxx +91 -0
- data/ext/couchbase/io/http_session.hxx +58 -19
- data/ext/couchbase/io/http_session_manager.hxx +26 -31
- data/ext/couchbase/io/mcbp_command.hxx +180 -0
- data/ext/couchbase/io/mcbp_message.hxx +5 -0
- data/ext/couchbase/io/mcbp_session.hxx +213 -98
- data/ext/couchbase/io/streams.hxx +165 -0
- data/ext/couchbase/operations.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataset_create.hxx +1 -1
- data/ext/couchbase/operations/bucket_create.hxx +4 -2
- data/ext/couchbase/operations/bucket_drop.hxx +4 -2
- data/ext/couchbase/operations/bucket_flush.hxx +4 -2
- data/ext/couchbase/operations/bucket_get.hxx +4 -2
- data/ext/couchbase/operations/bucket_get_all.hxx +4 -2
- data/ext/couchbase/operations/bucket_update.hxx +4 -2
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +4 -2
- data/ext/couchbase/operations/collection_create.hxx +4 -2
- data/ext/couchbase/operations/collection_drop.hxx +4 -2
- data/ext/couchbase/operations/document_analytics.hxx +0 -4
- data/ext/couchbase/operations/document_decrement.hxx +6 -3
- data/ext/couchbase/operations/document_get.hxx +3 -0
- data/ext/couchbase/operations/document_get_and_lock.hxx +3 -0
- data/ext/couchbase/operations/document_get_and_touch.hxx +5 -2
- data/ext/couchbase/operations/document_get_projected.hxx +12 -9
- data/ext/couchbase/operations/document_increment.hxx +6 -3
- data/ext/couchbase/operations/document_insert.hxx +5 -2
- data/ext/couchbase/operations/document_lookup_in.hxx +3 -0
- data/ext/couchbase/operations/document_mutate_in.hxx +6 -3
- data/ext/couchbase/operations/document_remove.hxx +3 -0
- data/ext/couchbase/operations/document_replace.hxx +5 -2
- data/ext/couchbase/operations/document_search.hxx +6 -7
- data/ext/couchbase/operations/document_touch.hxx +5 -2
- data/ext/couchbase/operations/document_unlock.hxx +3 -0
- data/ext/couchbase/operations/document_upsert.hxx +5 -2
- data/ext/couchbase/operations/query_index_build_deferred.hxx +3 -3
- data/ext/couchbase/operations/query_index_create.hxx +3 -3
- data/ext/couchbase/operations/query_index_drop.hxx +3 -3
- data/ext/couchbase/operations/query_index_get_all.hxx +3 -3
- data/ext/couchbase/operations/scope_create.hxx +4 -2
- data/ext/couchbase/operations/scope_drop.hxx +4 -2
- data/ext/couchbase/operations/scope_get_all.hxx +4 -2
- data/ext/couchbase/operations/search_index_analyze_document.hxx +2 -2
- data/ext/couchbase/operations/search_index_control_ingest.hxx +2 -2
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +2 -2
- data/ext/couchbase/operations/search_index_control_query.hxx +2 -2
- data/ext/couchbase/operations/search_index_drop.hxx +2 -2
- data/ext/couchbase/operations/search_index_get.hxx +2 -2
- data/ext/couchbase/operations/search_index_get_all.hxx +2 -2
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +2 -2
- data/ext/couchbase/operations/search_index_upsert.hxx +2 -2
- data/ext/couchbase/origin.hxx +148 -0
- data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +1 -6
- data/ext/couchbase/protocol/cmd_decrement.hxx +5 -5
- data/ext/couchbase/protocol/cmd_get_and_touch.hxx +5 -5
- data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +1 -6
- data/ext/couchbase/protocol/cmd_increment.hxx +5 -5
- data/ext/couchbase/protocol/cmd_info.hxx +0 -11
- data/ext/couchbase/protocol/cmd_insert.hxx +5 -5
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +6 -6
- data/ext/couchbase/protocol/cmd_replace.hxx +5 -5
- data/ext/couchbase/protocol/cmd_touch.hxx +1 -1
- data/ext/couchbase/protocol/cmd_upsert.hxx +5 -5
- data/ext/couchbase/timeout_defaults.hxx +7 -0
- data/ext/couchbase/utils/connection_string.hxx +139 -0
- data/ext/extconf.rb +44 -11
- data/ext/test/main.cxx +93 -15
- data/ext/third_party/http_parser/Makefile +160 -0
- data/ext/third_party/json/Makefile +77 -0
- data/lib/couchbase/analytics_options.rb +18 -4
- data/lib/couchbase/binary_collection.rb +2 -2
- data/lib/couchbase/binary_collection_options.rb +2 -2
- data/lib/couchbase/bucket.rb +4 -4
- data/lib/couchbase/cluster.rb +60 -46
- data/lib/couchbase/collection.rb +13 -13
- data/lib/couchbase/collection_options.rb +15 -9
- data/{bin/console → lib/couchbase/datastructures.rb} +4 -7
- data/lib/couchbase/datastructures/couchbase_list.rb +171 -0
- data/lib/couchbase/datastructures/couchbase_map.rb +205 -0
- data/lib/couchbase/datastructures/couchbase_queue.rb +145 -0
- data/lib/couchbase/datastructures/couchbase_set.rb +138 -0
- data/lib/couchbase/errors.rb +66 -63
- data/lib/couchbase/libcouchbase.bundle +0 -0
- data/lib/couchbase/management/user_manager.rb +1 -1
- data/lib/couchbase/mutation_state.rb +1 -0
- data/lib/couchbase/query_options.rb +25 -2
- data/lib/couchbase/scope.rb +0 -7
- data/lib/couchbase/search_options.rb +7 -0
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase/view_options.rb +4 -3
- metadata +20 -82
- data/.github/workflows/tests-6.0.3.yml +0 -52
- data/.github/workflows/tests-dev-preview.yml +0 -55
- data/.github/workflows/tests.yml +0 -50
- data/.gitignore +0 -20
- data/.gitmodules +0 -21
- data/.idea/.gitignore +0 -5
- data/.idea/dictionaries/gem_terms.xml +0 -18
- data/.idea/inspectionProfiles/Project_Default.xml +0 -8
- data/.idea/vcs.xml +0 -13
- data/bin/check-cluster +0 -31
- data/bin/fetch-stats +0 -19
- data/bin/init-cluster +0 -82
- data/bin/jenkins/build-extension +0 -35
- data/bin/jenkins/install-dependencies +0 -47
- data/bin/jenkins/test-with-cbdyncluster +0 -58
- data/bin/setup +0 -24
- data/ext/couchbase/configuration_monitor.hxx +0 -93
- data/ext/couchbase/operations/command.hxx +0 -163
- data/rbi/couchbase.rbi +0 -79
data/lib/couchbase/bucket.rb
CHANGED
@@ -26,7 +26,7 @@ module Couchbase
|
|
26
26
|
|
27
27
|
# @param [Couchbase::Backend] backend
|
28
28
|
def initialize(backend, name)
|
29
|
-
backend.open_bucket(name)
|
29
|
+
backend.open_bucket(name, true)
|
30
30
|
@backend = backend
|
31
31
|
@name = name
|
32
32
|
end
|
@@ -60,7 +60,7 @@ module Couchbase
|
|
60
60
|
#
|
61
61
|
# @return [Collection]
|
62
62
|
def default_collection
|
63
|
-
|
63
|
+
Collection.new(@backend, @name, :_default, :_default)
|
64
64
|
end
|
65
65
|
|
66
66
|
# Performs query to view index.
|
@@ -69,7 +69,7 @@ module Couchbase
|
|
69
69
|
# @param [String] view_name name of the view to query
|
70
70
|
# @param [ViewOptions] options
|
71
71
|
#
|
72
|
-
# @return [
|
72
|
+
# @return [ViewResult]
|
73
73
|
def view_query(design_document_name, view_name, options = ViewOptions.new)
|
74
74
|
resp = @backend.document_view(@name, design_document_name, view_name, options.namespace, {
|
75
75
|
timeout: options.timeout,
|
@@ -84,7 +84,7 @@ module Couchbase
|
|
84
84
|
group: options.group,
|
85
85
|
group_level: options.group_level,
|
86
86
|
key: (JSON.generate(options.key) unless options.key.nil?),
|
87
|
-
keys: options.keys
|
87
|
+
keys: (options.keys.map { |key| JSON.generate(key) } if options.keys),
|
88
88
|
order: options.order,
|
89
89
|
reduce: options.reduce,
|
90
90
|
on_error: options.on_error,
|
data/lib/couchbase/cluster.rb
CHANGED
@@ -67,18 +67,18 @@ module Couchbase
|
|
67
67
|
pipeline_cap: options.pipeline_cap,
|
68
68
|
metrics: options.metrics,
|
69
69
|
profile: options.profile,
|
70
|
-
positional_parameters: options.
|
71
|
-
named_parameters: options.
|
72
|
-
raw_parameters: options.
|
73
|
-
scan_consistency: options.
|
74
|
-
mutation_state: options.
|
70
|
+
positional_parameters: options.export_positional_parameters,
|
71
|
+
named_parameters: options.export_named_parameters,
|
72
|
+
raw_parameters: options.raw_parameters,
|
73
|
+
scan_consistency: options.scan_consistency,
|
74
|
+
mutation_state: (options.mutation_state.tokens.map { |t|
|
75
75
|
{
|
76
76
|
bucket_name: t.bucket_name,
|
77
77
|
partition_id: t.partition_id,
|
78
78
|
partition_uuid: t.partition_uuid,
|
79
79
|
sequence_number: t.sequence_number,
|
80
80
|
}
|
81
|
-
},
|
81
|
+
} if options.mutation_state),
|
82
82
|
})
|
83
83
|
|
84
84
|
QueryResult.new do |res|
|
@@ -119,9 +119,9 @@ module Couchbase
|
|
119
119
|
scan_consistency: options.scan_consistency,
|
120
120
|
readonly: options.readonly,
|
121
121
|
priority: options.priority,
|
122
|
-
positional_parameters: options.
|
123
|
-
named_parameters: options.
|
124
|
-
raw_parameters: options.
|
122
|
+
positional_parameters: options.export_positional_parameters,
|
123
|
+
named_parameters: options.export_named_parameters,
|
124
|
+
raw_parameters: options.raw_parameters,
|
125
125
|
})
|
126
126
|
|
127
127
|
AnalyticsResult.new do |res|
|
@@ -165,17 +165,17 @@ module Couchbase
|
|
165
165
|
highlight_style: options.highlight_style,
|
166
166
|
highlight_fields: options.highlight_fields,
|
167
167
|
fields: options.fields,
|
168
|
-
sort: options.sort
|
169
|
-
facets: options.facets
|
170
|
-
scan_consistency: options.
|
171
|
-
mutation_state: options.
|
168
|
+
sort: (options.sort.map { |v| JSON.generate(v) } if options.sort),
|
169
|
+
facets: (options.facets.map { |(k, v)| [k, JSON.generate(v)] } if options.facets),
|
170
|
+
scan_consistency: options.scan_consistency,
|
171
|
+
mutation_state: (options.mutation_state.tokens.map { |t|
|
172
172
|
{
|
173
173
|
bucket_name: t.bucket_name,
|
174
174
|
partition_id: t.partition_id,
|
175
175
|
partition_uuid: t.partition_uuid,
|
176
176
|
sequence_number: t.sequence_number,
|
177
177
|
}
|
178
|
-
},
|
178
|
+
} if options.mutation_state),
|
179
179
|
})
|
180
180
|
|
181
181
|
SearchResult.new do |res|
|
@@ -209,35 +209,52 @@ module Couchbase
|
|
209
209
|
row.explanation = JSON.parse(r[:explanation]) if r[:explanation]
|
210
210
|
end
|
211
211
|
end
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
212
|
+
if resp[:facets]
|
213
|
+
res.facets = resp[:facets].each_with_object({}) do |(k, v), o|
|
214
|
+
facet = case options.facets[k]
|
215
|
+
when SearchFacet::SearchFacetTerm
|
216
|
+
SearchFacetResult::TermFacetResult.new do |f|
|
217
|
+
f.terms =
|
218
|
+
if v[:terms]
|
219
|
+
v[:terms].map do |t|
|
220
|
+
SearchFacetResult::TermFacetResult::TermFacet.new(t[:term], t[:count])
|
221
|
+
end
|
222
|
+
else
|
223
|
+
[]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
when SearchFacet::SearchFacetDateRange
|
227
|
+
SearchFacetResult::DateRangeFacetResult.new do |f|
|
228
|
+
f.date_ranges =
|
229
|
+
if v[:date_ranges]
|
230
|
+
v[:date_ranges].map do |r|
|
231
|
+
SearchFacetResult::DateRangeFacetResult::DateRangeFacet.new(r[:name], r[:count], r[:start_time], r[:end_time])
|
232
|
+
end
|
233
|
+
else
|
234
|
+
[]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
when SearchFacet::SearchFacetNumericRange
|
238
|
+
SearchFacetResult::NumericRangeFacetResult.new do |f|
|
239
|
+
f.numeric_ranges =
|
240
|
+
if v[:numeric_ranges]
|
241
|
+
v[:numeric_ranges].map do |r|
|
242
|
+
SearchFacetResult::NumericRangeFacetResult::NumericRangeFacet.new(r[:name], r[:count], r[:min], r[:max])
|
243
|
+
end
|
244
|
+
else
|
245
|
+
[]
|
246
|
+
end
|
247
|
+
end
|
248
|
+
else
|
249
|
+
next # ignore unknown facet result
|
225
250
|
end
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
next # ignore unknown facet result
|
234
|
-
end
|
235
|
-
facet.name = v[:name]
|
236
|
-
facet.field = v[:field]
|
237
|
-
facet.total = v[:total]
|
238
|
-
facet.missing = v[:missing]
|
239
|
-
facet.other = v[:other]
|
240
|
-
o[k] = facet
|
251
|
+
facet.name = v[:name]
|
252
|
+
facet.field = v[:field]
|
253
|
+
facet.total = v[:total]
|
254
|
+
facet.missing = v[:missing]
|
255
|
+
facet.other = v[:other]
|
256
|
+
o[k] = facet
|
257
|
+
end
|
241
258
|
end
|
242
259
|
end
|
243
260
|
end
|
@@ -302,9 +319,6 @@ module Couchbase
|
|
302
319
|
# @param [String] connection_string connection string used to locate the Couchbase Cluster
|
303
320
|
# @param [ClusterOptions] options custom options when creating the cluster connection
|
304
321
|
def initialize(connection_string, options)
|
305
|
-
conn_info = Backend.parse_connection_string(connection_string)
|
306
|
-
raise ArgumentError, "missing hostname" if conn_info[:nodes].empty?
|
307
|
-
hostname = conn_info[:nodes].first[:address]
|
308
322
|
raise ArgumentError, "options must have authenticator configured" unless options.authenticator
|
309
323
|
username = options.authenticator.username
|
310
324
|
raise ArgumentError, "missing username" unless username
|
@@ -312,7 +326,7 @@ module Couchbase
|
|
312
326
|
raise ArgumentError, "missing password" unless password
|
313
327
|
|
314
328
|
@backend = Backend.new
|
315
|
-
@backend.open(
|
329
|
+
@backend.open(connection_string, username, password, {})
|
316
330
|
end
|
317
331
|
end
|
318
332
|
end
|
data/lib/couchbase/collection.rb
CHANGED
@@ -52,7 +52,7 @@ module Couchbase
|
|
52
52
|
resp = if options.need_projected_get?
|
53
53
|
@backend.document_get_projected(bucket_name, "#{@scope_name}.#{@name}", id,
|
54
54
|
options.timeout,
|
55
|
-
options.
|
55
|
+
options.with_expiry,
|
56
56
|
options.projections,
|
57
57
|
options.preserve_array_indexes)
|
58
58
|
else
|
@@ -63,7 +63,7 @@ module Couchbase
|
|
63
63
|
res.cas = resp[:cas]
|
64
64
|
res.flags = resp[:flags]
|
65
65
|
res.encoded = resp[:content]
|
66
|
-
res.
|
66
|
+
res.expiry = resp[:expiry] if resp.key?(:expiry)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -84,15 +84,15 @@ module Couchbase
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
# Fetches a full document and resets its expiration time to the
|
87
|
+
# Fetches a full document and resets its expiration time to the duration provided
|
88
88
|
#
|
89
89
|
# @param [String] id the document id which is used to uniquely identify it.
|
90
|
-
# @param [Integer]
|
90
|
+
# @param [Integer] expiry the new expiration time for the document
|
91
91
|
# @param [GetAndTouchOptions] options request customization
|
92
92
|
#
|
93
93
|
# @return [GetResult]
|
94
|
-
def get_and_touch(id,
|
95
|
-
resp = @backend.document_get_and_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout,
|
94
|
+
def get_and_touch(id, expiry, options = GetAndTouchOptions.new)
|
95
|
+
resp = @backend.document_get_and_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, expiry)
|
96
96
|
GetResult.new do |res|
|
97
97
|
res.transcoder = options.transcoder
|
98
98
|
res.cas = resp[:cas]
|
@@ -159,7 +159,7 @@ module Couchbase
|
|
159
159
|
blob, flags = options.transcoder.encode(content)
|
160
160
|
resp = @backend.document_insert(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
|
161
161
|
durability_level: options.durability_level,
|
162
|
-
|
162
|
+
expiry: options.expiry,
|
163
163
|
})
|
164
164
|
MutationResult.new do |res|
|
165
165
|
res.cas = resp[:cas]
|
@@ -178,7 +178,7 @@ module Couchbase
|
|
178
178
|
blob, flags = options.transcoder.encode(content)
|
179
179
|
resp = @backend.document_upsert(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
|
180
180
|
durability_level: options.durability_level,
|
181
|
-
|
181
|
+
expiry: options.expiry,
|
182
182
|
})
|
183
183
|
MutationResult.new do |res|
|
184
184
|
res.cas = resp[:cas]
|
@@ -197,7 +197,7 @@ module Couchbase
|
|
197
197
|
blob, flags = options.transcoder.encode(content)
|
198
198
|
resp = @backend.document_replace(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, blob, flags, {
|
199
199
|
durability_level: options.durability_level,
|
200
|
-
|
200
|
+
expiry: options.expiry,
|
201
201
|
cas: options.cas,
|
202
202
|
})
|
203
203
|
MutationResult.new do |res|
|
@@ -209,12 +209,12 @@ module Couchbase
|
|
209
209
|
# Update the expiration of the document with the given id
|
210
210
|
#
|
211
211
|
# @param [String] id the document id which is used to uniquely identify it.
|
212
|
-
# @param [Integer]
|
212
|
+
# @param [Integer] expiry new expiration time for the document
|
213
213
|
# @param [TouchOptions] options request customization
|
214
214
|
#
|
215
215
|
# @return [MutationResult]
|
216
|
-
def touch(id,
|
217
|
-
resp = @backend.document_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout,
|
216
|
+
def touch(id, expiry, options = TouchOptions.new)
|
217
|
+
resp = @backend.document_touch(bucket_name, "#{@scope_name}.#{@name}", id, options.timeout, expiry)
|
218
218
|
MutationResult.new do |res|
|
219
219
|
res.cas = resp[:cas]
|
220
220
|
end
|
@@ -291,7 +291,7 @@ module Couchbase
|
|
291
291
|
store_semantics: options.store_semantics,
|
292
292
|
access_deleted: options.access_deleted,
|
293
293
|
cas: options.cas,
|
294
|
-
|
294
|
+
expiry: options.expiry,
|
295
295
|
}
|
296
296
|
)
|
297
297
|
res = MutateInResult.new do |res|
|
@@ -21,7 +21,7 @@ module Couchbase
|
|
21
21
|
class Collection
|
22
22
|
class GetOptions < CommonOptions
|
23
23
|
# @return [Boolean] if the expiration should also fetched with get
|
24
|
-
attr_accessor :
|
24
|
+
attr_accessor :with_expiry
|
25
25
|
|
26
26
|
# @return [JsonTranscoder] transcoder used for decoding
|
27
27
|
attr_accessor :transcoder
|
@@ -30,7 +30,7 @@ module Couchbase
|
|
30
30
|
def initialize
|
31
31
|
@transcoder = JsonTranscoder.new
|
32
32
|
@preserve_array_indexes = false
|
33
|
-
@
|
33
|
+
@with_expiry = nil
|
34
34
|
@projections = nil
|
35
35
|
yield self if block_given?
|
36
36
|
end
|
@@ -57,7 +57,7 @@ module Couchbase
|
|
57
57
|
# @api private
|
58
58
|
# @return [Boolean]
|
59
59
|
def need_projected_get?
|
60
|
-
@
|
60
|
+
@with_expiry || !@projections.nil?
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -88,9 +88,10 @@ module Couchbase
|
|
88
88
|
attr_accessor :cas
|
89
89
|
|
90
90
|
# @return [Integer] the expiration if fetched and present
|
91
|
-
attr_accessor :
|
91
|
+
attr_accessor :expiry
|
92
92
|
|
93
93
|
# @return [String] The encoded content when loading the document
|
94
|
+
# @api private
|
94
95
|
attr_accessor :encoded
|
95
96
|
|
96
97
|
# Decodes the content of the document using given (or default transcoder)
|
@@ -108,6 +109,7 @@ module Couchbase
|
|
108
109
|
end
|
109
110
|
|
110
111
|
# @return [Integer] The flags from the operation
|
112
|
+
# @api private
|
111
113
|
attr_accessor :flags
|
112
114
|
|
113
115
|
# @return [JsonTranscoder] The default transcoder which should be used
|
@@ -186,7 +188,7 @@ module Couchbase
|
|
186
188
|
|
187
189
|
class InsertOptions < CommonOptions
|
188
190
|
# @return [Integer] expiration time to associate with the document
|
189
|
-
attr_accessor :
|
191
|
+
attr_accessor :expiry
|
190
192
|
|
191
193
|
# @return [Proc] transcoder used for encoding
|
192
194
|
attr_accessor :transcoder
|
@@ -204,7 +206,7 @@ module Couchbase
|
|
204
206
|
|
205
207
|
class UpsertOptions < CommonOptions
|
206
208
|
# @return [Integer] expiration time to associate with the document
|
207
|
-
attr_accessor :
|
209
|
+
attr_accessor :expiry
|
208
210
|
|
209
211
|
# @return [JsonTranscoder] transcoder used for encoding
|
210
212
|
attr_accessor :transcoder
|
@@ -222,7 +224,7 @@ module Couchbase
|
|
222
224
|
|
223
225
|
class ReplaceOptions < CommonOptions
|
224
226
|
# @return [Integer] expiration time to associate with the document
|
225
|
-
attr_accessor :
|
227
|
+
attr_accessor :expiry
|
226
228
|
|
227
229
|
# @return [JsonTranscoder] transcoder used for encoding
|
228
230
|
attr_accessor :transcoder
|
@@ -301,7 +303,7 @@ module Couchbase
|
|
301
303
|
#
|
302
304
|
# @return [Boolean] true if a value is present at the index, false otherwise
|
303
305
|
def exists?(index)
|
304
|
-
encoded[index]
|
306
|
+
!encoded[index].nil? && encoded[index].exists
|
305
307
|
end
|
306
308
|
|
307
309
|
# @return [Array<SubDocumentField>] holds the encoded subdocument responses
|
@@ -330,7 +332,7 @@ module Couchbase
|
|
330
332
|
|
331
333
|
class MutateInOptions < CommonOptions
|
332
334
|
# @return [Integer] expiration time to associate with the document
|
333
|
-
attr_accessor :
|
335
|
+
attr_accessor :expiry
|
334
336
|
|
335
337
|
# Describes how the outer document store semantics on subdoc should act
|
336
338
|
#
|
@@ -384,18 +386,22 @@ module Couchbase
|
|
384
386
|
yield self if block_given?
|
385
387
|
end
|
386
388
|
|
389
|
+
# @api private
|
387
390
|
def success?
|
388
391
|
first_error_index.nil?
|
389
392
|
end
|
390
393
|
|
394
|
+
# @api private
|
391
395
|
def first_error
|
392
396
|
encoded[first_error_index].error
|
393
397
|
end
|
394
398
|
|
395
399
|
# @return [Array<SubDocumentField>] holds the encoded subdocument responses
|
400
|
+
# @api private
|
396
401
|
attr_accessor :encoded
|
397
402
|
|
398
403
|
# @return [Integer, nil] index of first operation entry that generated an error
|
404
|
+
# @api private
|
399
405
|
attr_accessor :first_error_index
|
400
406
|
|
401
407
|
# @return [JsonTranscoder] The default transcoder which should be used
|
@@ -1,5 +1,3 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
# Copyright 2020 Couchbase, Inc.
|
4
2
|
#
|
5
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -14,8 +12,7 @@
|
|
14
12
|
# See the License for the specific language governing permissions and
|
15
13
|
# limitations under the License.
|
16
14
|
|
17
|
-
require "
|
18
|
-
require "
|
19
|
-
require "couchbase"
|
20
|
-
|
21
|
-
IRB.start(__FILE__)
|
15
|
+
require "couchbase/datastructures/couchbase_list"
|
16
|
+
require "couchbase/datastructures/couchbase_set"
|
17
|
+
require "couchbase/datastructures/couchbase_queue"
|
18
|
+
require "couchbase/datastructures/couchbase_map"
|
@@ -0,0 +1,171 @@
|
|
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/collection"
|
16
|
+
require "couchbase/errors"
|
17
|
+
|
18
|
+
module Couchbase
|
19
|
+
module Datastructures
|
20
|
+
# A {CouchbaseList} is implements +Enumerable+ interface and backed by {Collection} document (more specifically
|
21
|
+
# a JSON array).
|
22
|
+
#
|
23
|
+
# Note that as such, a {CouchbaseList} is restricted to the types that JSON array can contain.
|
24
|
+
class CouchbaseList
|
25
|
+
include Enumerable
|
26
|
+
|
27
|
+
# Create a new List, backed by the document identified by +id+ in +collection+.
|
28
|
+
#
|
29
|
+
# @param [String] id the id of the document to back the list.
|
30
|
+
# @param [Collection] collection the Couchbase collection through which to interact with the document.
|
31
|
+
# @param [CouchbaseListOptions] options customization of the datastructure
|
32
|
+
def initialize(id, collection, options = CouchbaseListOptions.new)
|
33
|
+
@id = id
|
34
|
+
@collection = collection
|
35
|
+
@options = options
|
36
|
+
@cas = 0
|
37
|
+
end
|
38
|
+
|
39
|
+
# Calls the given block once for each element in the list, passing that element as a parameter.
|
40
|
+
#
|
41
|
+
# @yieldparam [Object] item
|
42
|
+
#
|
43
|
+
# @return [CouchbaseList, Enumerable]
|
44
|
+
def each
|
45
|
+
if block_given?
|
46
|
+
begin
|
47
|
+
result = @collection.get(@id, @options.get_options)
|
48
|
+
current = result.content
|
49
|
+
@cas = result.cas
|
50
|
+
rescue Error::DocumentNotFound
|
51
|
+
current = []
|
52
|
+
@cas = 0
|
53
|
+
end
|
54
|
+
current.each do |entry|
|
55
|
+
yield entry
|
56
|
+
end
|
57
|
+
self
|
58
|
+
else
|
59
|
+
enum_for(:each)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Integer] returns the number of elements in the list.
|
64
|
+
def length
|
65
|
+
result = @collection.lookup_in(@id, [
|
66
|
+
LookupInSpec.count("")
|
67
|
+
], @options.lookup_in_options)
|
68
|
+
result.content(0)
|
69
|
+
rescue Error::DocumentNotFound
|
70
|
+
0
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method :size, :length
|
74
|
+
|
75
|
+
# @return [Boolean] returns true if list is empty
|
76
|
+
def empty?
|
77
|
+
size.zero?
|
78
|
+
end
|
79
|
+
|
80
|
+
# Appends the given object(s) on to the end of this error. This expression returns the array itself, so several
|
81
|
+
# appends may be chained together.
|
82
|
+
#
|
83
|
+
# @param [Object...] obj object(s) to append
|
84
|
+
# @return [CouchbaseList]
|
85
|
+
def push(*obj)
|
86
|
+
@collection.mutate_in(@id, [
|
87
|
+
MutateInSpec.array_append("", obj)
|
88
|
+
], @options.mutate_in_options)
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
alias_method :append, :push
|
93
|
+
|
94
|
+
# Prepends objects to the front of the list, moving other elements upwards
|
95
|
+
#
|
96
|
+
# @param [Object...] obj object(s) to prepend
|
97
|
+
# @return [CouchbaseList]
|
98
|
+
def unshift(*obj)
|
99
|
+
@collection.mutate_in(@id, [
|
100
|
+
MutateInSpec.array_prepend("", obj)
|
101
|
+
], @options.mutate_in_options)
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
alias_method :prepend, :unshift
|
106
|
+
|
107
|
+
# Inserts the given values before the element with the given +index+.
|
108
|
+
#
|
109
|
+
# @param [Integer] index
|
110
|
+
# @param [Object...] obj object(s) to insert
|
111
|
+
# @return [CouchbaseList]
|
112
|
+
def insert(index, *obj)
|
113
|
+
@collection.mutate_in(@id, [
|
114
|
+
MutateInSpec.array_insert("[#{index.to_i}]", obj)
|
115
|
+
])
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the element at +index+. A negative index counts from the end. Returns +nil+ if the index is out of range.
|
120
|
+
#
|
121
|
+
# @param [Integer] index
|
122
|
+
# @return [Object, nil]
|
123
|
+
def at(index)
|
124
|
+
result = @collection.lookup_in(@id, [
|
125
|
+
LookupInSpec.get("[#{index.to_i}]")
|
126
|
+
], @options.lookup_in_options)
|
127
|
+
result.exists?(0) ? result.content(0) : nil
|
128
|
+
rescue Error::DocumentNotFound
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
alias_method :[], :at
|
133
|
+
|
134
|
+
# Deletes the element at the specified +index+, returning that element, or nil
|
135
|
+
#
|
136
|
+
# @param [Integer] index
|
137
|
+
# @return [CouchbaseList]
|
138
|
+
def delete_at(index)
|
139
|
+
@collection.mutate_in(@id, [
|
140
|
+
MutateInSpec.remove("[#{index.to_i}]")
|
141
|
+
])
|
142
|
+
self
|
143
|
+
rescue Error::DocumentNotFound
|
144
|
+
self
|
145
|
+
end
|
146
|
+
|
147
|
+
# Removes all elements from the list
|
148
|
+
def clear
|
149
|
+
@collection.remove(@id, @options.remove_options)
|
150
|
+
nil
|
151
|
+
rescue Error::DocumentNotFound
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class CouchbaseListOptions
|
157
|
+
attr_accessor :get_options
|
158
|
+
attr_accessor :lookup_in_options
|
159
|
+
attr_accessor :mutate_in_options
|
160
|
+
attr_accessor :remove_options
|
161
|
+
|
162
|
+
def initialize
|
163
|
+
@get_options = Collection::GetOptions.new
|
164
|
+
@remove_options = Collection::RemoveOptions.new
|
165
|
+
@lookup_in_options = Collection::LookupInOptions.new
|
166
|
+
@mutate_in_options = Collection::MutateInOptions.new
|
167
|
+
@mutate_in_options.store_semantics = :upsert
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|