couchbase 3.0.1 → 3.0.2

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -4
  3. data/ext/build_config.hxx.in +2 -0
  4. data/ext/build_version.hxx.in +11 -8
  5. data/ext/cmake/BuildTracing.cmake +1 -1
  6. data/ext/cmake/CompilerWarnings.cmake +5 -0
  7. data/ext/cmake/Testing.cmake +3 -6
  8. data/ext/couchbase/bucket.hxx +9 -1
  9. data/ext/couchbase/cbsasl/client.h +1 -1
  10. data/ext/couchbase/cluster.hxx +89 -6
  11. data/ext/couchbase/configuration.hxx +2 -0
  12. data/ext/couchbase/couchbase.cxx +1647 -507
  13. data/ext/couchbase/diagnostics.hxx +0 -3
  14. data/ext/couchbase/io/dns_client.hxx +2 -2
  15. data/ext/couchbase/io/http_command.hxx +6 -3
  16. data/ext/couchbase/io/http_session.hxx +14 -18
  17. data/ext/couchbase/io/http_session_manager.hxx +83 -2
  18. data/ext/couchbase/io/mcbp_command.hxx +4 -1
  19. data/ext/couchbase/io/mcbp_context.hxx +37 -0
  20. data/ext/couchbase/io/mcbp_session.hxx +91 -30
  21. data/ext/couchbase/operations.hxx +5 -0
  22. data/ext/couchbase/operations/analytics_dataset_create.hxx +3 -2
  23. data/ext/couchbase/operations/analytics_dataset_drop.hxx +3 -2
  24. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +3 -2
  25. data/ext/couchbase/operations/analytics_dataverse_create.hxx +3 -2
  26. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +3 -2
  27. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +3 -2
  28. data/ext/couchbase/operations/analytics_index_create.hxx +3 -2
  29. data/ext/couchbase/operations/analytics_index_drop.hxx +3 -2
  30. data/ext/couchbase/operations/analytics_index_get_all.hxx +5 -2
  31. data/ext/couchbase/operations/analytics_link_connect.hxx +3 -2
  32. data/ext/couchbase/operations/analytics_link_disconnect.hxx +3 -2
  33. data/ext/couchbase/operations/bucket_create.hxx +3 -2
  34. data/ext/couchbase/operations/bucket_drop.hxx +3 -2
  35. data/ext/couchbase/operations/bucket_flush.hxx +3 -2
  36. data/ext/couchbase/operations/bucket_get.hxx +3 -2
  37. data/ext/couchbase/operations/bucket_get_all.hxx +3 -2
  38. data/ext/couchbase/operations/bucket_update.hxx +3 -2
  39. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +3 -2
  40. data/ext/couchbase/operations/collection_create.hxx +3 -2
  41. data/ext/couchbase/operations/collection_drop.hxx +3 -2
  42. data/ext/couchbase/operations/collections_manifest_get.hxx +3 -2
  43. data/ext/couchbase/operations/document_analytics.hxx +3 -2
  44. data/ext/couchbase/operations/document_append.hxx +77 -0
  45. data/ext/couchbase/operations/document_decrement.hxx +3 -2
  46. data/ext/couchbase/operations/document_exists.hxx +3 -2
  47. data/ext/couchbase/operations/document_get.hxx +3 -2
  48. data/ext/couchbase/operations/document_get_and_lock.hxx +3 -2
  49. data/ext/couchbase/operations/document_get_and_touch.hxx +3 -2
  50. data/ext/couchbase/operations/document_get_projected.hxx +3 -2
  51. data/ext/couchbase/operations/document_increment.hxx +3 -2
  52. data/ext/couchbase/operations/document_insert.hxx +3 -2
  53. data/ext/couchbase/operations/document_lookup_in.hxx +8 -2
  54. data/ext/couchbase/operations/document_mutate_in.hxx +13 -2
  55. data/ext/couchbase/operations/document_prepend.hxx +77 -0
  56. data/ext/couchbase/operations/document_query.hxx +3 -2
  57. data/ext/couchbase/operations/document_remove.hxx +5 -2
  58. data/ext/couchbase/operations/document_replace.hxx +3 -2
  59. data/ext/couchbase/operations/document_search.hxx +3 -2
  60. data/ext/couchbase/operations/document_touch.hxx +3 -2
  61. data/ext/couchbase/operations/document_unlock.hxx +3 -2
  62. data/ext/couchbase/operations/document_upsert.hxx +3 -2
  63. data/ext/couchbase/operations/document_view.hxx +3 -2
  64. data/ext/couchbase/operations/group_drop.hxx +3 -2
  65. data/ext/couchbase/operations/group_get.hxx +3 -2
  66. data/ext/couchbase/operations/group_get_all.hxx +3 -2
  67. data/ext/couchbase/operations/group_upsert.hxx +3 -2
  68. data/ext/couchbase/operations/http_noop.hxx +78 -0
  69. data/ext/couchbase/operations/mcbp_noop.hxx +61 -0
  70. data/ext/couchbase/operations/query_index_build_deferred.hxx +3 -2
  71. data/ext/couchbase/operations/query_index_create.hxx +3 -2
  72. data/ext/couchbase/operations/query_index_drop.hxx +3 -2
  73. data/ext/couchbase/operations/query_index_get_all.hxx +3 -2
  74. data/ext/couchbase/operations/role_get_all.hxx +3 -2
  75. data/ext/couchbase/operations/scope_create.hxx +3 -2
  76. data/ext/couchbase/operations/scope_drop.hxx +3 -2
  77. data/ext/couchbase/operations/scope_get_all.hxx +3 -2
  78. data/ext/couchbase/operations/search_get_stats.hxx +3 -2
  79. data/ext/couchbase/operations/search_index_analyze_document.hxx +3 -2
  80. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -2
  81. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +3 -2
  82. data/ext/couchbase/operations/search_index_control_query.hxx +3 -2
  83. data/ext/couchbase/operations/search_index_drop.hxx +3 -2
  84. data/ext/couchbase/operations/search_index_get.hxx +3 -2
  85. data/ext/couchbase/operations/search_index_get_all.hxx +3 -2
  86. data/ext/couchbase/operations/search_index_get_documents_count.hxx +3 -2
  87. data/ext/couchbase/operations/search_index_get_stats.hxx +3 -2
  88. data/ext/couchbase/operations/search_index_upsert.hxx +3 -2
  89. data/ext/couchbase/operations/user_drop.hxx +3 -2
  90. data/ext/couchbase/operations/user_get.hxx +3 -2
  91. data/ext/couchbase/operations/user_get_all.hxx +3 -2
  92. data/ext/couchbase/operations/user_upsert.hxx +3 -2
  93. data/ext/couchbase/operations/view_index_drop.hxx +3 -2
  94. data/ext/couchbase/operations/view_index_get.hxx +3 -2
  95. data/ext/couchbase/operations/view_index_get_all.hxx +3 -2
  96. data/ext/couchbase/operations/view_index_upsert.hxx +3 -2
  97. data/ext/couchbase/platform/terminate_handler.cc +5 -2
  98. data/ext/couchbase/protocol/client_opcode.hxx +368 -0
  99. data/ext/couchbase/protocol/cmd_append.hxx +145 -0
  100. data/ext/couchbase/protocol/cmd_hello.hxx +1 -0
  101. data/ext/couchbase/protocol/cmd_lookup_in.hxx +11 -3
  102. data/ext/couchbase/protocol/cmd_mutate_in.hxx +46 -4
  103. data/ext/couchbase/protocol/cmd_noop.hxx +82 -0
  104. data/ext/couchbase/protocol/cmd_prepend.hxx +145 -0
  105. data/ext/couchbase/protocol/durability_level.hxx +16 -0
  106. data/ext/couchbase/protocol/hello_feature.hxx +9 -0
  107. data/ext/couchbase/protocol/unsigned_leb128.h +2 -2
  108. data/ext/couchbase/service_type.hxx +1 -1
  109. data/ext/couchbase/version.hxx +18 -4
  110. data/ext/extconf.rb +9 -6
  111. data/ext/test/CMakeLists.txt +5 -0
  112. data/ext/test/test_helper.hxx +3 -3
  113. data/ext/test/test_helper_native.hxx +2 -5
  114. data/ext/test/test_native_binary_operations.cxx +186 -0
  115. data/ext/test/test_native_diagnostics.cxx +54 -3
  116. data/ext/test/test_ruby_trivial_crud.cxx +1 -1
  117. data/lib/couchbase.rb +1 -0
  118. data/lib/couchbase/analytics_options.rb +1 -71
  119. data/lib/couchbase/binary_collection.rb +60 -22
  120. data/lib/couchbase/binary_collection_options.rb +0 -76
  121. data/lib/couchbase/bucket.rb +40 -36
  122. data/lib/couchbase/cluster.rb +89 -156
  123. data/lib/couchbase/collection.rb +290 -72
  124. data/lib/couchbase/collection_options.rb +30 -243
  125. data/lib/couchbase/datastructures/couchbase_list.rb +5 -16
  126. data/lib/couchbase/datastructures/couchbase_map.rb +5 -16
  127. data/lib/couchbase/datastructures/couchbase_queue.rb +5 -16
  128. data/lib/couchbase/datastructures/couchbase_set.rb +5 -16
  129. data/lib/couchbase/diagnostics.rb +181 -0
  130. data/lib/couchbase/json_transcoder.rb +1 -1
  131. data/lib/couchbase/{common_options.rb → logger.rb} +24 -11
  132. data/lib/couchbase/management/query_index_manager.rb +1 -1
  133. data/lib/couchbase/management/user_manager.rb +3 -0
  134. data/lib/couchbase/options.rb +2094 -0
  135. data/lib/couchbase/query_options.rb +1 -144
  136. data/lib/couchbase/scope.rb +8 -25
  137. data/lib/couchbase/search_options.rb +0 -93
  138. data/lib/couchbase/version.rb +20 -1
  139. data/lib/couchbase/view_options.rb +1 -91
  140. metadata +19 -7
