couchbase 3.0.0.alpha.3 → 3.0.0.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-6.0.3.yml +4 -1
  3. data/.github/workflows/tests-dev-preview.yml +4 -1
  4. data/.github/workflows/tests.yml +4 -1
  5. data/README.md +1 -1
  6. data/bin/check-cluster +31 -0
  7. data/bin/init-cluster +16 -4
  8. data/examples/analytics.rb +221 -0
  9. data/examples/managing_analytics_indexes.rb +72 -0
  10. data/examples/managing_view_indexes.rb +54 -0
  11. data/examples/search_with_consistency.rb +84 -0
  12. data/examples/view.rb +50 -0
  13. data/ext/.clang-tidy +1 -0
  14. data/ext/build_version.hxx.in +1 -1
  15. data/ext/couchbase/bucket.hxx +0 -1
  16. data/ext/couchbase/couchbase.cxx +1421 -55
  17. data/ext/couchbase/io/dns_client.hxx +215 -0
  18. data/ext/couchbase/io/dns_codec.hxx +207 -0
  19. data/ext/couchbase/io/dns_config.hxx +116 -0
  20. data/ext/couchbase/io/dns_message.hxx +558 -0
  21. data/ext/couchbase/io/http_session.hxx +16 -4
  22. data/ext/couchbase/io/mcbp_session.hxx +2 -1
  23. data/ext/couchbase/mutation_token.hxx +1 -1
  24. data/ext/couchbase/operations.hxx +19 -0
  25. data/ext/couchbase/operations/analytics_dataset_create.hxx +117 -0
  26. data/ext/couchbase/operations/analytics_dataset_drop.hxx +103 -0
  27. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +107 -0
  28. data/ext/couchbase/operations/analytics_dataverse_create.hxx +104 -0
  29. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +104 -0
  30. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +91 -0
  31. data/ext/couchbase/operations/analytics_index_create.hxx +128 -0
  32. data/ext/couchbase/operations/analytics_index_drop.hxx +110 -0
  33. data/ext/couchbase/operations/analytics_index_get_all.hxx +106 -0
  34. data/ext/couchbase/operations/analytics_link_connect.hxx +102 -0
  35. data/ext/couchbase/operations/analytics_link_disconnect.hxx +101 -0
  36. data/ext/couchbase/operations/design_document.hxx +59 -0
  37. data/ext/couchbase/operations/document_analytics.hxx +293 -0
  38. data/ext/couchbase/operations/document_query.hxx +2 -2
  39. data/ext/couchbase/operations/document_search.hxx +19 -1
  40. data/ext/couchbase/operations/document_view.hxx +227 -0
  41. data/ext/couchbase/operations/search_index.hxx +17 -0
  42. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -1
  43. data/ext/couchbase/operations/view_index_drop.hxx +67 -0
  44. data/ext/couchbase/operations/view_index_get.hxx +90 -0
  45. data/ext/couchbase/operations/view_index_get_all.hxx +125 -0
  46. data/ext/couchbase/operations/view_index_upsert.hxx +87 -0
  47. data/ext/couchbase/service_type.hxx +38 -1
  48. data/ext/couchbase/timeout_defaults.hxx +3 -1
  49. data/ext/couchbase/utils/connection_string.hxx +231 -0
  50. data/ext/couchbase/version.hxx +1 -1
  51. data/ext/test/main.cxx +3 -12
  52. data/lib/couchbase/analytics_options.rb +165 -0
  53. data/lib/couchbase/bucket.rb +49 -0
  54. data/lib/couchbase/cluster.rb +46 -207
  55. data/lib/couchbase/management/analytics_index_manager.rb +138 -24
  56. data/lib/couchbase/management/view_index_manager.rb +63 -10
  57. data/lib/couchbase/query_options.rb +219 -0
  58. data/lib/couchbase/search_options.rb +6 -6
  59. data/lib/couchbase/version.rb +1 -1
  60. data/lib/couchbase/view_options.rb +155 -0
  61. metadata +34 -2
@@ -29,18 +29,34 @@ module Couchbase
29
29
  # @param [String] dataverse_name
30
30
  # @param [CreateDataverseOptions] options
