couchbase 3.9.0-aarch64-linux-musl

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 (149) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +202 -0
  3. data/README.md +154 -0
  4. data/ext/extconf.rb +0 -0
  5. data/lib/active_support/cache/couchbase_store.rb +407 -0
  6. data/lib/couchbase/3.2/libcouchbase.so +0 -0
  7. data/lib/couchbase/3.3/libcouchbase.so +0 -0
  8. data/lib/couchbase/3.4/libcouchbase.so +0 -0
  9. data/lib/couchbase/4.0/libcouchbase.so +0 -0
  10. data/lib/couchbase/analytics_options.rb +109 -0
  11. data/lib/couchbase/authenticator.rb +80 -0
  12. data/lib/couchbase/binary_collection.rb +145 -0
  13. data/lib/couchbase/binary_collection_options.rb +26 -0
  14. data/lib/couchbase/bucket.rb +173 -0
  15. data/lib/couchbase/cluster.rb +555 -0
  16. data/lib/couchbase/cluster_registry.rb +49 -0
  17. data/lib/couchbase/collection.rb +770 -0
  18. data/lib/couchbase/collection_options.rb +401 -0
  19. data/lib/couchbase/config_profiles.rb +57 -0
  20. data/lib/couchbase/configuration.rb +58 -0
  21. data/lib/couchbase/datastructures/couchbase_list.rb +192 -0
  22. data/lib/couchbase/datastructures/couchbase_map.rb +231 -0
  23. data/lib/couchbase/datastructures/couchbase_queue.rb +161 -0
  24. data/lib/couchbase/datastructures/couchbase_set.rb +145 -0
  25. data/lib/couchbase/datastructures.rb +26 -0
  26. data/lib/couchbase/deprecations.rb +61 -0
  27. data/lib/couchbase/diagnostics.rb +183 -0
  28. data/lib/couchbase/errors.rb +438 -0
  29. data/lib/couchbase/fork_hooks.rb +41 -0
  30. data/lib/couchbase/get_replica_strategy.rb +89 -0
  31. data/lib/couchbase/json_transcoder.rb +41 -0
  32. data/lib/couchbase/key_value_scan.rb +119 -0
  33. data/lib/couchbase/libcouchbase.rb +6 -0
  34. data/lib/couchbase/logger.rb +87 -0
  35. data/lib/couchbase/management/analytics_index_manager.rb +1160 -0
  36. data/lib/couchbase/management/bucket_manager.rb +479 -0
  37. data/lib/couchbase/management/collection_manager.rb +515 -0
  38. data/lib/couchbase/management/collection_query_index_manager.rb +247 -0
  39. data/lib/couchbase/management/query_index_manager.rb +671 -0
  40. data/lib/couchbase/management/scope_search_index_manager.rb +267 -0
  41. data/lib/couchbase/management/search_index_manager.rb +649 -0
  42. data/lib/couchbase/management/user_manager.rb +639 -0
  43. data/lib/couchbase/management/view_index_manager.rb +332 -0
  44. data/lib/couchbase/management.rb +31 -0
  45. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  46. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  47. data/lib/couchbase/metrics/meter.rb +27 -0
  48. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  49. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  50. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  51. data/lib/couchbase/mutation_state.rb +65 -0
  52. data/lib/couchbase/options.rb +3097 -0
  53. data/lib/couchbase/protostellar/binary_collection.rb +55 -0
  54. data/lib/couchbase/protostellar/bucket.rb +59 -0
  55. data/lib/couchbase/protostellar/client.rb +97 -0
  56. data/lib/couchbase/protostellar/cluster.rb +182 -0
  57. data/lib/couchbase/protostellar/collection.rb +156 -0
  58. data/lib/couchbase/protostellar/connect_options.rb +63 -0
  59. data/lib/couchbase/protostellar/error_handling.rb +204 -0
  60. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
  61. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
  62. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +42 -0
  63. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +51 -0
  64. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +38 -0
  65. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +52 -0
  66. data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +42 -0
  67. data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +55 -0
  68. data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +51 -0
  69. data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +67 -0
  70. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +31 -0
  71. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +40 -0
  72. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +51 -0
  73. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +54 -0
  74. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
  75. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
  76. data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +74 -0
  77. data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +93 -0
  78. data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +35 -0
  79. data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +40 -0
  80. data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
  81. data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
  82. data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +78 -0
  83. data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +41 -0
  84. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +36 -0
  85. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +66 -0
  86. data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +30 -0
  87. data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +39 -0
  88. data/lib/couchbase/protostellar/generated.rb +9 -0
  89. data/lib/couchbase/protostellar/management/bucket_manager.rb +67 -0
  90. data/lib/couchbase/protostellar/management/collection_manager.rb +94 -0
  91. data/lib/couchbase/protostellar/management/collection_query_index_manager.rb +124 -0
  92. data/lib/couchbase/protostellar/management/query_index_manager.rb +112 -0
  93. data/lib/couchbase/protostellar/management.rb +24 -0
  94. data/lib/couchbase/protostellar/request.rb +79 -0
  95. data/lib/couchbase/protostellar/request_behaviour.rb +42 -0
  96. data/lib/couchbase/protostellar/request_generator/admin/bucket.rb +124 -0
  97. data/lib/couchbase/protostellar/request_generator/admin/collection.rb +96 -0
  98. data/lib/couchbase/protostellar/request_generator/admin/query.rb +132 -0
  99. data/lib/couchbase/protostellar/request_generator/admin.rb +24 -0
  100. data/lib/couchbase/protostellar/request_generator/kv.rb +488 -0
  101. data/lib/couchbase/protostellar/request_generator/query.rb +133 -0
  102. data/lib/couchbase/protostellar/request_generator/search.rb +403 -0
  103. data/lib/couchbase/protostellar/request_generator.rb +26 -0
  104. data/lib/couchbase/protostellar/response_converter/admin/bucket.rb +55 -0
  105. data/lib/couchbase/protostellar/response_converter/admin/collection.rb +42 -0
  106. data/lib/couchbase/protostellar/response_converter/admin/query.rb +59 -0
  107. data/lib/couchbase/protostellar/response_converter/admin.rb +24 -0
  108. data/lib/couchbase/protostellar/response_converter/kv.rb +151 -0
  109. data/lib/couchbase/protostellar/response_converter/query.rb +84 -0
  110. data/lib/couchbase/protostellar/response_converter/search.rb +136 -0
  111. data/lib/couchbase/protostellar/response_converter.rb +26 -0
  112. data/lib/couchbase/protostellar/retry/action.rb +38 -0
  113. data/lib/couchbase/protostellar/retry/orchestrator.rb +61 -0
  114. data/lib/couchbase/protostellar/retry/reason.rb +67 -0
  115. data/lib/couchbase/protostellar/retry/strategies/best_effort.rb +49 -0
  116. data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
  117. data/lib/couchbase/protostellar/retry/strategies.rb +27 -0
  118. data/lib/couchbase/protostellar/retry.rb +28 -0
  119. data/lib/couchbase/protostellar/scope.rb +61 -0
  120. data/lib/couchbase/protostellar/timeout_defaults.rb +30 -0
  121. data/lib/couchbase/protostellar/timeouts.rb +83 -0
  122. data/lib/couchbase/protostellar.rb +29 -0
  123. data/lib/couchbase/query_options.rb +122 -0
  124. data/lib/couchbase/railtie.rb +47 -0
  125. data/lib/couchbase/raw_binary_transcoder.rb +39 -0
  126. data/lib/couchbase/raw_json_transcoder.rb +40 -0
  127. data/lib/couchbase/raw_string_transcoder.rb +42 -0
  128. data/lib/couchbase/scope.rb +272 -0
  129. data/lib/couchbase/search_options.rb +1744 -0
  130. data/lib/couchbase/subdoc.rb +293 -0
  131. data/lib/couchbase/tracing/noop_span.rb +29 -0
  132. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  133. data/lib/couchbase/tracing/request_span.rb +34 -0
  134. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  135. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  136. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  137. data/lib/couchbase/transcoder_flags.rb +64 -0
  138. data/lib/couchbase/utils/generic_logger_adapter.rb +40 -0
  139. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  140. data/lib/couchbase/utils/observability.rb +263 -0
  141. data/lib/couchbase/utils/observability_constants.rb +200 -0
  142. data/lib/couchbase/utils/stdlib_logger_adapter.rb +65 -0
  143. data/lib/couchbase/utils/time.rb +71 -0
  144. data/lib/couchbase/utils.rb +23 -0
  145. data/lib/couchbase/version.rb +25 -0
  146. data/lib/couchbase/view_options.rb +67 -0
  147. data/lib/couchbase.rb +32 -0
  148. data/lib/rails/generators/couchbase/config/config_generator.rb +29 -0
  149. metadata +228 -0