@@ -26,7 +26,7 @@ TEST_CASE("ruby: upsert document into default collection", "[ruby]")
26
26
  backend = Couchbase::Backend.new
27
27
  backend.open(CONNECTION_STRING, {username: USERNAME, password: PASSWORD}, {})
28
28
  backend.open_bucket(BUCKET, true)
29
- backend.document_upsert(BUCKET, "_default._default", "foo", 10_000, JSON.generate(foo: "bar"), 0, {})
29
+ backend.document_upsert(BUCKET, "_default._default", "foo", JSON.generate(foo: "bar"), 0, {})
30
30
  backend.close
31
31
  )");
32
32
  if (error) {
@@ -14,4 +14,5 @@
14
14
 
15
15
  require "couchbase/version"
16
16
  require "couchbase/libcouchbase"
17
+ require "couchbase/logger"
17
18
  require "couchbase/cluster"
@@ -12,80 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'couchbase/json_transcoder'
15
+ require "couchbase/json_transcoder"
16
16
 
17
17
  module Couchbase
18
18
  class Cluster
19
- class AnalyticsOptions
20
- # @return [Integer] Timeout in milliseconds
21
- attr_accessor :timeout
22
-
23
- # @return [String] Provides a custom client context ID for this query
24
- attr_accessor :client_context_id
25
-
26
- # @return [:not_bounded, :request_plus] specifies level of consistency for the query
27
- attr_accessor :scan_consistency
28
-
29
- # @return [Boolean] Allows explicitly marking a query as being readonly and not mutating any documents on the server side.
30
- attr_accessor :readonly
31
-
32
- # @return [Boolean] Allows to give certain requests higher priority than others
33
- attr_accessor :priority
34
-
35
- # @return [JsonTranscoder] transcoder to use on rows
36
- attr_accessor :transcoder
37
-
38
- # @api private
39
- # @return [Hash<String => #to_json>]
40
- attr_reader :raw_parameters
41
-
42
- # @yieldparam [AnalyticsOptions] self
43
- def initialize
44
- @transcoder = JsonTranscoder.new
45
- @raw_parameters = {}
46
- @positional_parameters = nil
47
- @named_parameters = nil
48
- @scan_consistency = nil
49
- yield self if block_given?
50
- end
51
-
52
- # Sets positional parameters for the query
53
- #
54
- # @param [Array] positional the list of parameters that have to be substituted in the statement
55
- def positional_parameters(positional)
56
- @positional_parameters = positional
57
- @named_parameters = nil
58
- end
59
-
60
- # @api private
61
- # @return [Array<String>, nil]
62
- def export_positional_parameters
63
- @positional_parameters&.map { |p| JSON.dump(p) }
64
- end
65
-
66
- # Sets named parameters for the query
67
- #
68
- # @param [Hash] named the key/value map of the parameters to substitute in the statement
69
- def named_parameters(named)
70
- @named_parameters = named
71
- @positional_parameters = nil
72
- end
73
-
74
- # Allows providing custom JSON key/value pairs for advanced usage
75
- #
76
- # @param [String] key the parameter name (key of the JSON property)
77
- # @param [Object] value the parameter value (value of the JSON property)
78
- def raw(key, value)
79
- @raw_parameters[key] = JSON.generate(value)
80
- end
81
-
82
- # @api private
83
- # @return [Hash<String => String>, nil]
84
- def export_named_parameters
85
- @named_parameters&.each_with_object({}) { |(n, v), o| o[n.to_s] = JSON.dump(v) }
86
- end
87
- end
88
-
89
19
  class AnalyticsWarning
90
20
  # @return [Integer]
91
21
  attr_accessor :code
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require "couchbase/options"
15
16
  require "couchbase/binary_collection_options"
16
17
 
17
18
  module Couchbase
@@ -28,35 +29,59 @@ module Couchbase
28
29
  #
29
30
  # @param [String] id the document id which is used to uniquely identify it
30
31
  # @param [String] content the binary content to append to the document
31
- # @param [AppendOptions] options custom options to customize the request
32
+ # @param [Options::Append] options custom options to customize the request
33
+ #
34
+ # @example Append "bar" to the content of the existing document
35
+ # collection.upsert("mydoc", "foo")
36
+ # collection.binary.append("mydoc", "bar", Options::Append(timeout: 3_000))
37
+ # collection.get("mydoc", Options::Get(transcoder: nil)).content #=> "foobar"
32
38
  #
33
39
  # @return [Collection::MutationResult]
34
- def append(id, content, options = AppendOptions.new) end
40
+ def append(id, content, options = Options::Append.new)
41
+ resp = @backend.document_append(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}",
42
+ id, content, options.to_backend)
43
+ Collection::MutationResult.new do |res|
44
+ res.cas = resp[:cas]
45
+ res.mutation_token = @collection.send(:extract_mutation_token, resp)
46
+ end
47
+ end
35
48
 
