couchbase 3.4.2-arm64-darwin-20 → 3.4.4-arm64-darwin-20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/couchbase/authenticator.rb +0 -1
- data/lib/couchbase/cluster.rb +1 -5
- data/lib/couchbase/collection.rb +108 -0
- data/lib/couchbase/collection_options.rb +100 -0
- data/lib/couchbase/config_profiles.rb +1 -1
- data/lib/couchbase/errors.rb +5 -0
- data/lib/couchbase/json_transcoder.rb +12 -5
- data/lib/couchbase/key_value_scan.rb +125 -0
- data/lib/couchbase/libcouchbase.bundle +0 -0
- data/lib/couchbase/management/collection_query_index_manager.rb +54 -15
- data/lib/couchbase/management/query_index_manager.rb +70 -5
- data/lib/couchbase/options.rb +151 -0
- data/lib/couchbase/raw_binary_transcoder.rb +37 -0
- data/lib/couchbase/raw_json_transcoder.rb +38 -0
- data/lib/couchbase/raw_string_transcoder.rb +40 -0
- data/lib/couchbase/scope.rb +1 -1
- data/lib/couchbase/search_options.rb +5 -0
- data/lib/couchbase/transcoder_flags.rb +62 -0
- data/lib/couchbase/utils/time.rb +14 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 114c1f905e9873c1e6c8ae96badf29c0c795c9dc653a66584ec41415b5a504c3
|
4
|
+
data.tar.gz: 7993c632a1513ab6359a91063bc22ce8aaf6402be1353f0fb0f7c2a975f5e57d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8220a5639d0c7b74b2a6376371ef495239178a49f29b836a6f902569c7f0491ab7df09fb6e049639ed7e6aeb21ee9c6fac145208cfff23095cc428cd1b12651b
|
7
|
+
data.tar.gz: 42c503acdc73e22ad85f346e56e47b7edc0d8b30c5887a5d8b2d2280e8e1edd288f19e09d8c1c294f422a559fb5970d8d6257e292aafb2045260fbd831ae5483
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![license](https://img.shields.io/github/license/couchbase/couchbase-ruby-client?color=brightgreen)](https://opensource.org/licenses/Apache-2.0)
|
4
4
|
[![gem](https://img.shields.io/gem/v/couchbase?color=brightgreen)](https://rubygems.org/gems/couchbase)
|
5
|
-
[![commits](https://img.shields.io/github/commits-since/couchbase/couchbase-ruby-client/latest?color=brightgreen)](https://github.com/couchbase/couchbase-ruby-client/commits/
|
5
|
+
[![commits](https://img.shields.io/github/commits-since/couchbase/couchbase-ruby-client/latest?color=brightgreen)](https://github.com/couchbase/couchbase-ruby-client/commits/main)
|
6
6
|
[![linters](https://img.shields.io/github/actions/workflow/status/couchbase/couchbase-ruby-client/linters.yml?branch=main&label=linters)](https://github.com/couchbase/couchbase-ruby-client/actions?query=workflow%3Alinters)
|
7
7
|
|
8
8
|
This repository contains the third generation of the official Couchbase SDK for Ruby (aka. SDKv3)
|
@@ -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.
|
26
|
+
gem "couchbase", "3.4.4"
|
27
27
|
```
|
28
28
|
|
29
29
|
And then execute:
|
data/lib/couchbase/cluster.rb
CHANGED
@@ -124,7 +124,7 @@ module Couchbase
|
|
124
124
|
metrics.warning_count = resp[:meta][:metrics][:warning_count]
|
125
125
|
end
|
126
126
|
end
|
127
|
-
|
127
|
+
meta.warnings = resp[:warnings].map { |warn| QueryWarning.new(warn[:code], warn[:message]) } if resp[:warnings]
|
128
128
|
end
|
129
129
|
res.instance_variable_set(:@rows, resp[:rows])
|
130
130
|
end
|
@@ -386,8 +386,6 @@ module Couchbase
|
|
386
386
|
raise ArgumentError, "missing connection_string" unless connection_string
|
387
387
|
raise ArgumentError, "missing username" unless credentials[:username]
|
388
388
|
raise ArgumentError, "missing password" unless credentials[:password]
|
389
|
-
|
390
|
-
open_options[:allowed_sasl_mechanisms] = PasswordAuthenticator::DEFAULT_SASL_MECHANISMS
|
391
389
|
else
|
392
390
|
options = args.shift
|
393
391
|
case options
|
@@ -396,8 +394,6 @@ module Couchbase
|
|
396
394
|
credentials[:password] = args.shift
|
397
395
|
raise ArgumentError, "missing username" unless credentials[:username]
|
398
396
|
raise ArgumentError, "missing password" unless credentials[:password]
|
399
|
-
|
400
|
-
open_options[:allowed_sasl_mechanisms] = PasswordAuthenticator::DEFAULT_SASL_MECHANISMS
|
401
397
|
when Options::Cluster
|
402
398
|
open_options = options&.to_backend || {}
|
403
399
|
authenticator = options&.authenticator
|
data/lib/couchbase/collection.rb
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
require "couchbase/errors"
|
16
16
|
require "couchbase/collection_options"
|
17
17
|
require "couchbase/binary_collection"
|
18
|
+
require "couchbase/key_value_scan"
|
18
19
|
|
19
20
|
module Couchbase
|
20
21
|
# Provides access to all collection APIs
|
@@ -481,11 +482,68 @@ module Couchbase
|
|
481
482
|
f.index = field[:index]
|
482
483
|
f.path = field[:path]
|
483
484
|
f.value = field[:value]
|
485
|
+
f.error = field[:error]
|
484
486
|
end
|
485
487
|
end
|
486
488
|
end
|
487
489
|
end
|
488
490
|
|
491
|
+
# Performs lookups to document fragments. Reads from the active node and all available replicas and returns the
|
492
|
+
# first result found
|
493
|
+
#
|
494
|
+
# @param [String] id the document id which is used to uniquely identify it.
|
495
|
+
# @param [Array<LookupInSpec>] specs the list of specifications which describe the types of the lookups to perform
|
496
|
+
# @param [Options::LookupInAnyReplica] options request customization
|
497
|
+
#
|
498
|
+
# @return [LookupInReplicaResult]
|
499
|
+
#
|
500
|
+
# @raise [Error::DocumentIrretrievable]
|
501
|
+
# @raise [Error::Timeout]
|
502
|
+
# @raise [Error::CouchbaseError]
|
503
|
+
# @raise [Error::FeatureNotAvailable]
|
504
|
+
def lookup_in_any_replica(id, specs, options = Options::LookupInAnyReplica::DEFAULT)
|
505
|
+
resp = @backend.document_lookup_in_any_replica(
|
506
|
+
bucket_name, @scope_name, @name, id,
|
507
|
+
specs.map do |s|
|
508
|
+
{
|
509
|
+
opcode: s.type,
|
510
|
+
xattr: s.xattr?,
|
511
|
+
path: s.path,
|
512
|
+
}
|
513
|
+
end, options.to_backend
|
514
|
+
)
|
515
|
+
extract_lookup_in_replica_result(resp, options)
|
516
|
+
end
|
517
|
+
|
518
|
+
# Performs lookups to document fragments. Reads from the active node and all available replicas and returns all of
|
519
|
+
# the results
|
520
|
+
#
|
521
|
+
# @param [String] id the document id which is used to uniquely identify it.
|
522
|
+
# @param [Array<LookupInSpec>] specs the list of specifications which describe the types of the lookups to perform
|
523
|
+
# @param [Options::LookupInAllReplicas] options request customization
|
524
|
+
#
|
525
|
+
# @return [Array<LookupInReplicaResult>]
|
526
|
+
#
|
527
|
+
# @raise [Error::DocumentNotFound]
|
528
|
+
# @raise [Error::Timeout]
|
529
|
+
# @raise [Error::CouchbaseError]
|
530
|
+
# @raise [Error::FeatureNotAvailable]
|
531
|
+
def lookup_in_all_replicas(id, specs, options = Options::LookupInAllReplicas::DEFAULT)
|
532
|
+
resp = @backend.document_lookup_in_all_replicas(
|
533
|
+
bucket_name, @scope_name, @name, id,
|
534
|
+
specs.map do |s|
|
535
|
+
{
|
536
|
+
opcode: s.type,
|
537
|
+
xattr: s.xattr?,
|
538
|
+
path: s.path,
|
539
|
+
}
|
540
|
+
end, options.to_backend
|
541
|
+
)
|
542
|
+
resp.map do |entry|
|
543
|
+
extract_lookup_in_replica_result(entry, options)
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
489
547
|
# Performs mutations to document fragments
|
490
548
|
#
|
491
549
|
# @param [String] id the document id which is used to uniquely identify it.
|
@@ -535,6 +593,38 @@ module Couchbase
|
|
535
593
|
end
|
536
594
|
end
|
537
595
|
|
596
|
+
# Performs a key-value scan operation on the collection
|
597
|
+
#
|
598
|
+
# @api uncommitted
|
599
|
+
#
|
600
|
+
# @param [RangeScan, PrefixScan, SamplingScan] scan_type the type of the scan
|
601
|
+
# @param [Options::Scan] options request customization
|
602
|
+
#
|
603
|
+
# @example Get a sample of up to 5 documents from the collection and store their IDs in an array
|
604
|
+
# result = collection.scan(SamplingScan.new(5), Options::Scan.new(ids_only: true))
|
605
|
+
# ids = result.map { |item| item.id }
|
606
|
+
#
|
607
|
+
# @example Get all documents whose ID starts with 'customer_1' and output their content
|
608
|
+
# result = collection.scan(PrefixScan.new("customer_1"))
|
609
|
+
# result.each { |item| puts item.content }
|
610
|
+
#
|
611
|
+
# @example Get all documents with ID between 'customer_1' and 'customer_2', excluding 'customer_2' and output their content
|
612
|
+
# result = collection.scan(RangeScan.new(
|
613
|
+
# from: ScanTerm.new("customer_1"),
|
614
|
+
# to: ScanTerm.new("customer_2", exclusive: true)
|
615
|
+
# ))
|
616
|
+
# result.each { |item| puts item.content }
|
617
|
+
#
|
618
|
+
# @return [ScanResults]
|
619
|
+
def scan(scan_type, options = Options::Scan::DEFAULT)
|
620
|
+
ScanResults.new(
|
621
|
+
core_scan_result: @backend.document_scan_create(
|
622
|
+
@bucket_name, @scope_name, @name, scan_type.to_backend, options.to_backend
|
623
|
+
),
|
624
|
+
transcoder: options.transcoder
|
625
|
+
)
|
626
|
+
end
|
627
|
+
|
538
628
|
private
|
539
629
|
|
540
630
|
def extract_mutation_token(resp)
|
@@ -548,6 +638,24 @@ module Couchbase
|
|
548
638
|
end
|
549
639
|
end
|
550
640
|
|
641
|
+
def extract_lookup_in_replica_result(resp, options)
|
642
|
+
LookupInReplicaResult.new do |res|
|
643
|
+
res.transcoder = options.transcoder
|
644
|
+
res.cas = resp[:cas]
|
645
|
+
res.deleted = resp[:deleted]
|
646
|
+
res.is_replica = resp[:is_replica]
|
647
|
+
res.encoded = resp[:fields].map do |field|
|
648
|
+
SubDocumentField.new do |f|
|
649
|
+
f.exists = field[:exists]
|
650
|
+
f.index = field[:index]
|
651
|
+
f.path = field[:path]
|
652
|
+
f.value = field[:value]
|
653
|
+
f.error = field[:error]
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
551
659
|
# @api private
|
552
660
|
# TODO: deprecate in 3.1
|
553
661
|
GetOptions = ::Couchbase::Options::Get
|
@@ -15,6 +15,9 @@
|
|
15
15
|
require "rubygems/deprecate"
|
16
16
|
|
17
17
|
require "couchbase/json_transcoder"
|
18
|
+
require "couchbase/raw_string_transcoder"
|
19
|
+
require "couchbase/raw_json_transcoder"
|
20
|
+
require "couchbase/raw_binary_transcoder"
|
18
21
|
require "couchbase/subdoc"
|
19
22
|
require "couchbase/mutation_state"
|
20
23
|
|
@@ -164,6 +167,8 @@ module Couchbase
|
|
164
167
|
# @return [Object] the decoded
|
165
168
|
def content(path_or_index, transcoder = self.transcoder)
|
166
169
|
field = get_field_at_index(path_or_index)
|
170
|
+
|
171
|
+
raise field.error unless field.error.nil?
|
167
172
|
raise Error::PathNotFound, "Path is not found: #{path_or_index}" unless field.exists
|
168
173
|
|
169
174
|
transcoder.decode(field.value, :json)
|
@@ -186,6 +191,8 @@ module Couchbase
|
|
186
191
|
end
|
187
192
|
return false unless field
|
188
193
|
|
194
|
+
raise field.error unless field.error.nil?
|
195
|
+
|
189
196
|
field.exists
|
190
197
|
end
|
191
198
|
|
@@ -227,6 +234,18 @@ module Couchbase
|
|
227
234
|
end
|
228
235
|
end
|
229
236
|
|
237
|
+
class LookupInReplicaResult < LookupInResult
|
238
|
+
# @return [Boolean] true if the document was read from a replica node
|
239
|
+
attr_accessor :is_replica
|
240
|
+
alias replica? is_replica
|
241
|
+
|
242
|
+
# @yieldparam [LookupInReplicaResult] self
|
243
|
+
def initialize
|
244
|
+
super
|
245
|
+
yield self if block_given?
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
230
249
|
class MutateInResult < MutationResult
|
231
250
|
# Decodes the content at the given index
|
232
251
|
#
|
@@ -291,10 +310,91 @@ module Couchbase
|
|
291
310
|
# @return [String] path
|
292
311
|
attr_accessor :path
|
293
312
|
|
313
|
+
# @return [CouchbaseError] error
|
314
|
+
attr_accessor :error
|
315
|
+
|
294
316
|
# @yieldparam [SubDocumentField] self
|
295
317
|
def initialize
|
296
318
|
yield self if block_given?
|
297
319
|
end
|
298
320
|
end
|
321
|
+
|
322
|
+
class ScanResult
|
323
|
+
# @return [String] identifier of the document
|
324
|
+
attr_accessor :id
|
325
|
+
|
326
|
+
# @return [Boolean] whether only ids are returned from this scan
|
327
|
+
attr_accessor :id_only
|
328
|
+
|
329
|
+
# @return [Integer, nil] holds the CAS value of the fetched document
|
330
|
+
attr_accessor :cas
|
331
|
+
|
332
|
+
# @return [Integer, nil] the expiration if fetched and present
|
333
|
+
attr_accessor :expiry
|
334
|
+
|
335
|
+
# @return [JsonTranscoder, RawBinaryTranscoder, RawJsonTranscoder, RawStringTranscoder, #decode] The default
|
336
|
+
# transcoder which should be used
|
337
|
+
attr_accessor :transcoder
|
338
|
+
|
339
|
+
def initialize(id:, id_only:, cas: nil, expiry: nil, encoded: nil, flags: nil, transcoder: JsonTranscoder.new)
|
340
|
+
@id = id
|
341
|
+
@id_only = id_only
|
342
|
+
@cas = cas
|
343
|
+
@expiry = expiry
|
344
|
+
@encoded = encoded
|
345
|
+
@flags = flags
|
346
|
+
@transcoder = transcoder
|
347
|
+
|
348
|
+
yield self if block_given?
|
349
|
+
end
|
350
|
+
|
351
|
+
# Decodes the content of the document using given (or default transcoder)
|
352
|
+
#
|
353
|
+
# @param [JsonTranscoder, RawJsonTranscoder, RawBinaryTranscoder, RawStringTranscoder] transcoder custom transcoder
|
354
|
+
#
|
355
|
+
# @return [Object, nil]
|
356
|
+
def content(transcoder = self.transcoder)
|
357
|
+
return nil if @encoded.nil?
|
358
|
+
|
359
|
+
transcoder ? transcoder.decode(@encoded, @flags) : @encoded
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
class ScanResults
|
364
|
+
include Enumerable
|
365
|
+
|
366
|
+
def initialize(core_scan_result:, transcoder:)
|
367
|
+
@core_scan_result = core_scan_result
|
368
|
+
@transcoder = transcoder
|
369
|
+
end
|
370
|
+
|
371
|
+
def each
|
372
|
+
return enum_for(:each) unless block_given?
|
373
|
+
|
374
|
+
loop do
|
375
|
+
resp = @core_scan_result.next_item
|
376
|
+
|
377
|
+
break if resp.nil?
|
378
|
+
|
379
|
+
if resp[:id_only]
|
380
|
+
yield ScanResult.new(
|
381
|
+
id: resp[:id],
|
382
|
+
id_only: resp[:id_only],
|
383
|
+
transcoder: @transcoder
|
384
|
+
)
|
385
|
+
else
|
386
|
+
yield ScanResult.new(
|
387
|
+
id: resp[:id],
|
388
|
+
id_only: resp[:id_only],
|
389
|
+
cas: resp[:cas],
|
390
|
+
expiry: resp[:expiry],
|
391
|
+
encoded: resp[:encoded],
|
392
|
+
flags: resp[:flags],
|
393
|
+
transcoder: @transcoder
|
394
|
+
)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
299
399
|
end
|
300
400
|
end
|
data/lib/couchbase/errors.rb
CHANGED
@@ -183,6 +183,11 @@ module Couchbase
|
|
183
183
|
class DurableWriteReCommitInProgress < CouchbaseError
|
184
184
|
end
|
185
185
|
|
186
|
+
# Happens when consistency requirements are specified but the partition uuid of the requirements do not align
|
187
|
+
# with the server
|
188
|
+
class MutationTokenOutdated < CouchbaseError
|
189
|
+
end
|
190
|
+
|
186
191
|
# Subdocument exception thrown when a path does not exist in the document. The exact meaning of path existence
|
187
192
|
# depends on the operation and inputs.
|
188
193
|
class PathNotFound < CouchbaseError
|
@@ -14,18 +14,25 @@
|
|
14
14
|
|
15
15
|
require "json"
|
16
16
|
|
17
|
+
require "couchbase/transcoder_flags"
|
18
|
+
|
17
19
|
module Couchbase
|
18
20
|
class JsonTranscoder
|
19
21
|
# @param [Object] document
|
20
22
|
# @return [Array<String, Integer>] pair of encoded document and flags
|
21
23
|
def encode(document)
|
22
|
-
|
24
|
+
raise Error::EncodingFailure, "The JsonTranscoder does not support binary data" if document.is_a?(String) && !document.valid_encoding?
|
25
|
+
|
26
|
+
[JSON.generate(document), TranscoderFlags.new(format: :json, lower_bits: 6).encode]
|
23
27
|
end
|
24
28
|
|
25
|
-
# @param [String
|
26
|
-
# @param [Integer, :json]
|
27
|
-
# @return Object decoded document
|
28
|
-
def decode(blob,
|
29
|
+
# @param [String] blob string of bytes, containing encoded representation of the document
|
30
|
+
# @param [Integer, :json] flags bit field, describing how the data encoded
|
31
|
+
# @return [Object] decoded document
|
32
|
+
def decode(blob, flags)
|
33
|
+
format = TranscoderFlags.decode(flags).format
|
34
|
+
raise Error::DecodingFailure, "Unable to decode #{format} with the JsonTranscoder" unless format == :json || format.nil?
|
35
|
+
|
29
36
|
JSON.parse(blob) unless blob&.empty?
|
30
37
|
end
|
31
38
|
end
|
@@ -0,0 +1,125 @@
|
|
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
|
+
module Couchbase
|
16
|
+
# A scan term used to specify the bounds of a range scan
|
17
|
+
class ScanTerm
|
18
|
+
attr_accessor :term # @return [ScanTerm]
|
19
|
+
attr_accessor :exclusive # @return [Boolean]
|
20
|
+
|
21
|
+
# Creates an instance of a ScanTerm
|
22
|
+
#
|
23
|
+
# @api uncommitted
|
24
|
+
#
|
25
|
+
# @param [String] term the key pattern of this term
|
26
|
+
# @param [Boolean] exclusive specifies if this term is excluded while scanning, the bounds are included by default
|
27
|
+
def initialize(term, exclusive: false)
|
28
|
+
@term = term
|
29
|
+
@exclusive = exclusive
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def to_backend
|
34
|
+
{
|
35
|
+
term: @term,
|
36
|
+
exclusive: @exclusive,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# A range scan performs a scan on a range of keys
|
42
|
+
class RangeScan
|
43
|
+
attr_accessor :from # @return [ScanTerm, nil]
|
44
|
+
attr_accessor :to # @return [ScanTerm, nil]
|
45
|
+
|
46
|
+
# Creates an instance of a RangeScan scan type
|
47
|
+
#
|
48
|
+
# @api uncommitted
|
49
|
+
#
|
50
|
+
# @param [ScanTerm, String, nil] from the lower bound of the range, if set
|
51
|
+
# @param [ScanTerm, String, nil] to the upper bound of the range, if set
|
52
|
+
def initialize(from: nil, to: nil)
|
53
|
+
@from =
|
54
|
+
if from.nil? || from.instance_of?(ScanTerm)
|
55
|
+
from
|
56
|
+
else
|
57
|
+
ScanTerm(from)
|
58
|
+
end
|
59
|
+
@to =
|
60
|
+
if to.nil? || to.instance_of?(ScanTerm)
|
61
|
+
to
|
62
|
+
else
|
63
|
+
ScanTerm(to)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @api private
|
68
|
+
def to_backend
|
69
|
+
{
|
70
|
+
scan_type: :range,
|
71
|
+
from: @from&.to_backend,
|
72
|
+
to: @to&.to_backend,
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# A prefix scan performs a scan that includes all documents whose keys start with the given prefix
|
78
|
+
class PrefixScan
|
79
|
+
attr_accessor :prefix # @return [String]
|
80
|
+
|
81
|
+
# Creates an instance of a PrefixScan scan type
|
82
|
+
#
|
83
|
+
# @api uncommitted
|
84
|
+
#
|
85
|
+
# @param [String, nil] prefix the prefix all document keys should start with
|
86
|
+
def initialize(prefix)
|
87
|
+
@prefix = prefix
|
88
|
+
end
|
89
|
+
|
90
|
+
# @api private
|
91
|
+
def to_backend
|
92
|
+
{
|
93
|
+
scan_type: :prefix,
|
94
|
+
prefix: @prefix,
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# A sampling scan performs a scan that randomly selects documents up to a configured limit
|
100
|
+
class SamplingScan
|
101
|
+
attr_accessor :limit # @return [Integer]
|
102
|
+
attr_accessor :seed # @return [Integer, nil]
|
103
|
+
|
104
|
+
# Creates an instance of a SamplingScan scan type
|
105
|
+
#
|
106
|
+
# @api uncommitted
|
107
|
+
#
|
108
|
+
# @param [Integer] limit the maximum number of documents the sampling scan can return
|
109
|
+
# @param [Integer, nil] seed the seed used for the random number generator that selects the documents. If not set,
|
110
|
+
# a seed is generated at random
|
111
|
+
def initialize(limit, seed = nil)
|
112
|
+
@limit = limit
|
113
|
+
@seed = seed
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api private
|
117
|
+
def to_backend
|
118
|
+
{
|
119
|
+
scan_type: :sampling,
|
120
|
+
limit: @limit,
|
121
|
+
seed: @seed,
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
Binary file
|
@@ -14,6 +14,7 @@
|
|
14
14
|
|
15
15
|
require "couchbase/management/query_index_manager"
|
16
16
|
require "couchbase/utils/time"
|
17
|
+
require "couchbase/errors"
|
17
18
|
|
18
19
|
module Couchbase
|
19
20
|
module Management
|
@@ -37,8 +38,18 @@ module Couchbase
|
|
37
38
|
#
|
38
39
|
# @return [Array<QueryIndex>]
|
39
40
|
#
|
40
|
-
# @raise [
|
41
|
+
# @raise [Error::InvalidArgument]
|
41
42
|
def get_all_indexes(options = Options::Query::GetAllIndexes.new)
|
43
|
+
unless options.scope_name.nil?
|
44
|
+
raise Error::InvalidArgument,
|
45
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
46
|
+
end
|
47
|
+
|
48
|
+
unless options.collection_name.nil?
|
49
|
+
raise Error::InvalidArgument,
|
50
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
51
|
+
end
|
52
|
+
|
42
53
|
res = @backend.collection_query_index_get_all(@bucket_name, @scope_name, @collection_name, options.to_backend)
|
43
54
|
res[:indexes].map do |idx|
|
44
55
|
QueryIndex.new do |index|
|
@@ -64,15 +75,17 @@ module Couchbase
|
|
64
75
|
#
|
65
76
|
# @return void
|
66
77
|
#
|
67
|
-
# @raise [
|
78
|
+
# @raise [Error::InvalidArgument]
|
68
79
|
# @raise [Error::IndexExists]
|
69
80
|
def create_index(index_name, fields, options = Options::Query::CreateIndex.new)
|
70
81
|
unless options.scope_name.nil?
|
71
|
-
raise
|
82
|
+
raise Error::InvalidArgument,
|
83
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
72
84
|
end
|
73
85
|
|
74
86
|
unless options.collection_name.nil?
|
75
|
-
raise
|
87
|
+
raise Error::InvalidArgument,
|
88
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
76
89
|
end
|
77
90
|
|
78
91
|
@backend.collection_query_index_create(@bucket_name, @scope_name, @collection_name, index_name, fields, options.to_backend)
|
@@ -84,15 +97,17 @@ module Couchbase
|
|
84
97
|
#
|
85
98
|
# @return void
|
86
99
|
#
|
87
|
-
# @raise [
|
100
|
+
# @raise [Error::InvalidArgument]
|
88
101
|
# @raise [Error::IndexExists]
|
89
102
|
def create_primary_index(options = Options::Query::CreatePrimaryIndex.new)
|
90
103
|
unless options.scope_name.nil?
|
91
|
-
raise
|
104
|
+
raise Error::InvalidArgument,
|
105
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
92
106
|
end
|
93
107
|
|
94
108
|
unless options.collection_name.nil?
|
95
|
-
raise
|
109
|
+
raise Error::InvalidArgument,
|
110
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
96
111
|
end
|
97
112
|
|
98
113
|
@backend.collection_query_index_create_primary(@bucket_name, @scope_name, @collection_name, options.to_backend)
|
@@ -105,15 +120,17 @@ module Couchbase
|
|
105
120
|
#
|
106
121
|
# @return void
|
107
122
|
#
|
108
|
-
# @raise [
|
123
|
+
# @raise [Error::InvalidArgument]
|
109
124
|
# @raise [Error::IndexNotFound]
|
110
125
|
def drop_index(index_name, options = Options::Query::DropIndex.new)
|
111
126
|
unless options.scope_name.nil?
|
112
|
-
raise
|
127
|
+
raise Error::InvalidArgument,
|
128
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
113
129
|
end
|
114
130
|
|
115
131
|
unless options.collection_name.nil?
|
116
|
-
raise
|
132
|
+
raise Error::InvalidArgument,
|
133
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
117
134
|
end
|
118
135
|
|
119
136
|
@backend.collection_query_index_drop(@bucket_name, @scope_name, @collection_name, index_name, options.to_backend)
|
@@ -125,15 +142,17 @@ module Couchbase
|
|
125
142
|
#
|
126
143
|
# @return void
|
127
144
|
#
|
128
|
-
# @raise [
|
145
|
+
# @raise [Error::InvalidArgument]
|
129
146
|
# @raise [Error::IndexNotFound]
|
130
147
|
def drop_primary_index(options = Options::Query::DropPrimaryIndex.new)
|
131
148
|
unless options.scope_name.nil?
|
132
|
-
raise
|
149
|
+
raise Error::InvalidArgument,
|
150
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
133
151
|
end
|
134
152
|
|
135
153
|
unless options.collection_name.nil?
|
136
|
-
raise
|
154
|
+
raise Error::InvalidArgument,
|
155
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
137
156
|
end
|
138
157
|
|
139
158
|
@backend.collection_query_index_drop_primary(@bucket_name, @scope_name, @collection_name, options.to_backend)
|
@@ -145,8 +164,18 @@ module Couchbase
|
|
145
164
|
#
|
146
165
|
# @return void
|
147
166
|
#
|
148
|
-
# @raise [
|
167
|
+
# @raise [Error::InvalidArgument]
|
149
168
|
def build_deferred_indexes(options = Options::Query::BuildDeferredIndexes.new)
|
169
|
+
unless options.scope_name.nil?
|
170
|
+
raise Error::InvalidArgument,
|
171
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
172
|
+
end
|
173
|
+
|
174
|
+
unless options.collection_name.nil?
|
175
|
+
raise Error::InvalidArgument,
|
176
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
177
|
+
end
|
178
|
+
|
150
179
|
@backend.collection_query_index_build_deferred(@bucket_name, @scope_name, @collection_name, options.to_backend)
|
151
180
|
end
|
152
181
|
|
@@ -156,9 +185,19 @@ module Couchbase
|
|
156
185
|
# @param [Integer, #in_milliseconds] timeout the time in milliseconds allowed for the operation to complete
|
157
186
|
# @param [Options::Query::WatchIndexes] options
|
158
187
|
#
|
159
|
-
# @raise [
|
188
|
+
# @raise [Error::InvalidArgument]
|
160
189
|
# @raise [Error::IndexNotFound]
|
161
190
|
def watch_indexes(index_names, timeout, options = Options::Query::WatchIndexes.new)
|
191
|
+
unless options.scope_name.nil?
|
192
|
+
raise Error::InvalidArgument,
|
193
|
+
"Scope name cannot be set in the options when using the Query Index manager at the collection level"
|
194
|
+
end
|
195
|
+
|
196
|
+
unless options.collection_name.nil?
|
197
|
+
raise Error::InvalidArgument,
|
198
|
+
"Collection name cannot be set in the options when using the Query Index manager at the collection level"
|
199
|
+
end
|
200
|
+
|
162
201
|
index_names.append("#primary") if options.watch_primary
|
163
202
|
|
164
203
|
interval_millis = 50
|