31
31
  #
32
+ # @return [void]
33
+ #
32
34
  # @raise [ArgumentError]
33
35
  # @raise [Error::DataverseExists]
34
- def create_dataverse(dataverse_name, options = CreateDataverseOptions.new) end
36
+ def create_dataverse(dataverse_name, options = CreateDataverseOptions.new)
37
+ @backend.analytics_dataverse_create(
38
+ dataverse_name,
39
+ options.ignore_if_exists,
40
+ options.timeout
41
+ )
42
+ end
35
43
 
36
44
  # Drops a dataverse
37
45
  #
38
46
  # @param [String] dataverse_name name of the dataverse
39
47
  # @param [DropDataverseOptions] options
40
48
  #
49
+ # @return [void]
50
+ #
41
51
  # @raise [ArgumentError]
42
52
  # @raise [Error::DataverseNotFound]
43
- def drop_dataverse(dataverse_name, options = DropDataverseOptions.new) end
53
+ def drop_dataverse(dataverse_name, options = DropDataverseOptions.new)
54
+ @backend.analytics_dataverse_drop(
55
+ dataverse_name,
56
+ options.ignore_if_does_not_exist,
57
+ options.timeout
58
+ )
59
+ end
44
60
 
45
61
  # Creates a new dataset
46
62
  #
@@ -48,18 +64,39 @@ module Couchbase
48
64
  # @param [String] bucket_name name of the bucket
49
65
  # @param [CreateDatasetOptions] options
50
66
  #
67
+ # @return [void]
68
+ #
51
69
  # @raise [ArgumentError]
52
70
  # @raise [Error::DatasetExists]
53
- def create_dataset(dataset_name, bucket_name, options = CreateDatasetOptions.new) end
71
+ # @raise [Error::LinkNotFound]
72
+ def create_dataset(dataset_name, bucket_name, options = CreateDatasetOptions.new)
73
+ @backend.analytics_dataset_create(
74
+ dataset_name,
75
+ bucket_name,
76
+ options.condition,
77
+ options.dataverse_name,
78
+ options.ignore_if_exists,
79
+ options.timeout
80
+ )
81
+ end
54
82
 
55
83
  # Drops a dataset
56
84
  #
57
85
  # @param [String] dataset_name name of the dataset
58
- # @param [DropDataverseOptions] options
59
- #
86
+ # @param [DropDatasetOptions] options
87
+ #
88
+ # @return [void]
89
+ #
60
90
  # @raise [ArgumentError]
61
91
  # @raise [Error::DatasetNotFound]
62
- def drop_dataset(dataset_name, options = DropDatasetOptions.new) end
92
+ def drop_dataset(dataset_name, options = DropDatasetOptions.new)
93
+ @backend.analytics_dataset_drop(
94
+ dataset_name,
95
+ options.dataverse_name,
96
+ options.ignore_if_does_not_exist,
97
+ options.timeout
98
+ )
99
+ end
63
100
 
64
101
  # Gets all datasets
65
102
  #
@@ -67,19 +104,38 @@ module Couchbase
67
104
  #
68
105
  # @return [Array<AnalyticsDataset>]
69
106
  def get_all_datasets(options = GetAllDatasetsOptions.new)
70
- # SELECT d.* FROM Metadata.`Dataset` d WHERE d.DataverseName <> "Metadata"
107
+ resp = @backend.analytics_dataset_get_all(options.timeout)
108
+ resp.map do |entry|
109
+ AnalyticsDataset.new do |dataset|
110
+ dataset.name = entry[:name]
111
+ dataset.dataverse_name = entry[:dataverse_name]
112
+ dataset.link_name = entry[:link_name]
113
+ dataset.bucket_name = entry[:bucket_name]
114
+ end
115
+ end
71
116
  end
72
117
 
73
118
  # Creates a new index
74
119
  #
75
120
  # @param [String] index_name name of the index
76
121
  # @param [String] dataset_name name of the dataset
77
- # @param [Hash<String, String>] fields mapping of the field name to field type
122
+ # @param [Hash<String => String>] fields mapping of the field name to field type
78
123
  # @param [CreateIndexOptions] options
79
124
  #
