couchbase 3.7.0 → 3.8.1

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 (349) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/ext/CMakeLists.txt +4 -1
  4. data/ext/cache/extconf_include.rb +4 -3
  5. data/ext/cache/mozilla-ca-bundle.crt +66 -665
  6. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  7. data/ext/couchbase/CMakeLists.txt +26 -11
  8. data/ext/couchbase/cmake/APKBUILD.in +17 -1
  9. data/ext/couchbase/cmake/Bundler.cmake +9 -1
  10. data/ext/couchbase/cmake/Cache.cmake +48 -19
  11. data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
  12. data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
  13. data/ext/couchbase/cmake/Packaging.cmake +48 -8
  14. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
  15. data/ext/couchbase/cmake/build_config.hxx.in +2 -0
  16. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
  17. data/ext/couchbase/cmake/tarball_glob.txt +10 -0
  18. data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
  19. data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
  20. data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
  21. data/ext/couchbase/core/bucket.cxx +128 -13
  22. data/ext/couchbase/core/bucket.hxx +12 -2
  23. data/ext/couchbase/core/cluster.cxx +304 -152
  24. data/ext/couchbase/core/cluster.hxx +32 -0
  25. data/ext/couchbase/core/cluster_credentials.cxx +25 -0
  26. data/ext/couchbase/core/cluster_credentials.hxx +5 -0
  27. data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
  28. data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
  29. data/ext/couchbase/core/cluster_options.hxx +4 -0
  30. data/ext/couchbase/core/deprecation_utils.hxx +26 -0
  31. data/ext/couchbase/core/error.hxx +27 -0
  32. data/ext/couchbase/core/error_context/base_error_context.hxx +32 -0
  33. data/ext/couchbase/core/error_context/key_value.cxx +1 -0
  34. data/ext/couchbase/core/error_context/key_value.hxx +23 -0
  35. data/ext/couchbase/core/error_context/key_value_error_context.hxx +35 -0
  36. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +41 -0
  37. data/ext/couchbase/core/free_form_http_request.hxx +0 -2
  38. data/ext/couchbase/core/http_component.cxx +12 -48
  39. data/ext/couchbase/core/impl/analytics.cxx +3 -2
  40. data/ext/couchbase/core/impl/analytics.hxx +2 -1
  41. data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
  42. data/ext/couchbase/core/impl/binary_collection.cxx +239 -128
  43. data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
  44. data/ext/couchbase/core/impl/collection.cxx +914 -372
  45. data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
  46. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
  47. data/ext/couchbase/core/impl/error.cxx +49 -17
  48. data/ext/couchbase/core/impl/error.hxx +15 -10
  49. data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
  50. data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
  51. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  52. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +44 -0
  53. data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
  54. data/ext/couchbase/core/impl/node_id.cxx +110 -0
  55. data/ext/couchbase/core/impl/node_id.hxx +40 -0
  56. data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
  57. data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
  58. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  59. data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
  60. data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
  61. data/ext/couchbase/core/impl/query.cxx +6 -3
  62. data/ext/couchbase/core/impl/query.hxx +3 -1
  63. data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
  64. data/ext/couchbase/core/impl/scope.cxx +53 -11
  65. data/ext/couchbase/core/impl/search.cxx +8 -4
  66. data/ext/couchbase/core/impl/search.hxx +6 -2
  67. data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
  68. data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
  69. data/ext/couchbase/core/io/config_tracker.cxx +9 -9
  70. data/ext/couchbase/core/io/config_tracker.hxx +2 -1
  71. data/ext/couchbase/core/io/http_command.hxx +98 -49
  72. data/ext/couchbase/core/io/http_context.hxx +2 -0
  73. data/ext/couchbase/core/io/http_session.cxx +23 -10
  74. data/ext/couchbase/core/io/http_session.hxx +17 -9
  75. data/ext/couchbase/core/io/http_session_manager.hxx +245 -270
  76. data/ext/couchbase/core/io/http_traits.hxx +0 -7
  77. data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
  78. data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
  79. data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
  80. data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
  81. data/ext/couchbase/core/io/streams.cxx +3 -3
  82. data/ext/couchbase/core/io/streams.hxx +3 -2
  83. data/ext/couchbase/core/meta/features.hxx +15 -0
  84. data/ext/couchbase/core/meta/version.cxx +13 -0
  85. data/ext/couchbase/core/meta/version.hxx +3 -0
  86. data/ext/couchbase/core/metrics/constants.hxx +23 -0
  87. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
  88. data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
  89. data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
  90. data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
  91. data/ext/couchbase/core/operations/document_append.hxx +0 -4
  92. data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
  93. data/ext/couchbase/core/operations/document_exists.hxx +0 -7
  94. data/ext/couchbase/core/operations/document_get.hxx +0 -7
  95. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +89 -29
  96. data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
  97. data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
  98. data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
  99. data/ext/couchbase/core/operations/document_get_projected.cxx +3 -4
  100. data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
  101. data/ext/couchbase/core/operations/document_increment.hxx +0 -5
  102. data/ext/couchbase/core/operations/document_insert.hxx +0 -4
  103. data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
  104. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +50 -4
  105. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
  106. data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
  107. data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
  108. data/ext/couchbase/core/operations/document_query.cxx +12 -12
  109. data/ext/couchbase/core/operations/document_query.hxx +0 -4
  110. data/ext/couchbase/core/operations/document_remove.hxx +0 -4
  111. data/ext/couchbase/core/operations/document_replace.hxx +0 -4
  112. data/ext/couchbase/core/operations/document_search.hxx +0 -7
  113. data/ext/couchbase/core/operations/document_touch.hxx +0 -7
  114. data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
  115. data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
  116. data/ext/couchbase/core/operations/document_view.cxx +2 -0
  117. data/ext/couchbase/core/operations/document_view.hxx +10 -13
  118. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  119. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
  120. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
  121. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
  122. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
  123. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
  124. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  125. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
  126. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
  127. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
  129. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
  130. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
  131. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
  132. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
  133. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
  134. data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
  135. data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
  136. data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
  137. data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
  138. data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
  139. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
  141. data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
  142. data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
  143. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
  144. data/ext/couchbase/core/operations/management/collection_create.cxx +11 -11
  145. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  146. data/ext/couchbase/core/operations/management/collection_drop.cxx +11 -11
  147. data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
  148. data/ext/couchbase/core/operations/management/collection_update.cxx +11 -11
  149. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  150. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  151. data/ext/couchbase/core/operations/management/error_utils.cxx +13 -7
  152. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
  153. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
  154. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
  155. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
  156. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
  157. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
  158. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
  159. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
  160. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
  161. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  162. data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
  163. data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
  164. data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
  165. data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
  166. data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
  167. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
  168. data/ext/couchbase/core/operations/management/query_index_create.cxx +5 -4
  169. data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
  170. data/ext/couchbase/core/operations/management/query_index_drop.cxx +7 -6
  171. data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
  173. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
  174. data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
  175. data/ext/couchbase/core/operations/management/scope_create.cxx +12 -13
  176. data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/scope_drop.cxx +8 -9
  178. data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
  179. data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
  180. data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
  181. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
  182. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
  183. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
  184. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
  185. data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
  186. data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
  187. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
  188. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  189. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
  190. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
  191. data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
  192. data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
  193. data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
  194. data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
  195. data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
  196. data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
  197. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  198. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
  199. data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
  200. data/ext/couchbase/core/operations.hxx +0 -1
  201. data/ext/couchbase/core/operations_fwd.hxx +8 -0
  202. data/ext/couchbase/core/origin.cxx +67 -12
  203. data/ext/couchbase/core/origin.hxx +13 -8
  204. data/ext/couchbase/core/orphan_reporter.cxx +164 -0
  205. data/ext/couchbase/core/orphan_reporter.hxx +65 -0
  206. data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
  207. data/ext/couchbase/core/sasl/client.cc +6 -0
  208. data/ext/couchbase/core/sasl/mechanism.cc +2 -1
  209. data/ext/couchbase/core/sasl/mechanism.h +2 -1
  210. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
  211. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
  212. data/ext/couchbase/core/tls_context_provider.cxx +44 -0
  213. data/ext/couchbase/core/tls_context_provider.hxx +44 -0
  214. data/ext/couchbase/core/topology/configuration.cxx +21 -0
  215. data/ext/couchbase/core/topology/configuration.hxx +28 -0
  216. data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
  217. data/ext/couchbase/core/tracing/constants.hxx +148 -68
  218. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
  219. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
  220. data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
  221. data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
  222. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
  223. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
  224. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
  225. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
  226. data/ext/couchbase/core/transactions/transactions.cxx +1 -1
  227. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
  228. data/ext/couchbase/core/utils/byteswap.hxx +12 -0
  229. data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
  230. data/ext/couchbase/core/utils/connection_string.cxx +2 -0
  231. data/ext/couchbase/core/utils/contains_string.cxx +61 -0
  232. data/ext/couchbase/core/utils/contains_string.hxx +26 -0
  233. data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
  234. data/ext/couchbase/couchbase/cluster.hxx +47 -0
  235. data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
  236. data/ext/couchbase/couchbase/collection.hxx +133 -15
  237. data/ext/couchbase/couchbase/error.hxx +16 -0
  238. data/ext/couchbase/couchbase/error_codes.hxx +48 -48
  239. data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
  240. data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
  241. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
  242. data/ext/couchbase/couchbase/network_options.hxx +19 -0
  243. data/ext/couchbase/couchbase/node_id.hxx +123 -0
  244. data/ext/couchbase/couchbase/node_id_for_options.hxx +61 -0
  245. data/ext/couchbase/couchbase/node_ids_options.hxx +62 -0
  246. data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
  247. data/ext/couchbase/couchbase/result.hxx +42 -0
  248. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
  249. data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
  250. data/ext/couchbase.cxx +4 -0
  251. data/ext/extconf.rb +1 -0
  252. data/ext/rcb_analytics.cxx +157 -47
  253. data/ext/rcb_backend.cxx +118 -71
  254. data/ext/rcb_buckets.cxx +39 -16
  255. data/ext/rcb_collections.cxx +36 -12
  256. data/ext/rcb_crud.cxx +589 -294
  257. data/ext/rcb_hdr_histogram.cxx +219 -0
  258. data/ext/rcb_hdr_histogram.hxx +28 -0
  259. data/ext/rcb_logger.cxx +15 -17
  260. data/ext/rcb_multi.cxx +142 -59
  261. data/ext/rcb_observability.cxx +132 -0
  262. data/ext/rcb_observability.hxx +49 -0
  263. data/ext/rcb_query.cxx +77 -27
  264. data/ext/rcb_search.cxx +92 -31
  265. data/ext/rcb_users.cxx +69 -26
  266. data/ext/rcb_utils.cxx +91 -0
  267. data/ext/rcb_utils.hxx +141 -168
  268. data/ext/rcb_views.cxx +36 -12
  269. data/lib/active_support/cache/couchbase_store.rb +6 -6
  270. data/lib/couchbase/authenticator.rb +14 -0
  271. data/lib/couchbase/binary_collection.rb +37 -22
  272. data/lib/couchbase/bucket.rb +46 -31
  273. data/lib/couchbase/cluster.rb +146 -61
  274. data/lib/couchbase/collection.rb +257 -186
  275. data/lib/couchbase/datastructures/couchbase_list.rb +82 -50
  276. data/lib/couchbase/datastructures/couchbase_map.rb +87 -50
  277. data/lib/couchbase/datastructures/couchbase_queue.rb +65 -38
  278. data/lib/couchbase/datastructures/couchbase_set.rb +58 -41
  279. data/lib/couchbase/deprecations.rb +1 -1
  280. data/lib/couchbase/diagnostics.rb +8 -8
  281. data/lib/couchbase/errors.rb +7 -1
  282. data/lib/couchbase/json_transcoder.rb +1 -1
  283. data/lib/couchbase/management/analytics_index_manager.rb +90 -59
  284. data/lib/couchbase/management/bucket_manager.rb +73 -45
  285. data/lib/couchbase/management/collection_manager.rb +86 -43
  286. data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
  287. data/lib/couchbase/management/query_index_manager.rb +88 -36
  288. data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
  289. data/lib/couchbase/management/search_index_manager.rb +401 -178
  290. data/lib/couchbase/management/user_manager.rb +343 -174
  291. data/lib/couchbase/management/view_index_manager.rb +166 -73
  292. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  293. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  294. data/lib/couchbase/metrics/meter.rb +27 -0
  295. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  296. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  297. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  298. data/lib/couchbase/options.rb +71 -5
  299. data/lib/couchbase/protostellar/client.rb +0 -2
  300. data/lib/couchbase/protostellar/cluster.rb +7 -0
  301. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
  302. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
  303. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +5 -24
  304. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +16 -0
  305. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +5 -24
  306. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +16 -0
  307. data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +5 -24
  308. data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +18 -0
  309. data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +2 -23
  310. data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +23 -0
  311. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +4 -25
  312. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +10 -0
  313. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +6 -25
  314. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +18 -0
  315. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
  316. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
  317. data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +3 -26
  318. data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +47 -0
  319. data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +4 -26
  320. data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +10 -0
  321. data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
  322. data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
  323. data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +5 -26
  324. data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +11 -0
  325. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +2 -23
  326. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +30 -0
  327. data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +2 -23
  328. data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +9 -0
  329. data/lib/couchbase/protostellar/request_generator/admin/collection.rb +4 -2
  330. data/lib/couchbase/protostellar/request_generator/admin/query.rb +2 -0
  331. data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
  332. data/lib/couchbase/protostellar/scope.rb +4 -0
  333. data/lib/couchbase/scope.rb +62 -48
  334. data/lib/couchbase/search_options.rb +18 -18
  335. data/lib/couchbase/tracing/noop_span.rb +29 -0
  336. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  337. data/lib/couchbase/tracing/request_span.rb +34 -0
  338. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  339. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  340. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  341. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  342. data/lib/couchbase/utils/observability.rb +263 -0
  343. data/lib/couchbase/utils/observability_constants.rb +200 -0
  344. data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
  345. data/lib/couchbase/version.rb +1 -1
  346. data/lib/couchbase.rb +2 -2
  347. metadata +72 -8
  348. data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +0 -52
  349. data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +0 -30
