couchbase 3.5.0-x86_64-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 (125) 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 +339 -0
  6. data/lib/couchbase/3.1/libcouchbase.so +0 -0
  7. data/lib/couchbase/3.2/libcouchbase.so +0 -0
  8. data/lib/couchbase/3.3/libcouchbase.so +0 -0
  9. data/lib/couchbase/analytics_options.rb +107 -0
  10. data/lib/couchbase/authenticator.rb +64 -0
  11. data/lib/couchbase/binary_collection.rb +128 -0
  12. data/lib/couchbase/binary_collection_options.rb +24 -0
  13. data/lib/couchbase/bucket.rb +144 -0
  14. data/lib/couchbase/cluster.rb +460 -0
  15. data/lib/couchbase/cluster_registry.rb +49 -0
  16. data/lib/couchbase/collection.rb +705 -0
  17. data/lib/couchbase/collection_options.rb +399 -0
  18. data/lib/couchbase/config_profiles.rb +55 -0
  19. data/lib/couchbase/configuration.rb +56 -0
  20. data/lib/couchbase/datastructures/couchbase_list.rb +160 -0
  21. data/lib/couchbase/datastructures/couchbase_map.rb +194 -0
  22. data/lib/couchbase/datastructures/couchbase_queue.rb +134 -0
  23. data/lib/couchbase/datastructures/couchbase_set.rb +128 -0
  24. data/lib/couchbase/datastructures.rb +24 -0
  25. data/lib/couchbase/diagnostics.rb +181 -0
  26. data/lib/couchbase/errors.rb +376 -0
  27. data/lib/couchbase/json_transcoder.rb +39 -0
  28. data/lib/couchbase/key_value_scan.rb +117 -0
  29. data/lib/couchbase/libcouchbase.rb +6 -0
  30. data/lib/couchbase/logger.rb +85 -0
  31. data/lib/couchbase/management/analytics_index_manager.rb +1127 -0
  32. data/lib/couchbase/management/bucket_manager.rb +443 -0
  33. data/lib/couchbase/management/collection_manager.rb +470 -0
  34. data/lib/couchbase/management/collection_query_index_manager.rb +222 -0
  35. data/lib/couchbase/management/query_index_manager.rb +617 -0
  36. data/lib/couchbase/management/scope_search_index_manager.rb +198 -0
  37. data/lib/couchbase/management/search_index_manager.rb +424 -0
  38. data/lib/couchbase/management/user_manager.rb +468 -0
  39. data/lib/couchbase/management/view_index_manager.rb +237 -0
  40. data/lib/couchbase/management.rb +29 -0
  41. data/lib/couchbase/mutation_state.rb +63 -0
  42. data/lib/couchbase/options.rb +2837 -0
  43. data/lib/couchbase/protostellar/binary_collection.rb +55 -0
  44. data/lib/couchbase/protostellar/bucket.rb +51 -0
  45. data/lib/couchbase/protostellar/client.rb +99 -0
  46. data/lib/couchbase/protostellar/cluster.rb +163 -0
  47. data/lib/couchbase/protostellar/collection.rb +152 -0
  48. data/lib/couchbase/protostellar/connect_options.rb +63 -0
  49. data/lib/couchbase/protostellar/error_handling.rb +203 -0
  50. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +61 -0
  51. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +35 -0
  52. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +57 -0
  53. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +36 -0
  54. data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +61 -0
  55. data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +37 -0
  56. data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +72 -0
  57. data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +44 -0
  58. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +52 -0
  59. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +30 -0
  60. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +70 -0
  61. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +36 -0
  62. data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +97 -0
  63. data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +46 -0
  64. data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +57 -0
  65. data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +30 -0
  66. data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +52 -0
  67. data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +30 -0
  68. data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +99 -0
  69. data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +30 -0
  70. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +57 -0
  71. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +36 -0
  72. data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +51 -0
  73. data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +30 -0
  74. data/lib/couchbase/protostellar/generated.rb +9 -0
  75. data/lib/couchbase/protostellar/management/bucket_manager.rb +67 -0
  76. data/lib/couchbase/protostellar/management/collection_manager.rb +94 -0
  77. data/lib/couchbase/protostellar/management/collection_query_index_manager.rb +124 -0
  78. data/lib/couchbase/protostellar/management/query_index_manager.rb +112 -0
  79. data/lib/couchbase/protostellar/management.rb +24 -0
  80. data/lib/couchbase/protostellar/request.rb +78 -0
  81. data/lib/couchbase/protostellar/request_behaviour.rb +42 -0
  82. data/lib/couchbase/protostellar/request_generator/admin/bucket.rb +124 -0
  83. data/lib/couchbase/protostellar/request_generator/admin/collection.rb +94 -0
  84. data/lib/couchbase/protostellar/request_generator/admin/query.rb +130 -0
  85. data/lib/couchbase/protostellar/request_generator/admin.rb +24 -0
  86. data/lib/couchbase/protostellar/request_generator/kv.rb +474 -0
  87. data/lib/couchbase/protostellar/request_generator/query.rb +133 -0
  88. data/lib/couchbase/protostellar/request_generator/search.rb +387 -0
  89. data/lib/couchbase/protostellar/request_generator.rb +26 -0
  90. data/lib/couchbase/protostellar/response_converter/admin/bucket.rb +55 -0
  91. data/lib/couchbase/protostellar/response_converter/admin/collection.rb +42 -0
  92. data/lib/couchbase/protostellar/response_converter/admin/query.rb +59 -0
  93. data/lib/couchbase/protostellar/response_converter/admin.rb +24 -0
  94. data/lib/couchbase/protostellar/response_converter/kv.rb +151 -0
  95. data/lib/couchbase/protostellar/response_converter/query.rb +84 -0
  96. data/lib/couchbase/protostellar/response_converter/search.rb +136 -0
  97. data/lib/couchbase/protostellar/response_converter.rb +26 -0
  98. data/lib/couchbase/protostellar/retry/action.rb +38 -0
  99. data/lib/couchbase/protostellar/retry/orchestrator.rb +60 -0
  100. data/lib/couchbase/protostellar/retry/reason.rb +67 -0
  101. data/lib/couchbase/protostellar/retry/strategies/best_effort.rb +49 -0
  102. data/lib/couchbase/protostellar/retry/strategies.rb +26 -0
  103. data/lib/couchbase/protostellar/retry.rb +28 -0
  104. data/lib/couchbase/protostellar/scope.rb +57 -0
  105. data/lib/couchbase/protostellar/timeout_defaults.rb +30 -0
  106. data/lib/couchbase/protostellar/timeouts.rb +83 -0
  107. data/lib/couchbase/protostellar.rb +29 -0
  108. data/lib/couchbase/query_options.rb +120 -0
  109. data/lib/couchbase/railtie.rb +45 -0
  110. data/lib/couchbase/raw_binary_transcoder.rb +37 -0
  111. data/lib/couchbase/raw_json_transcoder.rb +38 -0
  112. data/lib/couchbase/raw_string_transcoder.rb +40 -0
  113. data/lib/couchbase/scope.rb +256 -0
  114. data/lib/couchbase/search_options.rb +1622 -0
  115. data/lib/couchbase/subdoc.rb +290 -0
  116. data/lib/couchbase/transcoder_flags.rb +62 -0
  117. data/lib/couchbase/utils/generic_logger_adapter.rb +38 -0
  118. data/lib/couchbase/utils/stdlib_logger_adapter.rb +65 -0
  119. data/lib/couchbase/utils/time.rb +69 -0
  120. data/lib/couchbase/utils.rb +21 -0
  121. data/lib/couchbase/version.rb +23 -0
  122. data/lib/couchbase/view_options.rb +65 -0
  123. data/lib/couchbase.rb +28 -0
  124. data/lib/rails/generators/couchbase/config/config_generator.rb +27 -0
  125. metadata +190 -0
