couchbase 3.0.0.beta.1-universal-darwin-19 → 3.0.0-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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +227 -0
  3. data/.rubocop_todo.yml +47 -0
  4. data/CONTRIBUTING.md +110 -0
  5. data/Gemfile +4 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/couchbase.gemspec +40 -39
  9. data/examples/analytics.rb +123 -108
  10. data/examples/auth.rb +33 -0
  11. data/examples/crud.rb +16 -2
  12. data/examples/managing_analytics_indexes.rb +18 -4
  13. data/examples/managing_buckets.rb +17 -3
  14. data/examples/managing_collections.rb +22 -9
  15. data/examples/managing_query_indexes.rb +38 -18
  16. data/examples/managing_search_indexes.rb +21 -6
  17. data/examples/managing_view_indexes.rb +18 -4
  18. data/examples/query.rb +17 -3
  19. data/examples/query_with_consistency.rb +30 -20
  20. data/examples/search.rb +116 -101
  21. data/examples/search_with_consistency.rb +43 -30
  22. data/examples/subdocument.rb +42 -30
  23. data/examples/view.rb +19 -10
  24. data/ext/CMakeLists.txt +40 -2
  25. data/ext/build_version.hxx.in +1 -1
  26. data/ext/couchbase/bucket.hxx +190 -38
  27. data/ext/couchbase/cluster.hxx +22 -4
  28. data/ext/couchbase/configuration.hxx +14 -14
  29. data/ext/couchbase/couchbase.cxx +108 -12
  30. data/ext/couchbase/error_map.hxx +202 -2
  31. data/ext/couchbase/errors.hxx +8 -2
  32. data/ext/couchbase/io/dns_client.hxx +6 -6
  33. data/ext/couchbase/io/http_command.hxx +2 -2
  34. data/ext/couchbase/io/http_session.hxx +7 -11
  35. data/ext/couchbase/io/http_session_manager.hxx +3 -3
  36. data/ext/couchbase/io/mcbp_command.hxx +101 -44
  37. data/ext/couchbase/io/mcbp_session.hxx +144 -49
  38. data/ext/couchbase/io/retry_action.hxx +30 -0
  39. data/ext/couchbase/io/retry_context.hxx +39 -0
  40. data/ext/couchbase/io/retry_orchestrator.hxx +96 -0
  41. data/ext/couchbase/io/retry_reason.hxx +235 -0
  42. data/ext/couchbase/io/retry_strategy.hxx +156 -0
  43. data/ext/couchbase/operations/document_decrement.hxx +2 -0
  44. data/ext/couchbase/operations/document_exists.hxx +2 -0
  45. data/ext/couchbase/operations/document_get.hxx +2 -0
  46. data/ext/couchbase/operations/document_get_and_lock.hxx +2 -0
  47. data/ext/couchbase/operations/document_get_and_touch.hxx +2 -0
  48. data/ext/couchbase/operations/document_get_projected.hxx +2 -0
  49. data/ext/couchbase/operations/document_increment.hxx +2 -0
  50. data/ext/couchbase/operations/document_insert.hxx +2 -0
  51. data/ext/couchbase/operations/document_lookup_in.hxx +2 -0
  52. data/ext/couchbase/operations/document_mutate_in.hxx +3 -0
  53. data/ext/couchbase/operations/document_query.hxx +10 -0
  54. data/ext/couchbase/operations/document_remove.hxx +2 -0
  55. data/ext/couchbase/operations/document_replace.hxx +2 -0
  56. data/ext/couchbase/operations/document_search.hxx +8 -3
  57. data/ext/couchbase/operations/document_touch.hxx +2 -0
  58. data/ext/couchbase/operations/document_unlock.hxx +2 -0
  59. data/ext/couchbase/operations/document_upsert.hxx +2 -0
  60. data/ext/couchbase/operations/query_index_create.hxx +14 -4
  61. data/ext/couchbase/operations/query_index_drop.hxx +12 -2
  62. data/ext/couchbase/operations/query_index_get_all.hxx +11 -2
  63. data/ext/couchbase/origin.hxx +47 -17
  64. data/ext/couchbase/platform/backtrace.c +189 -0
  65. data/ext/couchbase/platform/backtrace.h +54 -0
  66. data/ext/couchbase/platform/terminate_handler.cc +122 -0
  67. data/ext/couchbase/platform/terminate_handler.h +36 -0
  68. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +6 -1
  69. data/ext/couchbase/protocol/status.hxx +14 -4
  70. data/ext/couchbase/version.hxx +2 -2
  71. data/ext/extconf.rb +39 -36
  72. data/ext/test/main.cxx +64 -16
  73. data/lib/couchbase.rb +0 -1
  74. data/lib/couchbase/analytics_options.rb +2 -4
  75. data/lib/couchbase/authenticator.rb +14 -0
  76. data/lib/couchbase/binary_collection.rb +9 -9
  77. data/lib/couchbase/binary_collection_options.rb +8 -6
  78. data/lib/couchbase/bucket.rb +18 -18
  79. data/lib/couchbase/cluster.rb +121 -90
  80. data/lib/couchbase/collection.rb +36 -38
  81. data/lib/couchbase/collection_options.rb +31 -17
  82. data/lib/couchbase/common_options.rb +1 -1
  83. data/lib/couchbase/datastructures/couchbase_list.rb +16 -16
  84. data/lib/couchbase/datastructures/couchbase_map.rb +18 -18
  85. data/lib/couchbase/datastructures/couchbase_queue.rb +13 -13
  86. data/lib/couchbase/datastructures/couchbase_set.rb +8 -7
  87. data/lib/couchbase/errors.rb +10 -3
  88. data/lib/couchbase/json_transcoder.rb +2 -2
  89. data/lib/couchbase/libcouchbase.bundle +0 -0
  90. data/lib/couchbase/management/analytics_index_manager.rb +37 -37
  91. data/lib/couchbase/management/bucket_manager.rb +25 -25
  92. data/lib/couchbase/management/collection_manager.rb +3 -3
  93. data/lib/couchbase/management/query_index_manager.rb +59 -14
  94. data/lib/couchbase/management/search_index_manager.rb +15 -12
  95. data/lib/couchbase/management/user_manager.rb +1 -1
  96. data/lib/couchbase/management/view_index_manager.rb +11 -5
  97. data/lib/couchbase/mutation_state.rb +12 -0
  98. data/lib/couchbase/query_options.rb +23 -9
  99. data/lib/couchbase/scope.rb +61 -1
  100. data/lib/couchbase/search_options.rb +40 -27
  101. data/lib/couchbase/subdoc.rb +31 -28
  102. data/lib/couchbase/version.rb +2 -2
  103. data/lib/couchbase/view_options.rb +0 -1
  104. metadata +20 -7