data/ext/rcb_crud.cxx CHANGED
@@ -17,6 +17,8 @@
17
17
 
18
18
  #include <core/cluster.hxx>
19
19
  #include <core/impl/subdoc/path_flags.hxx>
20
+ #include <core/operations/document_append.hxx>
21
+ #include <core/operations/document_decrement.hxx>
20
22
  #include <core/operations/document_exists.hxx>
21
23
  #include <core/operations/document_get.hxx>
22
24
  #include <core/operations/document_get_all_replicas.hxx>
@@ -24,11 +26,18 @@
24
26
  #include <core/operations/document_get_and_touch.hxx>
25
27
  #include <core/operations/document_get_any_replica.hxx>
26
28
  #include <core/operations/document_get_projected.hxx>
29
+ #include <core/operations/document_increment.hxx>
30
+ #include <core/operations/document_insert.hxx>
27
31
  #include <core/operations/document_lookup_in.hxx>
28
32
  #include <core/operations/document_lookup_in_all_replicas.hxx>
29
33
  #include <core/operations/document_lookup_in_any_replica.hxx>
34
+ #include <core/operations/document_mutate_in.hxx>
35
+ #include <core/operations/document_prepend.hxx>
36
+ #include <core/operations/document_remove.hxx>
37
+ #include <core/operations/document_replace.hxx>
30
38
  #include <core/operations/document_touch.hxx>
31
39
  #include <core/operations/document_unlock.hxx>
40
+ #include <core/operations/document_upsert.hxx>
32
41
  #include <core/utils/json.hxx>
33
42
 
34
43
  #include <couchbase/cluster.hxx>
@@ -41,6 +50,7 @@
41
50
  #include <ruby.h>
42
51
 
43
52
  #include "rcb_backend.hxx"
53
+ #include "rcb_observability.hxx"
44
54
  #include "rcb_utils.hxx"
45
55
 
46
56
  namespace couchbase
@@ -77,7 +87,8 @@ cb_Backend_document_get(VALUE self,
77
87
  VALUE scope,
78
88
  VALUE collection,
79
89
  VALUE id,
80
- VALUE options)
90
+ VALUE options,
91
+ VALUE observability_handler)
81
92
  {
82
93
  auto cluster = cb_backend_to_core_api_cluster(self);
83
94
 
@@ -96,12 +107,16 @@ cb_Backend_document_get(VALUE self,
96
107
 
97
108
  core::operations::get_request req{ doc_id };
98
109
  cb_extract_timeout(req, options);
110
+
111
+ auto parent_span = cb_create_parent_span(req, self);
112
+
99
113
  std::promise<core::operations::get_response> promise;
100
114
  auto f = promise.get_future();
101
115
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
102
116
  promise.set_value(std::forward<decltype(resp)>(resp));
103
117
  });
104
118
  auto resp = cb_wait_for_future(f);
119
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
105
120
  if (resp.ctx.ec()) {
106
121
  cb_throw_error(resp.ctx, "unable to fetch document");
107
122
  }
@@ -126,7 +141,8 @@ cb_Backend_document_get_any_replica(VALUE self,
126
141
  VALUE scope,
127
142
  VALUE collection,
128
143
  VALUE id,
129
- VALUE options)
144
+ VALUE options,
145
+ VALUE observability_handler)
130
146
  {
131
147
  auto cluster = cb_backend_to_core_api_cluster(self);
132
148
 
@@ -147,12 +163,15 @@ cb_Backend_document_get_any_replica(VALUE self,
147
163
  cb_extract_timeout(req, options);
148
164
  cb_extract_read_preference(req, options);
149
165
 
166
+ auto parent_span = cb_create_parent_span(req, self);
167
+
150
168
  std::promise<core::operations::get_any_replica_response> promise;
151
169
  auto f = promise.get_future();
152
170
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
153
171
  promise.set_value(std::forward<decltype(resp)>(resp));
154
172
  });
155
173
  auto resp = cb_wait_for_future(f);
174
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
156
175
  if (resp.ctx.ec()) {
157
176
  cb_throw_error(resp.ctx, "unable to get replica of the document");
158
177
  }
@@ -178,7 +197,8 @@ cb_Backend_document_get_all_replicas(VALUE self,
178
197
  VALUE scope,
179
198
  VALUE collection,
180
199
  VALUE id,
181
- VALUE options)
200
+ VALUE options,
201
+ VALUE observability_handler)
182
202
  {
183
203
  auto cluster = cb_backend_to_core_api_cluster(self);
184
204
 
@@ -199,12 +219,15 @@ cb_Backend_document_get_all_replicas(VALUE self,
199
219
  cb_extract_timeout(req, options);
200
220
  cb_extract_read_preference(req, options);
201
221
 
222
+ auto parent_span = cb_create_parent_span(req, self);
223
+
202
224
  std::promise<core::operations::get_all_replicas_response> promise;
203
225
  auto f = promise.get_future();
204
226
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
205
227
  promise.set_value(std::forward<decltype(resp)>(resp));
206
228
  });