125
+ # @return [void]
126
+ #
80
127
  # @raise [ArgumentError]
81
128
  # @raise [Error::IndexExists]
82
- def create_index(index_name, dataset_name, fields, options = CreateIndexOptions.new) end
129
+ def create_index(index_name, dataset_name, fields, options = CreateIndexOptions.new)
130
+ @backend.analytics_index_create(
131
+ index_name,
132
+ dataset_name,
133
+ fields.entries,
134
+ options.dataverse_name,
135
+ options.ignore_if_exists,
136
+ options.timeout
137
+ )
138
+ end
83
139
 
84
140
  # Drops an index
85
141
  #
@@ -87,9 +143,19 @@ module Couchbase
87
143
  # @param [String] dataset_name name of the dataset
88
144
  # @param [DropIndexOptions] options
89
145
  #
146
+ # @return [void]
147
+ #
90
148
  # @raise [ArgumentError]
91
149
  # @raise [Error::IndexNotFound]
92
- def drop_index(index_name, dataset_name, options = DropIndexOptions.new) end
150
+ def drop_index(index_name, dataset_name, options = DropIndexOptions.new)
151
+ @backend.analytics_index_drop(
152
+ index_name,
153
+ dataset_name,
154
+ options.dataverse_name,
155
+ options.ignore_if_does_not_exist,
156
+ options.timeout
157
+ )
158
+ end
93
159
 
94
160
  # Gets all indexes
95
161
  #
@@ -97,36 +163,63 @@ module Couchbase
97
163
  #
98
164
  # @return [Array<AnalyticsIndex>]
99
165
  def get_all_indexes(options = GetAllIndexesOptions.new)
100
- # SELECT d.* FROM Metadata.`Index` d WHERE d.DataverseName <> "Metadata"
166
+ resp = @backend.analytics_index_get_all(options.timeout)
167
+ resp.map do |entry|
168
+ AnalyticsIndex.new do |dataset|
169
+ dataset.name = entry[:name]
170
+ dataset.dataverse_name = entry[:dataverse_name]
171
+ dataset.dataset_name = entry[:dataset_name]
172
+ dataset.is_primary = entry[:is_primary]
173
+ end
174
+ end
101
175
  end
102
176
 
103
177
  # Connects a link
104
178
  #
105
179
  # @param [ConnectLinkOptions] options
106
180
  #
181
+ # @return [void]
182
+ #
107
183
  # @raise [ArgumentError]
108
184
  # @raise [Error::LinkNotFound]
109
- def connect_link(options = ConnectLinkOptions.new) end
185
+ def connect_link(options = ConnectLinkOptions.new)
186
+ @backend.analytics_link_connect(
187
+ options.link_name,
188
+ options.force,
189
+ options.dataverse_name,
190
+ options.timeout
191
+ )
192
+ end
110
193
 
111
194
  # Disconnects a link,
112
195
  #
113
196
  # @param [DisconnectLinkOptions] options
114
197
  #
198
+ # @return [void]
199
+ #
115
200
  # @raise [ArgumentError]
116
201
  # @raise [Error::LinkNotFound]
117
- def disconnect_link(options = DisconnectLinkOptions.new) end
202
+ def disconnect_link(options = DisconnectLinkOptions.new)
203
+ @backend.analytics_link_disconnect(
204
+ options.link_name,
205
+ options.dataverse_name,
206
+ options.timeout
207
+ )
208
+ end
118
209
 
119
210
  # Gets the pending mutations for all datasets.
120
- #
211
+ #
121
212
  # @note If a link is disconnected then it will return no results. If all links are disconnected, then
122
213
  # an empty object is returned.
123
214
  #
124
215
  # @param [GetPendingMutationsOptions] options
125
216
  #
126
- # @return [Hash<String, Integer>] dictionary, where keys are dataset coordinates encoded as +"dataverse.dataset"+
217
+ # @return [Hash<String => Integer>] dictionary, where keys are dataset coordinates encoded as +"dataverse.dataset"+
127
218
  # and values are number of mutations for given dataset.
128
219
  def get_pending_mutations(options = GetPendingMutationsOptions.new)