@@ -17,8 +17,8 @@
17
17
 
18
18
  #pragma once
19
19
 
20
- #define BACKEND_VERSION_MAJOR 0
21
- #define BACKEND_VERSION_MINOR 5
20
+ #define BACKEND_VERSION_MAJOR 1
21
+ #define BACKEND_VERSION_MINOR 0
22
22
  #define BACKEND_VERSION_PATCH 0
23
23
 
24
24
  #include <build_version.hxx>
@@ -1,80 +1,83 @@
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
+
1
15
  require "mkmf"
2
16
  require "tempfile"
3
17
 
4
18
  require_relative "../lib/couchbase/version"
5
19
  SDK_VERSION = Couchbase::VERSION[:sdk]
6
20
 
7
- unless find_executable("cmake")
8
- abort "ERROR: CMake is required to build couchbase extension."
9
- end
21
+ abort "ERROR: CMake is required to build couchbase extension." unless find_executable("cmake")
10
22
 
11
23
  def sys(*cmd)
12
24
  puts "-- #{Dir.pwd}"
13
- puts "-- #{cmd.join(" ")}"
25
+ puts "-- #{cmd.join(' ')}"
14
26
  system(*cmd)
15
27
  end
16
28
 
17
-
18
29
  build_type = ENV["DEBUG"] ? "Debug" : "RelWithDebInfo"
19
30
  cmake_flags = %W[
20
31
  -DCMAKE_BUILD_TYPE=#{build_type}
21
- -DRUBY_HDR_DIR=#{RbConfig::CONFIG["rubyhdrdir"]}
22
- -DRUBY_ARCH_HDR_DIR=#{RbConfig::CONFIG["rubyarchhdrdir"]}
32
+ -DRUBY_HDR_DIR=#{RbConfig::CONFIG['rubyhdrdir']}
33
+ -DRUBY_ARCH_HDR_DIR=#{RbConfig::CONFIG['rubyarchhdrdir']}
23
34
  -DTAOCPP_JSON_BUILD_TESTS=OFF
24
35
  -DTAOCPP_JSON_BUILD_EXAMPLES=OFF
25
36
  -DSNAPPY_BUILD_TESTS=OFF
26
37
  -DSNAPPY_INSTALL=OFF
27
38
  ]
28
39
 