207
229
  auto resp = cb_wait_for_future(f);
230
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
208
231
  if (resp.ctx.ec()) {
209
232
  cb_throw_error(resp.ctx, "unable to get all replicas for the document");
210
233
  }
@@ -235,7 +258,8 @@ cb_Backend_document_get_projected(VALUE self,
235
258
  VALUE scope,
236
259
  VALUE collection,
237
260
  VALUE id,
238
- VALUE options)
261
+ VALUE options,
262
+ VALUE observability_handler)
239
263
  {
240
264
  auto cluster = cb_backend_to_core_api_cluster(self);
241
265
 
@@ -257,6 +281,7 @@ cb_Backend_document_get_projected(VALUE self,
257
281
 
258
282
  core::operations::get_projected_request req{ doc_id };
259
283
  cb_extract_timeout(req, options);
284
+ auto parent_span = cb_create_parent_span(req, self);
260
285
  cb_extract_option_bool(req.with_expiry, options, "with_expiry");
261
286
  cb_extract_option_bool(req.preserve_array_indexes, options, "preserve_array_indexes");
262
287
  VALUE projections = Qnil;
@@ -280,6 +305,7 @@ cb_Backend_document_get_projected(VALUE self,
280
305
  promise.set_value(std::forward<decltype(resp)>(resp));
281
306
  });
282
307
  auto resp = cb_wait_for_future(f);
308
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
283
309
  if (resp.ctx.ec()) {
284
310
  cb_throw_error(resp.ctx, "unable fetch with projections");
285
311
  }
@@ -308,7 +334,8 @@ cb_Backend_document_get_and_lock(VALUE self,
308
334
  VALUE collection,
309
335
  VALUE id,
310
336
  VALUE lock_time,
311
- VALUE options)
337
+ VALUE options,
338
+ VALUE observability_handler)
312
339
  {
313
340
  auto cluster = cb_backend_to_core_api_cluster(self);
314
341
 
@@ -333,12 +360,15 @@ cb_Backend_document_get_and_lock(VALUE self,
333
360
  cb_extract_timeout(req, options);
334
361
  req.lock_time = NUM2UINT(lock_time);
335
362
 
363
+ auto parent_span = cb_create_parent_span(req, self);
364
+
336
365
  std::promise<core::operations::get_and_lock_response> promise;
337
366
  auto f = promise.get_future();
338
367
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
339
368
  promise.set_value(std::forward<decltype(resp)>(resp));
340
369
  });
341
370
  auto resp = cb_wait_for_future(f);
371
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
342
372
  if (resp.ctx.ec()) {
343
373
  cb_throw_error(resp.ctx, "unable lock and fetch");
344
374
  }
@@ -364,7 +394,8 @@ cb_Backend_document_get_and_touch(VALUE self,
364
394
  VALUE collection,
365
395
  VALUE id,
366
396
  VALUE expiry,
367
- VALUE options)
397
+ VALUE options,
398
+ VALUE observability_handler)
368
399
  {
369
400
  auto cluster = cb_backend_to_core_api_cluster(self);
370
401
 
@@ -389,12 +420,15 @@ cb_Backend_document_get_and_touch(VALUE self,
389
420
  auto [type, duration] = unpack_expiry(expiry, false);
390
421
  req.expiry = static_cast<std::uint32_t>(duration.count());
391
422
 
423
+ auto parent_span = cb_create_parent_span(req, self);
424
+
392
425
  std::promise<core::operations::get_and_touch_response> promise;
393
426
  auto f = promise.get_future();
394
427
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
395
428
  promise.set_value(std::forward<decltype(resp)>(resp));
396
429
  });
397
430
  auto resp = cb_wait_for_future(f);
431
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
398
432
  if (resp.ctx.ec()) {
399
433
  cb_throw_error(resp.ctx, "unable fetch and touch");
400
434
  }
@@ -420,7 +454,8 @@ cb_Backend_document_touch(VALUE self,
420
454
  VALUE collection,
421
455
  VALUE id,
422
456
  VALUE expiry,
423
- VALUE options)
457
+ VALUE options,
458
+ VALUE observability_handler)
424
459
  {
425
460
  auto cluster = cb_backend_to_core_api_cluster(self);
426
461
 
@@ -445,12 +480,15 @@ cb_Backend_document_touch(VALUE self,
445
480
  auto [type, duration] = unpack_expiry(expiry, false);
446
481
  req.expiry = static_cast<std::uint32_t>(duration.count());
447
482
 
483
+ auto parent_span = cb_create_parent_span(req, self);
484
+
448
485
  std::promise<core::operations::touch_response> promise;
449
486
  auto f = promise.get_future();
450
487
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
451
488
  promise.set_value(std::forward<decltype(resp)>(resp));
452
489
  });
453
490
  auto resp = cb_wait_for_future(f);
491
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
454
492
  if (resp.ctx.ec()) {
455
493
  cb_throw_error(resp.ctx, "unable to touch");
456
494
  }
@@ -473,7 +511,8 @@ cb_Backend_document_exists(VALUE self,
473
511
  VALUE scope,
474
512
  VALUE collection,
475
513
  VALUE id,
476
- VALUE options)
514
+ VALUE options,
515
+ VALUE observability_handler)
477
516
  {
478
517
  auto cluster = cb_backend_to_core_api_cluster(self);
479
518
 
@@ -496,12 +535,15 @@ cb_Backend_document_exists(VALUE self,
496
535
  core::operations::exists_request req{ doc_id };
497
536
  cb_extract_timeout(req, options);
498
537
 
538
+ auto parent_span = cb_create_parent_span(req, self);
539
+
499
540
  std::promise<core::operations::exists_response> promise;
500
541
  auto f = promise.get_future();
501
542
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
502
543
  promise.set_value(std::forward<decltype(resp)>(resp));
503
544
  });
504
545
  auto resp = cb_wait_for_future(f);
546
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
505
547
  if (resp.ctx.ec() && resp.ctx.ec() != couchbase::errc::key_value::document_not_found) {
506
548
  cb_throw_error(resp.ctx, "unable to exists");
507
549
  }
@@ -531,11 +573,13 @@ cb_Backend_document_unlock(VALUE self,
531
573
  VALUE collection,
532
574
  VALUE id,
533
575
  VALUE cas,
534
- VALUE options)
576
+ VALUE options,
577
+ VALUE observability_handler)
535
578
  {
536
579
  auto cluster = cb_backend_to_core_api_cluster(self);
537
580
 
538
581
  Check_Type(bucket, T_STRING);
582
+ Check_Type(scope, T_STRING);
539
583
  Check_Type(collection, T_STRING);
540
584
  Check_Type(id, T_STRING);
541
585
  if (!NIL_P(options)) {
@@ -548,19 +592,21 @@ cb_Backend_document_unlock(VALUE self,
548
592
  cb_string_new(scope),
549
593
  cb_string_new(collection),
550
594
  cb_string_new(id),
551
-
552
595
  };
553
596
 
554
597
  core::operations::unlock_request req{ doc_id };
555
598
  cb_extract_timeout(req, options);
556
599
  cb_extract_cas(req.cas, cas);
557
600
 
601
+ auto parent_span = cb_create_parent_span(req, self);
602
+
558
603
  std::promise<core::operations::unlock_response> promise;
559
604
  auto f = promise.get_future();
560
605
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
561
606
  promise.set_value(std::forward<decltype(resp)>(resp));
562
607
  });
563
608
  auto resp = cb_wait_for_future(f);
609
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
564
610
  if (resp.ctx.ec()) {
565
611
  cb_throw_error(resp.ctx, "unable to unlock");
566
612
  }
@@ -585,9 +631,10 @@ cb_Backend_document_upsert(VALUE self,
585
631
  VALUE id,
586
632
  VALUE content,
587
633
  VALUE flags,
588
- VALUE options)
634
+ VALUE options,
635
+ VALUE observability_handler)
589
636
  {
590
- auto cluster = cb_backend_to_public_api_cluster(self);
637
+ auto cluster = cb_backend_to_core_api_cluster(self);
591
638
 
592
639
  Check_Type(bucket, T_STRING);
593
640
  Check_Type(scope, T_STRING);
@@ -600,25 +647,51 @@ cb_Backend_document_upsert(VALUE self,
600
647
  }
601
648
 
602
649
  try {
603
- couchbase::upsert_options opts;
604
- set_timeout(opts, options);
605
- set_expiry(opts, options);
606
- set_durability(opts, options);
607
- set_preserve_expiry(opts, options);
608
-
609
- auto f = cluster.bucket(cb_string_new(bucket))
610
- .scope(cb_string_new(scope))
611
- .collection(cb_string_new(collection))
612
- .upsert(cb_string_new(id),
613
- couchbase::codec::encoded_value{ cb_binary_new(content), FIX2UINT(flags) },
614
- opts);
615
-
616
- auto [ctx, resp] = cb_wait_for_future(f);
617
- if (ctx.ec()) {
618
- cb_throw_error(ctx, "unable to upsert");
650
+ core::operations::upsert_request req{
651
+ core::document_id{
652
+ cb_string_new(bucket),
653
+ cb_string_new(scope),
654
+ cb_string_new(collection),
655
+ cb_string_new(id),
656
+ },
657
+ };
658
+ cb_extract_content(req, content);
659
+ cb_extract_flags(req, flags);
660
+ cb_extract_timeout(req, options);
661
+ cb_extract_expiry(req, options);
662
+ cb_extract_durability_level(req, options);
663
+ cb_extract_preserve_expiry(req, options);
664
+
665
+ auto parent_span = cb_create_parent_span(req, self);
666
+
667
+ std::promise<core::operations::upsert_response> promise;
668
+ auto f = promise.get_future();
669
+
670
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
671
+ legacy_durability.has_value()) {
672
+ cluster.execute(
673
+ core::operations::upsert_request_with_legacy_durability{
674
+ std::move(req),
675
+ legacy_durability.value().first,
676
+ legacy_durability.value().second,
677
+ },
678
+ [promise = std::move(promise)](auto&& resp) mutable {
679
+ promise.set_value(std::forward<decltype(resp)>(resp));
680
+ });
681
+ } else {
682
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
683
+ promise.set_value(std::forward<decltype(resp)>(resp));
684
+ });
619
685
  }