36
49
  # Prepends binary content to the document
37
50
  #
38
51
  # @param [String] id the document id which is used to uniquely identify it
39
52
  # @param [String] content the binary content to prepend to the document
40
- # @param [PrependOptions] options custom options to customize the request
53
+ # @param [Options::Prepend] options custom options to customize the request
54
+ #
55
+ # @example Prepend "bar" to the content of the existing document
56
+ # collection.upsert("mydoc", "foo")
57
+ # collection.binary.prepend("mydoc", "bar", Options::Prepend(timeout: 3_000))
58
+ # collection.get("mydoc", Options::Get(transcoder: nil)).content #=> "barfoo"
41
59
  #
42
60
  # @return [Collection::MutationResult]
43
- def prepend(id, content, options = PrependOptions.new) end
61
+ def prepend(id, content, options = Options::Prepend.new)
62
+ resp = @backend.document_prepend(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}",
63
+ id, content, options.to_backend)
64
+ Collection::MutationResult.new do |res|
65
+ res.cas = resp[:cas]
66
+ res.mutation_token = @collection.send(:extract_mutation_token, resp)
67
+ end
68
+ end
44
69
 
45
70
  # Increments the counter document by one of the number defined in the options
46
71
  #
47
72
  # @param [String] id the document id which is used to uniquely identify it