29
- if ENV["CB_CC"]
30
- cmake_flags << "-DCMAKE_C_COMPILER=#{ENV["CB_CC"]}"
31
- end
32
- if ENV["CB_CXX"]
33
- cmake_flags << "-DCMAKE_CXX_COMPILER=#{ENV["CB_CXX"]}"
34
- end
35
- if ENV["CB_STATIC"]
36
- cmake_flags << "-DSTATIC_STDLIB=ON"
37
- end
40
+ cmake_flags << "-DCMAKE_C_COMPILER=#{ENV['CB_CC']}" if ENV["CB_CC"]
41
+ cmake_flags << "-DCMAKE_CXX_COMPILER=#{ENV['CB_CXX']}" if ENV["CB_CXX"]
42
+ cmake_flags << "-DSTATIC_STDLIB=ON" if ENV["CB_STATIC"]
38
43
 
39
44
  openssl_root = `brew --prefix openssl 2> /dev/null`.strip
40
- unless openssl_root.empty?
41
- cmake_flags << "-DOPENSSL_ROOT_DIR=#{openssl_root}"
42
- end
45
+ cmake_flags << "-DOPENSSL_ROOT_DIR=#{openssl_root}" unless openssl_root.empty?
43
46
 
44
47
  project_path = File.expand_path(File.join(__dir__))
45
- build_dir = ENV['CB_EXT_BUILD_DIR'] || File.join(Dir.tmpdir, "cb-#{build_type}-#{RUBY_VERSION}-#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}-#{SDK_VERSION}")
46
- FileUtils.mkdir_p(build_dir)
48
+ build_dir = ENV['CB_EXT_BUILD_DIR'] ||
49
+ File.join(Dir.tmpdir, "cb-#{build_type}-#{RUBY_VERSION}-#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}-#{SDK_VERSION}")
50
+ FileUtils.rm_rf(build_dir, verbose: true) unless ENV['CB_PRESERVE_BUILD_DIR']
51
+ FileUtils.mkdir_p(build_dir, verbose: true)
47
52
  Dir.chdir(build_dir) do
48
53
  puts "-- build #{build_type} extension #{SDK_VERSION} for ruby #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}"
49
54
  sys("cmake", *cmake_flags, project_path)
50
55
  sys("make -j4 VERBOSE=1")
51
56
  end
52
- extension_name = "libcouchbase.#{RbConfig::CONFIG["SOEXT"] || RbConfig::CONFIG["DLEXT"]}"
57
+ extension_name = "libcouchbase.#{RbConfig::CONFIG['SOEXT'] || RbConfig::CONFIG['DLEXT']}"
53
58
  extension_path = File.expand_path(File.join(build_dir, extension_name))
54
- unless File.file?(extension_path)
55
- abort "ERROR: failed to build extension in #{extension_path}"
56
- end
59
+ abort "ERROR: failed to build extension in #{extension_path}" unless File.file?(extension_path)
57
60
  extension_name.gsub!(/\.dylib/, '.bundle')
58
61
  install_path = File.expand_path(File.join(__dir__, "..", "lib", "couchbase", extension_name))
59
62
  puts "-- copy extension to #{install_path}"
60
- FileUtils.cp(extension_path, install_path)
63
+ FileUtils.cp(extension_path, install_path, verbose: true)
61
64
  ext_directory = File.expand_path(__dir__)
62
65
  create_makefile("libcouchbase")
63
66
  if ENV["CB_REMOVE_EXT_DIRECTORY"]
64
67
  puts "-- CB_REMOVE_EXT_DIRECTORY is set, remove #{ext_directory}"
65
68
  Dir
66
- .glob("#{ext_directory}/*", File::FNM_DOTMATCH)
67
- .reject { |path| %w[. .. extconf.rb].include?(File.basename(path)) || File.basename(path).start_with?(".gem") }
68
- .each do |entry|
69
+ .glob("#{ext_directory}/*", File::FNM_DOTMATCH)
70
+ .reject { |path| %w[. .. extconf.rb].include?(File.basename(path)) || File.basename(path).start_with?(".gem") }
71
+ .each do |entry|
69
72
  puts "-- remove #{entry}"
70
- FileUtils.rm_rf(entry)
73
+ FileUtils.rm_rf(entry, verbose: true)
71
74
  end
72
75
  File.truncate("#{ext_directory}/extconf.rb", 0)
73
76
  puts "-- truncate #{ext_directory}/extconf.rb"
74
- File.write("#{ext_directory}/Makefile", <<EOF)
75
- .PHONY: all clean install
76
- all:
77
- clean:
78
- install:
79
- EOF
77
+ File.write("#{ext_directory}/Makefile", <<~MAKEFILE)
78
+ .PHONY: all clean install
79
+ all:
80
+ clean:
81
+ install:
82
+ MAKEFILE
80
83
  end
@@ -64,33 +64,81 @@ p Couchbase::VERSION
64
64
  include Couchbase
65
65
 
66
66
  # begin
67
- # load "/home/avsej/code/couchbase-ruby-client/test/query_test.rb"
67
+ # load "/home/avsej/code/couchbase-ruby-client/test/crud_test.rb"
68
68
  # rescue => ex