129
- # GET http://localhost:8095/analytics/node/agg/stats/remaining
220
+ @backend.analytics_get_pending_mutations(
221
+ options.timeout
222
+ )
130
223
  end
131
224
 
132
225
  class CreateDataverseOptions
@@ -136,6 +229,7 @@ module Couchbase
136
229
  # @return [Integer] the time in milliseconds allowed for the operation to complete
137
230
  attr_accessor :timeout
138
231
 
232
+ # @yieldparam [CreateDataverseOptions]
139
233
  def initialize
140
234
  @ignore_if_exists = false
141
235
  yield self if block_given?
@@ -144,11 +238,12 @@ module Couchbase
144
238
 
145
239
  class DropDataverseOptions
146
240
  # @return [Boolean] ignore if the dataverse does not exists
147
- attr_accessor :ignore_if_not_exists
241
+ attr_accessor :ignore_if_does_not_exist
148
242
 
149
243
  # @return [Integer] the time in milliseconds allowed for the operation to complete
150
244
  attr_accessor :timeout
151
245
 
246
+ # @yieldparam [DropDataverseOptions]
152
247
  def initialize
153
248
  @ignore_if_exists = false
154
249
  yield self if block_given?
@@ -168,6 +263,7 @@ module Couchbase
168
263
  # @return [Integer] the time in milliseconds allowed for the operation to complete
169
264
  attr_accessor :timeout
170
265
 
266
+ # @yieldparam [CreateDatasetOptions]
171
267
  def initialize
172
268
  @ignore_if_exists = false
173
269
  yield self if block_given?
@@ -176,7 +272,7 @@ module Couchbase
176
272
 
177
273
  class DropDatasetOptions
178
274
  # @return [Boolean] ignore if the dataset does not exists
179
- attr_accessor :ignore_if_not_exists
275
+ attr_accessor :ignore_if_does_not_exist
180
276
 
181
277
  # @return [String] The name of the dataverse to use (defaults to +nil+)
182
278
  attr_accessor :dataverse_name
@@ -184,8 +280,9 @@ module Couchbase
184
280
  # @return [Integer] the time in milliseconds allowed for the operation to complete
185
281
  attr_accessor :timeout
186
282
 
283
+ # @yieldparam [DropDatasetOptions]
187
284
  def initialize
188
- @ignore_if_not_exists = false
285
+ @ignore_if_does_not_exist = false
189
286
  yield self if block_given?
190
287
  end
191
288
  end
@@ -194,8 +291,8 @@ module Couchbase
194
291
  # @return [Integer] the time in milliseconds allowed for the operation to complete
195
292
  attr_accessor :timeout
196
293
 
294
+ # @yieldparam [GetAllDatasetsOptions]
197
295
  def initialize
198
- @ignore_if_not_exists = false
199
296
  yield self if block_given?
200
297
  end
201
298
  end
@@ -210,6 +307,7 @@ module Couchbase
210
307
  # @return [Integer] the time in milliseconds allowed for the operation to complete
211
308
  attr_accessor :timeout
212
309
 
310
+ # @yieldparam [CreateIndexOptions]
213
311
  def initialize
214
312
  @ignore_if_exists = false
215
313
  yield self if block_given?
@@ -218,7 +316,7 @@ module Couchbase
218
316
 
219
317
  class DropIndexOptions
220
318
  # @return [Boolean] ignore if the index does not exists
221
- attr_accessor :ignore_if_not_exists
319
+ attr_accessor :ignore_if_does_not_exist
222
320
 
223
321
  # @return [String] The name of the dataverse to use (defaults to +nil+)
224
322
  attr_accessor :dataverse_name
@@ -226,8 +324,9 @@ module Couchbase
226
324
  # @return [Integer] the time in milliseconds allowed for the operation to complete
227
325
  attr_accessor :timeout
228
326
 
327
+ # @yieldparam [DropIndexOptions]
229
328
  def initialize
230
- @ignore_if_not_exists = false
329
+ @ignore_if_does_not_exist = false
231
330
  yield self if block_given?
232
331
  end
233
332
  end
@@ -236,6 +335,7 @@ module Couchbase
236
335
  # @return [Integer] the time in milliseconds allowed for the operation to complete