48
- # @param [IncrementOptions] options custom options to customize the request
73
+ # @param [Options::Increment] options custom options to customize the request
74
+ #
75
+ # @example Increment value by 10, and initialize to 0 if it does not exist
76
+ # res = collection.binary.increment("raw_counter", Options::Increment(delta: 10, initial: 0))
77
+ # res.content #=> 0
78
+ # res = collection.binary.increment("raw_counter", Options::Increment(delta: 10, initial: 0))
79
+ # res.content #=> 10
49
80
  #
50
81
  # @return [CounterResult]
51
- def increment(id, options = IncrementOptions.new)
82
+ def increment(id, options = Options::Increment.new)
52
83
  resp = @backend.document_increment(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
53
- options.timeout,
54
- {
55
- delta: options.delta,
56
- initial_value: options.initial,
57
- expiry: options.expiry,
58
- durability_level: options.durability_level,
59
- })
84
+ options.to_backend)
60
85
  CounterResult.new do |res|
61
86
  res.cas = resp[:cas]
62
87
  res.content = resp[:content]
@@ -67,23 +92,36 @@ module Couchbase
67
92
  # Decrements the counter document by one of the number defined in the options
68
93
  #
69
94
  # @param [String] id the document id which is used to uniquely identify it
70
- # @param [DecrementOptions] options custom options to customize the request
95
+ # @param [Options::Decrement] options custom options to customize the request
96
+ #
97
+ # @example Decrement value by 2, and initialize to 100 if it does not exist
98
+ # res = collection.binary.decrement("raw_counter", Options::Decrement(delta: 2, initial: 100))
99
+ # res.value #=> 100
100
+ # res = collection.binary.decrement("raw_counter", Options::Decrement(delta: 2, initial: 100))
101
+ # res.value #=> 98
71
102
  #
72
103
  # @return [CounterResult]
73
- def decrement(id, options = DecrementOptions.new)
104
+ def decrement(id, options = Options::Decrement.new)
74
105
  resp = @backend.document_decrement(@collection.bucket_name, "#{@collection.scope_name}.#{@collection.name}", id,
75
- options.timeout,
76
- {
77
- delta: options.delta,
78
- initial_value: options.initial,
79
- expiry: options.expiry,
80
- durability_level: options.durability_level,
81
- })
106
+ options.to_backend)
82
107
  CounterResult.new do |res|
83
108
  res.cas = resp[:cas]
84
109
  res.content = resp[:content]
85
110
  res.mutation_token = @collection.send(:extract_mutation_token, resp)
86
111
  end
87
112
  end
113
+
114
+ # @api private
115
+ # TODO: deprecate in 3.1
116
+ AppendOptions = ::Couchbase::Options::Append
117
+ # @api private
118
+ # TODO: deprecate in 3.1
119
+ PrependOptions = ::Couchbase::Options::Prepend
120
+ # @api private
121
+ # TODO: deprecate in 3.1
122
+ IncrementOptions = ::Couchbase::Options::Increment
123
+ # @api private
124
+ # TODO: deprecate in 3.1
125
+ DecrementOptions = ::Couchbase::Options::Decrement
88
126
  end
89
127
  end
@@ -16,82 +16,6 @@ require "couchbase/collection_options"
16
16
 
17
17
  module Couchbase
18
18
  class BinaryCollection