69
69
  # p ex
70
70
  # puts ex.backtrace
71
- # raise
71
+ # rescue
72
72
  # end
73
73
 
74
74
  backend = Backend.new
75
- begin
76
- options = {
77
- }
78
- connstr = "couchbases://192.168.42.101?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
79
- # curl http://localhost:8091/pools/default/certificate > /tmp/couchbase-ssl-certificate.pem
80
- connstr = "couchbases://localhost.avsej.net?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
81
- connstr = "couchbases://mars.local?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
82
- p open: backend.open(connstr, "Administrator", "password", options)
75
+ connstr = "couchbase://localhost"
76
+ p open: backend.open(connstr, "Administrator", "password", {})
77
+ p bucket: backend.open_bucket("default", true)
78
+ p set: backend.document_upsert("default", "_default._default", "foo", 10_000, JSON.generate(foo: "bar"), 0, {})
79
+ p mutate: begin
80
+ backend.document_mutate_in(
81
+ "default", "_default._default", "foo", 10_000,
82
+ [
83
+ {:opcode => :dict_add, :path => "foo1", :param => "bar1"},
84
+ {:opcode => :dict_add, :path => "foo2", :param => "bar2"},
85
+ {:opcode => :dict_add, :path => "foo3", :param => "bar3"},
86
+ {:opcode => :dict_add, :path => "foo4", :param => "bar4"},
87
+ {:opcode => :dict_add, :path => "foo5", :param => "bar5"},
88
+ {:opcode => :dict_add, :path => "foo6", :param => "bar6"},
89
+ {:opcode => :dict_add, :path => "foo7", :param => "bar7"},
90
+ {:opcode => :dict_add, :path => "foo8", :param => "bar8"},
91
+ {:opcode => :dict_add, :path => "foo9", :param => "bar9"},
92
+ {:opcode => :dict_add, :path => "foo10", :param => "bar10"},
93
+ {:opcode => :dict_add, :path => "foo11", :param => "bar11"},
94
+ {:opcode => :dict_add, :path => "foo12", :param => "bar12"},
95
+ {:opcode => :dict_add, :path => "foo13", :param => "bar13"},
96
+ {:opcode => :dict_add, :path => "foo14", :param => "bar14"},
97
+ {:opcode => :dict_add, :path => "foo15", :param => "bar15"},
98
+ {:opcode => :dict_add, :path => "foo16", :param => "bar16"},
99
+ {:opcode => :dict_add, :path => "foo17", :param => "bar17"},
100
+ ], {})
83
101
  rescue => ex
84
- p err: ex
85
- puts ex.backtrace
102
+ ex
86
103
  end
104
+ puts
105
+ sleep(1)
106
+ p close: backend.close
107
+
108
+ # backend = Backend.new
109
+ # begin
110
+ # options = {
111
+ # }
112
+ # connstr = "couchbases://192.168.42.101?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
113
+ # # curl http://localhost:8091/pools/default/certificate > /tmp/couchbase-ssl-certificate.pem
114
+ # connstr = "couchbases://localhost.avsej.net?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
115
+ # connstr = "couchbases://mars.local?trust_certificate=/tmp/couchbase-ssl-certificate.pem"
116
+ # connstr = "couchbase://127.0.0.1:12000"
117
+ # connstr = "couchbase://localhost"
118
+ # p open: backend.open(connstr, "Administrator", "password", options)
119
+ # rescue => ex
120
+ # p err: ex
121
+ # puts ex.backtrace
122
+ # end
87
123
  # p bucket: backend.open_bucket("default", true)
88
- # ('aaa'..'zzz').to_a.sample(10).each do |key|
124
+ # keys = ('aaa'..'zzz').to_a.sample(10)
125
+ # keys.each do |key|
126
+ # STDERR.puts("........ #{key} .........")
89
127
  # p set: backend.document_upsert("default", "_default._default", key, 10_000, JSON.generate(foo: "bar"), 0, {})
90
- # p get: backend.document_get("default", "_default._default", key, nil)
128
+ # p get: (backend.document_get("default", "_default._default", key, nil) rescue nil)
91
129
  # end
92
- p query: backend.document_query('select "ruby rules" as greeting', {})
93
- p close: backend.close
130
+ # (1..10000).to_a.reverse.each do |i|
131
+ # sleep(1)
132
+ # STDERR.puts("........ #{i} .........")
133
+ # end
134
+ # keys.each do |key|
135
+ # STDERR.puts("........ #{key} .........")
136
+ # # p set: backend.document_upsert("default", "_default._default", key, 10_000, JSON.generate(foo: "bar"), 0, {})
137
+ # p get: (backend.document_get("default", "_default._default", key, nil) rescue nil)
138
+ # end
139
+ # p query: backend.document_query('select "ruby rules" as greeting', {})
140
+ # STDERR.puts("prepare to close backend")
141
+ # p close: backend.close
94
142
 