237
336
  attr_accessor :timeout
238
337
 
338
+ # @yieldparam [GetAllIndexesOptions]
239
339
  def initialize
240
340
  yield self if block_given?
241
341
  end
@@ -246,7 +346,7 @@ module Couchbase
246
346
  attr_accessor :link_name
247
347
 
248
348
  # @return [Boolean] Whether to force link creation even if the bucket UUID changed, for example due to the
249
- # bucket being deleted and recreated (defaults to +false+)
349
+ # bucket being deleted and recreated (defaults to +false+)
250
350
  attr_accessor :force
251
351
 
252
352
  # @return [String] The name of the dataverse to use (defaults to +nil+)
@@ -255,6 +355,7 @@ module Couchbase
255
355
  # @return [Integer] the time in milliseconds allowed for the operation to complete
256
356
  attr_accessor :timeout
257
357
 
358
+ # @yieldparam [ConnectLinkOptions]
258
359
  def initialize
259
360
  @link_name = "Local"
260
361
  @force = false
@@ -272,6 +373,7 @@ module Couchbase
272
373
  # @return [Integer] the time in milliseconds allowed for the operation to complete
273
374
  attr_accessor :timeout
274
375
 
376
+ # @yieldparam [DisconnectLinkOptions]
275
377
  def initialize
276
378
  @link_name = "Local"
277
379
  yield self if block_given?
@@ -282,6 +384,7 @@ module Couchbase
282
384
  # @return [Integer] the time in milliseconds allowed for the operation to complete
283
385
  attr_accessor :timeout
284
386
 
387
+ # @yieldparam [GetPendingMutationsOptions]
285
388
  def initialize
286
389
  yield self if block_given?
287
390
  end
@@ -300,6 +403,11 @@ module Couchbase
300
403
 
301
404
  # @return [String]
302
405
  attr_accessor :bucket_name
406
+
407
+ # @yieldparam [AnalyticsDataset]
408
+ def initialize
409
+ yield self if block_given?
410
+ end
303
411
  end
304
412
 
305
413
  class AnalyticsIndex
@@ -314,6 +422,12 @@ module Couchbase
314
422
 
315
423
  # @return [Boolean]
316
424
  attr_accessor :is_primary
425
+ alias_method :primary?, :is_primary
426
+
427
+ # @yieldparam [AnalyticsIndex]
428
+ def initialize
429
+ yield self if block_given?
430
+ end
317
431
  end
318
432
  end
319
- end
433
+ end
@@ -34,6 +34,9 @@ module Couchbase
34
34
  class ViewIndexManager
35
35
  alias_method :inspect, :to_s
36
36
 
37
+ # @return [String] name of the bucket
38
+ attr_accessor :bucket_name
39
+
37
40
  # @param [Couchbase::Backend] backend
38
41
  # @param [String] bucket_name
39
42
  def initialize(backend, bucket_name)
@@ -51,7 +54,8 @@ module Couchbase
51
54
  #
52
55
  # @raise [Error::DesignDocumentNotFound]
53
56
  def get_design_document(name, namespace, options = GetDesignDocumentOptions.new)
54
- # GET /{bucket_name}/_design/{namespace}_{name}
57
+ resp = @backend.view_index_get(@bucket_name, name, namespace, options.timeout)
58
+ extract_design_document(resp)
55
59
  end
56
60
 
57
61
  # Fetches all design documents from the server
@@ -61,7 +65,10 @@ module Couchbase
61
65
  #
62
66
  # @return [Array<DesignDocument>]
63
67
  def get_all_design_documents(namespace, options = GetAllDesignDocumentsOptions.new)
64
- # GET /pools/default/buckets/{bucket_name}/ddocs
68
+ resp = @backend.view_index_get_all(@bucket_name, namespace, options.timeout)
69
+ resp.map do |entry|
70
+ extract_design_document(entry)
71
+ end
65
72
  end
66
73
 
67
74
  # Updates or inserts the design document
@@ -69,8 +76,13 @@ module Couchbase
69
76
  # @param [DesignDocument] document
70
77
  # @param [:production, :development] namespace the namespace
71
78
  # @param [UpsertDesignDocumentOptions] options