19
- class AppendOptions < CommonOptions
20
- # @return [Integer] The default CAS used (0 means no CAS in this context)
21
- attr_accessor :cas
22
-
23
- # @yieldparam [AppendOptions] self
24
- def initialize
25
- super
26
- yield self if block_given?
27
- end
28
- end
29
-
30
- class PrependOptions < CommonOptions
31
- # @return [Integer] The default CAS used (0 means no CAS in this context)
32
- attr_accessor :cas
33
-
34
- # @yieldparam [PrependOptions] self
35
- def initialize
36
- super
37
- yield self if block_given?
38
- end
39
- end
40
-
41
- class IncrementOptions < CommonOptions
42
- # @return [Integer] the delta for the operation
43
- attr_reader :delta
44
-
45
- # @return [Integer] if present, holds the initial value
46
- attr_accessor :initial
47
-
48
- # @return [Integer] if set, holds the expiration for the operation
49
- attr_accessor :expiry
50
-
51
- # @return [:none, :majority, :majority_and_persist_to_active, :persist_to_majority] level of durability
52
- attr_accessor :durability_level
53
-
54
- # @yieldparam [IncrementOptions] self
55
- def initialize
56
- super
57
- @delta = 1
58
- yield self if block_given?
59
- end
60
-
61
- def delta=(value)
62
- raise ArgumentError, "the delta cannot be less than 0" if delta.negative?
63
-
64
- @delta = value
65
- end
66
- end
67
-
68
- class DecrementOptions < CommonOptions
69
- # @return [Integer] the delta for the operation
70
- attr_reader :delta
71
-
72
- # @return [Integer] if present, holds the initial value
73
- attr_accessor :initial
74
-
75
- # @return [Integer] if set, holds the expiration for the operation
76
- attr_accessor :expiry
77
-
78
- # @return [:none, :majority, :majority_and_persist_to_active, :persist_to_majority] level of durability
79
- attr_accessor :durability_level
80
-
81
- # @yieldparam [DecrementOptions] self
82
- def initialize
83
- super
84
- @delta = 1
85
- yield self if block_given?
86
- end
87
-
88
- def delta=(value)
89
- raise ArgumentError, "the delta cannot be less than 0" if delta.negative?
90
-
91
- @delta = value
92
- end
93
- end
94
-
95
19
  class CounterResult < ::Couchbase::Collection::MutationResult
96
20
  # @return [Integer] current value of the counter
97
21
  attr_accessor :content
@@ -15,7 +15,9 @@
15
15
  require "couchbase/scope"
16
16
  require "couchbase/management/collection_manager"
17
17
  require "couchbase/management/view_index_manager"
18
+ require "couchbase/options"
18
19
  require "couchbase/view_options"
20
+ require "couchbase/diagnostics"
19
21
 
20
22
  module Couchbase
21
23
  class Bucket
@@ -67,29 +69,18 @@ module Couchbase
67
69
  #
68
70
  # @param [String] design_document_name name of the design document
69
71
  # @param [String] view_name name of the view to query
70
- # @param [ViewOptions] options
72
+ # @param [Options::View] options
73
+ #
74
+ # @example Make sure the view engine catch up with all mutations and return keys starting from +["random_brewery:"]+
75
+ # bucket.view_query("beer", "brewery_beers",
76
+ # Options::View(
77
+ # start_key: ["random_brewery:"],
78
+ # scan_consistency: :request_plus
79
+ # ))
71
80
  #
72
81
  # @return [ViewResult]
73
- def view_query(design_document_name, view_name, options = ViewOptions.new)
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) },
88
- order: options.order,
89
- reduce: options.reduce,
90
- on_error: options.on_error,
91
- debug: options.debug,
92
- })
82
+ def view_query(design_document_name, view_name, options = Options::View.new)
83
+ resp = @backend.document_view(@name, design_document_name, view_name, options.namespace, options.to_backend)
93
84
  ViewResult.new do |res|
94
85
  res.meta_data = ViewMetaData.new do |meta|
95
86
  meta.total_rows = resp[:meta][:total_rows]
@@ -117,23 +108,36 @@ module Couchbase
117
108
 
118
109
  # Performs application-level ping requests against services in the couchbase cluster
119
110
  #
111
+ # @param [Options::Ping] options
112
+ #
120
113
  # @return [PingResult]
121
- def ping(options = PingOptions.new) end
122
-
123
- class PingOptions
124
- # @return [String] Holds custom report id.
125
- attr_accessor :report_id
126
-
127
- # @return [Array<Symbol>] The service types to limit this diagnostics request
128
- attr_accessor :service_types
129
-
130
- # @return [Integer] the time in milliseconds allowed for the operation to complete
131
- attr_accessor :timeout
132
-
133
- def initialize
134
- @service_types = [:kv, :query, :analytics, :search, :views, :management]
135
- yield self if block_given?
114
+ def ping(options = Options::Ping.new)
115
+ resp = @backend.ping(@name, options.to_backend)
116
+ PingResult.new do |res|
117
+ res.version = resp[:version]
118
+ res.id = resp[:id]
119
+ res.sdk = resp[:sdk]
120
+ resp[:services].each do |type, svcs|
121
+ res.services[type] = svcs.map do |svc|
122
+ PingResult::ServiceInfo.new do |info|
123
+ info.id = svc[:id]
124
+ info.state = svc[:state]
125
+ info.latency = svc[:latency]
126
+ info.remote = svc[:remote]
127
+ info.local = svc[:local]
128
+ info.error = svc[:error]
129
+ end
130
+ end
131
+ end
136
132
  end