95
143
  # backend = Backend.new
96
144
  # begin
@@ -15,4 +15,3 @@
15
15
  require "couchbase/version"
16
16
  require "couchbase/libcouchbase"
17
17
  require "couchbase/cluster"
18
-
@@ -60,10 +60,9 @@ module Couchbase
60
60
  # @api private
61
61
  # @return [Array<String>, nil]
62
62
  def export_positional_parameters
63
- @positional_parameters.map { |p| JSON.dump(p) } if @positional_parameters
63
+ @positional_parameters&.map { |p| JSON.dump(p) }
64
64
  end
65
65
 
66
-
67
66
  # Sets named parameters for the query
68
67
  #
69
68
  # @param [Hash] named the key/value map of the parameters to substitute in the statement
@@ -83,7 +82,7 @@ module Couchbase
83
82
  # @api private
84
83
  # @return [Hash<String => String>, nil]
85
84
  def export_named_parameters
86
- @named_parameters.each_with_object({}) { |(n, v), o| o[n.to_s] = JSON.dump(v) } if @named_parameters
85
+ @named_parameters&.each_with_object({}) { |(n, v), o| o[n.to_s] = JSON.dump(v) }
87
86
  end
88
87
  end
89
88
 
@@ -176,4 +175,3 @@ module Couchbase
176
175
  end
177
176
  end
178
177
  end
179
-
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Couchbase
16
+ # Authenticator for username/password credentials
16
17
  class PasswordAuthenticator
17
18
  attr_accessor :username
18
19
  attr_accessor :password
@@ -22,4 +23,17 @@ module Couchbase
22
23
  @password = password
23
24
  end
24
25
  end
26
+
27
+ # Authenticator for TLS client certificate
28
+ #
29
+ # @see https://docs.couchbase.com/server/current/manage/manage-security/configure-client-certificates.html
30
+ class CertificateAuthenticator
31
+ attr_accessor :certificate_path
32
+ attr_accessor :key_path
33
+
34
+ def initialize(certificate_path, key_path)
35
+ @certificate_path = certificate_path
36
+ @key_path = key_path
37
+ end
38
+ end
25
39
  end
@@ -16,7 +16,7 @@ require "couchbase/binary_collection_options"
16
16
 
17
17
  module Couchbase
18
18
  class BinaryCollection
19
- alias_method :inspect, :to_s
19
+ alias inspect to_s
20
20
 
21
21
  # @param [Couchbase::Collection] collection parent collection
22
22
  def initialize(collection)
@@ -52,10 +52,10 @@ module Couchbase
52
52
  resp = @backend.document_increment(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
53
53
  options.timeout,
54
54
  {
55
- delta: options.delta,
56
- initial_value: options.initial,
57
- expiry: options.expiry,
58
- durability_level: options.durability_level,
55
+ delta: options.delta,
56
+ initial_value: options.initial,
57
+ expiry: options.expiry,
58
+ durability_level: options.durability_level,
59
59
  })
60
60
  CounterResult.new do |res|
61
61
  res.cas = resp[:cas]
@@ -74,10 +74,10 @@ module Couchbase
74
74
  resp = @backend.document_decrement(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
75
75
  options.timeout,
76
76
  {
77
- delta: options.delta,
78
- initial_value: options.initial,
79
- expiry: options.expiry,
80
- durability_level: options.durability_level,
77
+ delta: options.delta,
78
+ initial_value: options.initial,
79
+ expiry: options.expiry,
80
+ durability_level: options.durability_level,
81
81
  })
82
82
  CounterResult.new do |res|
83
83
  res.cas = resp[:cas]
@@ -22,6 +22,7 @@ module Couchbase
22
22
 
23
23
  # @yieldparam [AppendOptions] self
24
24
  def initialize
25
+ super
25
26
  yield self if block_given?
26
27
  end
27
28
  end
@@ -32,6 +33,7 @@ module Couchbase
32
33
 
33
34
  # @yieldparam [PrependOptions] self
34
35
  def initialize
36
+ super
35
37
  yield self if block_given?
36
38
  end
37
39
  end
@@ -51,14 +53,14 @@ module Couchbase
51
53
 
52
54
  # @yieldparam [IncrementOptions] self
53
55
  def initialize
56
+ super
54
57
  @delta = 1
55
58
  yield self if block_given?
56
59
  end
57
60
 
58
61
  def delta=(value)
59
- if delta < 0
60
- raise ArgumentError, "the delta cannot be less than 0"
61
- end
62
+ raise ArgumentError, "the delta cannot be less than 0" if delta.negative?
63
+
62
64
  @delta = value