620
686
 
621
- return to_mutation_result_value(resp);
687
+ auto resp = cb_wait_for_future(f);
688
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
689
+ if (resp.ctx.ec()) {
690
+ cb_throw_error(resp.ctx, "unable to upsert");
691
+ }
692
+
693
+ return cb_create_mutation_result(resp);
694
+
622
695
  } catch (const std::system_error& se) {
623
696
  rb_exc_raise(cb_map_error_code(
624
697
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -635,9 +708,10 @@ cb_Backend_document_append(VALUE self,
635
708
  VALUE collection,
636
709
  VALUE id,
637
710
  VALUE content,
638
- VALUE options)
711
+ VALUE options,
712
+ VALUE observability_handler)
639
713
  {
640
- auto cluster = cb_backend_to_public_api_cluster(self);
714
+ auto cluster = cb_backend_to_core_api_cluster(self);
641
715
 
642
716
  Check_Type(bucket, T_STRING);
643
717
  Check_Type(scope, T_STRING);
@@ -649,22 +723,49 @@ cb_Backend_document_append(VALUE self,
649
723
  }
650
724
 
651
725
  try {
652
- couchbase::append_options opts;
653
- set_timeout(opts, options);
654
- set_durability(opts, options);
655
-
656
- auto f = cluster.bucket(cb_string_new(bucket))
657
- .scope(cb_string_new(scope))
658
- .collection(cb_string_new(collection))
659
- .binary()
660
- .append(cb_string_new(id), cb_binary_new(content), opts);
661
-
662
- auto [ctx, resp] = cb_wait_for_future(f);
663
- if (ctx.ec()) {
664
- cb_throw_error(ctx, "unable to append");
726
+ core::operations::append_request req{
727
+ core::document_id{
728
+ cb_string_new(bucket),
729
+ cb_string_new(scope),
730
+ cb_string_new(collection),
731
+ cb_string_new(id),
732
+ },
733
+ };
734
+ cb_extract_content(req, content);
735
+ cb_extract_timeout(req, options);
736
+ cb_extract_durability_level(req, options);
737
+ cb_extract_cas(req, options);
738
+
739
+ auto parent_span = cb_create_parent_span(req, self);
740
+
741
+ std::promise<core::operations::append_response> promise;
742
+ auto f = promise.get_future();
743
+
744
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
745
+ legacy_durability.has_value()) {
746
+ cluster.execute(
747
+ core::operations::append_request_with_legacy_durability{
748
+ std::move(req),
749
+ legacy_durability.value().first,
750
+ legacy_durability.value().second,
751
+ },
752
+ [promise = std::move(promise)](auto&& resp) mutable {
753
+ promise.set_value(std::forward<decltype(resp)>(resp));
754
+ });
755
+ } else {
756
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
757
+ promise.set_value(std::forward<decltype(resp)>(resp));
758
+ });
665
759
  }
666
760
 
667
- return to_mutation_result_value(resp);
761
+ auto resp = cb_wait_for_future(f);
762
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
763
+ if (resp.ctx.ec()) {
764
+ cb_throw_error(resp.ctx, "unable to append");
765
+ }
766
+
767
+ return cb_create_mutation_result(resp);
768
+
668
769
  } catch (const std::system_error& se) {
669
770
  rb_exc_raise(cb_map_error_code(
670
771
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -681,9 +782,10 @@ cb_Backend_document_prepend(VALUE self,
681
782
  VALUE collection,
682
783
  VALUE id,
683
784
  VALUE content,
684
- VALUE options)
785
+ VALUE options,
786
+ VALUE observability_handler)
685
787
  {
686
- auto cluster = cb_backend_to_public_api_cluster(self);
788
+ auto cluster = cb_backend_to_core_api_cluster(self);
687
789
 
688
790
  Check_Type(bucket, T_STRING);
689
791
  Check_Type(scope, T_STRING);
@@ -695,22 +797,48 @@ cb_Backend_document_prepend(VALUE self,
695
797
  }
696
798
 
697
799
  try {
698
- couchbase::prepend_options opts;
699
- set_timeout(opts, options);
700
- set_durability(opts, options);
701
-
702
- auto f = cluster.bucket(cb_string_new(bucket))
703
- .scope(cb_string_new(scope))
704
- .collection(cb_string_new(collection))
705
- .binary()
706
- .prepend(cb_string_new(id), cb_binary_new(content), opts);
707
-
708
- auto [ctx, resp] = cb_wait_for_future(f);
709
- if (ctx.ec()) {
710
- cb_throw_error(ctx, "unable to prepend");
800
+ core::operations::prepend_request req{
801
+ core::document_id{
802
+ cb_string_new(bucket),
803
+ cb_string_new(scope),
804
+ cb_string_new(collection),
805
+ cb_string_new(id),
806
+ },
807
+ };
808
+ cb_extract_content(req, content);
809
+ cb_extract_timeout(req, options);
810
+ cb_extract_durability_level(req, options);
811
+ cb_extract_cas(req, options);
812
+
813
+ auto parent_span = cb_create_parent_span(req, self);
814
+
815
+ std::promise<core::operations::prepend_response> promise;
816
+ auto f = promise.get_future();
817
+
818
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
819
+ legacy_durability.has_value()) {
820
+ cluster.execute(
821
+ core::operations::prepend_request_with_legacy_durability{
822
+ std::move(req),
823
+ legacy_durability.value().first,
824
+ legacy_durability.value().second,
825
+ },
826
+ [promise = std::move(promise)](auto&& resp) mutable {
827
+ promise.set_value(std::forward<decltype(resp)>(resp));
828
+ });
829
+ } else {
830
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
831
+ promise.set_value(std::forward<decltype(resp)>(resp));
832
+ });
833
+ }
834
+
835
+ auto resp = cb_wait_for_future(f);
836
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
837
+ if (resp.ctx.ec()) {
838
+ cb_throw_error(resp.ctx, "unable to prepend");
711
839
  }
712
840
 
713
- return to_mutation_result_value(resp);
841
+ return cb_create_mutation_result(resp);
714
842
  } catch (const std::system_error& se) {
715
843
  rb_exc_raise(cb_map_error_code(
716
844
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -728,9 +856,10 @@ cb_Backend_document_replace(VALUE self,
728
856
  VALUE id,
729
857
  VALUE content,
730
858
  VALUE flags,
731
- VALUE options)
859
+ VALUE options,
860
+ VALUE observability_handler)
732
861
  {
733
- auto cluster = cb_backend_to_public_api_cluster(self);
862
+ auto cluster = cb_backend_to_core_api_cluster(self);
734
863
 
735
864
  Check_Type(bucket, T_STRING);
736
865
  Check_Type(scope, T_STRING);
@@ -743,26 +872,51 @@ cb_Backend_document_replace(VALUE self,
743
872
  }
744
873
 
745
874
  try {
746
- couchbase::replace_options opts;
747
- set_timeout(opts, options);
748
- set_expiry(opts, options);
749
- set_durability(opts, options);
750
- set_preserve_expiry(opts, options);
751
- set_cas(opts, options);
752
-
753
- auto f = cluster.bucket(cb_string_new(bucket))
754
- .scope(cb_string_new(scope))
755
- .collection(cb_string_new(collection))
756
- .replace(cb_string_new(id),
757
- couchbase::codec::encoded_value{ cb_binary_new(content), FIX2UINT(flags) },
758
- opts);
759
-
760
- auto [ctx, resp] = cb_wait_for_future(f);
761
- if (ctx.ec()) {
762
- cb_throw_error(ctx, "unable to replace");
875
+ core::operations::replace_request req{
876
+ core::document_id{
877
+ cb_string_new(bucket),
878
+ cb_string_new(scope),
879
+ cb_string_new(collection),
880
+ cb_string_new(id),
881
+ },
882
+ };
883
+ cb_extract_content(req, content);
884
+ cb_extract_flags(req, flags);
885
+ cb_extract_timeout(req, options);
886
+ cb_extract_expiry(req, options);
887
+ cb_extract_durability_level(req, options);
888
+ cb_extract_preserve_expiry(req, options);
889
+ cb_extract_cas(req, options);
890
+
891
+ auto parent_span = cb_create_parent_span(req, self);
892
+
893
+ std::promise<core::operations::replace_response> promise;
894
+ auto f = promise.get_future();
895
+
896
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
897
+ legacy_durability.has_value()) {
898
+ cluster.execute(
899
+ core::operations::replace_request_with_legacy_durability{
900
+ std::move(req),
901
+ legacy_durability.value().first,
902
+ legacy_durability.value().second,
903
+ },
904
+ [promise = std::move(promise)](auto&& resp) mutable {
905
+ promise.set_value(std::forward<decltype(resp)>(resp));
906
+ });
907
+ } else {
908
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
909
+ promise.set_value(std::forward<decltype(resp)>(resp));
910
+ });
763
911
  }
764
912
 
765
- return to_mutation_result_value(resp);
913
+ auto resp = cb_wait_for_future(f);
914
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
915
+ if (resp.ctx.ec()) {
916
+ cb_throw_error(resp.ctx, "unable to replace");
917
+ }
918
+ return cb_create_mutation_result(resp);
919
+
766
920
  } catch (const std::system_error& se) {
767
921
  rb_exc_raise(cb_map_error_code(
768
922
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -780,9 +934,10 @@ cb_Backend_document_insert(VALUE self,
780
934
  VALUE id,
781
935
  VALUE content,
782
936
  VALUE flags,
783
- VALUE options)
937
+ VALUE options,
938
+ VALUE observability_handler)
784
939
  {
785
- auto cluster = cb_backend_to_public_api_cluster(self);
940
+ auto cluster = cb_backend_to_core_api_cluster(self);
786
941
 
787
942
  Check_Type(bucket, T_STRING);
788
943
  Check_Type(scope, T_STRING);
@@ -795,24 +950,48 @@ cb_Backend_document_insert(VALUE self,
795
950
  }
796
951
 
797
952
  try {
798
- couchbase::insert_options opts;
799
- set_timeout(opts, options);
800
- set_expiry(opts, options);
801
- set_durability(opts, options);
802
-
803
- auto f = cluster.bucket(cb_string_new(bucket))
804
- .scope(cb_string_new(scope))
805
- .collection(cb_string_new(collection))
806
- .insert(cb_string_new(id),
807
- couchbase::codec::encoded_value{ cb_binary_new(content), FIX2UINT(flags) },
808
- opts);
809
-
810
- auto [ctx, resp] = cb_wait_for_future(f);
811
- if (ctx.ec()) {
812
- cb_throw_error(ctx, "unable to insert");
953
+ core::operations::insert_request req{
954
+ core::document_id{
955
+ cb_string_new(bucket),
956
+ cb_string_new(scope),
957
+ cb_string_new(collection),
958
+ cb_string_new(id),
959
+ },
960
+ };
961
+ cb_extract_content(req, content);
962
+ cb_extract_flags(req, flags);
963
+ cb_extract_timeout(req, options);
964
+ cb_extract_expiry(req, options);
965
+ cb_extract_durability_level(req, options);
966
+
967
+ auto parent_span = cb_create_parent_span(req, self);
968
+
969
+ std::promise<core::operations::insert_response> promise;
970
+ auto f = promise.get_future();
971
+
972
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
973
+ legacy_durability.has_value()) {
974
+ cluster.execute(
975
+ core::operations::insert_request_with_legacy_durability{
976
+ std::move(req),
977
+ legacy_durability.value().first,
978
+ legacy_durability.value().second,
979
+ },
980
+ [promise = std::move(promise)](auto&& resp) mutable {
981
+ promise.set_value(std::forward<decltype(resp)>(resp));
982
+ });
983
+ } else {
984
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
985
+ promise.set_value(std::forward<decltype(resp)>(resp));
986
+ });
987
+ }
988
+ auto resp = cb_wait_for_future(f);
989
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
990
+ if (resp.ctx.ec()) {
991
+ cb_throw_error(resp.ctx, "unable to insert");
813
992
  }
993
+ return cb_create_mutation_result(resp);
814
994
 
815
- return to_mutation_result_value(resp);
816
995
  } catch (const std::system_error& se) {
817
996
  rb_exc_raise(cb_map_error_code(
818
997
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -828,9 +1007,10 @@ cb_Backend_document_remove(VALUE self,
828
1007
  VALUE scope,
829
1008
  VALUE collection,
830
1009
  VALUE id,
831
- VALUE options)
1010
+ VALUE options,
1011
+ VALUE observability_handler)
832
1012
  {
833
- auto cluster = cb_backend_to_public_api_cluster(self);
1013
+ auto cluster = cb_backend_to_core_api_cluster(self);
834
1014
 
835
1015
  Check_Type(bucket, T_STRING);
836
1016
  Check_Type(scope, T_STRING);
@@ -841,22 +1021,46 @@ cb_Backend_document_remove(VALUE self,
841
1021
  }
842
1022
 
843
1023
  try {
844
- couchbase::remove_options opts;
845
- set_timeout(opts, options);
846
- set_durability(opts, options);
847
- set_cas(opts, options);
848
-
849
- auto f = cluster.bucket(cb_string_new(bucket))
850
- .scope(cb_string_new(scope))
851
- .collection(cb_string_new(collection))
852
- .remove(cb_string_new(id), opts);
853
-
854
- auto [ctx, resp] = cb_wait_for_future(f);
855
- if (ctx.ec()) {
856
- cb_throw_error(ctx, "unable to remove");
1024
+ core::operations::remove_request req{
1025
+ core::document_id{
1026
+ cb_string_new(bucket),
1027
+ cb_string_new(scope),
1028
+ cb_string_new(collection),
1029
+ cb_string_new(id),
1030
+ },
1031
+ };
1032
+ cb_extract_timeout(req, options);
1033
+ cb_extract_durability_level(req, options);
1034
+ cb_extract_cas(req, options);
1035
+
1036
+ auto parent_span = cb_create_parent_span(req, self);
1037
+
1038
+ std::promise<core::operations::remove_response> promise;
1039
+ auto f = promise.get_future();
1040
+
1041
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
1042
+ legacy_durability.has_value()) {
1043
+ cluster.execute(
1044
+ core::operations::remove_request_with_legacy_durability{
1045
+ std::move(req),
1046
+ legacy_durability.value().first,
1047
+ legacy_durability.value().second,
1048
+ },
1049
+ [promise = std::move(promise)](auto&& resp) mutable {
1050
+ promise.set_value(std::forward<decltype(resp)>(resp));
1051
+ });
1052
+ } else {
1053
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
1054
+ promise.set_value(std::forward<decltype(resp)>(resp));
1055
+ });
857
1056
  }
858
1057
 
859
- return to_mutation_result_value(resp);
1058
+ auto resp = cb_wait_for_future(f);
1059
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1060
+ if (resp.ctx.ec()) {
1061
+ cb_throw_error(resp.ctx, "unable to remove");
1062
+ }
1063
+ return cb_create_mutation_result(resp);
860
1064
  } catch (const std::system_error& se) {
861
1065
  rb_exc_raise(cb_map_error_code(
862
1066
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -872,9 +1076,10 @@ cb_Backend_document_increment(VALUE self,
872
1076
  VALUE scope,
873
1077
  VALUE collection,
874
1078
  VALUE id,
875
- VALUE options)
1079
+ VALUE options,
1080
+ VALUE observability_handler)
876
1081
  {
877
- auto cluster = cb_backend_to_public_api_cluster(self);
1082
+ auto cluster = cb_backend_to_core_api_cluster(self);
878
1083
 
879
1084
  Check_Type(bucket, T_STRING);
880
1085
  Check_Type(scope, T_STRING);
@@ -885,27 +1090,53 @@ cb_Backend_document_increment(VALUE self,
885
1090
  }
886
1091
 
887
1092
  try {
888
- couchbase::increment_options opts;
889
- set_timeout(opts, options);
890
- set_durability(opts, options);
891
- set_expiry(opts, options);
892
- set_delta(opts, options);
893
- set_initial_value(opts, options);
894
-
895
- auto f = cluster.bucket(cb_string_new(bucket))
896
- .scope(cb_string_new(scope))
897
- .collection(cb_string_new(collection))
898
- .binary()
899
- .increment(cb_string_new(id), opts);
900
-
901
- auto [ctx, resp] = cb_wait_for_future(f);
902
- if (ctx.ec()) {
903
- cb_throw_error(ctx, "unable to increment");
1093
+ core::operations::increment_request req{
1094
+ core::document_id{
1095
+ cb_string_new(bucket),
1096
+ cb_string_new(scope),
1097
+ cb_string_new(collection),
1098
+ cb_string_new(id),
1099
+ },
1100
+ };
1101
+
1102
+ cb_extract_timeout(req, options);
1103
+ cb_extract_expiry(req, options);
1104
+ cb_extract_option_uint64(req.delta, options, "delta");
1105
+ cb_extract_option_uint64(req.initial_value, options, "initial_value");
1106
+ cb_extract_durability_level(req, options);
1107
+
1108
+ auto parent_span = cb_create_parent_span(req, self);
1109
+
1110
+ std::promise<core::operations::increment_response> promise;
1111
+ auto f = promise.get_future();
1112
+
1113
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
1114
+ legacy_durability.has_value()) {
1115
+ cluster.execute(
1116
+ core::operations::increment_request_with_legacy_durability{
1117
+ std::move(req),
1118
+ legacy_durability.value().first,
1119
+ legacy_durability.value().second,
1120
+ },
1121
+ [promise = std::move(promise)](auto&& resp) mutable {
1122
+ promise.set_value(std::forward<decltype(resp)>(resp));
1123
+ });
1124
+ } else {
1125
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
1126
+ promise.set_value(std::forward<decltype(resp)>(resp));
1127
+ });
1128
+ }
1129
+
1130
+ auto resp = cb_wait_for_future(f);
1131
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1132
+ if (resp.ctx.ec()) {
1133
+ cb_throw_error(resp.ctx, "unable to increment");
904
1134
  }
905
1135
 
906
- VALUE res = to_mutation_result_value(resp);
907
- rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content()));
1136
+ VALUE res = cb_create_mutation_result(resp);
1137
+ rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content));
908
1138
  return res;
1139
+
909
1140
  } catch (const std::system_error& se) {
910
1141
  rb_exc_raise(cb_map_error_code(
911
1142
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -921,9 +1152,10 @@ cb_Backend_document_decrement(VALUE self,
921
1152
  VALUE scope,
922
1153
  VALUE collection,
923
1154
  VALUE id,
924
- VALUE options)
1155
+ VALUE options,
1156
+ VALUE observability_handler)
925
1157
  {
926
- auto cluster = cb_backend_to_public_api_cluster(self);
1158
+ auto cluster = cb_backend_to_core_api_cluster(self);
927
1159
 
928
1160
  Check_Type(bucket, T_STRING);
929
1161
  Check_Type(scope, T_STRING);
@@ -934,26 +1166,51 @@ cb_Backend_document_decrement(VALUE self,
934
1166
  }
935
1167
 
936
1168
  try {
937
- couchbase::decrement_options opts;
938
- set_timeout(opts, options);
939
- set_durability(opts, options);
940
- set_expiry(opts, options);
941
- set_delta(opts, options);
942
- set_initial_value(opts, options);
943
-
944
- auto f = cluster.bucket(cb_string_new(bucket))
945
- .scope(cb_string_new(scope))
946
- .collection(cb_string_new(collection))
947
- .binary()
948
- .decrement(cb_string_new(id), opts);
949
-
950
- auto [ctx, resp] = cb_wait_for_future(f);
951
- if (ctx.ec()) {
952
- cb_throw_error(ctx, "unable to decrement");
1169
+ core::operations::decrement_request req{
1170
+ core::document_id{
1171
+ cb_string_new(bucket),
1172
+ cb_string_new(scope),
1173
+ cb_string_new(collection),
1174
+ cb_string_new(id),
1175
+ },
1176
+ };
1177
+
1178
+ cb_extract_timeout(req, options);
1179
+ cb_extract_expiry(req, options);
1180
+ cb_extract_option_uint64(req.delta, options, "delta");
1181
+ cb_extract_option_uint64(req.initial_value, options, "initial_value");
1182
+ cb_extract_durability_level(req, options);
1183
+
1184
+ auto parent_span = cb_create_parent_span(req, self);
1185
+
1186
+ std::promise<core::operations::decrement_response> promise;
1187
+ auto f = promise.get_future();
1188
+
1189
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
1190
+ legacy_durability.has_value()) {
1191
+ cluster.execute(
1192
+ core::operations::decrement_request_with_legacy_durability{
1193
+ std::move(req),
1194
+ legacy_durability.value().first,
1195
+ legacy_durability.value().second,
1196
+ },
1197
+ [promise = std::move(promise)](auto&& resp) mutable {
1198
+ promise.set_value(std::forward<decltype(resp)>(resp));
1199
+ });
1200
+ } else {
1201
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
1202
+ promise.set_value(std::forward<decltype(resp)>(resp));
1203
+ });
953
1204
  }
954
1205
 
955
- VALUE res = to_mutation_result_value(resp);
956
- rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content()));
1206
+ auto resp = cb_wait_for_future(f);
1207
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1208
+ if (resp.ctx.ec()) {
1209
+ cb_throw_error(resp.ctx, "unable to decrement");
1210
+ }
1211
+
1212
+ VALUE res = cb_create_mutation_result(resp);
1213
+ rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content));
957
1214
  return res;