137
133
  end
134
+
135
+ # @api private
136
+ # TODO: deprecate in 3.1
137
+ PingOptions = ::Couchbase::Options::Ping
138
+
139
+ # @api private
140
+ # TODO: deprecate in 3.1
141
+ ViewOptions = ::Couchbase::Options::View
138
142
  end
139
143
  end
@@ -21,9 +21,12 @@ require "couchbase/management/query_index_manager"
21
21
  require "couchbase/management/analytics_index_manager"
22
22
  require "couchbase/management/search_index_manager"
23
23
 
24
+ require "couchbase/options"
25
+
24
26
  require "couchbase/search_options"
25
27
  require "couchbase/query_options"
26
28
  require "couchbase/analytics_options"
29
+ require "couchbase/diagnostics"
27
30
 
28
31
  module Couchbase
29
32
  class Cluster
@@ -33,14 +36,32 @@ module Couchbase
33
36
  #
34
37
  # @overload connect(connection_string, options)
35
38
  # @param [String] connection_string connection string used to locate the Couchbase Cluster
36
- # @param [ClusterOptions] options custom options when creating the cluster connection
39
+ # @param [Options::Cluster] options custom options when creating the cluster connection
37
40
  #
38
41
  # @overload connect(connection_string, username, password, options)
39
42
  # Shortcut for {PasswordAuthenticator}
40
43
  # @param [String] connection_string connection string used to locate the Couchbase Cluster
41
44
  # @param [String] username name of the user
42
45
  # @param [String] password password of the user
43
- # @param [ClusterOptions, nil] options custom options when creating the cluster connection
46
+ # @param [Options::Cluster, nil] options custom options when creating the cluster connection
47
+ #
48
+ # @example Explicitly create options object and initialize PasswordAuthenticator internally
49
+ # options = Cluster::ClusterOptions.new
50
+ # options.authenticate("Administrator", "password")
51
+ # Cluster.connect("couchbase://localhost", options)
52
+ #
53
+ # @example Pass authenticator object to Options
54
+ # Cluster.connect("couchbase://localhost",
55
+ # Options::Cluster(authenticator: PasswordAuthenticator.new("Administrator", "password")))
56
+ #
57
+ # @example Shorter version, more useful for interactive sessions
58
+ # Cluster.connect("couchbase://localhost", "Administrator", "password")
59
+ #
60
+ # @example Authentication with TLS client certificate (note +couchbases://+ schema)
61
+ # Cluster.connect("couchbases://localhost?trust_certificate=/tmp/ca.pem",
62
+ # Options::Cluster(authenticator: CertificateAuthenticator.new("/tmp/certificate.pem", "/tmp/private.key")))
63
+ #
64
+ # @see https://docs.couchbase.com/server/current/manage/manage-security/configure-client-certificates.html
44
65
  #
45
66
  # @return [Cluster]
46
67
  def self.connect(connection_string, *options)
@@ -59,30 +80,15 @@ module Couchbase
59
80
  # Performs a query against the query (N1QL) services
60
81
  #
61
82
  # @param [String] statement the N1QL query statement
62
- # @param [QueryOptions] options the custom options for this query
83
+ # @param [Options::Query] options the custom options for this query
84
+ #
85
+ # @example Select first ten hotels from travel sample dataset
86
+ # cluster.query("SELECT * FROM `travel-sample` WHERE type = $type LIMIT 10",
87
+ # Options::Query(named_parameters: {type: "hotel"}, metrics: true))
63
88
  #
64
89
  # @return [QueryResult]
65
- def query(statement, options = QueryOptions.new)
66
- resp = @backend.document_query(statement, {
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
- flex_index: options.flex_index,
73
- scan_wait: options.scan_wait,
74
- scan_cap: options.scan_cap,
75
- pipeline_batch: options.pipeline_batch,
76
- pipeline_cap: options.pipeline_cap,
77
- metrics: options.metrics,
78
- profile: options.profile,
79
- positional_parameters: options.export_positional_parameters,
80
- named_parameters: options.export_named_parameters,
81
- scope_qualifier: options.scope_qualifier,
82
- raw_parameters: options.raw_parameters,
83
- scan_consistency: options.scan_consistency,
84
- mutation_state: options.mutation_state&.to_a,
85
- })
90
+ def query(statement, options = Options::Query.new)
91
+ resp = @backend.document_query(statement, options.to_backend)
86
92
 
87
93
  QueryResult.new do |res|
88
94
  res.meta_data = QueryMetaData.new do |meta|