63
65
  end
64
66
  end
@@ -78,14 +80,14 @@ module Couchbase
78
80
 
79
81
  # @yieldparam [DecrementOptions] self
80
82
  def initialize
83
+ super
81
84
  @delta = 1
82
85
  yield self if block_given?
83
86
  end
84
87
 
85
88
  def delta=(value)
86
- if delta < 0
87
- raise ArgumentError, "the delta cannot be less than 0"
88
- end
89
+ raise ArgumentError, "the delta cannot be less than 0" if delta.negative?
90
+
89
91
  @delta = value
90
92
  end
91
93
  end
@@ -22,7 +22,7 @@ module Couchbase
22
22
  # @return [String] name of the bucket
23
23
  attr_reader :name
24
24
 
25
- alias_method :inspect, :to_s
25
+ alias inspect to_s
26
26
 
27
27
  # @param [Couchbase::Backend] backend
28
28
  def initialize(backend, name)
@@ -72,23 +72,23 @@ module Couchbase
72
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
- timeout: options.timeout,
76
- scan_consistency: options.scan_consistency,
77
- skip: options.skip,
78
- limit: options.limit,
79
- start_key: (JSON.generate(options.start_key) unless options.start_key.nil?),
80
- end_key: (JSON.generate(options.end_key) unless options.end_key.nil?),
81
- start_key_doc_id: options.start_key_doc_id,
82
- end_key_doc_id: options.end_key_doc_id,
83
- inclusive_end: options.inclusive_end,
84
- group: options.group,
85
- group_level: options.group_level,
86
- key: (JSON.generate(options.key) unless options.key.nil?),
87
- keys: (options.keys.map { |key| JSON.generate(key) } if options.keys),
88
- order: options.order,
89
- reduce: options.reduce,
90
- on_error: options.on_error,
91
- debug: options.debug,
75
+ timeout: options.timeout,
76
+ scan_consistency: options.scan_consistency,
77
+ skip: options.skip,
78
+ limit: options.limit,
79
+ start_key: (JSON.generate(options.start_key) unless options.start_key.nil?),
80
+ end_key: (JSON.generate(options.end_key) unless options.end_key.nil?),
81
+ start_key_doc_id: options.start_key_doc_id,
82
+ end_key_doc_id: options.end_key_doc_id,
83
+ inclusive_end: options.inclusive_end,
84
+ group: options.group,
85
+ group_level: options.group_level,
86
+ key: (JSON.generate(options.key) unless options.key.nil?),
87
+ keys: options.keys&.map { |key| JSON.generate(key) },
88
+ order: options.order,
89
+ reduce: options.reduce,
90
+ on_error: options.on_error,
91
+ debug: options.debug,
92
92
  })
93
93
  ViewResult.new do |res|
94
94
  res.meta_data = ViewMetaData.new do |meta|
@@ -27,16 +27,24 @@ require "couchbase/analytics_options"
27
27
 
28
28
  module Couchbase
29
29
  class Cluster
30
- alias_method :inspect, :to_s
30
+ alias inspect to_s
31
31
 
32
32
  # Connect to the Couchbase cluster
33
33
  #
34
- # @param [String] connection_string connection string used to locate the Couchbase Cluster
35
- # @param [ClusterOptions] options custom options when creating the cluster connection
34
+ # @overload connect(connection_string, options)
35
+ # @param [String] connection_string connection string used to locate the Couchbase Cluster
36
+ # @param [ClusterOptions] options custom options when creating the cluster connection
37
+ #
38
+ # @overload connect(connection_string, username, password, options)
39
+ # Shortcut for {PasswordAuthenticator}
40
+ # @param [String] connection_string connection string used to locate the Couchbase Cluster
41
+ # @param [String] username name of the user
42
+ # @param [String] password password of the user
43
+ # @param [ClusterOptions, nil] options custom options when creating the cluster connection
36
44
  #
37
45
  # @return [Cluster]
38
- def self.connect(connection_string, options)
39
- Cluster.new(connection_string, options)
46
+ def self.connect(connection_string, *options)
47
+ Cluster.new(connection_string, *options)
40
48
  end
41
49
 
42
50
  # Returns an instance of the {Bucket}
@@ -56,29 +64,23 @@ module Couchbase
56
64
  # @return [QueryResult]
57
65
  def query(statement, options = QueryOptions.new)