79
+ #
80
+ # @return [void]
72
81
  def upsert_design_document(document, namespace, options = UpsertDesignDocumentOptions.new)
73
- # PUT /{bucket_name}/_design/{namespace}_{name}
82
+ @backend.view_index_upsert(@bucket_name, {
83
+ name: document.name,
84
+ views: document.views.map { |name, view| {name: name, map: view.map_function, reduce: view.reduce_function} }
85
+ }, namespace, options.timeout)
74
86
  end
75
87
 
76
88
  # Removes the design document
@@ -79,9 +91,11 @@ module Couchbase
79
91
  # @param [:production, :development] namespace the namespace
80
92
  # @param [DropDesignDocumentOptions] options
81
93
  #
94
+ # @return [void]
95
+ #
82
96
  # @raise [Error::DesignDocumentNotFound]
83
97
  def drop_design_document(name, namespace, options = DropDesignDocumentOptions.new)
84
- # DELETE /{bucket_name}/_design/{namespace}_{name}
98
+ @backend.view_index_drop(@bucket_name, name, namespace, options.timeout)
85
99
  end
86
100
 
87
101
  # Publishes the design document.
@@ -92,9 +106,13 @@ module Couchbase
92
106
  # @param [String] name design document name
93
107
  # @param [PublishDesignDocumentOptions] options
94
108
  #
109
+ # @return [void]
110
+ #
95
111
  # @raise [ArgumentError]
96
112
  # @raise [Error::DesignDocumentNotFound]
97
113
  def publish_design_document(name, options = PublishDesignDocumentOptions.new)
114
+ document = get_design_document(name, :development, GetDesignDocumentOptions.new { |o| o.timeout = options.timeout })
115
+ upsert_design_document(document, :production, UpsertDesignDocumentOptions.new { |o| o.timeout = options.timeout })
98
116
  end
99
117
 
100
118
  class GetDesignDocumentOptions
@@ -147,17 +165,48 @@ module Couchbase
147
165
  end
148
166
  end
149
167
 
168
+ private
169
+
170
+ def extract_design_document(resp)
171
+ DesignDocument.new do |design_document|
172
+ design_document.name = resp[:name]
173
+ design_document.namespace = resp[:namespace]
174
+ resp[:views].each do |name, view_resp|
175
+ design_document.views[name] = View.new(view_resp[:map], view_resp[:reduce])
176
+ end
177
+ end
178
+ end
150
179
  end
151
180
 
152
181
  class View
153
- # @return [String] map function in javascript
154
- attr_accessor :map
182
+ # @return [String] name of the view
183
+ attr_accessor :view
155
184
 
156
- # @return [String] reduce function in javascript
157
- attr_accessor :reduce
185
+ # @return [String] map function in javascript as String
186
+ attr_accessor :map_function
187
+ alias_method :map, :map_function
158
188
 
189
+ # @return [String] reduce function in javascript as String
190
+ attr_accessor :reduce_function
191
+ alias_method :reduce, :reduce_function
192
+
193
+ # @return [Boolean] true if map function is defined
194
+ def has_map?
195
+ !@map_function.nil?
196
+ end
197
+
198
+ # @return [Boolean] true if map function is defined
199
+ def has_reduce?
200
+ !@reduce_function.nil?
201
+ end
202
+
203
+ # @param [String] map
204
+ # @param [String] reduce
205
+ #
159
206
  # @yieldparam [View] self
160
- def initialize
207
+ def initialize(map = nil, reduce = nil)
208
+ @map_function = map
209
+ @reduce_function = reduce
161
210
  yield self if block_given?
162
211
  end
163
212
  end
@@ -166,11 +215,15 @@ module Couchbase
166
215
  # @return [String] name
167
216
  attr_accessor :name
168
217
 
169
- # @return [Hash<String, View>]
218
+ # @return [Hash<String => View>]
170
219
  attr_accessor :views
171
220
 
221
+ # @return [:production, :development]
222
+ attr_accessor :namespace
223
+
172
224
  # @yieldparam [DesignDocument] self
173
225
  def initialize
226
+ @views = {}
174
227
  yield self if block_given?
175
228
  end
176
229
  end