@@ -112,20 +118,15 @@ module Couchbase
112
118
  # Performs an analytics query
113
119
  #
114
120
  # @param [String] statement the N1QL query statement
115
- # @param [AnalyticsOptions] options the custom options for this query
121
+ # @param [Options::Analytics] options the custom options for this query
122
+ #
123
+ # @example Select name of the given user
124
+ # cluster.analytics_query("SELECT u.name AS uname FROM GleambookUsers u WHERE u.id = $user_id ",
125
+ # Options::Analytics(named_parameters: {user_id: 2}))
116
126
  #
117
127
  # @return [AnalyticsResult]
118
- def analytics_query(statement, options = AnalyticsOptions.new)
119
- resp = @backend.document_analytics(statement, {
120
- timeout: options.timeout,
121
- client_context_id: options.client_context_id,
122
- scan_consistency: options.scan_consistency,
123
- readonly: options.readonly,
124
- priority: options.priority,
125
- positional_parameters: options.export_positional_parameters,
126
- named_parameters: options.export_named_parameters,
127
- raw_parameters: options.raw_parameters,
128
- })
128
+ def analytics_query(statement, options = Options::Analytics.new)
129
+ resp = @backend.document_analytics(statement, options.to_backend)
129
130
 
130
131
  AnalyticsResult.new do |res|
131
132
  res.transcoder = options.transcoder
@@ -156,24 +157,20 @@ module Couchbase
156
157
  #
157
158
  # @param [String] index_name the name of the search index
158
159
  # @param [SearchQuery] query the query tree
159
- # @param [SearchOptions] options the query tree
160
+ # @param [Options::Search] options the query tree
161
+ #
162
+ # @example Return first 10 results of "hop beer" query and request highlighting
163
+ # cluster.search_query("beer_index", Cluster::SearchQuery.match_phrase("hop beer"),
164
+ # Options::Search(
165
+ # limit: 10,
166
+ # fields: %w[name],
167
+ # highlight_style: :html,
168
+ # highlight_fields: %w[name description]
169
+ # ))
160
170
  #
161
171
  # @return [SearchResult]
162
- def search_query(index_name, query, options = SearchOptions.new)
163
- resp = @backend.document_search(index_name, JSON.generate(query), {
164
- timeout: options.timeout,
165
- limit: options.limit,
166
- skip: options.skip,
167
- explain: options.explain,
168
- disable_scoring: options.disable_scoring,
169
- highlight_style: options.highlight_style,
170
- highlight_fields: options.highlight_fields,
171
- fields: options.fields,
172
- sort: options.sort&.map { |v| JSON.generate(v) },
173
- facets: options.facets&.map { |(k, v)| [k, JSON.generate(v)] },
174
- scan_consistency: options.scan_consistency,
175
- mutation_state: options.mutation_state&.to_a,
176
- })
172
+ def search_query(index_name, query, options = Options::Search.new)
173
+ resp = @backend.document_search(index_name, JSON.generate(query), options.to_backend)
177
174
 
178
175
  SearchResult.new do |res|
179
176
  res.meta_data = SearchMetaData.new do |meta|
@@ -293,10 +290,11 @@ module Couchbase
293
290
  #
294
291
  # It does not proactively perform any I/O against the network
295
292
  #
293
+ # @param [Options::Diagnostics] options
294
+ #
296
295
  # @return [DiagnosticsResult]
297
- def diagnostics(options = DiagnosticsOptions.new)
296
+ def diagnostics(options = Options::Diagnostics.new)
298
297
  resp = @backend.diagnostics(options.report_id)
299
- pp resp
300
298
  DiagnosticsResult.new do |res|
301
299
  res.version = resp[:version]
302
300
  res.id = resp[:id]
@@ -309,113 +307,37 @@ module Couchbase
309
307
  info.last_activity_us = svc[:last_activity_us]
310
308
  info.remote = svc[:remote]
311
309
  info.local = svc[:local]
310
+ info.details = svc[:details]
312
311
  end
313
312
  end
314
313
  end
315
314
  end
316
315
  end
317
316
 