58
66
  resp = @backend.document_query(statement, {
59
- timeout: options.timeout,
60
- adhoc: options.adhoc,
61
- client_context_id: options.client_context_id,
62
- max_parallelism: options.max_parallelism,
63
- readonly: options.readonly,
64
- scan_wait: options.scan_wait,
65
- scan_cap: options.scan_cap,
66
- pipeline_batch: options.pipeline_batch,
67
- pipeline_cap: options.pipeline_cap,
68
- metrics: options.metrics,
69
- profile: options.profile,
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
- {
76
- bucket_name: t.bucket_name,
77
- partition_id: t.partition_id,
78
- partition_uuid: t.partition_uuid,
79
- sequence_number: t.sequence_number,
80
- }
81
- } if options.mutation_state),
67
+ timeout: options.timeout,
68
+ adhoc: options.adhoc,
69
+ client_context_id: options.client_context_id,
70
+ max_parallelism: options.max_parallelism,
71
+ readonly: options.readonly,
72
+ scan_wait: options.scan_wait,
73
+ scan_cap: options.scan_cap,
74
+ pipeline_batch: options.pipeline_batch,
75
+ pipeline_cap: options.pipeline_cap,
76
+ metrics: options.metrics,
77
+ profile: options.profile,
78
+ positional_parameters: options.export_positional_parameters,
79
+ named_parameters: options.export_named_parameters,
80
+ scope_qualifier: options.scope_qualifier,
81
+ raw_parameters: options.raw_parameters,
82
+ scan_consistency: options.scan_consistency,
83
+ mutation_state: options.mutation_state&.to_a,
82
84
  })
83
85
 
84
86
  QueryResult.new do |res|
@@ -114,14 +116,14 @@ module Couchbase
114
116
  # @return [AnalyticsResult]
115
117
  def analytics_query(statement, options = AnalyticsOptions.new)
116
118
  resp = @backend.document_analytics(statement, {
117
- timeout: options.timeout,
118
- client_context_id: options.client_context_id,
119
- scan_consistency: options.scan_consistency,
120
- readonly: options.readonly,
121
- priority: options.priority,
122
- positional_parameters: options.export_positional_parameters,
123
- named_parameters: options.export_named_parameters,
124
- raw_parameters: options.raw_parameters,
119
+ timeout: options.timeout,
120
+ client_context_id: options.client_context_id,
121
+ scan_consistency: options.scan_consistency,
122
+ readonly: options.readonly,
123
+ priority: options.priority,
124
+ positional_parameters: options.export_positional_parameters,
125
+ named_parameters: options.export_named_parameters,
126
+ raw_parameters: options.raw_parameters,
125
127
  })
126
128
 
127
129
  AnalyticsResult.new do |res|
@@ -158,24 +160,17 @@ module Couchbase
158
160
  # @return [SearchResult]
159
161
  def search_query(index_name, query, options = SearchOptions.new)
160
162
  resp = @backend.document_search(index_name, JSON.generate(query), {
161
- timeout: options.timeout,
162
- limit: options.limit,
163
- skip: options.skip,
164
- explain: options.explain,
165
- highlight_style: options.highlight_style,
166
- highlight_fields: options.highlight_fields,
167
- fields: options.fields,
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
- {
173
- bucket_name: t.bucket_name,
174
- partition_id: t.partition_id,
175
- partition_uuid: t.partition_uuid,
176
- sequence_number: t.sequence_number,
177
- }
178
- } if options.mutation_state),
163
+ timeout: options.timeout,
164
+ limit: options.limit,
165
+ skip: options.skip,
166
+ explain: options.explain,
167
+ highlight_style: options.highlight_style,
168
+ highlight_fields: options.highlight_fields,
169
+ fields: options.fields,
170
+ sort: options.sort&.map { |v| JSON.generate(v) },
171
+ facets: options.facets&.map { |(k, v)| [k, JSON.generate(v)] },
172
+ scan_consistency: options.scan_consistency,
173
+ mutation_state: options.mutation_state&.to_a,
179
174
  })
180
175
 
181
176
  SearchResult.new do |res|
@@ -185,6 +180,7 @@ module Couchbase
185
180
  meta.metrics.success_partition_count = resp[:meta_data][:metrics][:success_partition_count]
186
181
  meta.metrics.took = resp[:meta_data][:metrics][:took]
187
182
  meta.metrics.total_rows = resp[:meta_data][:metrics][:total_rows]
183
+ meta.errors = resp[:meta_data][:errors]
188
184
  end
189
185
  res.rows = resp[:rows].map do |r|
190
186
  SearchRow.new do |row|
@@ -194,16 +190,16 @@ module Couchbase
194
190
  row.score = r[:score]
195
191
  row.fragments = r[:fragments]
196
192
  row.locations = SearchRowLocations.new(
197
- r[:locations].map do |loc|
198
- SearchRowLocation.new do |location|
199
- location.field = loc[:field]
200
- location.term = loc[:term]
201
- location.position = loc[:position]
202
- location.start_offset = loc[:start_offset]
203
- location.end_offset = loc[:end_offset]
204
- location.array_positions = loc[:array_positions]
205
- end
193
+ r[:locations].map do |loc|
194
+ SearchRowLocation.new do |location|
195
+ location.field = loc[:field]
196
+ location.term = loc[:term]
197
+ location.position = loc[:position]
198
+ location.start_offset = loc[:start_offset]
199
+ location.end_offset = loc[:end_offset]
200
+ location.array_positions = loc[:array_positions]
206
201
  end
202
+ end
207
203
  )
