couchbase 3.0.2 → 3.0.3
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/README.md +2 -2
- data/ext/CMakeLists.txt +3 -0
- data/ext/build_version.hxx.in +1 -1
- data/ext/cmake/CompilerWarnings.cmake +1 -0
- data/ext/cmake/PreventInSourceBuilds.cmake +4 -1
- data/ext/couchbase/bucket.hxx +28 -2
- data/ext/couchbase/cluster.hxx +8 -2
- data/ext/couchbase/couchbase.cxx +955 -511
- data/ext/couchbase/error_context/analytics.hxx +46 -0
- data/ext/couchbase/error_context/http.hxx +44 -0
- data/ext/couchbase/error_context/key_value.hxx +47 -0
- data/ext/couchbase/error_context/query.hxx +46 -0
- data/ext/couchbase/error_context/search.hxx +47 -0
- data/ext/couchbase/error_context/view.hxx +47 -0
- data/ext/couchbase/io/dns_codec.hxx +1 -2
- data/ext/couchbase/io/http_command.hxx +16 -3
- data/ext/couchbase/io/http_context.hxx +1 -1
- data/ext/couchbase/io/http_session.hxx +12 -6
- data/ext/couchbase/io/http_session_manager.hxx +25 -24
- data/ext/couchbase/io/mcbp_session.hxx +8 -2
- data/ext/couchbase/io/retry_context.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataset_create.hxx +19 -12
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +18 -10
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +16 -10
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +18 -11
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +17 -11
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +17 -10
- data/ext/couchbase/operations/analytics_index_create.hxx +17 -11
- data/ext/couchbase/operations/analytics_index_drop.hxx +16 -10
- data/ext/couchbase/operations/analytics_index_get_all.hxx +14 -10
- data/ext/couchbase/operations/analytics_link_connect.hxx +15 -9
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +16 -10
- data/ext/couchbase/operations/bucket_create.hxx +33 -10
- data/ext/couchbase/operations/bucket_drop.hxx +9 -8
- data/ext/couchbase/operations/bucket_flush.hxx +8 -8
- data/ext/couchbase/operations/bucket_get.hxx +15 -10
- data/ext/couchbase/operations/bucket_get_all.hxx +14 -7
- data/ext/couchbase/operations/bucket_settings.hxx +16 -0
- data/ext/couchbase/operations/bucket_update.hxx +32 -10
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +6 -6
- data/ext/couchbase/operations/collection_create.hxx +19 -13
- data/ext/couchbase/operations/collection_drop.hxx +18 -12
- data/ext/couchbase/operations/collections_manifest_get.hxx +5 -10
- data/ext/couchbase/operations/document_analytics.hxx +39 -17
- data/ext/couchbase/operations/document_append.hxx +5 -10
- data/ext/couchbase/operations/document_decrement.hxx +5 -10
- data/ext/couchbase/operations/document_exists.hxx +4 -6
- data/ext/couchbase/operations/document_get.hxx +6 -10
- data/ext/couchbase/operations/document_get_and_lock.hxx +4 -9
- data/ext/couchbase/operations/document_get_and_touch.hxx +4 -9
- data/ext/couchbase/operations/document_get_projected.hxx +21 -14
- data/ext/couchbase/operations/document_increment.hxx +5 -10
- data/ext/couchbase/operations/document_insert.hxx +5 -10
- data/ext/couchbase/operations/document_lookup_in.hxx +4 -9
- data/ext/couchbase/operations/document_mutate_in.hxx +7 -12
- data/ext/couchbase/operations/document_prepend.hxx +5 -10
- data/ext/couchbase/operations/document_query.hxx +45 -28
- data/ext/couchbase/operations/document_remove.hxx +5 -10
- data/ext/couchbase/operations/document_replace.hxx +5 -10
- data/ext/couchbase/operations/document_search.hxx +37 -16
- data/ext/couchbase/operations/document_touch.hxx +4 -9
- data/ext/couchbase/operations/document_unlock.hxx +4 -9
- data/ext/couchbase/operations/document_upsert.hxx +5 -10
- data/ext/couchbase/operations/document_view.hxx +29 -13
- data/ext/couchbase/operations/group_drop.hxx +7 -7
- data/ext/couchbase/operations/group_get.hxx +14 -10
- data/ext/couchbase/operations/group_get_all.hxx +14 -8
- data/ext/couchbase/operations/group_upsert.hxx +15 -9
- data/ext/couchbase/operations/http_noop.hxx +5 -5
- data/ext/couchbase/operations/mcbp_noop.hxx +3 -9
- data/ext/couchbase/operations/query_index_build_deferred.hxx +15 -9
- data/ext/couchbase/operations/query_index_create.hxx +16 -10
- data/ext/couchbase/operations/query_index_drop.hxx +16 -10
- data/ext/couchbase/operations/query_index_get_all.hxx +13 -7
- data/ext/couchbase/operations/role_get_all.hxx +14 -8
- data/ext/couchbase/operations/scope_create.hxx +19 -13
- data/ext/couchbase/operations/scope_drop.hxx +17 -11
- data/ext/couchbase/operations/scope_get_all.hxx +15 -10
- data/ext/couchbase/operations/search_get_stats.hxx +5 -5
- data/ext/couchbase/operations/search_index_analyze_document.hxx +25 -13
- data/ext/couchbase/operations/search_index_control_ingest.hxx +23 -11
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +23 -11
- data/ext/couchbase/operations/search_index_control_query.hxx +23 -11
- data/ext/couchbase/operations/search_index_drop.hxx +22 -10
- data/ext/couchbase/operations/search_index_get.hxx +22 -10
- data/ext/couchbase/operations/search_index_get_all.hxx +13 -7
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +24 -13
- data/ext/couchbase/operations/search_index_get_stats.hxx +16 -10
- data/ext/couchbase/operations/search_index_upsert.hxx +23 -11
- data/ext/couchbase/operations/user_drop.hxx +8 -8
- data/ext/couchbase/operations/user_get.hxx +14 -10
- data/ext/couchbase/operations/user_get_all.hxx +14 -8
- data/ext/couchbase/operations/user_upsert.hxx +15 -9
- data/ext/couchbase/operations/view_index_drop.hxx +7 -7
- data/ext/couchbase/operations/view_index_get.hxx +15 -9
- data/ext/couchbase/operations/view_index_get_all.hxx +15 -9
- data/ext/couchbase/operations/view_index_upsert.hxx +8 -8
- data/ext/couchbase/origin.hxx +1 -0
- data/ext/couchbase/platform/terminate_handler.cc +12 -8
- data/ext/couchbase/protocol/client_request.hxx +2 -1
- data/ext/couchbase/protocol/client_response.hxx +18 -15
- data/ext/couchbase/protocol/cmd_exists.hxx +1 -0
- data/ext/couchbase/protocol/cmd_get.hxx +1 -1
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +3 -4
- data/ext/couchbase/protocol/enhanced_error_info.hxx +28 -0
- data/ext/couchbase/utils/connection_string.hxx +1 -1
- data/ext/couchbase/version.hxx +1 -1
- data/ext/extconf.rb +1 -1
- data/ext/test/test_native_binary_operations.cxx +18 -18
- data/ext/test/test_native_diagnostics.cxx +2 -2
- data/ext/test/test_native_trivial_crud.cxx +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/file_reader.hpp +1 -5
- data/lib/active_support/cache/couchbase_store.rb +362 -0
- data/lib/couchbase.rb +2 -0
- data/lib/couchbase/authenticator.rb +26 -0
- data/lib/couchbase/binary_collection.rb +1 -0
- data/lib/couchbase/bucket.rb +1 -0
- data/lib/couchbase/cluster.rb +51 -27
- data/lib/couchbase/collection.rb +19 -4
- data/lib/couchbase/collection_options.rb +10 -0
- data/lib/couchbase/configuration.rb +57 -0
- data/lib/couchbase/datastructures.rb +6 -0
- data/lib/couchbase/errors.rb +111 -3
- data/lib/couchbase/management.rb +27 -0
- data/lib/couchbase/management/bucket_manager.rb +9 -2
- data/lib/couchbase/management/collection_manager.rb +1 -1
- data/lib/couchbase/management/user_manager.rb +18 -2
- data/lib/couchbase/options.rb +33 -23
- data/lib/couchbase/railtie.rb +45 -0
- data/lib/couchbase/scope.rb +44 -3
- data/lib/couchbase/utils.rb +21 -0
- data/lib/couchbase/utils/time.rb +52 -0
- data/lib/couchbase/version.rb +1 -1
- data/lib/rails/generators/couchbase/config/config_generator.rb +27 -0
- metadata +19 -5
data/lib/couchbase.rb
CHANGED
|
@@ -15,12 +15,34 @@
|
|
|
15
15
|
module Couchbase
|
|
16
16
|
# Authenticator for username/password credentials
|
|
17
17
|
class PasswordAuthenticator
|
|
18
|
+
DEFAULT_SASL_MECHANISMS = [:scram_sha512, :scram_sha256, :scram_sha1].freeze
|
|
19
|
+
|
|
18
20
|
attr_accessor :username
|
|
19
21
|
attr_accessor :password
|
|
22
|
+
attr_accessor :allowed_sasl_mechanisms
|
|
20
23
|
|
|
24
|
+
# Creates a new password authenticator with the default settings.
|
|
25
|
+
#
|
|
26
|
+
# @param [String] password the username to use for all authentication requests
|
|
27
|
+
# @param [String] username the password
|
|
21
28
|
def initialize(username, password)
|
|
22
29
|
@username = username
|
|
23
30
|
@password = password
|
|
31
|
+
@allowed_sasl_mechanisms = DEFAULT_SASL_MECHANISMS
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Creates a LDAP compatible password authenticator which is INSECURE if not used with TLS.
|
|
35
|
+
#
|
|
36
|
+
# Please note that this is INSECURE and will leak user credentials on the wire to eavesdroppers. This should
|
|
37
|
+
# only be enabled in trusted environments.
|
|
38
|
+
#
|
|
39
|
+
# @param [String] username the username to use for all authentication.
|
|
40
|
+
# @param [String] password the password to use alongside the username.
|
|
41
|
+
# @return [PasswordAuthenticator]
|
|
42
|
+
def self.ldap_compatible(username, password)
|
|
43
|
+
new(username, password).tap do |auth|
|
|
44
|
+
auth.allowed_sasl_mechanisms = [:plain]
|
|
45
|
+
end
|
|
24
46
|
end
|
|
25
47
|
end
|
|
26
48
|
|
|
@@ -31,6 +53,10 @@ module Couchbase
|
|
|
31
53
|
attr_accessor :certificate_path
|
|
32
54
|
attr_accessor :key_path
|
|
33
55
|
|
|
56
|
+
# Creates a new authenticator with certificate and key paths
|
|
57
|
+
#
|
|
58
|
+
# @param [String] certificate_path path to certificate
|
|
59
|
+
# @param [String] key_path path to private key
|
|
34
60
|
def initialize(certificate_path, key_path)
|
|
35
61
|
@certificate_path = certificate_path
|
|
36
62
|
@key_path = key_path
|
data/lib/couchbase/bucket.rb
CHANGED
data/lib/couchbase/cluster.rb
CHANGED
|
@@ -12,15 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
require "couchbase/configuration"
|
|
15
16
|
require "couchbase/authenticator"
|
|
16
17
|
require "couchbase/bucket"
|
|
17
18
|
|
|
18
|
-
require "couchbase/management
|
|
19
|
-
require "couchbase/management/bucket_manager"
|
|
20
|
-
require "couchbase/management/query_index_manager"
|
|
21
|
-
require "couchbase/management/analytics_index_manager"
|
|
22
|
-
require "couchbase/management/search_index_manager"
|
|
23
|
-
|
|
19
|
+
require "couchbase/management"
|
|
24
20
|
require "couchbase/options"
|
|
25
21
|
|
|
26
22
|
require "couchbase/search_options"
|
|
@@ -29,6 +25,7 @@ require "couchbase/analytics_options"
|
|
|
29
25
|
require "couchbase/diagnostics"
|
|
30
26
|
|
|
31
27
|
module Couchbase
|
|
28
|
+
# The main entry point when connecting to a Couchbase cluster.
|
|
32
29
|
class Cluster
|
|
33
30
|
alias inspect to_s
|
|
34
31
|
|
|
@@ -86,6 +83,14 @@ module Couchbase
|
|
|
86
83
|
# cluster.query("SELECT * FROM `travel-sample` WHERE type = $type LIMIT 10",
|
|
87
84
|
# Options::Query(named_parameters: {type: "hotel"}, metrics: true))
|
|
88
85
|
#
|
|
86
|
+
# @example Execute query with consistency requirement. Make sure that the index is in sync with selected mutation
|
|
87
|
+
# res = collection.upsert("user:42", {
|
|
88
|
+
# "name" => "Brass Doorknob",
|
|
89
|
+
# "email" => "brass.doorknob@example.com",
|
|
90
|
+
# })
|
|
91
|
+
# cluster.query("SELECT name, email FROM `mybucket`",
|
|
92
|
+
# Options::Query(consistent_with: MutationState.new(res.mutation_token)))
|
|
93
|
+
#
|
|
89
94
|
# @return [QueryResult]
|
|
90
95
|
def query(statement, options = Options::Query.new)
|
|
91
96
|
resp = @backend.document_query(statement, options.to_backend)
|
|
@@ -354,42 +359,61 @@ module Couchbase
|
|
|
354
359
|
# @param [String] username name of the user
|
|
355
360
|
# @param [String] password password of the user
|
|
356
361
|
# @param [Options::Cluster, nil] options custom options when creating the cluster connection
|
|
362
|
+
#
|
|
363
|
+
# @overload new(configuration)
|
|
364
|
+
# @param [Configuration] configuration configuration object
|
|
357
365
|
def initialize(connection_string, *args)
|
|
358
366
|
credentials = {}
|
|
367
|
+
open_options = {}
|
|
359
368
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
credentials[:username] = options
|
|
364
|
-
credentials[:password] =
|
|
369
|
+
if connection_string.is_a?(Configuration)
|
|
370
|
+
options = connection_string
|
|
371
|
+
connection_string = options.connection_string
|
|
372
|
+
credentials[:username] = options.username
|
|
373
|
+
credentials[:password] = options.password
|
|
374
|
+
raise ArgumentError, "missing connection_string" unless connection_string
|
|
365
375
|
raise ArgumentError, "missing username" unless credentials[:username]
|
|
366
376
|
raise ArgumentError, "missing password" unless credentials[:password]
|
|
367
|
-
when Options::Cluster
|
|
368
|
-
authenticator = options&.authenticator
|
|
369
|
-
case authenticator
|
|
370
|
-
when PasswordAuthenticator
|
|
371
|
-
credentials[:username] = authenticator&.username
|
|
372
|
-
raise ArgumentError, "missing username" unless credentials[:username]
|
|
373
377
|
|
|
374
|
-
|
|
378
|
+
open_options[:allowed_sasl_mechanisms] = PasswordAuthenticator::DEFAULT_SASL_MECHANISMS
|
|
379
|
+
else
|
|
380
|
+
options = args.shift
|
|
381
|
+
case options
|
|
382
|
+
when String
|
|
383
|
+
credentials[:username] = options
|
|
384
|
+
credentials[:password] = args.shift
|
|
385
|
+
raise ArgumentError, "missing username" unless credentials[:username]
|
|
375
386
|
raise ArgumentError, "missing password" unless credentials[:password]
|
|
376
387
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
388
|
+
open_options[:allowed_sasl_mechanisms] = PasswordAuthenticator::DEFAULT_SASL_MECHANISMS
|
|
389
|
+
when Options::Cluster
|
|
390
|
+
authenticator = options&.authenticator
|
|
391
|
+
case authenticator
|
|
392
|
+
when PasswordAuthenticator
|
|
393
|
+
credentials[:username] = authenticator&.username
|
|
394
|
+
raise ArgumentError, "missing username" unless credentials[:username]
|
|
395
|
+
|
|
396
|
+
credentials[:password] = authenticator&.password
|
|
397
|
+
raise ArgumentError, "missing password" unless credentials[:password]
|
|
398
|
+
|
|
399
|
+
open_options[:allowed_sasl_mechanisms] = authenticator&.allowed_sasl_mechanisms
|
|
400
|
+
when CertificateAuthenticator
|
|
401
|
+
credentials[:certificate_path] = authenticator&.certificate_path
|
|
402
|
+
raise ArgumentError, "missing certificate path" unless credentials[:certificate_path]
|
|
380
403
|
|
|
381
|
-
|
|
382
|
-
|
|
404
|
+
credentials[:key_path] = authenticator&.key_path
|
|
405
|
+
raise ArgumentError, "missing key path" unless credentials[:key_path]
|
|
383
406
|
|
|
407
|
+
else
|
|
408
|
+
raise ArgumentError, "options must have authenticator configured"
|
|
409
|
+
end
|
|
384
410
|
else
|
|
385
|
-
raise ArgumentError, "
|
|
411
|
+
raise ArgumentError, "unexpected second argument, have to be String or ClusterOptions"
|
|
386
412
|
end
|
|
387
|
-
else
|
|
388
|
-
raise ArgumentError, "unexpected second argument, have to be String or ClusterOptions"
|
|
389
413
|
end
|
|
390
414
|
|
|
391
415
|
@backend = Backend.new
|
|
392
|
-
@backend.open(connection_string, credentials,
|
|
416
|
+
@backend.open(connection_string, credentials, open_options)
|
|
393
417
|
end
|
|
394
418
|
|
|
395
419
|
# @api private
|
data/lib/couchbase/collection.rb
CHANGED
|
@@ -17,6 +17,7 @@ require "couchbase/collection_options"
|
|
|
17
17
|
require "couchbase/binary_collection"
|
|
18
18
|
|
|
19
19
|
module Couchbase
|
|
20
|
+
# Provides access to all collection APIs
|
|
20
21
|
class Collection
|
|
21
22
|
attr_reader :bucket_name
|
|
22
23
|
attr_reader :scope_name
|
|
@@ -142,7 +143,7 @@ module Couchbase
|
|
|
142
143
|
# Fetches a full document and resets its expiration time to the duration provided
|
|
143
144
|
#
|
|
144
145
|
# @param [String] id the document id which is used to uniquely identify it.
|
|
145
|
-
# @param [Integer, #in_seconds] expiry the new expiration time for the document
|
|
146
|
+
# @param [Integer, #in_seconds, Time] expiry the new expiration time for the document
|
|
146
147
|
# @param [Options::GetAndTouch] options request customization
|
|
147
148
|
#
|
|
148
149
|
# @example Retrieve document and prolong its expiration for another 10 seconds
|
|
@@ -151,7 +152,7 @@ module Couchbase
|
|
|
151
152
|
# @return [GetResult]
|
|
152
153
|
def get_and_touch(id, expiry, options = Options::GetAndTouch.new)
|
|
153
154
|
resp = @backend.document_get_and_touch(bucket_name, "#{@scope_name}.#{@name}", id,
|
|
154
|
-
|
|
155
|
+
Utils::Time.extract_expiry_time(expiry),
|
|
155
156
|
options.to_backend)
|
|
156
157
|
GetResult.new do |res|
|
|
157
158
|
res.transcoder = options.transcoder
|
|
@@ -258,6 +259,7 @@ module Couchbase
|
|
|
258
259
|
MutationResult.new do |res|
|
|
259
260
|
res.cas = entry[:cas]
|
|
260
261
|
res.mutation_token = extract_mutation_token(entry)
|
|
262
|
+
res.error = entry[:error]
|
|
261
263
|
end
|
|
262
264
|
end
|
|
263
265
|
end
|
|
@@ -338,6 +340,7 @@ module Couchbase
|
|
|
338
340
|
MutationResult.new do |res|
|
|
339
341
|
res.cas = entry[:cas]
|
|
340
342
|
res.mutation_token = extract_mutation_token(entry)
|
|
343
|
+
res.error = entry[:error]
|
|
341
344
|
end
|
|
342
345
|
end
|
|
343
346
|
end
|
|
@@ -366,7 +369,7 @@ module Couchbase
|
|
|
366
369
|
# Update the expiration of the document with the given id
|
|
367
370
|
#
|
|
368
371
|
# @param [String] id the document id which is used to uniquely identify it.
|
|
369
|
-
# @param [Integer, #in_seconds] expiry new expiration time for the document
|
|
372
|
+
# @param [Integer, #in_seconds, Time] expiry new expiration time for the document
|
|
370
373
|
# @param [Options::Touch] options request customization
|
|
371
374
|
#
|
|
372
375
|
# @example Reset expiration timer for document to 30 seconds
|
|
@@ -375,7 +378,7 @@ module Couchbase
|
|
|
375
378
|
# @return [MutationResult]
|
|
376
379
|
def touch(id, expiry, options = Options::Touch.new)
|
|
377
380
|
resp = @backend.document_touch(bucket_name, "#{@scope_name}.#{@name}", id,
|
|
378
|
-
|
|
381
|
+
Utils::Time.extract_expiry_time(expiry),
|
|
379
382
|
options.to_backend)
|
|
380
383
|
MutationResult.new do |res|
|
|
381
384
|
res.cas = resp[:cas]
|
|
@@ -411,6 +414,11 @@ module Couchbase
|
|
|
411
414
|
# ]
|
|
412
415
|
# collection.lookup_in("customer123", lookup_specs)
|
|
413
416
|
#
|
|
417
|
+
# @example Retrieve country name and check if pending purchases array is empty
|
|
418
|
+
# collection.lookup_in "customer123", [
|
|
419
|
+
# LookupInSpec.get("addresses.delivery.country"),
|
|
420
|
+
# LookupInSpec.exists("purchases.pending[-1]"),
|
|
421
|
+
# ]
|
|
414
422
|
# @return [LookupInResult]
|
|
415
423
|
def lookup_in(id, specs, options = Options::LookupIn.new)
|
|
416
424
|
resp = @backend.document_lookup_in(
|
|
@@ -453,6 +461,13 @@ module Couchbase
|
|
|
453
461
|
# ]
|
|
454
462
|
# collection.mutate_in("customer123", mutation_specs, Options::MutateIn(expiry: 10))
|
|
455
463
|
#
|
|
464
|
+
# @example Write meta attribute, remove array entry and replace email field
|
|
465
|
+
# collection.mutate_in("customer123", [
|
|
466
|
+
# MutateInSpec.upsert("_framework.model_type", "Customer").xattr,
|
|
467
|
+
# MutateInSpec.remove("addresses.billing[2]"),
|
|
468
|
+
# MutateInSpec.replace("email", "dougr96@hotmail.com"),
|
|
469
|
+
# ])
|
|
470
|
+
#
|
|
456
471
|
# @return [MutateInResult]
|
|
457
472
|
def mutate_in(id, specs, options = Options::MutateIn.new)
|
|
458
473
|
resp = @backend.document_mutate_in(
|
|
@@ -32,6 +32,11 @@ module Couchbase
|
|
|
32
32
|
# @return [Error::CouchbaseError, nil] error associated with the result, or nil (used in {Collection#get_multi})
|
|
33
33
|
attr_accessor :error
|
|
34
34
|
|
|
35
|
+
# @return [Boolean] true if error was not associated with the result (useful for multi-operations)
|
|
36
|
+
def success?
|
|
37
|
+
!error
|
|
38
|
+
end
|
|
39
|
+
|
|
35
40
|
# @return [String] The encoded content when loading the document
|
|
36
41
|
# @api private
|
|
37
42
|
attr_accessor :encoded
|
|
@@ -112,6 +117,11 @@ module Couchbase
|
|
|
112
117
|
# {Collection#remove_multi})
|
|
113
118
|
attr_accessor :error
|
|
114
119
|
|
|
120
|
+
# @return [Boolean] true if error was not associated with the result (useful for multi-operations)
|
|
121
|
+
def success?
|
|
122
|
+
!error
|
|
123
|
+
end
|
|
124
|
+
|
|
115
125
|
# @yieldparam [MutationResult] self
|
|
116
126
|
def initialize
|
|
117
127
|
@error = nil
|
|
@@ -0,0 +1,57 @@
|
|
|
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 "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["RACK_ENV"] || ENV["COUCHBASE_ENV"] or raise ::Couchbase::Error::NoEnvironment
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
module Couchbase
|
|
16
|
+
# This namespace includes easy-to-use wrappers for various concurrent data-structures.
|
|
17
|
+
module Datastructures
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
15
21
|
require "couchbase/datastructures/couchbase_list"
|
|
16
22
|
require "couchbase/datastructures/couchbase_set"
|
|
17
23
|
require "couchbase/datastructures/couchbase_queue"
|
data/lib/couchbase/errors.rb
CHANGED
|
@@ -12,34 +12,59 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
require "json"
|
|
16
|
+
|
|
15
17
|
module Couchbase
|
|
18
|
+
# This namespace contains all error types that the library might raise.
|
|
16
19
|
module Error
|
|
17
20
|
class CouchbaseError < StandardError
|
|
21
|
+
# @return [Hash] attributes associated with the error
|
|
22
|
+
attr_reader :context
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super
|
|
26
|
+
end
|
|
18
27
|
end
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
class InvalidArgument < ArgumentError
|
|
30
|
+
# @return [Hash] attributes associated with the error
|
|
31
|
+
attr_reader :context
|
|
21
32
|
|
|
22
|
-
|
|
33
|
+
def to_s
|
|
34
|
+
defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super
|
|
35
|
+
end
|
|
23
36
|
end
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
# Common exceptions
|
|
39
|
+
|
|
40
|
+
class RequestCanceled < CouchbaseError
|
|
26
41
|
end
|
|
27
42
|
|
|
28
43
|
class ServiceNotAvailable < CouchbaseError
|
|
29
44
|
end
|
|
30
45
|
|
|
46
|
+
# Indicates an operation failed because there has been an internal error in the server.
|
|
31
47
|
class InternalServerFailure < CouchbaseError
|
|
32
48
|
end
|
|
33
49
|
|
|
50
|
+
# Every exception that has to do with authentication problems should either instantiate or subclass from this type.
|
|
34
51
|
class AuthenticationFailure < CouchbaseError
|
|
35
52
|
end
|
|
36
53
|
|
|
37
54
|
class TemporaryFailure < CouchbaseError
|
|
38
55
|
end
|
|
39
56
|
|
|
57
|
+
# Indicates an operation failed because parsing of the input returned with an error.
|
|
40
58
|
class ParsingFailure < CouchbaseError
|
|
41
59
|
end
|
|
42
60
|
|
|
61
|
+
# Indicates an optimistic locking failure.
|
|
62
|
+
#
|
|
63
|
+
# The operation failed because the specified compare and swap (CAS) value differs from the document's actual CAS
|
|
64
|
+
# value. This means the document was modified since the original CAS value was acquired.
|
|
65
|
+
#
|
|
66
|
+
# The application should usually respond by fetching a fresh version of the document and repeating the failed
|
|
67
|
+
# operation.
|
|
43
68
|
class CasMismatch < CouchbaseError
|
|
44
69
|
end
|
|
45
70
|
|
|
@@ -58,123 +83,201 @@ module Couchbase
|
|
|
58
83
|
class IndexExists < CouchbaseError
|
|
59
84
|
end
|
|
60
85
|
|
|
86
|
+
# Raised when provided content could not be successfully encoded.
|
|
61
87
|
class EncodingFailure < CouchbaseError
|
|
62
88
|
end
|
|
63
89
|
|
|
90
|
+
# Raised when provided content could not be successfully decoded.
|
|
64
91
|
class DecodingFailure < CouchbaseError
|
|
65
92
|
end
|
|
66
93
|
|
|
67
94
|
class UnsupportedOperation < CouchbaseError
|
|
68
95
|
end
|
|
69
96
|
|
|
97
|
+
# The {Timeout} signals that an operation timed out before it could be completed.
|
|
98
|
+
#
|
|
99
|
+
# It is important to understand that the timeout itself is always just the effect an underlying cause, never the
|
|
100
|
+
# issue itself. The root cause might not even be on the application side, also the network and server need to be
|
|
101
|
+
# taken into account.
|
|
102
|
+
#
|
|
103
|
+
# Right now the SDK can throw two different implementations of this class:
|
|
104
|
+
#
|
|
105
|
+
# {AmbiguousTimeout}::
|
|
106
|
+
# The operation might have caused a side effect on the server and should not be retried without
|
|
107
|
+
# actions and checks.
|
|
108
|
+
#
|
|
109
|
+
# {UnambiguousTimeout}::
|
|
110
|
+
# The operation has not caused a side effect on the server and is safe to retry. This is always the case for
|
|
111
|
+
# idempotent operations. For non-idempotent operations it depends on the state the operation was in at the time of
|
|
112
|
+
# cancellation.
|
|
70
113
|
class Timeout < CouchbaseError
|
|
71
114
|
end
|
|
72
115
|
|
|
116
|
+
# This is a special case of the timeout exception, signaling that the timeout happened with an ambiguous cause.
|
|
73
117
|
class AmbiguousTimeout < Timeout
|
|
74
118
|
end
|
|
75
119
|
|
|
120
|
+
# This is a special case of the timeout exception, signaling that the timeout happened with no ambiguous cause.
|
|
76
121
|
class UnambiguousTimeout < Timeout
|
|
77
122
|
end
|
|
78
123
|
|
|
124
|
+
# Exception which states that the feature is not available.
|
|
79
125
|
class FeatureNotAvailable < CouchbaseError
|
|
80
126
|
end
|
|
81
127
|
|
|
82
128
|
# KeyValue exceptions
|
|
83
129
|
|
|
130
|
+
# Indicates an operation failed because the key does not exist.
|
|
84
131
|
class DocumentNotFound < CouchbaseError
|
|
85
132
|
end
|
|
86
133
|
|
|
134
|
+
# Indicates an operation completed but no successful document was retrievable.
|
|
87
135
|
class DocumentIrretrievable < CouchbaseError
|
|
88
136
|
end
|
|
89
137
|
|
|
138
|
+
# Thrown when the server reports a temporary failure that is very likely to be lock-related (like an already locked
|
|
139
|
+
# key or a bad cas used for unlock).
|
|
140
|
+
#
|
|
141
|
+
# See https://issues.couchbase.com/browse/MB-13087 for an explanation of why this is only _likely_ to be
|
|
142
|
+
# lock-related.
|
|
90
143
|
class DocumentLocked < CouchbaseError
|
|
91
144
|
end
|
|
92
145
|
|
|
146
|
+
# Thrown when the request is too big for some reason.
|
|
93
147
|
class ValueTooLarge < CouchbaseError
|
|
94
148
|
end
|
|
95
149
|
|
|
150
|
+
# Indicates an operation failed because the key already exists.
|
|
96
151
|
class DocumentExists < CouchbaseError
|
|
97
152
|
end
|
|
98
153
|
|
|
154
|
+
# This exception is raised when a durability level has been requested that is not available on the server.
|
|
99
155
|
class DurabilityLevelNotAvailable < CouchbaseError
|
|
100
156
|
end
|
|
101
157
|
|
|
158
|
+
# The given durability requirements are currently impossible to achieve, as not enough configured replicas are
|
|
159
|
+
# currently available.
|
|
102
160
|
class DurabilityImpossible < CouchbaseError
|
|
103
161
|
end
|
|
104
162
|
|
|
163
|
+
# The synchronous replication durability work can return an ambiguous error (or we timeout waiting for the response,
|
|
164
|
+
# which is effectively the same). Here we know the change is on a majority of replicas, or it's on none.
|
|
105
165
|
class DurabilityAmbiguous < CouchbaseError
|
|
106
166
|
end
|
|
107
167
|
|
|
168
|
+
# Returned if an attempt is made to mutate a key which already has a durable write pending.
|
|
108
169
|
class DurableWriteInProgress < CouchbaseError
|
|
109
170
|
end
|
|
110
171
|
|
|
172
|
+
# The requested key has a SyncWrite which is being re-committed.
|
|
111
173
|
class DurableWriteReCommitInProgress < CouchbaseError
|
|
112
174
|
end
|
|
113
175
|
|
|
176
|
+
# Subdocument exception thrown when a path does not exist in the document. The exact meaning of path existence
|
|
177
|
+
# depends on the operation and inputs.
|
|
114
178
|
class PathNotFound < CouchbaseError
|
|
115
179
|
end
|
|
116
180
|
|
|
181
|
+
# Subdocument exception thrown when the path structure conflicts with the document structure (for example, if a
|
|
182
|
+
# path mentions foo.bar[0].baz, but foo.bar is actually a JSON object).
|
|
117
183
|
class PathMismatch < CouchbaseError
|
|
118
184
|
end
|
|
119
185
|
|
|
186
|
+
# Subdocument exception thrown when path has a syntax error, or path syntax is incorrect for the operation (for
|
|
187
|
+
# example, if operation requires an array index).
|
|
120
188
|
class PathInvalid < CouchbaseError
|
|
121
189
|
end
|
|
122
190
|
|
|
191
|
+
# Subdocument exception thrown when path is too deep to parse. Depth of a path is determined by how many components
|
|
192
|
+
# (or levels) it contains.
|
|
193
|
+
#
|
|
194
|
+
# The current limitation is there to ensure a single parse does not consume too much memory (overloading the
|
|
195
|
+
# server). This error is similar to other TooDeep errors, which all relate to various validation stages to ensure
|
|
196
|
+
# the server does not consume too much memory when parsing a single document.
|
|
123
197
|
class PathTooDeep < CouchbaseError
|
|
124
198
|
end
|
|
125
199
|
|
|
126
200
|
class PathTooBig < CouchbaseError
|
|
127
201
|
end
|
|
128
202
|
|
|
203
|
+
# Subdocument exception thrown when proposed value would make the document too deep to parse.
|
|
204
|
+
#
|
|
205
|
+
# The current limitation is there to ensure a single parse does not consume too much memory (overloading the
|
|
206
|
+
# server). This error is similar to other TooDeep errors, which all relate to various validation stages to ensure
|
|
207
|
+
# the server does not consume too much memory when parsing a single document.
|
|
129
208
|
class ValueTooDeep < CouchbaseError
|
|
130
209
|
end
|
|
131
210
|
|
|
211
|
+
# Subdocument exception thrown when the provided value cannot be inserted at the given path.
|
|
212
|
+
#
|
|
213
|
+
# It is actually thrown when the delta in an counter operation is valid, but applying that delta would
|
|
214
|
+
# result in an out-of-range number (server interprets numbers as 64-bit integers).
|
|
132
215
|
class ValueInvalid < CouchbaseError
|
|
133
216
|
end
|
|
134
217
|
|
|
218
|
+
# Subdocument exception thrown when the targeted enclosing document itself is not JSON.
|
|
135
219
|
class DocumentNotJson < CouchbaseError
|
|
136
220
|
end
|
|
137
221
|
|
|
222
|
+
# Subdocument exception thrown when existing number value in document is too big.
|
|
223
|
+
#
|
|
224
|
+
# The value is interpreted as 64 bit on the server side.
|
|
138
225
|
class NumberTooBig < CouchbaseError
|
|
139
226
|
end
|
|
140
227
|
|
|
228
|
+
# Subdocument exception thrown when the delta in an arithmetic operation (eg counter) is invalid. In this SDK, this
|
|
229
|
+
# is equivalent to saying that the delta is zero.
|
|
230
|
+
#
|
|
231
|
+
# Note that the server also returns the corresponding error code when the delta value itself is too big, or not a
|
|
232
|
+
# number, but since the SDK enforces deltas to be of type long, these cases shouldn't come up.
|
|
141
233
|
class DeltaInvalid < CouchbaseError
|
|
142
234
|
end
|
|
143
235
|
|
|
236
|
+
# Subdocument exception thrown when a path already exists and it shouldn't
|
|
144
237
|
class PathExists < CouchbaseError
|
|
145
238
|
end
|
|
146
239
|
|
|
240
|
+
# Subdocument exception thrown when a macro has been requested which is not recognised by the server.
|
|
147
241
|
class XattrUnknownMacro < CouchbaseError
|
|
148
242
|
end
|
|
149
243
|
|
|
244
|
+
# Subdocument exception thrown when more than one xattr key has been requested.
|
|
150
245
|
class XattrInvalidKeyCombo < CouchbaseError
|
|
151
246
|
end
|
|
152
247
|
|
|
248
|
+
# Subdocument exception thrown when a virtual attribute has been requested which is not recognised by the server.
|
|
153
249
|
class XattrUnknownVirtualAttribute < CouchbaseError
|
|
154
250
|
end
|
|
155
251
|
|
|
252
|
+
# Subdocument exception thrown when the virtual attribute cannot be modified.
|
|
156
253
|
class XattrCannotModifyVirtualAttribute < CouchbaseError
|
|
157
254
|
end
|
|
158
255
|
|
|
159
256
|
# Query exceptions
|
|
160
257
|
|
|
258
|
+
# Indicates an operation failed because there has been an issue with the query planner.
|
|
161
259
|
class PlanningFailure < CouchbaseError
|
|
162
260
|
end
|
|
163
261
|
|
|
262
|
+
# Indicates an operation failed because there has been an issue with the query planner or similar.
|
|
164
263
|
class IndexFailure < CouchbaseError
|
|
165
264
|
end
|
|
166
265
|
|
|
266
|
+
# Indicates an operation failed because there has been an issue with query prepared statements.
|
|
167
267
|
class PreparedStatementFailure < CouchbaseError
|
|
168
268
|
end
|
|
169
269
|
|
|
170
270
|
# Analytics exceptions
|
|
171
271
|
|
|
272
|
+
# The analytics query failed to compile.
|
|
172
273
|
class CompilationFailure < CouchbaseError
|
|
173
274
|
end
|
|
174
275
|
|
|
276
|
+
# Indicates the analytics server job queue is full
|
|
175
277
|
class JobQueueFull < CouchbaseError
|
|
176
278
|
end
|
|
177
279
|
|
|
280
|
+
# The queried dataset is not found on the server.
|
|
178
281
|
class DatasetNotFound < CouchbaseError
|
|
179
282
|
end
|
|
180
283
|
|
|
@@ -203,6 +306,7 @@ module Couchbase
|
|
|
203
306
|
class DesignDocumentNotFound < CouchbaseError
|
|
204
307
|
end
|
|
205
308
|
|
|
309
|
+
# The queried view is not found on the server
|
|
206
310
|
class ViewNotFound < CouchbaseError
|
|
207
311
|
end
|
|
208
312
|
|
|
@@ -233,5 +337,9 @@ module Couchbase
|
|
|
233
337
|
|
|
234
338
|
class BackendError < CouchbaseError
|
|
235
339
|
end
|
|
340
|
+
|
|
341
|
+
# Environment name string cannot be determined
|
|
342
|
+
class NoEnvironment < CouchbaseError
|
|
343
|
+
end
|
|
236
344
|
end
|
|
237
345
|
end
|