958
1215
 
959
1216
  } catch (const std::system_error& se) {
@@ -972,7 +1229,8 @@ cb_Backend_document_lookup_in(VALUE self,
972
1229
  VALUE collection,
973
1230
  VALUE id,
974
1231
  VALUE specs,
975
- VALUE options)
1232
+ VALUE options,
1233
+ VALUE observability_handler)
976
1234
  {
977
1235
  auto cluster = cb_backend_to_core_api_cluster(self);
978
1236
 
@@ -1037,12 +1295,15 @@ cb_Backend_document_lookup_in(VALUE self,
1037
1295
  core::impl::subdoc::build_lookup_in_path_flags(xattr, false) });
1038
1296
  }
1039
1297
 
1298
+ auto parent_span = cb_create_parent_span(req, self);
1299
+
1040
1300
  std::promise<core::operations::lookup_in_response> promise;
1041
1301
  auto f = promise.get_future();
1042
1302
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
1043
1303
  promise.set_value(std::forward<decltype(resp)>(resp));
1044
1304
  });
1045
1305
  auto resp = cb_wait_for_future(f);
1306
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1046
1307
  if (resp.ctx.ec()) {
1047
1308
  cb_throw_error(resp.ctx, "unable to perform lookup_in operation");
1048
1309
  }