208
204
  row.instance_variable_set("@fields", r[:fields])
209
205
  row.explanation = JSON.parse(r[:explanation]) if r[:explanation]
@@ -215,35 +211,35 @@ module Couchbase
215
211
  when SearchFacet::SearchFacetTerm
216
212
  SearchFacetResult::TermFacetResult.new do |f|
217
213
  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
- []
214
+ if v[:terms]
215
+ v[:terms].map do |t|
216
+ SearchFacetResult::TermFacetResult::TermFacet.new(t[:term], t[:count])
224
217
  end
218
+ else
219
+ []
220
+ end
225
221
  end
226
222
  when SearchFacet::SearchFacetDateRange
227
223
  SearchFacetResult::DateRangeFacetResult.new do |f|
228
224
  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
- []
225
+ if v[:date_ranges]
226
+ v[:date_ranges].map do |r|
227
+ SearchFacetResult::DateRangeFacetResult::DateRangeFacet.new(r[:name], r[:count], r[:start_time], r[:end_time])
235
228
  end
229
+ else
230
+ []
231
+ end
236
232
  end
237
233
  when SearchFacet::SearchFacetNumericRange
238
234
  SearchFacetResult::NumericRangeFacetResult.new do |f|
239
235
  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
- []
236
+ if v[:numeric_ranges]
237
+ v[:numeric_ranges].map do |r|
238
+ SearchFacetResult::NumericRangeFacetResult::NumericRangeFacet.new(r[:name], r[:count], r[:min], r[:max])
246
239
  end
240
+ else
241
+ []
242
+ end
247
243
  end
248
244
  else
249
245
  next # ignore unknown facet result
@@ -316,17 +312,52 @@ module Couchbase
316
312
 
317
313
  # Initialize {Cluster} object
318
314
  #
319
- # @param [String] connection_string connection string used to locate the Couchbase Cluster
320
- # @param [ClusterOptions] options custom options when creating the cluster connection
321
- def initialize(connection_string, options)
322
- raise ArgumentError, "options must have authenticator configured" unless options.authenticator
323
- username = options.authenticator.username
324
- raise ArgumentError, "missing username" unless username
325
- password = options.authenticator.password
326
- raise ArgumentError, "missing password" unless password
315
+ # @overload new(connection_string, options)
316
+ # @param [String] connection_string connection string used to locate the Couchbase Cluster
317
+ # @param [ClusterOptions] options custom options when creating the cluster connection
318
+ #
319
+ # @overload new(connection_string, username, password, options)
320
+ # Shortcut for {PasswordAuthenticator}
321
+ # @param [String] connection_string connection string used to locate the Couchbase Cluster
322
+ # @param [String] username name of the user
323
+ # @param [String] password password of the user
324
+ # @param [ClusterOptions, nil] options custom options when creating the cluster connection
325
+ def initialize(connection_string, *args)
326
+ credentials = {}
327
+
328
+ options = args.shift
329
+ case options
330
+ when String
331
+ credentials[:username] = options
332
+ credentials[:password] = args.shift
333
+ raise ArgumentError, "missing username" unless credentials[:username]
334
+ raise ArgumentError, "missing password" unless credentials[:password]
335
+ when ClusterOptions
336
+ authenticator = options&.authenticator
337
+ case authenticator
338
+ when PasswordAuthenticator
339
+ credentials[:username] = authenticator&.username
340
+ raise ArgumentError, "missing username" unless credentials[:username]
341
+
342
+ credentials[:password] = authenticator&.password
343
+ raise ArgumentError, "missing password" unless credentials[:password]
344
+
345
+ when CertificateAuthenticator
346
+ credentials[:certificate_path] = authenticator&.certificate_path
347
+ raise ArgumentError, "missing certificate path" unless credentials[:certificate_path]
348
+
349
+ credentials[:key_path] = authenticator&.key_path
350
+ raise ArgumentError, "missing key path" unless credentials[:key_path]
351
+
352
+ else
353
+ raise ArgumentError, "options must have authenticator configured"
354
+ end
355
+ else
356
+ raise ArgumentError, "unexpected second argument, have to be String or ClusterOptions"
357
+ end
327
358
 
328
359
  @backend = Backend.new
329
- @backend.open(connection_string, username, password, {})
360
+ @backend.open(connection_string, credentials, {})
330
361
  end
331
362
  end
332
363
  end