@@ -0,0 +1,130 @@
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/admin/query/v1/query_pb"
18
+ require "couchbase/protostellar/request"
19
+
20
+ module Couchbase
21
+ module Protostellar
22
+ module RequestGenerator
23
+ module Admin
24
+ class Query
25
+ def initialize(bucket_name: nil, scope_name: nil, collection_name: nil)
26
+ @bucket_name = bucket_name
27
+ @scope_name = scope_name
28
+ @collection_name = collection_name
29
+ end
30
+
31
+ def get_all_indexes_request(options, bucket_name = nil)
32
+ proto_req = Generated::Admin::Query::V1::GetAllIndexesRequest.new(
33
+ **location(
34
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
35
+ )
36
+ )
37
+
38
+ create_request(proto_req, :get_all_indexes, options, idempotent: true)
39
+ end
40
+
41
+ def create_primary_index_request(options, bucket_name = nil)
42
+ proto_opts = {
43
+ deferred: options.deferred,
44
+ }
45
+ proto_opts[:name] = options.index_name unless options.index_name.nil?
46
+ proto_opts[:num_replicas] = options.num_replicas unless options.num_replicas.nil?
47
+
48
+ proto_req = Generated::Admin::Query::V1::CreatePrimaryIndexRequest.new(
49
+ **location(
50
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
51
+ ),
52
+ **proto_opts
53
+ )
54
+
55
+ create_request(proto_req, :create_primary_index, options)
56
+ end
57
+
58
+ def create_index_request(index_name, fields, options, bucket_name = nil)
59
+ proto_opts = {
60
+ deferred: options.deferred,
61
+ }
62
+ proto_opts[:num_replicas] = options.num_replicas unless options.num_replicas.nil?
63
+
64
+ proto_req = Generated::Admin::Query::V1::CreateIndexRequest.new(
65
+ **location(
66
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
67
+ ),
68
+ name: index_name,
69
+ fields: fields,
70
+ **proto_opts
71
+ )
72
+
73
+ create_request(proto_req, :create_index, options)
74
+ end
75
+
76
+ def drop_primary_index_request(options, bucket_name = nil)
77
+ proto_req = Generated::Admin::Query::V1::DropPrimaryIndexRequest.new(
78
+ **location(
79
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
80
+ )
81
+ )
82
+
83
+ create_request(proto_req, :drop_primary_index, options)
84
+ end
85
+
86
+ def drop_index_request(index_name, options, bucket_name = nil)
87
+ proto_req = Generated::Admin::Query::V1::DropIndexRequest.new(
88
+ **location(
89
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
90
+ ),
91
+ name: index_name
92
+ )
93
+
94
+ create_request(proto_req, :drop_index, options)
95
+ end
96
+
97
+ def build_deferred_indexes_request(options, bucket_name = nil)
98
+ proto_req = Generated::Admin::Query::V1::BuildDeferredIndexesRequest.new(
99
+ **location(
100
+ bucket_name: bucket_name, scope_name: options.scope_name, collection_name: options.collection_name
101
+ )
102
+ )
103
+
104
+ create_request(proto_req, :build_deferred_indexes, options)
105
+ end
106
+
107
+ private
108
+
109
+ def location(bucket_name: nil, scope_name: nil, collection_name: nil)
110
+ {
111
+ bucket_name: @bucket_name || bucket_name,
112
+ scope_name: @scope_name || scope_name,
113
+ collection_name: @collection_name || collection_name,
114
+ }.compact
115
+ end
116
+
117
+ def create_request(proto_request, rpc, options, idempotent: false)
118
+ Request.new(
119
+ service: :query_admin,
120
+ rpc: rpc,
121
+ proto_request: proto_request,
122
+ idempotent: idempotent,
123
+ timeout: options.timeout
124
+ )
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,24 @@
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
+ module Couchbase
18
+ module Protostellar
19
+ module RequestGenerator
20
+ module Admin
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,474 @@
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: lock_time.respond_to?(:in_seconds) ? lock_time.public_send(: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, idempotent: true)
351
+ end
352
+
353
+ def get_any_replica_request(id, options)
354
+ # Uses the GetAllReplicas request and returns the first item from the result
355
+ get_all_replicas_request(id, options)
356
+ end
357
+
358
+ private
359
+
360
+ def create_kv_request(proto_request, rpc, options, idempotent: false)
361
+ Request.new(
362
+ service: :kv,
363
+ rpc: rpc,
364
+ proto_request: proto_request,
365
+ timeout: options.timeout,
366
+ idempotent: idempotent
367
+ )
368
+ end
369
+
370
+ def get_expiry(options_or_expiry)
371
+ if options_or_expiry.respond_to?(:expiry)
372
+ type, time_or_duration = Couchbase::Utils::Time.extract_expiry_time(options_or_expiry.expiry)
373
+ else
374
+ type, time_or_duration = Couchbase::Utils::Time.extract_expiry_time(options_or_expiry)
375
+ end
376
+
377
+ if time_or_duration.nil?
378
+ return [:expiry_secs, 0] if options_or_expiry.respond_to?(:expiry) # Expiry in KV options - expiry should be removed
379
+
380
+ return [nil, nil]
381
+ end
382
+
383
+ case type
384
+ when :duration
385
+ [:expiry_secs, time_or_duration]
386
+ when :time_point
387
+ timestamp = Google::Protobuf::Timestamp.new(
388
+ seconds: time_or_duration
389
+ )
390
+ [:expiry_time, timestamp]
391
+ else
392
+ raise Couchbase::Error::CouchbaseError, "Unexpected expiry type"
393
+ end
394
+ end
395
+
396
+ def get_durability_level(options)
397
+ if options.durability_level == :none
398
+ nil
399
+ else
400
+ DURABILITY_LEVEL_MAP[options.durability_level]
401
+ end
402
+ end
403
+
404
+ def get_lookup_in_spec(lookup_in_spec)
405
+ Generated::KV::V1::LookupInRequest::Spec.new(
406
+ operation: get_lookup_in_operation(lookup_in_spec),
407
+ path: lookup_in_spec.path,
408
+ flags: get_lookup_in_spec_flags(lookup_in_spec)
409
+ )
410
+ end
411
+
412
+ def get_lookup_in_operation(lookup_in_spec)
413
+ LOOKUP_IN_OPERATION_TYPE_MAP[lookup_in_spec.type]
414
+ end
415
+
416
+ def get_lookup_in_spec_flags(lookup_in_spec)
417
+ Generated::KV::V1::LookupInRequest::Spec::Flags.new(
418
+ xattr: lookup_in_spec.xattr?
419
+ )
420
+ end
421
+
422
+ def get_lookup_in_flags(options)
423
+ Generated::KV::V1::LookupInRequest::Flags.new(
424
+ access_deleted: options.access_deleted
425
+ )
426
+ end
427
+
428
+ def get_mutate_in_spec(mutate_in_spec)
429
+ if mutate_in_spec.expand_macros?
430
+ raise Couchbase::Error::FeatureNotAvailable, "The #{Protostellar::NAME} protocol does not support expanding macros"
431
+ end
432
+
433
+ Generated::KV::V1::MutateInRequest::Spec.new(
434
+ operation: get_mutate_in_operation(mutate_in_spec),
435
+ path: mutate_in_spec.path,
436
+ content: mutate_in_spec.param.to_s,
437
+ flags: get_mutate_in_spec_flags(mutate_in_spec)
438
+ )
439
+ end
440
+
441
+ def get_mutate_in_operation(mutate_in_spec)
442
+ MUTATE_IN_OPERATION_TYPE_MAP[mutate_in_spec.type]
443
+ end
444
+
445
+ def get_mutate_in_spec_flags(mutate_in_spec)
446
+ Generated::KV::V1::MutateInRequest::Spec::Flags.new(
447
+ create_path: mutate_in_spec.create_path?,
448
+ xattr: mutate_in_spec.xattr?
449
+ )
450
+ end
451
+
452
+ def get_mutate_in_flags(options)
453
+ Generated::KV::V1::MutateInRequest::Flags.new(
454
+ access_deleted: options.access_deleted
455
+ )
456
+ end
457
+
458
+ def get_mutate_in_store_semantic(options)
459
+ MUTATE_IN_STORE_SEMANTIC_MAP[options.store_semantics]
460
+ end
461
+
462
+ def get_encoded(content, options)
463
+ if options.transcoder.nil?
464
+ encoded = content.to_s
465
+ flag = 0
466
+ else
467
+ encoded, flag = options.transcoder.encode(content)
468
+ end
469
+ [encoded, flag]
470
+ end
471
+ end
472
+ end
473
+ end
474
+ end