318
- class ClusterOptions
319
- attr_accessor :authenticator
320
-
321
- # @yieldparam [ClusterOptions] self
322
- def initialize
323
- yield self if block_given?
324
- end
325
-
326
- def authenticate(username, password)
327
- @authenticator = PasswordAuthenticator.new(username, password)
328
- self
329
- end
330
- end
331
-
332
- class DiagnosticsOptions
333
- # @return [String] Holds custom report id.
334
- attr_accessor :report_id
335
-
336
- # @yieldparam [DiagnosticsOptions] self
337
- def initialize
338
- yield self if block_given?
339
- end
340
- end
341
-
342
- class DiagnosticsResult
343
- class ServiceInfo
344
- # @return [String] endpoint unique identifier
345
- attr_accessor :id
346
-
347
- # Possible states are:
348
- #
349
- # :disconnected:: the endpoint is not reachable
350
- # :connecting:: currently connecting (includes auth, handshake, etc.)
351
- # :connected:: connected and ready
352
- # :disconnecting:: disconnecting (after being connected)
353
- #
354
- # @return [Symbol] state of the endpoint
355
- attr_accessor :state
356
-
357
- # @return [Integer] how long ago the endpoint was active (in microseconds)
358
- attr_accessor :last_activity_us
359
-
360
- # @return [String] remote address of the connection
361
- attr_accessor :remote
362
-
363
- # @return [String] local address of the connection
364
- attr_accessor :local
365
-
366
- # @yieldparam [ServiceInfo] self
367
- def initialize
368
- yield self if block_given?
369
- end
370
-
371
- def to_json(*args)
372
- data = {
373
- id: @id,
374
- state: @state,
375
- remote: @remote,
376
- local: @local,
377
- }
378
- data[:last_activity_us] = @last_activity_us if defined? @last_activity_us
379
- data.to_json(*args)
317
+ # Performs application-level ping requests against services in the couchbase cluster
318
+ #
319
+ # @param [Options::Ping] options
320
+ #
321
+ # @return [PingResult]
322
+ def ping(options = Options::Ping.new)
323
+ resp = @backend.ping(nil, options.to_backend)
324
+ PingResult.new do |res|
325
+ res.version = resp[:version]
326
+ res.id = resp[:id]
327
+ res.sdk = resp[:sdk]
328
+ resp[:services].each do |type, svcs|
329
+ res.services[type] = svcs.map do |svc|
330
+ PingResult::ServiceInfo.new do |info|
331
+ info.id = svc[:id]
332
+ info.state = svc[:state]
333
+ info.latency = svc[:latency]
334
+ info.remote = svc[:remote]
335
+ info.local = svc[:local]
336
+ info.error = svc[:error]
337
+ end
338
+ end
380
339
  end
381
340
  end
382
-
383
- # @return [String] report id
384
- attr_accessor :id
385
-
386
- # @return [String] SDK identifier
387
- attr_accessor :sdk
388
-
389
- # Returns information about currently service endpoints, that known to the library at the moment.
390
- #
391
- # :kv:: Key/Value data service
392
- # :query:: N1QL query service
393
- # :analytics:: Analtyics service
394
- # :search:: Full text search service
395
- # :views:: Views service
396
- # :mgmt:: Management service
397
- #
398
- # @return [Hash<Symbol, ServiceInfo>] map service types to info
399
- attr_accessor :services
400
-
401
- # @yieldparam [DiagnosticsResult] self
402
- def initialize
403
- @services = Hash.new
404
- yield self if block_given?
405
- end
406
-
407
- # @api private
408
- # @return [Integer] version
409
- attr_accessor :version
410
-
411
- def to_json(*args)
412
- {
413
- version: @version,
414
- id: @id,
415
- sdk: @sdk,
416
- services: @services,
417
- }.to_json(*args)
418
- end
419
341
  end
420
342
 
421
343
  private
@@ -424,14 +346,14 @@ module Couchbase
424
346
  #
425
347
  # @overload new(connection_string, options)
426
348
  # @param [String] connection_string connection string used to locate the Couchbase Cluster
427
- # @param [ClusterOptions] options custom options when creating the cluster connection
349
+ # @param [Options::Cluster] options custom options when creating the cluster connection
428
350
  #
429
351
  # @overload new(connection_string, username, password, options)
430
352
  # Shortcut for {PasswordAuthenticator}
431
353
  # @param [String] connection_string connection string used to locate the Couchbase Cluster
432
354
  # @param [String] username name of the user
433
355
  # @param [String] password password of the user
434
- # @param [ClusterOptions, nil] options custom options when creating the cluster connection
356
+ # @param [Options::Cluster, nil] options custom options when creating the cluster connection
435
357
  def initialize(connection_string, *args)
436
358
  credentials = {}
437
359
 
@@ -442,7 +364,7 @@ module Couchbase
442
364
  credentials[:password] = args.shift
443
365
  raise ArgumentError, "missing username" unless credentials[:username]
444
366
  raise ArgumentError, "missing password" unless credentials[:password]
445
- when ClusterOptions
367
+ when Options::Cluster
446
368
  authenticator = options&.authenticator
447
369
  case authenticator
448
370
  when PasswordAuthenticator
@@ -469,5 +391,16 @@ module Couchbase
469
391
  @backend = Backend.new
470
392
  @backend.open(connection_string, credentials, {})
471
393
  end
394
+
395
+ # @api private
396
+ ClusterOptions = ::Couchbase::Options::Cluster
397
+ # @api private
398
+ DiagnosticsOptions = ::Couchbase::Options::Diagnostics
399
+ # @api private
400
+ AnalyticsOptions = ::Couchbase::Options::Analytics
401
+ # @api private
402
+ QueryOptions = ::Couchbase::Options::Query
403
+ # @api private
404
+ SearchOptions = ::Couchbase::Options::Search
472
405
  end
473
406
  end