couchbase 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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