@@ -1098,7 +1359,8 @@ cb_Backend_document_lookup_in_any_replica(VALUE self,
1098
1359
  VALUE collection,
1099
1360
  VALUE id,
1100
1361
  VALUE specs,
1101
- VALUE options)
1362
+ VALUE options,
1363
+ VALUE observability_handler)
1102
1364
  {
1103
1365
 
1104
1366
  auto cluster = cb_backend_to_core_api_cluster(self);
@@ -1163,12 +1425,15 @@ cb_Backend_document_lookup_in_any_replica(VALUE self,
1163
1425
  core::impl::subdoc::build_lookup_in_path_flags(xattr, false) });
1164
1426
  }
1165
1427
 
1428
+ auto parent_span = cb_create_parent_span(req, self);
1429
+
1166
1430
  std::promise<core::operations::lookup_in_any_replica_response> promise;
1167
1431
  auto f = promise.get_future();
1168
1432
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
1169
1433
  promise.set_value(std::forward<decltype(resp)>(resp));
1170
1434
  });
1171
1435
  auto resp = cb_wait_for_future(f);
1436
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1172
1437
  if (resp.ctx.ec()) {
1173
1438
  cb_throw_error(resp.ctx, "unable to perform lookup_in_any_replica operation");
1174
1439
  }
@@ -1227,7 +1492,8 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self,
1227
1492
  VALUE collection,
1228
1493
  VALUE id,
1229
1494
  VALUE specs,
1230
- VALUE options)
1495
+ VALUE options,
1496
+ VALUE observability_handler)
1231
1497
  {
1232
1498
  auto cluster = cb_backend_to_core_api_cluster(self);
1233
1499
 
@@ -1292,12 +1558,16 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self,
1292
1558
  {},
1293
1559
  core::impl::subdoc::build_lookup_in_path_flags(xattr, false) });
1294
1560
  }
1561
+
1562
+ auto parent_span = cb_create_parent_span(req, self);
1563
+
1295
1564
  std::promise<core::operations::lookup_in_all_replicas_response> promise;
1296
1565
  auto f = promise.get_future();
1297
1566
  cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable {
1298
1567
  promise.set_value(std::forward<decltype(resp)>(resp));
1299
1568
  });
1300
1569
  auto resp = cb_wait_for_future(f);
1570
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1301
1571
  if (resp.ctx.ec()) {
1302
1572
  cb_throw_error(resp.ctx, "unable to perform lookup_in_all_replicas operation");
1303
1573
  }