@@ -0,0 +1,488 @@
1
+ # Copyright 2023. Couchbase, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # frozen_string_literal: true
16
+
17
+ require "couchbase/json_transcoder"
18
+ require "couchbase/utils/time"
19
+ require "couchbase/errors"
20
+
21
+ require "couchbase/protostellar/generated/kv/v1/kv_pb"
22
+ require "couchbase/protostellar/request"
23
+
24
+ require "google/protobuf/well_known_types"
25
+
26
+ module Couchbase
27
+ module Protostellar
28
+ module RequestGenerator
29
+ class KV
30
+ DURABILITY_LEVEL_MAP = {
31
+ :majority => :DURABILITY_LEVEL_MAJORITY,
32
+ :majority_and_persist_to_active => :DURABILITY_LEVEL_MAJORITY_AND_PERSIST_TO_ACTIVE,
33
+ :persist_to_majority => :DURABILITY_LEVEL_PERSIST_TO_MAJORITY,
34
+ }.freeze
35
+
36
+ LOOKUP_IN_OPERATION_TYPE_MAP = {
37
+ :get => :OPERATION_GET,
38
+ :get_doc => :OPERATION_GET,
39
+ :exists => :OPERATION_EXISTS,
40
+ :count => :OPERATION_COUNT,
41
+ }.freeze
42
+
43
+ MUTATE_IN_OPERATION_TYPE_MAP = {
44
+ :set_doc => :OPERATION_REPLACE,
45
+ :replace => :OPERATION_REPLACE,
46
+ :dict_add => :OPERATION_INSERT,
47
+ :remove_doc => :OPERATION_REMOVE,
48
+ :remove => :OPERATION_REMOVE,
49
+ :dict_upsert => :OPERATION_UPSERT,
50
+ :array_push_last => :OPERATION_ARRAY_APPEND,
51
+ :array_push_first => :OPERATION_ARRAY_PREPEND,
52
+ :array_insert => :OPERATION_ARRAY_INSERT,
53
+ :array_add_unique => :OPERATION_ARRAY_ADD_UNIQUE,
54
+ :counter => :OPERATION_COUNTER,
55
+ }.freeze
56
+
57
+ MUTATE_IN_STORE_SEMANTIC_MAP = {
58
+ :replace => :STORE_SEMANTIC_REPLACE,
59
+ :upsert => :STORE_SEMANTIC_UPSERT,
60
+ :insert => :STORE_SEMANTIC_INSERT,
61
+ }.freeze
62
+
63
+ attr_reader :bucket_name
64
+ attr_reader :scope_name
65
+ attr_reader :collection_name
66
+
67
+ def initialize(bucket_name, scope_name, collection_name)
68
+ @bucket_name = bucket_name
69
+ @scope_name = scope_name
70
+ @collection_name = collection_name
71
+ end
72
+
73
+ def location
74
+ {
75
+ bucket_name: @bucket_name,
76
+ scope_name: @scope_name,
77
+ collection_name: @collection_name,
78
+ }
79
+ end
80
+
81
+ def get_request(id, options)
82
+ proto_opts = {
83
+ project: options.projections,
84
+ }
85
+
86
+ proto_req = Generated::KV::V1::GetRequest.new(
87
+ key: id,
88
+ **location,
89
+ **proto_opts,
90
+ )
91
+
92
+ create_kv_request(proto_req, :get, options, idempotent: true)
93
+ end
94
+
95
+ def get_and_touch_request(id, expiry, options)
96
+ expiry_type, expiry_value = get_expiry(expiry)
97
+
98
+ raise ArgumentError, "Expiry cannot be nil" if expiry_value.nil?
99
+
100
+ proto_req = Generated::KV::V1::GetAndTouchRequest.new(
101
+ **{expiry_type => expiry_value},
102
+ **location,
103
+ key: id,
104
+ )
105
+
106
+ create_kv_request(proto_req, :get_and_touch, options)
107
+ end
108
+
109
+ def get_and_lock_request(id, lock_time, options)
110
+ proto_req = Generated::KV::V1::GetAndLockRequest.new(
111
+ **location,
112
+ key: id,
113
+ lock_time_secs: lock_time.respond_to?(:in_seconds) ? lock_time.in_seconds : lock_time,
114
+ )
115
+
116
+ create_kv_request(proto_req, :get_and_lock, options)
117
+ end
118
+
119
+ def unlock_request(id, cas, options)
120
+ proto_req = Generated::KV::V1::UnlockRequest.new(
121
+ **location,
122
+ key: id,
123
+ cas: cas,
124
+ )
125
+
126
+ create_kv_request(proto_req, :unlock, options)
127
+ end
128
+
129
+ def touch_request(id, expiry, options)
130
+ expiry_type, expiry_value = get_expiry(expiry)
131
+
132
+ raise ArgumentError, "Expiry cannot be nil" if expiry_value.nil?
133
+
134
+ proto_req = Generated::KV::V1::TouchRequest.new(
135
+ **{expiry_type => expiry_value},
136
+ **location,
137
+ key: id,
138
+ )
139
+
140
+ create_kv_request(proto_req, :touch, options)
141
+ end
142
+
143
+ def upsert_request(id, content, options)
144
+ encoded, flag = get_encoded(content, options)
145
+
146
+ proto_opts = {
147
+ content_flags: flag,
148
+ preserve_expiry_on_existing: options.preserve_expiry,
149
+ }
150
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
151
+
152
+ expiry_type, expiry_value = get_expiry(options)
153
+ proto_opts[expiry_type] = expiry_value
154
+
155
+ proto_req = Generated::KV::V1::UpsertRequest.new(
156
+ key: id,
157
+ content_uncompressed: encoded,
158
+ **location,
159
+ **proto_opts,
160
+ )
161
+
162
+ create_kv_request(proto_req, :upsert, options)
163
+ end
164
+
165
+ def insert_request(id, content, options)
166
+ encoded, flag = get_encoded(content, options)
167
+
168
+ proto_opts = {
169
+ content_flags: flag,
170
+ }
171
+
172
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
173
+ expiry_type, expiry_value = get_expiry(options)
174
+ proto_opts[expiry_type] = expiry_value unless expiry_value.nil?
175
+
176
+ proto_req = Generated::KV::V1::InsertRequest.new(
177
+ key: id,
178
+ content_uncompressed: encoded,
179
+ **location,
180
+ **proto_opts,
181
+ )
182
+
183
+ create_kv_request(proto_req, :insert, options)
184
+ end
185
+
186
+ def replace_request(id, content, options)
187
+ encoded, flag = get_encoded(content, options)
188
+
189
+ proto_opts = {
190
+ content_flags: flag,
191
+ }
192
+
193
+ proto_opts[:cas] = options.cas unless options.cas.nil?
194
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
195
+
196
+ unless options.preserve_expiry
197
+ expiry_type, expiry_value = get_expiry(options)
198
+ proto_opts[expiry_type] = expiry_value
199
+ end
200
+
201
+ proto_req = Generated::KV::V1::ReplaceRequest.new(
202
+ key: id,
203
+ content_uncompressed: encoded,
204
+ **location,
205
+ **proto_opts,
206
+ )
207
+
208
+ create_kv_request(proto_req, :replace, options)
209
+ end
210
+
211
+ def remove_request(id, options)
212
+ proto_opts = {}
213
+
214
+ proto_opts[:cas] = options.cas unless options.cas.nil?
215
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
216
+
217
+ proto_req = Generated::KV::V1::RemoveRequest.new(
218
+ key: id,
219
+ **location,
220
+ **proto_opts,
221
+ )
222
+
223
+ create_kv_request(proto_req, :remove, options)
224
+ end
225
+
226
+ def exists_request(id, options)
227
+ proto_opts = {}
228
+
229
+ proto_req = Generated::KV::V1::ExistsRequest.new(
230
+ key: id,
231
+ **proto_opts,
232
+ **location,
233
+ )
234
+
235
+ create_kv_request(proto_req, :exists, options)
236
+ end
237
+
238
+ def mutate_in_request(id, specs, options)
239
+ if options.create_as_deleted
240
+ raise Error::FeatureNotAvailable, "The #{Couchbase::Protostellar::NAME} protocol does not support create_as_deleted"
241
+ end
242
+
243
+ proto_opts = {
244
+ flags: get_mutate_in_flags(options),
245
+ store_semantic: get_mutate_in_store_semantic(options),
246
+ durability_level: get_durability_level(options),
247
+ }
248
+ proto_opts[:cas] = options.cas unless options.cas.nil?
249
+
250
+ unless options.preserve_expiry
251
+ expiry_type, expiry_value = get_expiry(options)
252
+ proto_opts[expiry_type] = expiry_value
253
+ end
254
+
255
+ proto_req = Generated::KV::V1::MutateInRequest.new(
256
+ key: id,
257
+ **location,
258
+ specs: specs.map { |s| get_mutate_in_spec(s) },
259
+ **proto_opts,
260
+ )
261
+
262
+ create_kv_request(proto_req, :mutate_in, options)
263
+ end
264
+
265
+ def lookup_in_request(id, specs, options)
266
+ proto_opts = {
267
+ flags: get_lookup_in_flags(options),
268
+ }
269
+
270
+ proto_req = Generated::KV::V1::LookupInRequest.new(
271
+ key: id,
272
+ **location,
273
+ specs: specs.map { |s| get_lookup_in_spec(s) },
274
+ **proto_opts,
275
+ )
276
+
277
+ create_kv_request(proto_req, :lookup_in, options, idempotent: true)
278
+ end
279
+
280
+ def increment_request(id, options)
281
+ proto_opts = {
282
+ delta: options.delta,
283
+ }
284
+ expiry_type, expiry_value = get_expiry(options)
285
+ proto_opts[expiry_type] = expiry_value unless expiry_value.nil?
286
+ proto_opts[:initial] = options.initial unless options.initial.nil?
287
+
288
+ proto_req = Generated::KV::V1::IncrementRequest.new(
289
+ key: id,
290
+ **location,
291
+ **proto_opts,
292
+ )
293
+
294
+ create_kv_request(proto_req, :increment, options)
295
+ end
296
+
297
+ def decrement_request(id, options)
298
+ proto_opts = {
299
+ delta: options.delta,
300
+ }
301
+ expiry_type, expiry_value = get_expiry(options)
302
+ proto_opts[expiry_type] = expiry_value unless expiry_value.nil?
303
+ proto_opts[:initial] = options.initial unless options.initial.nil?
304
+
305
+ proto_req = Generated::KV::V1::DecrementRequest.new(
306
+ key: id,
307
+ **location,
308
+ **proto_opts,
309
+ )
310
+
311
+ create_kv_request(proto_req, :decrement, options)
312
+ end
313
+
314
+ def append_request(id, content, options)
315
+ proto_opts = {}
316
+ proto_opts[:cas] = options.cas unless options.cas.nil?
317
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
318
+
319
+ proto_req = Generated::KV::V1::AppendRequest.new(
320
+ key: id,
321
+ content: content,
322
+ **location,
323
+ **proto_opts,
324
+ )
325
+
326
+ create_kv_request(proto_req, :append, options)
327
+ end
328
+
329
+ def prepend_request(id, content, options)
330
+ proto_opts = {}
331
+ proto_opts[:cas] = options.cas unless options.cas.nil?
332
+ proto_opts[:durability_level] = get_durability_level(options) unless options.durability_level == :none
333
+
334
+ proto_req = Generated::KV::V1::PrependRequest.new(
335
+ key: id,
336
+ content: content,
337
+ **location,
338
+ **proto_opts,
339
+ )
340
+
341
+ create_kv_request(proto_req, :prepend, options)
342
+ end
343
+
344
+ def get_all_replicas_request(id, options)
345
+ proto_req = Generated::KV::V1::GetAllReplicasRequest.new(
346
+ key: id,
347
+ **location,
348
+ )
349
+
350
+ create_kv_request(proto_req, :get_all_replicas, options,
351
+ idempotent: true, retry_strategy: Retry::Strategies::BestEffort::DEFAULT)
352
+ end
353
+
354
+ def get_any_replica_request(id, options)
355
+ # Uses the GetAllReplicas request and returns the first item from the result
356
+ get_all_replicas_request(id, options)
357
+ end
358
+
359
+ private
360
+
361
+ def create_kv_request(proto_request, rpc, options, idempotent: false,
362
+ retry_strategy: kv_retry_strategy(options.retry_strategy))
363
+ Request.new(
364
+ service: :kv,
365
+ rpc: rpc,
366
+ proto_request: proto_request,
367
+ timeout: options.timeout,
368
+ retry_strategy: retry_strategy,
369
+ idempotent: idempotent,
370
+ )
371
+ end
372
+
373
+ def kv_retry_strategy(name)
374
+ case name
375
+ when nil, :best_effort
376
+ Retry::Strategies::BestEffort::DEFAULT
377
+ when :fail_fast
378
+ Retry::Strategies::FailFast::DEFAULT
379
+ else
380
+ raise Error::InvalidArgument, "retry_strategy must be :best_effort or :fail_fast, but given #{name.inspect}"
381
+ end
382
+ end
383
+
384
+ def get_expiry(options_or_expiry)
385
+ if options_or_expiry.respond_to?(:expiry)
386
+ type, time_or_duration = Couchbase::Utils::Time.extract_expiry_time(options_or_expiry.expiry)
387
+ else
388
+ type, time_or_duration = Couchbase::Utils::Time.extract_expiry_time(options_or_expiry)
389
+ end
390
+
391
+ if time_or_duration.nil?
392
+ return [:expiry_secs, 0] if options_or_expiry.respond_to?(:expiry) # Expiry in KV options - expiry should be removed
393
+
394
+ return [nil, nil]
395
+ end
396
+
397
+ case type
398
+ when :duration
399
+ [:expiry_secs, time_or_duration]
400
+ when :time_point
401
+ timestamp = Google::Protobuf::Timestamp.new(
402
+ seconds: time_or_duration,
403
+ )
404
+ [:expiry_time, timestamp]
405
+ else
406
+ raise Couchbase::Error::CouchbaseError, "Unexpected expiry type"
407
+ end
408
+ end
409
+
410
+ def get_durability_level(options)
411
+ if options.durability_level == :none
412
+ nil
413
+ else
414
+ DURABILITY_LEVEL_MAP[options.durability_level]
415
+ end
416
+ end
417
+
418
+ def get_lookup_in_spec(lookup_in_spec)
419
+ Generated::KV::V1::LookupInRequest::Spec.new(
420
+ operation: get_lookup_in_operation(lookup_in_spec),
421
+ path: lookup_in_spec.path,
422
+ flags: get_lookup_in_spec_flags(lookup_in_spec),
423
+ )
424
+ end
425
+
426
+ def get_lookup_in_operation(lookup_in_spec)
427
+ LOOKUP_IN_OPERATION_TYPE_MAP[lookup_in_spec.type]
428
+ end
429
+
430
+ def get_lookup_in_spec_flags(lookup_in_spec)
431
+ Generated::KV::V1::LookupInRequest::Spec::Flags.new(
432
+ xattr: lookup_in_spec.xattr?,
433
+ )
434
+ end
435
+
436
+ def get_lookup_in_flags(options)
437
+ Generated::KV::V1::LookupInRequest::Flags.new(
438
+ access_deleted: options.access_deleted,
439
+ )
440
+ end
441
+
442
+ def get_mutate_in_spec(mutate_in_spec)
443
+ if mutate_in_spec.expand_macros?
444
+ raise Couchbase::Error::FeatureNotAvailable, "The #{Protostellar::NAME} protocol does not support expanding macros"
445
+ end
446
+
447
+ Generated::KV::V1::MutateInRequest::Spec.new(
448
+ operation: get_mutate_in_operation(mutate_in_spec),
449
+ path: mutate_in_spec.path,
450
+ content: mutate_in_spec.param.to_s,
451
+ flags: get_mutate_in_spec_flags(mutate_in_spec),
452
+ )
453
+ end
454
+
455
+ def get_mutate_in_operation(mutate_in_spec)
456
+ MUTATE_IN_OPERATION_TYPE_MAP[mutate_in_spec.type]
457
+ end
458
+
459
+ def get_mutate_in_spec_flags(mutate_in_spec)
460
+ Generated::KV::V1::MutateInRequest::Spec::Flags.new(
461
+ create_path: mutate_in_spec.create_path?,
462
+ xattr: mutate_in_spec.xattr?,
463
+ )
464
+ end
465
+
466
+ def get_mutate_in_flags(options)
467
+ Generated::KV::V1::MutateInRequest::Flags.new(
468
+ access_deleted: options.access_deleted,
469
+ )
470
+ end
471
+
472
+ def get_mutate_in_store_semantic(options)
473
+ MUTATE_IN_STORE_SEMANTIC_MAP[options.store_semantics]
474
+ end
475
+
476
+ def get_encoded(content, options)
477
+ if options.transcoder.nil?
478
+ encoded = content.to_s
479
+ flag = 0
480
+ else
481
+ encoded, flag = options.transcoder.encode(content)
482
+ end
483
+ [encoded, flag]
484
+ end
485
+ end
486
+ end
487
+ end
488
+ end
@@ -0,0 +1,133 @@
1
+ # Copyright 2023. Couchbase, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # frozen_string_literal: true
16
+
17
+ require "couchbase/protostellar/generated/query/v1/query_pb"
18
+ require 'couchbase/protostellar/generated/kv/v1/kv_pb'
19
+ require "couchbase/protostellar/request"
20
+
21
+ require "google/protobuf/well_known_types"
22
+
23
+ module Couchbase
24
+ module Protostellar
25
+ module RequestGenerator
26
+ class Query
27
+ SCAN_CONSISTENCY_MAP = {
28
+ :not_bounded => :SCAN_CONSISTENCY_NOT_BOUNDED,
29
+ :request_plus => :SCAN_CONSISTENCY_REQUEST_PLUS,
30
+ }.freeze
31
+
32
+ PROFILE_MODE_MAP = {
33
+ :off => :PROFILE_MODE_OFF,
34
+ :phases => :PROFILE_MODE_PHASES,
35
+ :timings => :PROFILE_MODE_TIMINGS,
36
+ }.freeze
37
+
38
+ attr_reader :bucket_name
39
+ attr_reader :scope_name
40
+
41
+ def initialize(bucket_name: nil, scope_name: nil)
42
+ @bucket_name = bucket_name
43
+ @scope_name = scope_name
44
+ end
45
+
46
+ def query_request(statement, options)
47
+ proto_opts = {}
48
+
49
+ bucket_name = @bucket_name
50
+ scope_name = @scope_name
51
+ unless options.scope_qualifier.nil?
52
+ if options.scope_qualifier.include? ":"
53
+ bucket_name, scope_name = options.scope_qualifier.split(":")[1].split(".")
54
+ else
55
+ bucket_name, scope_name = options.scope_qualifier.split(".")
56
+ end
57
+ end
58
+ proto_opts[:scope_name] = scope_name unless scope_name.nil?
59
+ proto_opts[:bucket_name] = bucket_name unless bucket_name.nil?
60
+
61
+ proto_opts[:read_only] = options.readonly unless options.readonly.nil?
62
+ proto_opts[:prepared] = !options.adhoc
63
+
64
+ tuning_opts = create_tuning_options(options)
65
+ proto_opts[:tuning_options] = tuning_opts unless tuning_opts.nil?
66
+
67
+ proto_opts[:client_context_id] = options.client_context_id unless options.client_context_id.nil?
68
+ unless options.instance_variable_get(:@scan_consistency).nil?
69
+ proto_opts[:scan_consistency] =
70
+ SCAN_CONSISTENCY_MAP[options.instance_variable_get(:@scan_consistency)]
71
+ end
72
+ proto_opts[:positional_parameters] = options.export_positional_parameters unless options.export_positional_parameters.nil?
73
+ proto_opts[:named_parameters] = options.export_named_parameters unless options.export_named_parameters.nil?
74
+ proto_opts[:flex_index] = options.flex_index unless options.flex_index.nil?
75
+ proto_opts[:preserve_expiry] = options.preserve_expiry unless options.preserve_expiry.nil?
76
+ proto_opts[:consistent_with] = get_consistent_with(options) unless options.mutation_state.nil?
77
+ proto_opts[:profile_mode] = PROFILE_MODE_MAP[options.profile]
78
+
79
+ proto_req = Generated::Query::V1::QueryRequest.new(
80
+ statement: statement,
81
+ **proto_opts,
82
+ )
83
+
84
+ create_query_request(proto_req, :query, options, idempotent: options.readonly)
85
+ end
86
+
87
+ private
88
+
89
+ def create_query_request(proto_request, rpc, options, idempotent: false)
90
+ Request.new(
91
+ service: :query,
92
+ rpc: rpc,
93
+ proto_request: proto_request,
94
+ timeout: options.timeout,
95
+ idempotent: idempotent,
96
+ )
97
+ end
98
+
99
+ def create_tuning_options(options)
100
+ tuning_opts = {}
101
+ tuning_opts[:max_parallelism] = options.max_parallelism unless options.max_parallelism.nil?
102
+ tuning_opts[:pipeline_batch] = options.pipeline_batch unless options.pipeline_batch.nil?
103
+ tuning_opts[:pipeline_cap] = options.pipeline_cap unless options.pipeline_cap.nil?
104
+ unless options.scan_wait.nil?
105
+ duration_millis = Utils::Time.extract_duration(options.scan_wait)
106
+ tuning_opts[:scan_wait] = Google::Protobuf::Duration.new(
107
+ seconds: duration_millis / 1000,
108
+ nanos: (duration_millis % 1000) * (10**6),
109
+ )
110
+ end
111
+ tuning_opts[:scan_cap] = options.scan_cap unless options.scan_cap.nil?
112
+ tuning_opts[:disable_metrics] = options.metrics.nil? || !options.metrics
113
+ if tuning_opts.empty?
114
+ nil
115
+ else
116
+ Generated::Query::V1::QueryRequest::TuningOptions.new(**tuning_opts)
117
+ end
118
+ end
119
+
120
+ def get_consistent_with(options)
121
+ options.mutation_state.tokens.map do |t|
122
+ Generated::KV::V1::MutationToken.new(
123
+ bucket_name: t.bucket_name,
124
+ vbucket_id: t.partition_id,
125
+ vbucket_uuid: t.partition_uuid,
126
+ seq_no: t.sequence_number,
127
+ )
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end