@@ -1365,9 +1635,10 @@ cb_Backend_document_mutate_in(VALUE self,
1365
1635
  VALUE collection,
1366
1636
  VALUE id,
1367
1637
  VALUE specs,
1368
- VALUE options)
1638
+ VALUE options,
1639
+ VALUE observability_handler)
1369
1640
  {
1370
- auto cluster = cb_backend_to_public_api_cluster(self);
1641
+ auto cluster = cb_backend_to_core_api_cluster(self);
1371
1642
 
1372
1643
  Check_Type(bucket, T_STRING);
1373
1644
  Check_Type(scope, T_STRING);
@@ -1384,15 +1655,22 @@ cb_Backend_document_mutate_in(VALUE self,
1384
1655
  }
1385
1656
 
1386
1657
  try {
1387
- couchbase::mutate_in_options opts;
1388
- set_timeout(opts, options);
1389
- set_durability(opts, options);
1390
- set_expiry(opts, options);
1391
- set_preserve_expiry(opts, options);
1392
- set_access_deleted(opts, options);
1393
- set_create_as_deleted(opts, options);
1394
- set_cas(opts, options);
1395
- set_store_semantics(opts, options);
1658
+ core::operations::mutate_in_request req{
1659
+ core::document_id{
1660
+ cb_string_new(bucket),
1661
+ cb_string_new(scope),
1662
+ cb_string_new(collection),
1663
+ cb_string_new(id),
1664
+ },
1665
+ };
1666
+ cb_extract_timeout(req, options);
1667
+ cb_extract_durability_level(req, options);
1668
+ cb_extract_expiry(req, options);
1669
+ cb_extract_preserve_expiry(req, options);
1670
+ cb_extract_option_bool(req.access_deleted, options, "access_deleted");
1671
+ cb_extract_option_bool(req.create_as_deleted, options, "create_as_deleted");
1672
+ cb_extract_cas(req, options);
1673
+ cb_extract_store_semantics(req, options);
1396
1674
 
1397
1675
  static VALUE xattr_property = rb_id2sym(rb_intern("xattr"));
1398
1676
  static VALUE create_path_property = rb_id2sym(rb_intern("create_path"));
@@ -1402,130 +1680,147 @@ cb_Backend_document_mutate_in(VALUE self,
1402
1680
  static VALUE param_property = rb_id2sym(rb_intern("param"));
1403
1681
 
1404
1682
  couchbase::mutate_in_specs cxx_specs;
1405
- auto entries_size = static_cast<std::size_t>(RARRAY_LEN(specs));
1406
- for (std::size_t i = 0; i < entries_size; ++i) {
1407
- VALUE entry = rb_ary_entry(specs, static_cast<long>(i));
1408
- cb_check_type(entry, T_HASH);
1409
- bool xattr = RTEST(rb_hash_aref(entry, xattr_property));
1410
- bool create_path = RTEST(rb_hash_aref(entry, create_path_property));
1411
- bool expand_macros = RTEST(rb_hash_aref(entry, expand_macros_property));
1412
- VALUE path = rb_hash_aref(entry, path_property);
1413
- cb_check_type(path, T_STRING);
1414
- VALUE operation = rb_hash_aref(entry, opcode_property);
1415
- cb_check_type(operation, T_SYMBOL);
1416
- VALUE param = rb_hash_aref(entry, param_property);
1417
- if (ID operation_id = rb_sym2id(operation); operation_id == rb_intern("dict_add")) {
1418
- cb_check_type(param, T_STRING);
1419
- cxx_specs.push_back(couchbase::mutate_in_specs::insert_raw(
1420
- cb_string_new(path), cb_binary_new(param), expand_macros)
1421
- .xattr(xattr)
1422
- .create_path(create_path));
1423
- } else if (operation_id == rb_intern("dict_upsert")) {
1424
- cb_check_type(param, T_STRING);
1425
-
1426
- cxx_specs.push_back(couchbase::mutate_in_specs::upsert_raw(
1427
- cb_string_new(path), cb_binary_new(param), expand_macros)
1428
- .xattr(xattr)
1429
- .create_path(create_path));
1430
- } else if (operation_id == rb_intern("remove")) {
1431
- cxx_specs.push_back(couchbase::mutate_in_specs::remove(cb_string_new(path)).xattr(xattr));
1432
- } else if (operation_id == rb_intern("replace")) {
1433
- cb_check_type(param, T_STRING);
1434
- cxx_specs.push_back(couchbase::mutate_in_specs::replace_raw(
1435
- cb_string_new(path), cb_binary_new(param), expand_macros)
1436
- .xattr(xattr));
1437
- } else if (operation_id == rb_intern("array_push_last")) {
1438
- cb_check_type(param, T_STRING);
1439
- cxx_specs.push_back(
1440
- couchbase::mutate_in_specs::array_append_raw(cb_string_new(path), cb_binary_new(param))
1441
- .xattr(xattr)
1442
- .create_path(create_path));
1443
- } else if (operation_id == rb_intern("array_push_first")) {
1444
- cb_check_type(param, T_STRING);
1445
- cxx_specs.push_back(
1446
- couchbase::mutate_in_specs::array_prepend_raw(cb_string_new(path), cb_binary_new(param))
1447
- .xattr(xattr)
1448
- .create_path(create_path));
1449
- } else if (operation_id == rb_intern("array_insert")) {
1450
- cb_check_type(param, T_STRING);
1451
- cxx_specs.push_back(
1452
- couchbase::mutate_in_specs::array_insert_raw(cb_string_new(path), cb_binary_new(param))
1453
- .xattr(xattr)
1454
- .create_path(create_path));
1455
- } else if (operation_id == rb_intern("array_add_unique")) {
1456
- cb_check_type(param, T_STRING);
1457
- cxx_specs.push_back(couchbase::mutate_in_specs::array_add_unique_raw(
1458
- cb_string_new(path), cb_binary_new(param), expand_macros)
1459
- .xattr(xattr)
1460
- .create_path(create_path));
1461
- } else if (operation_id == rb_intern("counter")) {
1462
- if (TYPE(param) == T_FIXNUM || TYPE(param) == T_BIGNUM) {
1463
- if (std::int64_t num = NUM2LL(param); num < 0) {
1464
- cxx_specs.push_back(couchbase::mutate_in_specs::decrement(cb_string_new(path), -1 * num)
1465
- .xattr(xattr)
1466
- .create_path(create_path));
1683
+ {
1684
+ auto entries_size = static_cast<std::size_t>(RARRAY_LEN(specs));
1685
+ for (std::size_t i = 0; i < entries_size; ++i) {
1686
+ VALUE entry = rb_ary_entry(specs, static_cast<long>(i));
1687
+ cb_check_type(entry, T_HASH);
1688
+ bool xattr = RTEST(rb_hash_aref(entry, xattr_property));
1689
+ bool create_path = RTEST(rb_hash_aref(entry, create_path_property));
1690
+ bool expand_macros = RTEST(rb_hash_aref(entry, expand_macros_property));
1691
+ VALUE path = rb_hash_aref(entry, path_property);
1692
+ cb_check_type(path, T_STRING);
1693
+ VALUE operation = rb_hash_aref(entry, opcode_property);
1694
+ cb_check_type(operation, T_SYMBOL);
1695
+ VALUE param = rb_hash_aref(entry, param_property);
1696
+ if (ID operation_id = rb_sym2id(operation); operation_id == rb_intern("dict_add")) {
1697
+ cb_check_type(param, T_STRING);
1698
+ cxx_specs.push_back(couchbase::mutate_in_specs::insert_raw(
1699
+ cb_string_new(path), cb_binary_new(param), expand_macros)
1700
+ .xattr(xattr)
1701
+ .create_path(create_path));
1702
+ } else if (operation_id == rb_intern("dict_upsert")) {
1703
+ cb_check_type(param, T_STRING);
1704
+
1705
+ cxx_specs.push_back(couchbase::mutate_in_specs::upsert_raw(
1706
+ cb_string_new(path), cb_binary_new(param), expand_macros)
1707
+ .xattr(xattr)
1708
+ .create_path(create_path));
1709
+ } else if (operation_id == rb_intern("remove")) {
1710
+ cxx_specs.push_back(couchbase::mutate_in_specs::remove(cb_string_new(path)).xattr(xattr));
1711
+ } else if (operation_id == rb_intern("replace")) {
1712
+ cb_check_type(param, T_STRING);
1713
+ cxx_specs.push_back(couchbase::mutate_in_specs::replace_raw(
1714
+ cb_string_new(path), cb_binary_new(param), expand_macros)
1715
+ .xattr(xattr));
1716
+ } else if (operation_id == rb_intern("array_push_last")) {
1717
+ cb_check_type(param, T_STRING);
1718
+ cxx_specs.push_back(
1719
+ couchbase::mutate_in_specs::array_append_raw(cb_string_new(path), cb_binary_new(param))
1720
+ .xattr(xattr)
1721
+ .create_path(create_path));
1722
+ } else if (operation_id == rb_intern("array_push_first")) {
1723
+ cb_check_type(param, T_STRING);
1724
+ cxx_specs.push_back(
1725
+ couchbase::mutate_in_specs::array_prepend_raw(cb_string_new(path), cb_binary_new(param))
1726
+ .xattr(xattr)
1727
+ .create_path(create_path));
1728
+ } else if (operation_id == rb_intern("array_insert")) {
1729
+ cb_check_type(param, T_STRING);
1730
+ cxx_specs.push_back(
1731
+ couchbase::mutate_in_specs::array_insert_raw(cb_string_new(path), cb_binary_new(param))
1732
+ .xattr(xattr)
1733
+ .create_path(create_path));
1734
+ } else if (operation_id == rb_intern("array_add_unique")) {
1735
+ cb_check_type(param, T_STRING);
1736
+ cxx_specs.push_back(couchbase::mutate_in_specs::array_add_unique_raw(
1737
+ cb_string_new(path), cb_binary_new(param), expand_macros)
1738
+ .xattr(xattr)
1739
+ .create_path(create_path));
1740
+ } else if (operation_id == rb_intern("counter")) {
1741
+ if (TYPE(param) == T_FIXNUM || TYPE(param) == T_BIGNUM) {
1742
+ if (std::int64_t num = NUM2LL(param); num < 0) {
1743
+ cxx_specs.push_back(
1744
+ couchbase::mutate_in_specs::decrement(cb_string_new(path), -1 * num)
1745
+ .xattr(xattr)
1746
+ .create_path(create_path));
1747
+ } else {
1748
+ cxx_specs.push_back(couchbase::mutate_in_specs::increment(cb_string_new(path), num)
1749
+ .xattr(xattr)
1750
+ .create_path(create_path));
1751
+ }
1467
1752
  } else {
1468
- cxx_specs.push_back(couchbase::mutate_in_specs::increment(cb_string_new(path), num)
1469
- .xattr(xattr)
1470
- .create_path(create_path));
1753
+ throw ruby_exception(
1754
+ exc_invalid_argument(),
1755
+ rb_sprintf("subdocument counter operation expects number, but given: %+" PRIsVALUE,
1756
+ param));
1471
1757
  }
1758
+ } else if (operation_id == rb_intern("set_doc")) {
1759
+ cb_check_type(param, T_STRING);
1760
+ cxx_specs.push_back(
1761
+ couchbase::mutate_in_specs::replace_raw("", cb_binary_new(param), expand_macros)
1762
+ .xattr(xattr));
1763
+ } else if (operation_id == rb_intern("remove_doc")) {
1764
+ cxx_specs.push_back(couchbase::mutate_in_specs::remove("").xattr(xattr));
1472
1765
  } else {
1473
1766
  throw ruby_exception(
1474
1767
  exc_invalid_argument(),
1475
- rb_sprintf("subdocument counter operation expects number, but given: %+" PRIsVALUE,
1476
- param));
1768
+ rb_sprintf("unsupported operation for subdocument mutation: %+" PRIsVALUE, operation));
1477
1769
  }
1478
- } else if (operation_id == rb_intern("set_doc")) {
1479
- cb_check_type(param, T_STRING);
1480
- cxx_specs.push_back(
1481
- couchbase::mutate_in_specs::replace_raw("", cb_binary_new(param), expand_macros)
1482
- .xattr(xattr));
1483
- } else if (operation_id == rb_intern("remove_doc")) {
1484
- cxx_specs.push_back(couchbase::mutate_in_specs::remove("").xattr(xattr));
1485
- } else {
1486
- throw ruby_exception(
1487
- exc_invalid_argument(),
1488
- rb_sprintf("unsupported operation for subdocument mutation: %+" PRIsVALUE, operation));
1489
1770
  }
1490
1771
  }
1772
+ req.specs = cxx_specs.specs();
1491
1773
 
1492
- auto f = cluster.bucket(cb_string_new(bucket))
1493
- .scope(cb_string_new(scope))
1494
- .collection(cb_string_new(collection))
1495
- .mutate_in(cb_string_new(id), cxx_specs, opts);
1774
+ auto parent_span = cb_create_parent_span(req, self);
1496
1775
 
1497
- auto [ctx, resp] = cb_wait_for_future(f);
1498
- if (ctx.ec()) {
1499
- cb_throw_error(ctx, "unable to mutate_in");
1776
+ std::promise<core::operations::mutate_in_response> promise;
1777
+ auto f = promise.get_future();
1778
+
1779
+ if (const auto legacy_durability = extract_legacy_durability_constraints(options);
1780
+ legacy_durability.has_value()) {
1781
+ cluster.execute(
1782
+ core::operations::mutate_in_request_with_legacy_durability{
1783
+ std::move(req),
1784
+ legacy_durability.value().first,
1785
+ legacy_durability.value().second,
1786
+ },
1787
+ [promise = std::move(promise)](auto&& resp) mutable {
1788
+ promise.set_value(std::forward<decltype(resp)>(resp));
1789
+ });
1790
+ } else {
1791
+ cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
1792
+ promise.set_value(std::forward<decltype(resp)>(resp));
1793
+ });
1794
+ }
1795
+
1796
+ auto resp = cb_wait_for_future(f);
1797
+ cb_add_core_spans(observability_handler, std::move(parent_span), resp.ctx.retry_attempts());
1798
+ if (resp.ctx.ec()) {
1799
+ cb_throw_error(resp.ctx, "unable to mutate_in");
1500
1800
  }
1501
1801
 
1502
1802
  static VALUE deleted_property = rb_id2sym(rb_intern("deleted"));
1503
1803
  static VALUE fields_property = rb_id2sym(rb_intern("fields"));
1504
1804
  static VALUE index_property = rb_id2sym(rb_intern("index"));
1505
- static VALUE cas_property = rb_id2sym(rb_intern("cas"));
1506
1805
  static VALUE value_property = rb_id2sym(rb_intern("value"));
1507
1806
 
1508
- VALUE res = to_mutation_result_value(resp);
1509
- rb_hash_aset(res, deleted_property, resp.is_deleted() ? Qtrue : Qfalse);
1510
- if (!ctx.ec()) {
1511
- rb_hash_aset(res, cas_property, cb_cas_to_num(resp.cas()));
1512
-
1513
- VALUE fields = rb_ary_new_capa(static_cast<long>(entries_size));
1514
- rb_hash_aset(res, fields_property, fields);
1515
- for (std::size_t i = 0; i < entries_size; ++i) {
1516
- VALUE entry = rb_hash_new();
1517
- rb_hash_aset(entry, index_property, ULL2NUM(i));
1518
- rb_hash_aset(entry,
1519
- path_property,
1520
- rb_hash_aref(rb_ary_entry(specs, static_cast<long>(i)), path_property));
1521
- if (resp.has_value(i)) {
1522
- auto value = resp.content_as<tao::json::value>(i);
1523
- rb_hash_aset(entry, value_property, cb_str_new(core::utils::json::generate(value)));
1524
- }
1525
- rb_ary_store(fields, static_cast<long>(i), entry);
1807
+ VALUE res = cb_create_mutation_result(resp);
1808
+ rb_hash_aset(res, deleted_property, resp.deleted ? Qtrue : Qfalse);
1809
+ VALUE fields = rb_ary_new_capa(static_cast<long>(resp.fields.size()));
1810
+ rb_hash_aset(res, fields_property, fields);
1811
+ for (std::size_t i = 0; i < resp.fields.size(); ++i) {
1812
+ VALUE entry = rb_hash_new();
1813
+ rb_hash_aset(entry, index_property, ULL2NUM(i));
1814
+ rb_hash_aset(entry,
1815
+ path_property,
1816
+ rb_hash_aref(rb_ary_entry(specs, static_cast<long>(i)), path_property));
1817
+ if (!resp.fields.at(i).value.empty()) {
1818
+ rb_hash_aset(entry, value_property, cb_str_new(resp.fields.at(i).value));
1526
1819
  }
1820
+ rb_ary_store(fields, static_cast<long>(i), entry);
1527
1821
  }
1528
1822
  return res;
1823
+
1529
1824
  } catch (const std::system_error& se) {
1530
1825
  rb_exc_raise(cb_map_error_code(
1531
1826
  se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
@@ -1540,28 +1835,28 @@ cb_Backend_document_mutate_in(VALUE self,
1540
1835
  void
1541
1836
  init_crud(VALUE cBackend)
1542
1837
  {
1543
- rb_define_method(cBackend, "document_get", cb_Backend_document_get, 5);
1544
- rb_define_method(cBackend, "document_get_any_replica", cb_Backend_document_get_any_replica, 5);
1545
- rb_define_method(cBackend, "document_get_all_replicas", cb_Backend_document_get_all_replicas, 5);
1546
- rb_define_method(cBackend, "document_get_projected", cb_Backend_document_get_projected, 5);
1547
- rb_define_method(cBackend, "document_get_and_lock", cb_Backend_document_get_and_lock, 6);
1548
- rb_define_method(cBackend, "document_get_and_touch", cb_Backend_document_get_and_touch, 6);
1549
- rb_define_method(cBackend, "document_insert", cb_Backend_document_insert, 7);
1550
- rb_define_method(cBackend, "document_replace", cb_Backend_document_replace, 7);
1551
- rb_define_method(cBackend, "document_upsert", cb_Backend_document_upsert, 7);
1552
- rb_define_method(cBackend, "document_append", cb_Backend_document_append, 6);
1553
- rb_define_method(cBackend, "document_prepend", cb_Backend_document_prepend, 6);
1554
- rb_define_method(cBackend, "document_remove", cb_Backend_document_remove, 5);
1555
- rb_define_method(cBackend, "document_lookup_in", cb_Backend_document_lookup_in, 6);
1838
+ rb_define_method(cBackend, "document_get", cb_Backend_document_get, 6);
1839
+ rb_define_method(cBackend, "document_get_any_replica", cb_Backend_document_get_any_replica, 6);
1840
+ rb_define_method(cBackend, "document_get_all_replicas", cb_Backend_document_get_all_replicas, 6);
1841
+ rb_define_method(cBackend, "document_get_projected", cb_Backend_document_get_projected, 6);
1842
+ rb_define_method(cBackend, "document_get_and_lock", cb_Backend_document_get_and_lock, 7);
1843
+ rb_define_method(cBackend, "document_get_and_touch", cb_Backend_document_get_and_touch, 7);
1844
+ rb_define_method(cBackend, "document_insert", cb_Backend_document_insert, 8);
1845
+ rb_define_method(cBackend, "document_replace", cb_Backend_document_replace, 8);
1846
+ rb_define_method(cBackend, "document_upsert", cb_Backend_document_upsert, 8);
1847
+ rb_define_method(cBackend, "document_append", cb_Backend_document_append, 7);
1848
+ rb_define_method(cBackend, "document_prepend", cb_Backend_document_prepend, 7);
1849
+ rb_define_method(cBackend, "document_remove", cb_Backend_document_remove, 6);
1850
+ rb_define_method(cBackend, "document_lookup_in", cb_Backend_document_lookup_in, 7);
1556
1851
  rb_define_method(
1557
- cBackend, "document_lookup_in_any_replica", cb_Backend_document_lookup_in_any_replica, 6);
1852
+ cBackend, "document_lookup_in_any_replica", cb_Backend_document_lookup_in_any_replica, 7);
1558
1853
  rb_define_method(
1559
- cBackend, "document_lookup_in_all_replicas", cb_Backend_document_lookup_in_all_replicas, 6);
1560
- rb_define_method(cBackend, "document_mutate_in", cb_Backend_document_mutate_in, 6);
1561
- rb_define_method(cBackend, "document_touch", cb_Backend_document_touch, 6);
1562
- rb_define_method(cBackend, "document_exists", cb_Backend_document_exists, 5);
1563
- rb_define_method(cBackend, "document_unlock", cb_Backend_document_unlock, 6);
1564
- rb_define_method(cBackend, "document_increment", cb_Backend_document_increment, 5);
1565
- rb_define_method(cBackend, "document_decrement", cb_Backend_document_decrement, 5);
1854
+ cBackend, "document_lookup_in_all_replicas", cb_Backend_document_lookup_in_all_replicas, 7);
1855
+ rb_define_method(cBackend, "document_mutate_in", cb_Backend_document_mutate_in, 7);
1856
+ rb_define_method(cBackend, "document_touch", cb_Backend_document_touch, 7);
1857
+ rb_define_method(cBackend, "document_exists", cb_Backend_document_exists, 6);
1858
+ rb_define_method(cBackend, "document_unlock", cb_Backend_document_unlock, 7);
1859
+ rb_define_method(cBackend, "document_increment", cb_Backend_document_increment, 6);
1860
+ rb_define_method(cBackend, "document_decrement", cb_Backend_document_decrement, 6);
1566
1861
  }
1567
1862
  } // namespace couchbase::ruby